mirror of
https://github.com/lzh-1625/go_process_manager.git
synced 2025-09-26 20:11:20 +08:00
Compare commits
39 Commits
f1b27e85f4
...
3fb8cd4dad
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3fb8cd4dad | ||
![]() |
274a4d93df | ||
![]() |
c383e1737f | ||
![]() |
2a40d560d4 | ||
![]() |
d968ce2a3e | ||
![]() |
51ff529a88 | ||
![]() |
ed237e1ddb | ||
![]() |
f980e79e02 | ||
![]() |
cb15544ea3 | ||
![]() |
c69056d1b7 | ||
![]() |
39b199eac6 | ||
![]() |
4343dfaa31 | ||
![]() |
0e09afe962 | ||
![]() |
5356eb4199 | ||
![]() |
b4c7ab9f2c | ||
![]() |
b307808b70 | ||
![]() |
6aac70de9a | ||
![]() |
b598b590e7 | ||
![]() |
c3262afe13 | ||
![]() |
9823ca0cef | ||
![]() |
b4ad29e9cf | ||
![]() |
dca76fd5d3 | ||
![]() |
ba36662759 | ||
![]() |
3f5deab95a | ||
![]() |
a9657d35b8 | ||
![]() |
0b4133e510 | ||
![]() |
c54e81321e | ||
![]() |
a1ab697848 | ||
![]() |
c154abe568 | ||
![]() |
39dc4f13e4 | ||
![]() |
8aa700407c | ||
![]() |
726c5f861d | ||
![]() |
0db3e60460 | ||
![]() |
ec9f1fefdb | ||
![]() |
a05d9c3f03 | ||
![]() |
cf184745ed | ||
![]() |
be73582e28 | ||
![]() |
0fae7cac25 | ||
![]() |
efcf8d9ca6 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -5,4 +5,5 @@ data.db
|
||||
config.yaml
|
||||
ltest
|
||||
gtest
|
||||
mtest
|
||||
mtest
|
||||
log.bleve
|
@@ -25,7 +25,6 @@ func init() {
|
||||
initArgs()
|
||||
initLogHandle()
|
||||
initLog()
|
||||
initEs()
|
||||
initLogHanler()
|
||||
initWaitCond()
|
||||
initProcess()
|
||||
@@ -82,10 +81,6 @@ func initLog() {
|
||||
logger.InitLog()
|
||||
}
|
||||
|
||||
func initEs() {
|
||||
logic.EsLogic.InitEs()
|
||||
}
|
||||
|
||||
func initProcess() {
|
||||
logic.ProcessCtlLogic.ProcessInit()
|
||||
}
|
||||
@@ -128,6 +123,7 @@ func initListenKillSignal() {
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sigs
|
||||
logger.Logger.Info("进程正在退出,等待全部进程停止")
|
||||
logic.ProcessCtlLogic.KillAllProcess()
|
||||
log.Print("已停止所有进程")
|
||||
os.Exit(0)
|
||||
|
@@ -1,4 +1,5 @@
|
||||
SET CGO_ENABLED=0
|
||||
SET GOOS=linux
|
||||
SET GOARCH=amd64
|
||||
go build -ldflags="-s -w" -o go_process_manager cmd/go_process_manager/main.go
|
||||
SET CGO_ENABLED=0
|
||||
SET GOOS=linux
|
||||
SET GOARCH=amd64
|
||||
@REM go build -ldflags="-s -w" -tags="slim" -o go_process_manager -trimpath cmd/go_process_manager/main.go
|
||||
go build -ldflags="-s -w" -o go_process_manager -trimpath cmd/go_process_manager/main.go
|
5
build.sh
Normal file
5
build.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
export CGO_ENABLED=0
|
||||
export GOOS=linux
|
||||
export GOARCH=amd64
|
||||
# go build -ldflags="-s -w" -tags="slim" -o go_process_manager -trimpath cmd/go_process_manager/main.go
|
||||
go build -ldflags="-s -w" -o go_process_manager -trimpath cmd/go_process_manager/main.go
|
@@ -7,7 +7,34 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var startTitle = `
|
||||
----------------------------------------------------------------------------
|
||||
_____ _____ _____
|
||||
/\ \ /\ \ /\ \
|
||||
/::\ \ /::\ \ /::\____\
|
||||
/::::\ \ /::::\ \ /::::| |
|
||||
/::::::\ \ /::::::\ \ /:::::| |
|
||||
/:::/\:::\ \ /:::/\:::\ \ /::::::| |
|
||||
/:::/ \:::\ \ /:::/__\:::\ \ /:::/|::| |
|
||||
/:::/ \:::\ \ /::::\ \:::\ \ /:::/ |::| |
|
||||
/:::/ / \:::\ \ /::::::\ \:::\ \ /:::/ |::|___|______
|
||||
/:::/ / \:::\ ___\ /:::/\:::\ \:::\____\ /:::/ |::::::::\ \
|
||||
/:::/____/ ___\:::| |/:::/ \:::\ \:::| |/:::/ |:::::::::\____\
|
||||
\:::\ \ /\ /:::|____|\::/ \:::\ /:::|____|\::/ / ~~~~~/:::/ /
|
||||
\:::\ /::\ \::/ / \/_____/\:::\/:::/ / \/____/ /:::/ /
|
||||
\:::\ \:::\ \/____/ \::::::/ / /:::/ /
|
||||
\:::\ \:::\____\ \::::/ / /:::/ /
|
||||
\:::\ /:::/ / \::/____/ /:::/ /
|
||||
\:::\/:::/ / ~~ /:::/ /
|
||||
\::::::/ / /:::/ /
|
||||
\::::/ / /:::/ /
|
||||
\::/____/ \::/ /
|
||||
\/____/
|
||||
----------------------------------------------------------------------------
|
||||
`
|
||||
|
||||
func main() {
|
||||
print(startTitle)
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
route.Route()
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ var CF = new(configuration)
|
||||
type configuration struct {
|
||||
LogLevel string `default:"debug" describe:"日志等级[debug,info]"`
|
||||
Listen string `default:":8797" describe:"监听端口"`
|
||||
EsEnable bool `default:"false" describe:"启用Elasticsearch"`
|
||||
StorgeType string `default:"sqlite" describe:"存储引擎[sqlite、es、bleve]"`
|
||||
EsUrl string `default:"" describe:"Elasticsearch url"`
|
||||
EsIndex string `default:"server_log_v1" describe:"Elasticsearch index"`
|
||||
EsUsername string `default:"" describe:"Elasticsearch用户名"`
|
||||
|
38
go.mod
38
go.mod
@@ -6,6 +6,35 @@ require (
|
||||
github.com/containerd/cgroups/v3 v3.0.4
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/opencontainers/runtime-spec v1.2.0
|
||||
github.com/vcaesar/gse-bleve v0.40.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.22.0 // indirect
|
||||
github.com/blevesearch/bleve_index_api v1.2.8 // indirect
|
||||
github.com/blevesearch/geo v0.2.3 // indirect
|
||||
github.com/blevesearch/go-faiss v1.0.25 // indirect
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.3.10 // indirect
|
||||
github.com/blevesearch/segment v0.9.1 // indirect
|
||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
|
||||
github.com/blevesearch/vellum v1.1.0 // indirect
|
||||
github.com/blevesearch/zapx/v11 v11.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v12 v12.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v13 v13.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v14 v14.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v15 v15.4.2 // indirect
|
||||
github.com/blevesearch/zapx/v16 v16.2.4 // indirect
|
||||
github.com/go-ego/gse v0.70.2 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/mschoch/smat v0.2.0 // indirect
|
||||
github.com/vcaesar/cedar v0.20.1 // indirect
|
||||
go.etcd.io/bbolt v1.4.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -48,7 +77,7 @@ require (
|
||||
github.com/gdamore/encoding v1.0.0 // indirect
|
||||
github.com/gdamore/tcell/v2 v2.7.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
@@ -86,23 +115,24 @@ require (
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
google.golang.org/protobuf v1.35.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/blevesearch/bleve/v2 v2.5.2
|
||||
github.com/creack/pty v1.1.21
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang-jwt/jwt/v5 v5.2.3
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/olivere/elastic/v7 v7.0.32
|
||||
github.com/panjf2000/ants/v2 v2.10.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/runletapp/go-console v0.0.0-20211204140000-27323a28410a
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/timandy/routine v1.1.4
|
||||
go.uber.org/zap v1.26.0
|
||||
golang.org/x/net v0.31.0 // indirect
|
||||
gorm.io/gen v0.3.27
|
||||
|
86
go.sum
86
go.sum
@@ -1,5 +1,46 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/RoaringBitmap/roaring/v2 v2.4.5 h1:uGrrMreGjvAtTBobc0g5IrW1D5ldxDQYe2JW2gggRdg=
|
||||
github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0=
|
||||
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4=
|
||||
github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||
github.com/blevesearch/bleve/v2 v2.5.2 h1:Ab0r0MODV2C5A6BEL87GqLBySqp/s9xFgceCju6BQk8=
|
||||
github.com/blevesearch/bleve/v2 v2.5.2/go.mod h1:5Dj6dUQxZM6aqYT3eutTD/GpWKGFSsV8f7LDidFbwXo=
|
||||
github.com/blevesearch/bleve_index_api v1.2.8 h1:Y98Pu5/MdlkRyLM0qDHostYo7i+Vv1cDNhqTeR4Sy6Y=
|
||||
github.com/blevesearch/bleve_index_api v1.2.8/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0=
|
||||
github.com/blevesearch/geo v0.2.3 h1:K9/vbGI9ehlXdxjxDRJtoAMt7zGAsMIzc6n8zWcwnhg=
|
||||
github.com/blevesearch/geo v0.2.3/go.mod h1:K56Q33AzXt2YExVHGObtmRSFYZKYGv0JEN5mdacJJR8=
|
||||
github.com/blevesearch/go-faiss v1.0.25 h1:lel1rkOUGbT1CJ0YgzKwC7k+XH0XVBHnCVWahdCXk4U=
|
||||
github.com/blevesearch/go-faiss v1.0.25/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
|
||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.3.10 h1:Yqk0XD1mE0fDZAJXTjawJ8If/85JxnLd8v5vG/jWE/s=
|
||||
github.com/blevesearch/scorch_segment_api/v2 v2.3.10/go.mod h1:Z3e6ChN3qyN35yaQpl00MfI5s8AxUJbpTR/DL8QOQ+8=
|
||||
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
|
||||
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
|
||||
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
|
||||
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A=
|
||||
github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ=
|
||||
github.com/blevesearch/vellum v1.1.0 h1:CinkGyIsgVlYf8Y2LUQHvdelgXr6PYuvoDIajq6yR9w=
|
||||
github.com/blevesearch/vellum v1.1.0/go.mod h1:QgwWryE8ThtNPxtgWJof5ndPfx0/YMBh+W2weHKPw8Y=
|
||||
github.com/blevesearch/zapx/v11 v11.4.2 h1:l46SV+b0gFN+Rw3wUI1YdMWdSAVhskYuvxlcgpQFljs=
|
||||
github.com/blevesearch/zapx/v11 v11.4.2/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc=
|
||||
github.com/blevesearch/zapx/v12 v12.4.2 h1:fzRbhllQmEMUuAQ7zBuMvKRlcPA5ESTgWlDEoB9uQNE=
|
||||
github.com/blevesearch/zapx/v12 v12.4.2/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58=
|
||||
github.com/blevesearch/zapx/v13 v13.4.2 h1:46PIZCO/ZuKZYgxI8Y7lOJqX3Irkc3N8W82QTK3MVks=
|
||||
github.com/blevesearch/zapx/v13 v13.4.2/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk=
|
||||
github.com/blevesearch/zapx/v14 v14.4.2 h1:2SGHakVKd+TrtEqpfeq8X+So5PShQ5nW6GNxT7fWYz0=
|
||||
github.com/blevesearch/zapx/v14 v14.4.2/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8=
|
||||
github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFxEsp31k=
|
||||
github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw=
|
||||
github.com/blevesearch/zapx/v16 v16.2.4 h1:tGgfvleXTAkwsD5mEzgM3zCS/7pgocTCnO1oyAUjlww=
|
||||
github.com/blevesearch/zapx/v16 v16.2.4/go.mod h1:Rti/REtuuMmzwsI8/C/qIzRaEoSK/wiFYw5e5ctUKKs=
|
||||
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
|
||||
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
|
||||
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
|
||||
@@ -45,6 +86,8 @@ github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9g
|
||||
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/go-ego/gse v0.70.2 h1:y2UMOHJMtI+0b2GjxTtQfKON5DMmlyX1hOQHTo8UVVs=
|
||||
github.com/go-ego/gse v0.70.2/go.mod h1:kesekpZfcFQ/kwd9b27VZHUOH5dQUjaaQUZ4OGt4Hj4=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
@@ -66,19 +109,27 @@ github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MG
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0=
|
||||
github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
|
||||
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
|
||||
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/iamacarpet/go-winpty v1.0.2 h1:jwPVTYrjAHZx6Mcm6K5i9G4opMp5TblEHH5EQCl/Gzw=
|
||||
@@ -139,6 +190,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
|
||||
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
|
||||
github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
|
||||
github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k=
|
||||
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
|
||||
@@ -181,10 +234,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/timandy/routine v1.1.4 h1:L9eAli/ROJcW6LhmwZcusYQcdAqxAXGOQhEXLQSNWOA=
|
||||
github.com/timandy/routine v1.1.4/go.mod h1:siBcl8iIsGmhLCajRGRcy7Y7FVcicNXkr97JODdt9fc=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4=
|
||||
github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0=
|
||||
github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4=
|
||||
@@ -193,9 +245,17 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/vcaesar/cedar v0.20.1 h1:cDOmYWdprO7ZW8cngJrDi8Zivnscj9dA/y8Y+2SB1P0=
|
||||
github.com/vcaesar/cedar v0.20.1/go.mod h1:iMDweyuW76RvSrCkQeZeQk4iCbshiPzcCvcGCtpM7iI=
|
||||
github.com/vcaesar/gse-bleve v0.40.0 h1:Qnv/9v8uyqNkFHxdK4VLN4EwZ0WLxudSgBcUzd2uxQs=
|
||||
github.com/vcaesar/gse-bleve v0.40.0/go.mod h1:ORZ+jIAEIQeC6PEai24UJr8wisHAWrSukKXTPVVPXzc=
|
||||
github.com/vcaesar/tt v0.20.0 h1:9t2Ycb9RNHcP0WgQgIaRKJBB+FrRdejuaL6uWIHuoBA=
|
||||
github.com/vcaesar/tt v0.20.0/go.mod h1:GHPxQYhn+7OgKakRusH7KJ0M5MhywoeLb8Fcffs/Gtg=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
|
||||
go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
|
||||
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
|
||||
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
@@ -237,8 +297,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
@@ -259,12 +319,16 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o=
|
||||
golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
|
||||
|
@@ -1,42 +1,14 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func rOk(ctx *gin.Context, message string, data any) {
|
||||
jsonData := map[string]any{
|
||||
"code": 0,
|
||||
"msg": message,
|
||||
}
|
||||
if data != nil {
|
||||
jsonData["data"] = data
|
||||
}
|
||||
ctx.JSON(http.StatusOK, jsonData)
|
||||
}
|
||||
|
||||
func errCheck(ctx *gin.Context, isErr bool, errData any) {
|
||||
if !isErr {
|
||||
return
|
||||
}
|
||||
if err, ok := errData.(error); ok {
|
||||
log.Logger.Warn(errData)
|
||||
ctx.Set(constants.CTXFLG_ERR, err.Error())
|
||||
}
|
||||
if err, ok := errData.(string); ok {
|
||||
ctx.Set(constants.CTXFLG_ERR, err)
|
||||
}
|
||||
panic(0)
|
||||
}
|
||||
|
||||
func getRole(ctx *gin.Context) constants.Role {
|
||||
if v, ok := ctx.Get(constants.CTXFLG_ROLE); ok {
|
||||
return v.(constants.Role)
|
||||
@@ -56,20 +28,37 @@ func hasOprPermission(ctx *gin.Context, uuid int, op constants.OprPermission) bo
|
||||
return isAdmin(ctx) || reflect.ValueOf(repository.PermissionRepository.GetPermission(getUserName(ctx), uuid)).FieldByName(string(op)).Bool()
|
||||
}
|
||||
|
||||
func getQueryInt(ctx *gin.Context, query string) (i int) {
|
||||
i, err := strconv.Atoi(ctx.Query(query))
|
||||
errCheck(ctx, err != nil, "Invalid parameters!")
|
||||
return
|
||||
type Response struct {
|
||||
StatusCode int
|
||||
Code int
|
||||
Data any
|
||||
Msg string
|
||||
}
|
||||
|
||||
func getQueryString(ctx *gin.Context, query string) (s string) {
|
||||
s = ctx.Query(query)
|
||||
errCheck(ctx, s == "", "Invalid parameters!")
|
||||
return
|
||||
func NewResponse() *Response {
|
||||
return &Response{StatusCode: 200}
|
||||
}
|
||||
|
||||
func bind[T any](ctx *gin.Context) T {
|
||||
var data T
|
||||
errCheck(ctx, ctx.ShouldBind(&data) != nil, "Invalid parameters!")
|
||||
return data
|
||||
func (r *Response) SetStatusCode(code int) *Response {
|
||||
r.StatusCode = code
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Response) SetDate(data any) *Response {
|
||||
r.Data = data
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Response) SetCode(code int) *Response {
|
||||
r.Code = code
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Response) SetMessage(msg any) *Response {
|
||||
if str, ok := msg.(string); ok {
|
||||
r.Msg = str
|
||||
} else if err, ok := msg.(error); ok {
|
||||
r.Msg = err.Error()
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/logic"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -10,18 +11,19 @@ type configApi struct{}
|
||||
|
||||
var ConfigApi = new(configApi)
|
||||
|
||||
func (c *configApi) GetSystemConfiguration(ctx *gin.Context) {
|
||||
result := logic.ConfigLogic.GetSystemConfiguration()
|
||||
rOk(ctx, "Operation successful!", result)
|
||||
func (c *configApi) GetSystemConfiguration(ctx *gin.Context, _ any) []model.SystemConfigurationVo {
|
||||
return logic.ConfigLogic.GetSystemConfiguration()
|
||||
}
|
||||
|
||||
func (c *configApi) SetSystemConfiguration(ctx *gin.Context) {
|
||||
req := bind[map[string]string](ctx)
|
||||
errCheck(ctx, logic.ConfigLogic.SetSystemConfiguration(req) != nil, "Set config fail!")
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (c *configApi) SetSystemConfiguration(ctx *gin.Context, _ any) (err error) {
|
||||
req := map[string]string{}
|
||||
if err = ctx.BindJSON(&req); err != nil {
|
||||
return err
|
||||
}
|
||||
err = logic.ConfigLogic.SetSystemConfiguration(req)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *configApi) EsConfigReload(ctx *gin.Context) {
|
||||
errCheck(ctx, !logic.EsLogic.InitEs(), "Incorrect username or password!")
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (c *configApi) LogConfigReload(ctx *gin.Context, _ any) (err error) {
|
||||
return logic.LogLogicImpl.Init()
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/logic"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -10,24 +11,25 @@ type file struct{}
|
||||
|
||||
var FileApi = new(file)
|
||||
|
||||
func (f *file) FilePathHandler(ctx *gin.Context) {
|
||||
path := getQueryString(ctx, "path")
|
||||
rOk(ctx, "Operation successful!", logic.FileLogic.GetFileAndDirByPath(path))
|
||||
func (f *file) FilePathHandler(ctx *gin.Context, req model.FilePathHandlerReq) []model.FileStruct {
|
||||
return logic.FileLogic.GetFileAndDirByPath(req.Path)
|
||||
}
|
||||
|
||||
func (f *file) FileWriteHandler(ctx *gin.Context) {
|
||||
func (f *file) FileWriteHandler(ctx *gin.Context, _ any) (err error) {
|
||||
path := ctx.PostForm("filePath")
|
||||
fi, err := ctx.FormFile("data")
|
||||
errCheck(ctx, err != nil, "Read file data failed!")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fiReader, _ := fi.Open()
|
||||
err = logic.FileLogic.UpdateFileData(path, fiReader, fi.Size)
|
||||
errCheck(ctx, err != nil, "Update file data operation failed!")
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *file) FileReadHandler(ctx *gin.Context) {
|
||||
path := getQueryString(ctx, "filePath")
|
||||
bytes, err := logic.FileLogic.ReadFileFromPath(path)
|
||||
errCheck(ctx, err != nil, "Operation failed!")
|
||||
rOk(ctx, "Operation successful!", string(bytes))
|
||||
func (f *file) FileReadHandler(ctx *gin.Context, req model.FileReadHandlerReq) any {
|
||||
bytes, err := logic.FileLogic.ReadFileFromPath(req.FilePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
@@ -15,10 +16,9 @@ type logApi struct{}
|
||||
|
||||
var LogApi = new(logApi)
|
||||
|
||||
func (a *logApi) GetLog(ctx *gin.Context) {
|
||||
req := bind[model.GetLogReq](ctx)
|
||||
func (a *logApi) GetLog(ctx *gin.Context, req model.GetLogReq) any {
|
||||
if isAdmin(ctx) {
|
||||
rOk(ctx, "Query successful!", logic.LogLogicImpl.Search(req, req.FilterName...))
|
||||
return logic.LogLogicImpl.Search(req, req.FilterName...)
|
||||
} else {
|
||||
processNameList := repository.PermissionRepository.GetProcessNameByPermission(getUserName(ctx), constants.OPERATION_LOG)
|
||||
filterName := slices.DeleteFunc(req.FilterName, func(s string) bool {
|
||||
@@ -27,11 +27,13 @@ func (a *logApi) GetLog(ctx *gin.Context) {
|
||||
if len(filterName) == 0 {
|
||||
filterName = processNameList
|
||||
}
|
||||
errCheck(ctx, len(filterName) == 0, "No information found!")
|
||||
rOk(ctx, "Query successful!", logic.LogLogicImpl.Search(req, filterName...))
|
||||
if len(filterName) == 0 {
|
||||
return errors.New("no information found")
|
||||
}
|
||||
return logic.LogLogicImpl.Search(req, filterName...)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *logApi) GetRunningLog(ctx *gin.Context) {
|
||||
rOk(ctx, "Query successful!", logic.Loghandler.GetRunning())
|
||||
func (a *logApi) GetRunningLog(ctx *gin.Context, _ any) int {
|
||||
return logic.Loghandler.GetRunning()
|
||||
}
|
||||
|
@@ -11,14 +11,12 @@ var PermissionApi = new(permissionApi)
|
||||
|
||||
type permissionApi struct{}
|
||||
|
||||
func (p *permissionApi) EditPermssion(ctx *gin.Context) {
|
||||
req := bind[model.Permission](ctx)
|
||||
err := repository.PermissionRepository.EditPermssion(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (p *permissionApi) EditPermssion(ctx *gin.Context, req model.Permission) (err error) {
|
||||
return repository.PermissionRepository.EditPermssion(req)
|
||||
}
|
||||
|
||||
func (p *permissionApi) GetPermissionList(ctx *gin.Context) {
|
||||
result := repository.PermissionRepository.GetPermssionList(getQueryString(ctx, "account"))
|
||||
rOk(ctx, "Query successful!", result)
|
||||
func (p *permissionApi) GetPermissionList(ctx *gin.Context, req struct {
|
||||
Account string `form:"account" binding:"required"`
|
||||
}) any {
|
||||
return repository.PermissionRepository.GetPermssionList(req.Account)
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -16,114 +17,126 @@ type procApi struct{}
|
||||
|
||||
var ProcApi = new(procApi)
|
||||
|
||||
func (p *procApi) CreateNewProcess(ctx *gin.Context) {
|
||||
req := bind[model.Process](ctx)
|
||||
func (p *procApi) CreateNewProcess(ctx *gin.Context, req model.Process) any {
|
||||
index, err := repository.ProcessRepository.AddProcessConfig(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Uuid = index
|
||||
proc, err := logic.ProcessCtlLogic.NewProcess(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
logic.ProcessCtlLogic.AddProcess(req.Uuid, proc)
|
||||
rOk(ctx, "Operation successful!", gin.H{
|
||||
"id": req.Uuid,
|
||||
})
|
||||
}
|
||||
|
||||
func (p *procApi) DeleteNewProcess(ctx *gin.Context) {
|
||||
uuid := getQueryInt(ctx, "uuid")
|
||||
logic.ProcessCtlLogic.KillProcess(uuid)
|
||||
logic.ProcessCtlLogic.DeleteProcess(uuid)
|
||||
err := repository.ProcessRepository.DeleteProcessConfig(uuid)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
}
|
||||
|
||||
func (p *procApi) KillProcess(ctx *gin.Context) {
|
||||
uuid := getQueryInt(ctx, "uuid")
|
||||
err := logic.ProcessCtlLogic.KillProcess(uuid)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
}
|
||||
|
||||
func (p *procApi) StartProcess(ctx *gin.Context) {
|
||||
uuid := getQueryInt(ctx, "uuid")
|
||||
prod, err := logic.ProcessCtlLogic.GetProcess(uuid)
|
||||
if err != nil { // 进程不存在则创建
|
||||
proc, err := logic.ProcessCtlLogic.RunNewProcess(repository.ProcessRepository.GetProcessConfigById(uuid))
|
||||
errCheck(ctx, err != nil, err)
|
||||
logic.ProcessCtlLogic.AddProcess(uuid, proc)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
return
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logic.ProcessCtlLogic.AddProcess(req.Uuid, proc)
|
||||
return gin.H{
|
||||
"id": req.Uuid,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *procApi) DeleteNewProcess(ctx *gin.Context, req struct {
|
||||
Uuid int `form:"uuid" binding:"required"`
|
||||
}) (err error) {
|
||||
logic.ProcessCtlLogic.KillProcess(req.Uuid)
|
||||
logic.ProcessCtlLogic.DeleteProcess(req.Uuid)
|
||||
return repository.ProcessRepository.DeleteProcessConfig(req.Uuid)
|
||||
}
|
||||
|
||||
func (p *procApi) KillProcess(ctx *gin.Context, req struct {
|
||||
Uuid int `form:"uuid" binding:"required"`
|
||||
}) (err error) {
|
||||
return logic.ProcessCtlLogic.KillProcess(req.Uuid)
|
||||
}
|
||||
|
||||
func (p *procApi) StartProcess(ctx *gin.Context, req struct {
|
||||
Uuid int `form:"uuid" binding:"required"`
|
||||
}) (err error) {
|
||||
prod, err := logic.ProcessCtlLogic.GetProcess(req.Uuid)
|
||||
if err != nil { // 进程不存在则创建
|
||||
proConfig, err := repository.ProcessRepository.GetProcessConfigById(req.Uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proc, err := logic.ProcessCtlLogic.RunNewProcess(proConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logic.ProcessCtlLogic.AddProcess(req.Uuid, proc)
|
||||
return nil
|
||||
}
|
||||
if prod.State.State == 1 {
|
||||
return errors.New("process is currently running")
|
||||
}
|
||||
errCheck(ctx, prod.State.State == 1, "The process is currently running.")
|
||||
prod.ResetRestartTimes()
|
||||
err = prod.Start()
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *procApi) StartAllProcess(ctx *gin.Context) {
|
||||
func (p *procApi) StartAllProcess(ctx *gin.Context, _ any) (err error) {
|
||||
if isAdmin(ctx) {
|
||||
logic.ProcessCtlLogic.ProcessStartAll()
|
||||
} else {
|
||||
logic.ProcessCtlLogic.ProcesStartAllByUsername(getUserName(ctx))
|
||||
}
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *procApi) KillAllProcess(ctx *gin.Context) {
|
||||
func (p *procApi) KillAllProcess(ctx *gin.Context, _ any) (err error) {
|
||||
if isAdmin(ctx) {
|
||||
logic.ProcessCtlLogic.KillAllProcess()
|
||||
} else {
|
||||
logic.ProcessCtlLogic.KillAllProcessByUserName(getUserName(ctx))
|
||||
}
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *procApi) GetProcessList(ctx *gin.Context) {
|
||||
func (p *procApi) GetProcessList(ctx *gin.Context, _ any) any {
|
||||
if isAdmin(ctx) {
|
||||
rOk(ctx, "Query successful!", logic.ProcessCtlLogic.GetProcessList())
|
||||
return logic.ProcessCtlLogic.GetProcessList()
|
||||
} else {
|
||||
rOk(ctx, "Query successful!", logic.ProcessCtlLogic.GetProcessListByUser(getUserName(ctx)))
|
||||
return logic.ProcessCtlLogic.GetProcessListByUser(getUserName(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
func (p *procApi) UpdateProcessConfig(ctx *gin.Context) {
|
||||
req := bind[model.Process](ctx)
|
||||
func (p *procApi) UpdateProcessConfig(ctx *gin.Context, req model.Process) (err error) {
|
||||
logic.ProcessCtlLogic.UpdateProcessConfig(req)
|
||||
err := repository.ProcessRepository.UpdateProcessConfig(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
err = repository.ProcessRepository.UpdateProcessConfig(req)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *procApi) GetProcessConfig(ctx *gin.Context) {
|
||||
uuid := getQueryInt(ctx, "uuid")
|
||||
data := repository.ProcessRepository.GetProcessConfigById(uuid)
|
||||
errCheck(ctx, data.Uuid == 0, "No information found!")
|
||||
rOk(ctx, "Query successful!", data)
|
||||
func (p *procApi) GetProcessConfig(ctx *gin.Context, req struct {
|
||||
Uuid int `form:"uuid" binding:"required"`
|
||||
}) any {
|
||||
data, err := repository.ProcessRepository.GetProcessConfigById(req.Uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func (p *procApi) ProcessControl(ctx *gin.Context) {
|
||||
func (p *procApi) ProcessControl(ctx *gin.Context, req struct {
|
||||
Uuid int `form:"uuid" binding:"required"`
|
||||
}) (err error) {
|
||||
user := getUserName(ctx)
|
||||
uuid := getQueryInt(ctx, "uuid")
|
||||
proc, err := logic.ProcessCtlLogic.GetProcess(uuid)
|
||||
errCheck(ctx, err != nil, err)
|
||||
proc, err := logic.ProcessCtlLogic.GetProcess(req.Uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proc.ProcessControl(user)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
return
|
||||
}
|
||||
|
||||
func (p *procApi) ProcessCreateShare(ctx *gin.Context) {
|
||||
req := bind[model.ProcessShare](ctx)
|
||||
func (p *procApi) ProcessCreateShare(ctx *gin.Context, req model.ProcessShare) any {
|
||||
token := utils.UnwarpIgnore(uuid.NewRandom()).String()
|
||||
err := repository.WsShare.AddShareData(model.WsShare{
|
||||
if err := repository.WsShare.AddShareData(model.WsShare{
|
||||
ExpireTime: time.Now().Add(time.Minute * time.Duration(req.Minutes)),
|
||||
Write: req.Write,
|
||||
Token: token,
|
||||
Pid: req.Pid,
|
||||
CreateBy: getUserName(ctx),
|
||||
})
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", gin.H{
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return gin.H{
|
||||
"token": token,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -11,32 +11,26 @@ type pushApi struct{}
|
||||
|
||||
var PushApi = new(pushApi)
|
||||
|
||||
func (p *pushApi) GetPushList(ctx *gin.Context) {
|
||||
rOk(ctx, "Query successful!", repository.PushRepository.GetPushList())
|
||||
func (p *pushApi) GetPushList(ctx *gin.Context, __ any) any {
|
||||
return repository.PushRepository.GetPushList()
|
||||
}
|
||||
|
||||
func (p *pushApi) GetPushById(ctx *gin.Context) {
|
||||
id := getQueryInt(ctx, "id")
|
||||
rOk(ctx, "Query successful!", repository.PushRepository.GetPushConfigById(id))
|
||||
func (p *pushApi) GetPushById(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) any {
|
||||
return repository.PushRepository.GetPushConfigById(req.Id)
|
||||
}
|
||||
|
||||
func (p *pushApi) AddPushConfig(ctx *gin.Context) {
|
||||
req := bind[model.Push](ctx)
|
||||
err := repository.PushRepository.AddPushConfig(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (p *pushApi) AddPushConfig(ctx *gin.Context, req model.Push) (err error) {
|
||||
return repository.PushRepository.AddPushConfig(req)
|
||||
}
|
||||
|
||||
func (p *pushApi) UpdatePushConfig(ctx *gin.Context) {
|
||||
req := bind[model.Push](ctx)
|
||||
err := repository.PushRepository.UpdatePushConfig(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (p *pushApi) UpdatePushConfig(ctx *gin.Context, req model.Push) (err error) {
|
||||
return repository.PushRepository.UpdatePushConfig(req)
|
||||
}
|
||||
|
||||
func (p *pushApi) DeletePushConfig(ctx *gin.Context) {
|
||||
id := getQueryInt(ctx, "id")
|
||||
err := repository.PushRepository.DeletePushConfig(id)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (p *pushApi) DeletePushConfig(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) (err error) {
|
||||
return repository.PushRepository.DeletePushConfig(req.Id)
|
||||
}
|
||||
|
@@ -12,62 +12,58 @@ type taskApi struct{}
|
||||
|
||||
var TaskApi = new(taskApi)
|
||||
|
||||
func (t *taskApi) CreateTask(ctx *gin.Context) {
|
||||
req := bind[model.Task](ctx)
|
||||
err := logic.TaskLogic.CreateTask(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) CreateTask(ctx *gin.Context, req model.Task) (err error) {
|
||||
return logic.TaskLogic.CreateTask(req)
|
||||
}
|
||||
|
||||
func (t *taskApi) GetTaskById(ctx *gin.Context) {
|
||||
result, err := repository.TaskRepository.GetTaskById(getQueryInt(ctx, "id"))
|
||||
errCheck(ctx, err != nil, "Query failed!")
|
||||
rOk(ctx, "Operation successful!", result)
|
||||
func (t *taskApi) GetTaskById(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) any {
|
||||
result, err := repository.TaskRepository.GetTaskById(req.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (t *taskApi) GetTaskList(ctx *gin.Context) {
|
||||
result := logic.TaskLogic.GetAllTaskJob()
|
||||
rOk(ctx, "Operation successful!", result)
|
||||
func (t *taskApi) GetTaskList(ctx *gin.Context, _ any) any {
|
||||
return logic.TaskLogic.GetAllTaskJob()
|
||||
}
|
||||
|
||||
func (t *taskApi) DeleteTaskById(ctx *gin.Context) {
|
||||
err := logic.TaskLogic.DeleteTask(getQueryInt(ctx, "id"))
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) DeleteTaskById(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) (err error) {
|
||||
return logic.TaskLogic.DeleteTask(req.Id)
|
||||
|
||||
}
|
||||
|
||||
func (t *taskApi) StartTask(ctx *gin.Context) {
|
||||
go logic.TaskLogic.RunTaskById(getQueryInt(ctx, "id"))
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) StartTask(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) (err error) {
|
||||
go logic.TaskLogic.RunTaskById(req.Id)
|
||||
return
|
||||
}
|
||||
|
||||
func (t *taskApi) StopTask(ctx *gin.Context) {
|
||||
errCheck(ctx, logic.TaskLogic.StopTaskJob(getQueryInt(ctx, "id")) != nil, "Operation failed!")
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) StopTask(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) (err error) {
|
||||
return logic.TaskLogic.StopTaskJob(req.Id)
|
||||
}
|
||||
|
||||
func (t *taskApi) EditTask(ctx *gin.Context) {
|
||||
req := bind[model.Task](ctx)
|
||||
err := logic.TaskLogic.EditTask(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) EditTask(ctx *gin.Context, req model.Task) (err error) {
|
||||
return logic.TaskLogic.EditTask(req)
|
||||
}
|
||||
|
||||
func (t *taskApi) EditTaskEnable(ctx *gin.Context) {
|
||||
req := bind[model.Task](ctx)
|
||||
err := logic.TaskLogic.EditTaskEnable(req.Id, req.Enable)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) EditTaskEnable(ctx *gin.Context, req model.Task) (err error) {
|
||||
return logic.TaskLogic.EditTaskEnable(req.Id, req.Enable)
|
||||
}
|
||||
|
||||
func (t *taskApi) RunTaskByKey(ctx *gin.Context) {
|
||||
err := logic.TaskLogic.RunTaskByKey(ctx.Param("key"))
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) RunTaskByKey(ctx *gin.Context, _ any) (err error) {
|
||||
return logic.TaskLogic.RunTaskByKey(ctx.Param("key"))
|
||||
}
|
||||
|
||||
func (t *taskApi) CreateTaskApiKey(ctx *gin.Context) {
|
||||
err := logic.TaskLogic.CreateApiKey(getQueryInt(ctx, "id"))
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (t *taskApi) CreateTaskApiKey(ctx *gin.Context, req struct {
|
||||
Id int `form:"id" binding:"required"`
|
||||
}) (err error) {
|
||||
return logic.TaskLogic.CreateApiKey(req.Id)
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
@@ -16,57 +18,64 @@ var UserApi = new(userApi)
|
||||
|
||||
const DEFAULT_ROOT_PASSWORD = "root"
|
||||
|
||||
func (u *userApi) LoginHandler(ctx *gin.Context) {
|
||||
req := bind[map[string]string](ctx)
|
||||
account := req["account"]
|
||||
password := req["password"]
|
||||
errCheck(ctx, !u.checkLoginInfo(account, password), "Incorrect username or password!")
|
||||
token, err := utils.GenToken(account)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", gin.H{
|
||||
func (u *userApi) LoginHandler(ctx *gin.Context, req model.LoginHandlerReq) any {
|
||||
if !u.checkLoginInfo(req.Account, req.Password) {
|
||||
return errors.New("incorrect username or password")
|
||||
}
|
||||
token, err := utils.GenerateToken(req.Account)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return gin.H{
|
||||
"code": 0,
|
||||
"token": token,
|
||||
"username": account,
|
||||
"role": repository.UserRepository.GetUserByName(account).Role,
|
||||
})
|
||||
"username": req.Account,
|
||||
"role": repository.UserRepository.GetUserByName(req.Account).Role,
|
||||
}
|
||||
}
|
||||
|
||||
func (u *userApi) CreateUser(ctx *gin.Context) {
|
||||
req := bind[model.User](ctx)
|
||||
errCheck(ctx, req.Role == constants.ROLE_ROOT, "Creation of root accounts is forbidden!")
|
||||
errCheck(ctx, req.Account == constants.CONSOLE, "Operation failed!")
|
||||
errCheck(ctx, len(req.Password) < config.CF.UserPassWordMinLength, "Password is too short")
|
||||
err := repository.UserRepository.CreateUser(req)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (u *userApi) CreateUser(ctx *gin.Context, req model.User) (err error) {
|
||||
if req.Role == constants.ROLE_ROOT {
|
||||
return errors.New("creation of root accounts is forbidden")
|
||||
}
|
||||
if req.Account == constants.CONSOLE {
|
||||
return errors.New("operation failed")
|
||||
}
|
||||
if len(req.Password) < config.CF.UserPassWordMinLength {
|
||||
return errors.New("password is too short")
|
||||
}
|
||||
err = repository.UserRepository.CreateUser(req)
|
||||
return
|
||||
}
|
||||
|
||||
func (u *userApi) ChangePassword(ctx *gin.Context) {
|
||||
req := bind[model.User](ctx)
|
||||
func (u *userApi) ChangePassword(ctx *gin.Context, req model.User) (err error) {
|
||||
reqUser := getUserName(ctx)
|
||||
errCheck(ctx, getRole(ctx) != constants.ROLE_ROOT && req.Account != "", "Invalid parameters!")
|
||||
if getRole(ctx) != constants.ROLE_ROOT && req.Account != "" {
|
||||
return errors.New("invalid parameters")
|
||||
}
|
||||
var userName string
|
||||
if req.Account != "" {
|
||||
userName = req.Account
|
||||
} else {
|
||||
userName = reqUser
|
||||
}
|
||||
errCheck(ctx, len(req.Password) < config.CF.UserPassWordMinLength, "Password is too short")
|
||||
err := repository.UserRepository.UpdatePassword(userName, req.Password)
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
|
||||
if len(req.Password) < config.CF.UserPassWordMinLength {
|
||||
return errors.New("password is too short")
|
||||
}
|
||||
err = repository.UserRepository.UpdatePassword(userName, req.Password)
|
||||
return
|
||||
}
|
||||
|
||||
func (u *userApi) DeleteUser(ctx *gin.Context) {
|
||||
account := getQueryString(ctx, "account")
|
||||
errCheck(ctx, account == "root", "Deletion of root accounts is forbidden!")
|
||||
err := repository.UserRepository.DeleteUser(account)
|
||||
errCheck(ctx, err != nil, "Deletion of root accounts failed!")
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func (u *userApi) DeleteUser(ctx *gin.Context, req model.User) (err error) {
|
||||
if req.Account == "root" {
|
||||
return errors.New("deletion of root accounts is forbidden")
|
||||
}
|
||||
err = repository.UserRepository.DeleteUser(req.Account)
|
||||
return
|
||||
}
|
||||
|
||||
func (u *userApi) GetUserList(ctx *gin.Context) {
|
||||
rOk(ctx, "Query successful!", repository.UserRepository.GetUserList())
|
||||
func (u *userApi) GetUserList(ctx *gin.Context, _ any) any {
|
||||
return repository.UserRepository.GetUserList()
|
||||
}
|
||||
|
||||
func (u *userApi) checkLoginInfo(account, password string) bool {
|
||||
|
@@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -9,9 +10,9 @@ import (
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/logic"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
"github.com/lzh-1625/go_process_manager/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/websocket"
|
||||
@@ -47,19 +48,22 @@ var upgrader = websocket.Upgrader{
|
||||
WriteBufferSize: 1024,
|
||||
}
|
||||
|
||||
func (w *wsApi) WebsocketHandle(ctx *gin.Context) {
|
||||
func (w *wsApi) WebsocketHandle(ctx *gin.Context, req model.WebsocketHandleReq) (err error) {
|
||||
reqUser := getUserName(ctx)
|
||||
uuid := getQueryInt(ctx, "uuid")
|
||||
proc, err := logic.ProcessCtlLogic.GetProcess(uuid)
|
||||
errCheck(ctx, err != nil, "Operation failed!")
|
||||
errCheck(ctx, proc.HasWsConn(reqUser), "A connection already exists; unable to establish a new one!")
|
||||
errCheck(ctx, proc.Control.Controller != reqUser && !proc.VerifyControl(), "Insufficient permissions; please check your access rights!")
|
||||
proc, err := logic.ProcessCtlLogic.GetProcess(req.Uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if proc.HasWsConn(reqUser) {
|
||||
return errors.New("connection already exists")
|
||||
}
|
||||
if proc.Control.Controller != reqUser && !proc.VerifyControl() {
|
||||
return errors.New("insufficient permissions")
|
||||
}
|
||||
conn, err := upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
|
||||
errCheck(ctx, err != nil, "WebSocket connection upgrade failed!")
|
||||
|
||||
log.Logger.AddAdditionalInfo("processName", proc.Name)
|
||||
log.Logger.AddAdditionalInfo("userName", reqUser)
|
||||
defer log.Logger.DeleteAdditionalInfo(2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Logger.Infow("ws连接成功")
|
||||
|
||||
@@ -71,8 +75,8 @@ func (w *wsApi) WebsocketHandle(ctx *gin.Context) {
|
||||
}
|
||||
proc.ReadCache(wci)
|
||||
if proc.State.State == 1 {
|
||||
proc.SetTerminalSize(utils.GetIntByString(ctx.Query("cols")), utils.GetIntByString(ctx.Query("rows")))
|
||||
w.startWsConnect(wci, cancel, proc, hasOprPermission(ctx, uuid, constants.OPERATION_TERMINAL_WRITE))
|
||||
proc.SetTerminalSize(req.Cols, req.Rows)
|
||||
w.startWsConnect(wci, cancel, proc, hasOprPermission(ctx, req.Uuid, constants.OPERATION_TERMINAL_WRITE))
|
||||
proc.AddConn(reqUser, wci)
|
||||
defer proc.DeleteConn(reqUser)
|
||||
}
|
||||
@@ -89,27 +93,41 @@ func (w *wsApi) WebsocketHandle(ctx *gin.Context) {
|
||||
log.Logger.Infow("ws连接断开", "操作类型", "tcp连接建立已被关闭")
|
||||
}
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *wsApi) WebsocketShareHandle(ctx *gin.Context) {
|
||||
token := getQueryString(ctx, "token")
|
||||
data, err := repository.WsShare.GetWsShareDataByToken(token)
|
||||
errCheck(ctx, err != nil, "Operation failed!")
|
||||
errCheck(ctx, data.ExpireTime.Unix() <= time.Now().Unix(), "Share expired!")
|
||||
func (w *wsApi) WebsocketShareHandle(ctx *gin.Context, req model.WebsocketHandleReq) (err error) {
|
||||
data, err := repository.WsShare.GetWsShareDataByToken(req.Token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if data.ExpireTime.Before(time.Now()) {
|
||||
return errors.New("share expired")
|
||||
}
|
||||
proc, err := logic.ProcessCtlLogic.GetProcess(data.Pid)
|
||||
errCheck(ctx, err != nil, err)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
guestName := "guest-" + strconv.Itoa(int(data.ID)) // 构造访客用户名
|
||||
errCheck(ctx, proc.HasWsConn(guestName), "A connection already exists; unable to establish a new one!")
|
||||
errCheck(ctx, proc.State.State != 1, "The process is currently running.")
|
||||
errCheck(ctx, !proc.VerifyControl(), "Insufficient permissions; please check your access rights!")
|
||||
if proc.HasWsConn(guestName) {
|
||||
return errors.New("connection already exists")
|
||||
}
|
||||
if proc.State.State != 1 {
|
||||
return errors.New("process not is running")
|
||||
}
|
||||
if !proc.VerifyControl() {
|
||||
return errors.New("insufficient permissions")
|
||||
}
|
||||
conn, err := upgrader.Upgrade(ctx.Writer, ctx.Request, nil)
|
||||
errCheck(ctx, err != nil, "WebSocket connection upgrade failed!")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Logger.Infow("ws连接成功")
|
||||
data.UpdatedAt = time.Now()
|
||||
repository.WsShare.Edit(data)
|
||||
|
||||
proc.SetTerminalSize(utils.GetIntByString(ctx.Query("cols")), utils.GetIntByString(ctx.Query("rows")))
|
||||
proc.SetTerminalSize(req.Cols, req.Rows)
|
||||
wsCtx, cancel := context.WithCancel(context.Background())
|
||||
wci := &WsConnetInstance{
|
||||
WsConnect: conn,
|
||||
@@ -135,6 +153,7 @@ func (w *wsApi) WebsocketShareHandle(ctx *gin.Context) {
|
||||
log.Logger.Infow("ws连接断开", "操作类型", "分享时间已结束")
|
||||
}
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
|
||||
func (w *wsApi) startWsConnect(wci *WsConnetInstance, cancel context.CancelFunc, proc logic.Process, write bool) {
|
||||
@@ -178,12 +197,10 @@ func (w *wsApi) startWsConnect(wci *WsConnetInstance, cancel context.CancelFunc,
|
||||
|
||||
}
|
||||
|
||||
func GetWsShareList(ctx *gin.Context) {
|
||||
rOk(ctx, "Operation successful!", logic.WsSahreLogic.GetWsShareList())
|
||||
func GetWsShareList(ctx *gin.Context, _ any) any {
|
||||
return logic.WsSahreLogic.GetWsShareList()
|
||||
}
|
||||
|
||||
func DeleteWsShareById(ctx *gin.Context) {
|
||||
err := logic.WsSahreLogic.DeleteById(ctx.GetInt("id"))
|
||||
errCheck(ctx, err != nil, err)
|
||||
rOk(ctx, "Operation successful!", nil)
|
||||
func DeleteWsShareById(ctx *gin.Context, _ any) any {
|
||||
return logic.WsSahreLogic.DeleteById(ctx.GetInt("id"))
|
||||
}
|
||||
|
@@ -20,7 +20,7 @@ var (
|
||||
|
||||
func InitLogHandle() {
|
||||
Loghandler.antsPool, _ = ants.NewPool(config.CF.LogHandlerPoolSize, ants.WithNonblocking(true), ants.WithExpiryDuration(3*time.Second), ants.WithPanicHandler(func(i interface{}) {
|
||||
log.Logger.Error("es消息储存失败")
|
||||
log.Logger.Warnw("日志储存失败", "err", i)
|
||||
}))
|
||||
}
|
||||
|
||||
|
@@ -2,55 +2,16 @@ package logic
|
||||
|
||||
import (
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/search"
|
||||
|
||||
_ "github.com/lzh-1625/go_process_manager/internal/app/search/bleve"
|
||||
_ "github.com/lzh-1625/go_process_manager/internal/app/search/es"
|
||||
_ "github.com/lzh-1625/go_process_manager/internal/app/search/sqlite"
|
||||
)
|
||||
|
||||
type LogLogic interface {
|
||||
Search(req model.GetLogReq, filterProcessName ...string) model.LogResp
|
||||
Insert(log string, processName string, using string, ts int64)
|
||||
}
|
||||
|
||||
var LogLogicImpl LogLogic
|
||||
var LogLogicImpl search.LogLogic
|
||||
|
||||
func InitLog() {
|
||||
if config.CF.EsEnable {
|
||||
LogLogicImpl = LogEs
|
||||
} else {
|
||||
LogLogicImpl = LogSqlite
|
||||
}
|
||||
}
|
||||
|
||||
type logSqlite struct{}
|
||||
|
||||
var LogSqlite = new(logSqlite)
|
||||
|
||||
func (l *logSqlite) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
|
||||
req.FilterName = filterProcessName
|
||||
data, total := repository.LogRepository.SearchLog(req)
|
||||
return model.LogResp{
|
||||
Data: data,
|
||||
Total: total,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *logSqlite) Insert(log string, processName string, using string, ts int64) {
|
||||
repository.LogRepository.InsertLog(model.ProcessLog{
|
||||
Log: log,
|
||||
Name: processName,
|
||||
Using: using,
|
||||
Time: ts,
|
||||
})
|
||||
}
|
||||
|
||||
type logEs struct{}
|
||||
|
||||
var LogEs = new(logEs)
|
||||
|
||||
func (l *logEs) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
|
||||
return EsLogic.Search(req, filterProcessName...)
|
||||
}
|
||||
|
||||
func (l *logEs) Insert(log string, processName string, using string, ts int64) {
|
||||
EsLogic.Insert(log, processName, using, ts)
|
||||
LogLogicImpl = search.GetSearchImpl(config.CF.StorgeType)
|
||||
LogLogicImpl.Init()
|
||||
}
|
||||
|
@@ -33,7 +33,7 @@ type Process interface {
|
||||
|
||||
type ProcessBase struct {
|
||||
Process
|
||||
p *os.Process
|
||||
op *os.Process
|
||||
Name string
|
||||
Pid int
|
||||
StartCommand []string
|
||||
@@ -84,7 +84,7 @@ type ConnectInstance interface {
|
||||
}
|
||||
|
||||
func (p *ProcessBase) watchDog() {
|
||||
state, _ := p.p.Wait()
|
||||
state, _ := p.op.Wait()
|
||||
if p.cgroup.enable && p.cgroup.delete != nil {
|
||||
err := p.cgroup.delete()
|
||||
if err != nil {
|
||||
@@ -128,7 +128,7 @@ func (p *ProcessBase) pInit() {
|
||||
p.State.manualStopFlag = false
|
||||
p.State.startTime = time.Now()
|
||||
p.ws = make(map[string]ConnectInstance)
|
||||
p.Pid = p.p.Pid
|
||||
p.Pid = p.op.Pid
|
||||
p.doOnInit()
|
||||
p.InitPerformanceStatus()
|
||||
p.initPsutil()
|
||||
@@ -263,8 +263,6 @@ func (p *ProcessBase) monitorHanler() {
|
||||
if !p.monitor.enable {
|
||||
return
|
||||
}
|
||||
log.Logger.AddAdditionalInfo("name", p.Name)
|
||||
log.Logger.AddAdditionalInfo("pid", p.Pid)
|
||||
defer log.Logger.Infow("性能监控结束")
|
||||
ticker := time.NewTicker(time.Second * time.Duration(config.CF.PerformanceInfoInterval))
|
||||
defer ticker.Stop()
|
||||
@@ -308,7 +306,7 @@ func (p *ProcessBase) initPsutil() {
|
||||
}
|
||||
|
||||
func (p *ProcessBase) Kill() error {
|
||||
p.p.Signal(syscall.SIGINT)
|
||||
p.op.Signal(syscall.SIGINT)
|
||||
select {
|
||||
case <-p.StopChan:
|
||||
{
|
||||
@@ -317,7 +315,7 @@ func (p *ProcessBase) Kill() error {
|
||||
case <-time.After(time.Second * time.Duration(config.CF.KillWaitTime)):
|
||||
{
|
||||
log.Logger.Debugw("进程kill超时,强制停止进程", "name", p.Name)
|
||||
return p.p.Kill()
|
||||
return p.op.Kill()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,3 +1,6 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package logic
|
||||
|
||||
import "github.com/lzh-1625/go_process_manager/log"
|
||||
|
@@ -47,11 +47,11 @@ func (p *processCtlLogic) KillProcess(uuid int) error {
|
||||
func (p *processCtlLogic) GetProcess(uuid int) (*ProcessBase, error) {
|
||||
process, ok := p.processMap.Load(uuid)
|
||||
if !ok {
|
||||
return nil, errors.New("进程获取失败")
|
||||
return nil, errors.New("process not exist")
|
||||
}
|
||||
result, ok := process.(*ProcessBase)
|
||||
if !ok {
|
||||
return nil, errors.New("进程类型错误")
|
||||
return nil, errors.New("process type error")
|
||||
|
||||
}
|
||||
return result, nil
|
||||
@@ -114,25 +114,25 @@ func (p *processCtlLogic) getProcessInfoList(processConfiglist []model.Process)
|
||||
Name: v.Name,
|
||||
Uuid: v.Uuid,
|
||||
}
|
||||
if value, ok := p.processMap.Load(v.Uuid); ok {
|
||||
process := value.(*ProcessBase)
|
||||
pi.State.Info = process.State.Info
|
||||
pi.State.State = process.State.State
|
||||
pi.StartTime = process.GetStartTimeFormat()
|
||||
pi.User = process.GetUserString()
|
||||
|
||||
pi.Usage.Cpu = process.performanceStatus.cpu
|
||||
pi.Usage.Mem = process.performanceStatus.mem
|
||||
if config.CF.PerformanceCapacityDisplay {
|
||||
pi.Usage.CpuCapacity = float64(runtime.NumCPU()) * 100.0
|
||||
pi.Usage.MemCapacity = float64(utils.UnwarpIgnore(mem.VirtualMemory()).Total >> 10)
|
||||
}
|
||||
pi.Usage.Time = process.performanceStatus.time
|
||||
pi.TermType = process.Type()
|
||||
pi.CgroupEnable = process.Config.cgroupEnable
|
||||
pi.CpuLimit = process.Config.cpuLimit
|
||||
pi.MemoryLimit = process.Config.memoryLimit
|
||||
process, err := p.GetProcess(v.Uuid)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
pi.State.Info = process.State.Info
|
||||
pi.State.State = process.State.State
|
||||
pi.StartTime = process.GetStartTimeFormat()
|
||||
pi.User = process.GetUserString()
|
||||
pi.Usage.Cpu = process.performanceStatus.cpu
|
||||
pi.Usage.Mem = process.performanceStatus.mem
|
||||
if config.CF.PerformanceCapacityDisplay {
|
||||
pi.Usage.CpuCapacity = float64(runtime.NumCPU()) * 100.0
|
||||
pi.Usage.MemCapacity = float64(utils.UnwarpIgnore(mem.VirtualMemory()).Total >> 10)
|
||||
}
|
||||
pi.Usage.Time = process.performanceStatus.time
|
||||
pi.TermType = process.Type()
|
||||
pi.CgroupEnable = process.Config.cgroupEnable
|
||||
pi.CpuLimit = process.Config.cpuLimit
|
||||
pi.MemoryLimit = process.Config.memoryLimit
|
||||
processInfoList = append(processInfoList, pi)
|
||||
}
|
||||
return processInfoList
|
||||
@@ -150,7 +150,10 @@ func (p *processCtlLogic) ProcessStartAll() {
|
||||
}
|
||||
|
||||
func (p *processCtlLogic) RunPrcessById(id int) (*ProcessBase, error) {
|
||||
config := repository.ProcessRepository.GetProcessConfigById(id)
|
||||
config, err := repository.ProcessRepository.GetProcessConfigById(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proc, err := p.RunNewProcess(config)
|
||||
if err != nil {
|
||||
log.Logger.Warnw("初始化启动进程失败", config.Name, "name", "err", err)
|
||||
@@ -163,7 +166,6 @@ func (p *processCtlLogic) RunPrcessById(id int) (*ProcessBase, error) {
|
||||
func (p *processCtlLogic) ProcessInit() {
|
||||
config := repository.ProcessRepository.GetAllProcessConfig()
|
||||
for _, v := range config {
|
||||
|
||||
proc, err := p.NewProcess(v)
|
||||
if err != nil {
|
||||
log.Logger.Warnw("初始化启动进程失败", v.Name, "name", "err", err)
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/google/shlex"
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
@@ -31,14 +32,12 @@ func (p *ProcessPty) Type() constants.TerminalType {
|
||||
|
||||
func (p *ProcessPty) Start() (err error) {
|
||||
defer func() {
|
||||
log.Logger.DeleteAdditionalInfo(1)
|
||||
if err != nil {
|
||||
p.Config.AutoRestart = false
|
||||
p.SetState(constants.PROCESS_WARNNING)
|
||||
p.State.Info = "进程启动失败:" + err.Error()
|
||||
}
|
||||
}()
|
||||
log.Logger.AddAdditionalInfo("进程名称", p.Name)
|
||||
if ok := p.SetState(constants.PROCESS_START, func() bool {
|
||||
return p.State.State != 1
|
||||
}); !ok {
|
||||
@@ -58,7 +57,7 @@ func (p *ProcessPty) Start() (err error) {
|
||||
})
|
||||
p.pty = pf
|
||||
log.Logger.Infow("进程启动成功", "进程名称", p.Name, "重启次数", p.State.restartTimes)
|
||||
p.p = cmd.Process
|
||||
p.op = cmd.Process
|
||||
p.pInit()
|
||||
p.push("进程启动成功")
|
||||
return nil
|
||||
@@ -115,7 +114,9 @@ func (p *ProcessPty) readInit() {
|
||||
}
|
||||
|
||||
func (p *ProcessPty) ReadCache(ws ConnectInstance) {
|
||||
ws.Write(p.cacheBytesBuf.Bytes())
|
||||
if p.cacheBytesBuf != nil {
|
||||
ws.Write(p.cacheBytesBuf.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
func (p *ProcessPty) bufHanle(b []byte) {
|
||||
@@ -135,7 +136,7 @@ func (p *ProcessPty) doOnInit() {
|
||||
func NewProcessPty(pconfig model.Process) *ProcessBase {
|
||||
p := ProcessBase{
|
||||
Name: pconfig.Name,
|
||||
StartCommand: strings.Split(pconfig.Cmd, " "),
|
||||
StartCommand: utils.UnwarpIgnore(shlex.Split(pconfig.Cmd)),
|
||||
WorkDir: pconfig.Cwd,
|
||||
}
|
||||
processPty := ProcessPty{
|
||||
|
@@ -30,14 +30,12 @@ func (p *ProcessPty) Type() constants.TerminalType {
|
||||
|
||||
func (p *ProcessPty) Start() (err error) {
|
||||
defer func() {
|
||||
log.Logger.DeleteAdditionalInfo(1)
|
||||
if err != nil {
|
||||
p.Config.AutoRestart = false
|
||||
p.SetState(constants.PROCESS_WARNNING)
|
||||
p.State.Info = "进程启动失败:" + err.Error()
|
||||
}
|
||||
}()
|
||||
log.Logger.AddAdditionalInfo("进程名称", p.Name)
|
||||
if ok := p.SetState(constants.PROCESS_START, func() bool {
|
||||
return p.State.State != 1
|
||||
}); !ok {
|
||||
@@ -61,7 +59,7 @@ func (p *ProcessPty) Start() (err error) {
|
||||
log.Logger.Errorw("进程启动失败", "err", err)
|
||||
return err
|
||||
}
|
||||
p.p, err = os.FindProcess(pid)
|
||||
p.op, err = os.FindProcess(pid)
|
||||
if err != nil {
|
||||
log.Logger.Errorw("进程启动失败", "err", err)
|
||||
return err
|
||||
|
@@ -4,7 +4,8 @@ import (
|
||||
"bufio"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/google/shlex"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
@@ -38,14 +39,12 @@ func (p *ProcessStd) Write(input string) (err error) {
|
||||
|
||||
func (p *ProcessStd) Start() (err error) {
|
||||
defer func() {
|
||||
log.Logger.DeleteAdditionalInfo(1)
|
||||
if err != nil {
|
||||
p.Config.AutoRestart = false
|
||||
p.SetState(constants.PROCESS_WARNNING)
|
||||
p.State.Info = "进程启动失败:" + err.Error()
|
||||
}
|
||||
}()
|
||||
log.Logger.AddAdditionalInfo("进程名称", p.Name)
|
||||
if ok := p.SetState(constants.PROCESS_START, func() bool {
|
||||
return p.State.State != 1
|
||||
}); !ok {
|
||||
@@ -72,7 +71,7 @@ func (p *ProcessStd) Start() (err error) {
|
||||
return err
|
||||
}
|
||||
log.Logger.Infow("进程启动成功", "重启次数", p.State.restartTimes)
|
||||
p.p = cmd.Process
|
||||
p.op = cmd.Process
|
||||
p.pInit()
|
||||
p.push("进程启动成功")
|
||||
return nil
|
||||
@@ -135,7 +134,7 @@ func (p *ProcessStd) Read() string {
|
||||
func NewProcessStd(pconfig model.Process) *ProcessBase {
|
||||
p := ProcessBase{
|
||||
Name: pconfig.Name,
|
||||
StartCommand: strings.Split(pconfig.Cmd, " "),
|
||||
StartCommand: utils.UnwarpIgnore(shlex.Split(pconfig.Cmd)),
|
||||
WorkDir: pconfig.Cwd,
|
||||
}
|
||||
processStd := ProcessStd{
|
||||
|
@@ -2,57 +2,62 @@ package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/middle"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
func (t *taskLogic) RunTaskById(id int) error {
|
||||
task, err := t.getTaskJob(id)
|
||||
if err != nil {
|
||||
return errors.New("id不存在")
|
||||
}
|
||||
if task.Running {
|
||||
return errors.New("task is running")
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
task.Cancel = cancel
|
||||
t.run(ctx, task)
|
||||
return nil
|
||||
type TaskJob struct {
|
||||
Cron *cron.Cron `json:"-"`
|
||||
TaskConfig *model.Task `json:"task"`
|
||||
Running bool `json:"running"`
|
||||
Cancel context.CancelFunc `json:"-"`
|
||||
StartTime time.Time `json:"startTime"`
|
||||
EndTime time.Time `json:"endTime"`
|
||||
}
|
||||
|
||||
func (t *taskLogic) run(ctx context.Context, data *model.TaskJob) {
|
||||
data.Running = true
|
||||
func NewTaskJob(data model.Task) (*TaskJob, error) {
|
||||
tj := &TaskJob{
|
||||
TaskConfig: &data,
|
||||
StartTime: time.Now(),
|
||||
}
|
||||
if data.Enable && data.CronExpression != "" {
|
||||
err := tj.InitCronHandle()
|
||||
if err != nil {
|
||||
log.Logger.Warnw("定时任务启动失败", "err", err, "task", data.Id)
|
||||
}
|
||||
}
|
||||
return tj, nil
|
||||
}
|
||||
|
||||
func (t *TaskJob) Run(ctx context.Context) {
|
||||
t.Running = true
|
||||
middle.TaskWaitCond.Trigger()
|
||||
defer func() {
|
||||
data.Running = false
|
||||
t.Running = false
|
||||
middle.TaskWaitCond.Trigger()
|
||||
}()
|
||||
log.Logger.AddAdditionalInfo("taskId", data.Task.Id)
|
||||
defer log.Logger.DeleteAdditionalInfo(1)
|
||||
var ok bool
|
||||
// 判断条件是否满足
|
||||
if data.Task.Condition == constants.PASS {
|
||||
if t.TaskConfig.Condition == constants.PASS {
|
||||
ok = true
|
||||
} else {
|
||||
proc, err := ProcessCtlLogic.GetProcess(data.Task.OperationTarget)
|
||||
proc, err := ProcessCtlLogic.GetProcess(t.TaskConfig.OperationTarget)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ok = conditionHandle[data.Task.Condition](data.Task, proc)
|
||||
ok = conditionHandle[t.TaskConfig.Condition](t.TaskConfig, proc)
|
||||
}
|
||||
log.Logger.Debugw("任务条件判断", "pass", ok)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
proc, err := ProcessCtlLogic.GetProcess(data.Task.OperationTarget)
|
||||
proc, err := ProcessCtlLogic.GetProcess(t.TaskConfig.OperationTarget)
|
||||
if err != nil {
|
||||
log.Logger.Debugw("不存在该进程,结束任务")
|
||||
return
|
||||
@@ -60,98 +65,66 @@ func (t *taskLogic) run(ctx context.Context, data *model.TaskJob) {
|
||||
|
||||
// 执行操作
|
||||
log.Logger.Infow("任务开始执行")
|
||||
if !OperationHandle[data.Task.Operation](data.Task, proc) {
|
||||
if !OperationHandle[t.TaskConfig.Operation](t.TaskConfig, proc) {
|
||||
log.Logger.Errorw("任务执行失败")
|
||||
return
|
||||
}
|
||||
log.Logger.Infow("任务执行成功", "target", data.Task.OperationTarget)
|
||||
log.Logger.Infow("任务执行成功", "target", t.TaskConfig.OperationTarget)
|
||||
|
||||
if data.Task.NextId != nil {
|
||||
nextTask, err := t.getTaskJob(*data.Task.NextId)
|
||||
if t.TaskConfig.NextId != nil {
|
||||
nextTask, err := TaskLogic.getTaskJob(*t.TaskConfig.NextId)
|
||||
if err != nil {
|
||||
log.Logger.Errorw("无法获取到下一个节点,结束任务", "nextId", data.Task.NextId)
|
||||
log.Logger.Errorw("无法获取到下一个节点,结束任务", "nextId", t.TaskConfig.NextId)
|
||||
return
|
||||
}
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
log.Logger.Infow("任务流被手动结束")
|
||||
default:
|
||||
log.Logger.Debugw("执行下一个节点", "nextId", *data.Task.NextId)
|
||||
log.Logger.Debugw("执行下一个节点", "nextId", *t.TaskConfig.NextId)
|
||||
if nextTask.Running {
|
||||
log.Logger.Errorw("下一个节点已在运行,结束任务", "nextId", data.Task.NextId)
|
||||
log.Logger.Errorw("下一个节点已在运行,结束任务", "nextId", t.TaskConfig.NextId)
|
||||
return
|
||||
}
|
||||
t.run(ctx, nextTask)
|
||||
nextTask.Run(ctx)
|
||||
}
|
||||
} else {
|
||||
log.Logger.Infow("任务流结束")
|
||||
}
|
||||
}
|
||||
|
||||
type conditionFunc func(data *model.Task, proc *ProcessBase) bool
|
||||
|
||||
var conditionHandle = map[constants.Condition]conditionFunc{
|
||||
constants.RUNNING: func(data *model.Task, proc *ProcessBase) bool {
|
||||
return proc.State.State == 1
|
||||
},
|
||||
constants.NOT_RUNNING: func(data *model.Task, proc *ProcessBase) bool {
|
||||
return proc.State.State != 1
|
||||
},
|
||||
constants.EXCEPTION: func(data *model.Task, proc *ProcessBase) bool {
|
||||
return proc.State.State == 2
|
||||
},
|
||||
func (t *TaskJob) InitCronHandle() error {
|
||||
if _, err := cron.ParseStandard(t.TaskConfig.CronExpression); err != nil { // cron表达式校验
|
||||
log.Logger.Errorw("cron解析失败", "cron", t.TaskConfig.CronExpression, "err", err)
|
||||
return err
|
||||
}
|
||||
c := cron.New()
|
||||
_, err := c.AddFunc(t.TaskConfig.CronExpression, func() {
|
||||
log.Logger.Infow("定时任务启动")
|
||||
if t.Running {
|
||||
log.Logger.Infow("任务已在运行,跳过当前任务")
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
t.Cancel = cancel
|
||||
t.Run(ctx)
|
||||
log.Logger.Infow("定时任务结束")
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Start()
|
||||
t.Cron = c
|
||||
return nil
|
||||
}
|
||||
|
||||
// 执行操作,返回结果是否成功
|
||||
type operationFunc func(data *model.Task, proc *ProcessBase) bool
|
||||
|
||||
var OperationHandle = map[constants.TaskOperation]operationFunc{
|
||||
constants.TASK_START: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State == 1 {
|
||||
log.Logger.Debugw("进程已在运行")
|
||||
return false
|
||||
}
|
||||
go proc.Start()
|
||||
return true
|
||||
},
|
||||
|
||||
constants.TASK_START_WAIT_DONE: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State == 1 {
|
||||
log.Logger.Debugw("进程已在运行")
|
||||
return false
|
||||
}
|
||||
if err := proc.Start(); err != nil {
|
||||
log.Logger.Debugw("进程启动失败")
|
||||
return false
|
||||
}
|
||||
select {
|
||||
case <-proc.StopChan:
|
||||
log.Logger.Debugw("进程停止,任务完成")
|
||||
return true
|
||||
case <-time.After(time.Second * time.Duration(config.CF.TaskTimeout)):
|
||||
log.Logger.Errorw("任务超时")
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
||||
constants.TASK_STOP: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State != 1 {
|
||||
log.Logger.Debugw("进程未在运行")
|
||||
return false
|
||||
}
|
||||
log.Logger.Debugw("异步停止任务")
|
||||
proc.State.manualStopFlag = true
|
||||
go proc.Kill()
|
||||
return true
|
||||
},
|
||||
|
||||
constants.TASK_STOP_WAIT_DONE: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State != 1 {
|
||||
log.Logger.Debugw("进程未在运行")
|
||||
return false
|
||||
}
|
||||
log.Logger.Debugw("停止任务并等待结束")
|
||||
proc.State.manualStopFlag = true
|
||||
return proc.Kill() == nil
|
||||
},
|
||||
func (t *TaskJob) EditStatus(status bool) error {
|
||||
if t.Cron != nil && !status {
|
||||
t.Cron.Stop()
|
||||
} else if err := t.InitCronHandle(); err != nil {
|
||||
return err
|
||||
}
|
||||
t.TaskConfig.Enable = status
|
||||
return nil
|
||||
}
|
||||
|
78
internal/app/logic/task_exec.go
Normal file
78
internal/app/logic/task_exec.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
)
|
||||
|
||||
type conditionFunc func(data *model.Task, proc *ProcessBase) bool
|
||||
|
||||
var conditionHandle = map[constants.Condition]conditionFunc{
|
||||
constants.RUNNING: func(data *model.Task, proc *ProcessBase) bool {
|
||||
return proc.State.State == 1
|
||||
},
|
||||
constants.NOT_RUNNING: func(data *model.Task, proc *ProcessBase) bool {
|
||||
return proc.State.State != 1
|
||||
},
|
||||
constants.EXCEPTION: func(data *model.Task, proc *ProcessBase) bool {
|
||||
return proc.State.State == 2
|
||||
},
|
||||
}
|
||||
|
||||
// 执行操作,返回结果是否成功
|
||||
type operationFunc func(data *model.Task, proc *ProcessBase) bool
|
||||
|
||||
var OperationHandle = map[constants.TaskOperation]operationFunc{
|
||||
constants.TASK_START: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State == 1 {
|
||||
log.Logger.Debugw("进程已在运行")
|
||||
return false
|
||||
}
|
||||
go proc.Start()
|
||||
return true
|
||||
},
|
||||
|
||||
constants.TASK_START_WAIT_DONE: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State == 1 {
|
||||
log.Logger.Debugw("进程已在运行")
|
||||
return false
|
||||
}
|
||||
if err := proc.Start(); err != nil {
|
||||
log.Logger.Debugw("进程启动失败")
|
||||
return false
|
||||
}
|
||||
select {
|
||||
case <-proc.StopChan:
|
||||
log.Logger.Debugw("进程停止,任务完成")
|
||||
return true
|
||||
case <-time.After(time.Second * time.Duration(config.CF.TaskTimeout)):
|
||||
log.Logger.Errorw("任务超时")
|
||||
return false
|
||||
}
|
||||
},
|
||||
|
||||
constants.TASK_STOP: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State != 1 {
|
||||
log.Logger.Debugw("进程未在运行")
|
||||
return false
|
||||
}
|
||||
log.Logger.Debugw("异步停止任务")
|
||||
proc.State.manualStopFlag = true
|
||||
go proc.Kill()
|
||||
return true
|
||||
},
|
||||
|
||||
constants.TASK_STOP_WAIT_DONE: func(data *model.Task, proc *ProcessBase) bool {
|
||||
if proc.State.State != 1 {
|
||||
log.Logger.Debugw("进程未在运行")
|
||||
return false
|
||||
}
|
||||
log.Logger.Debugw("停止任务并等待结束")
|
||||
proc.State.manualStopFlag = true
|
||||
return proc.Kill() == nil
|
||||
},
|
||||
}
|
@@ -3,17 +3,13 @@ package logic
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
"github.com/lzh-1625/go_process_manager/utils"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
type taskLogic struct {
|
||||
@@ -22,53 +18,25 @@ type taskLogic struct {
|
||||
|
||||
var TaskLogic = new(taskLogic)
|
||||
|
||||
func (t *taskLogic) getTaskJob(id int) (*model.TaskJob, error) {
|
||||
func (t *taskLogic) getTaskJob(id int) (*TaskJob, error) {
|
||||
c, ok := t.taskJobMap.Load(id)
|
||||
if !ok {
|
||||
return nil, errors.New("don't exist this task id")
|
||||
}
|
||||
return c.(*model.TaskJob), nil
|
||||
return c.(*TaskJob), nil
|
||||
}
|
||||
|
||||
func (t *taskLogic) InitTaskJob() {
|
||||
for _, v := range repository.TaskRepository.GetAllTask() {
|
||||
tj := &model.TaskJob{
|
||||
Task: &v,
|
||||
StartTime: time.Now(),
|
||||
}
|
||||
if tj.Task.Cron != "" {
|
||||
c := cron.New()
|
||||
_, err := c.AddFunc(v.Cron, t.cronHandle(tj))
|
||||
if err != nil {
|
||||
log.Logger.Errorw("定时任务创建失败", "err", err, "id", v.Id)
|
||||
continue
|
||||
}
|
||||
if v.Enable {
|
||||
c.Start()
|
||||
}
|
||||
tj.Cron = c
|
||||
tj, err := NewTaskJob(v)
|
||||
if err != nil {
|
||||
log.Logger.Warnw("任务初始化失败", "err", err)
|
||||
continue
|
||||
}
|
||||
t.taskJobMap.Store(v.Id, tj)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *taskLogic) cronHandle(data *model.TaskJob) func() {
|
||||
return func() {
|
||||
log.Logger.AddAdditionalInfo("id", data.Task.Id)
|
||||
defer log.Logger.DeleteAdditionalInfo(1)
|
||||
log.Logger.Infow("定时任务启动")
|
||||
if data.Running {
|
||||
log.Logger.Infow("任务已在运行,跳过当前任务")
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
data.Cancel = cancel
|
||||
t.run(ctx, data)
|
||||
log.Logger.Infow("定时任务结束")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *taskLogic) StopTaskJob(id int) error {
|
||||
taskJob, err := t.getTaskJob(id)
|
||||
if err != nil {
|
||||
@@ -96,9 +64,9 @@ func (t *taskLogic) GetAllTaskJob() []model.TaskVo {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
result[i].Id = task.Task.Id
|
||||
result[i].Id = task.TaskConfig.Id
|
||||
result[i].Running = task.Running
|
||||
result[i].Enable = task.Task.Enable
|
||||
result[i].Enable = task.TaskConfig.Enable
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -115,37 +83,27 @@ func (t *taskLogic) DeleteTask(id int) (err error) {
|
||||
}
|
||||
|
||||
func (t *taskLogic) CreateTask(data model.Task) error {
|
||||
tj := &model.TaskJob{
|
||||
Task: &data,
|
||||
StartTime: time.Now(),
|
||||
}
|
||||
if data.Cron != "" {
|
||||
if _, err := cron.ParseStandard(data.Cron); err != nil { // cron表达式校验
|
||||
log.Logger.Errorw("cron解析失败", "cron", data.Cron, "err", err)
|
||||
return err
|
||||
} else {
|
||||
c := cron.New()
|
||||
c.AddFunc(data.Cron, t.cronHandle(tj))
|
||||
tj.Cron = c
|
||||
}
|
||||
tj, err := NewTaskJob(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
taskId, err := repository.TaskRepository.AddTask(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data.Id = taskId
|
||||
t.taskJobMap.Store(data.Id, tj)
|
||||
tj.TaskConfig.Id = taskId
|
||||
t.taskJobMap.Store(taskId, tj)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *taskLogic) EditTask(data model.Task) error {
|
||||
tj, err := t.getTaskJob(data.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("task with id %v does not exist", data.Id)
|
||||
return errors.New("task id not exist")
|
||||
}
|
||||
|
||||
if tj.Running {
|
||||
return errors.New("can't edit task while it is running")
|
||||
return errors.New("can't edit running task")
|
||||
}
|
||||
|
||||
if tj.Cron != nil {
|
||||
@@ -153,37 +111,9 @@ func (t *taskLogic) EditTask(data model.Task) error {
|
||||
tj.Cron = nil
|
||||
}
|
||||
|
||||
// 更新任务
|
||||
tj.Task = &data
|
||||
tj.TaskConfig = &data
|
||||
tj.TaskConfig.Enable = false
|
||||
|
||||
// 如果 Cron 字段为空,直接禁用任务并返回
|
||||
if tj.Task.Cron == "" {
|
||||
tj.Task.Enable = false
|
||||
return repository.TaskRepository.EditTask(data)
|
||||
}
|
||||
|
||||
// 校验 Cron 表达式
|
||||
if _, err := cron.ParseStandard(tj.Task.Cron); err != nil {
|
||||
tj.Task.Enable = false
|
||||
return fmt.Errorf("invalid cron expression: %v", err)
|
||||
}
|
||||
|
||||
// 创建 Cron 调度器
|
||||
c := cron.New()
|
||||
_, err = c.AddFunc(data.Cron, t.cronHandle(tj))
|
||||
if err != nil {
|
||||
log.Logger.Errorw("failed to create cron job", "err", err, "id", data.Id)
|
||||
tj.Task.Enable = false
|
||||
return fmt.Errorf("failed to create cron job: %v", err)
|
||||
}
|
||||
|
||||
// 启动 Cron 调度器
|
||||
if data.Enable {
|
||||
c.Start()
|
||||
}
|
||||
tj.Cron = c
|
||||
|
||||
// 更新任务到数据库
|
||||
return repository.TaskRepository.EditTask(data)
|
||||
}
|
||||
|
||||
@@ -192,16 +122,12 @@ func (t *taskLogic) EditTaskEnable(id int, status bool) error {
|
||||
if err != nil {
|
||||
return errors.New("don't exist this task id")
|
||||
}
|
||||
if tj.Cron != nil {
|
||||
if status {
|
||||
tj.Cron.Start()
|
||||
} else {
|
||||
tj.Cron.Stop()
|
||||
}
|
||||
} else if status {
|
||||
return errors.New("cron job create failed")
|
||||
if tj.TaskConfig.CronExpression == "" {
|
||||
return errors.New("task cron expression is empty")
|
||||
}
|
||||
if err := tj.EditStatus(status); err != nil {
|
||||
return err
|
||||
}
|
||||
tj.Task.Enable = status
|
||||
if err := repository.TaskRepository.EditTaskEnable(id, status); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -239,3 +165,18 @@ func (t *taskLogic) RunTaskByTriggerEvent(processName string, event constants.Pr
|
||||
t.RunTaskById(v.Id)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *taskLogic) RunTaskById(id int) error {
|
||||
task, err := t.getTaskJob(id)
|
||||
if err != nil {
|
||||
return errors.New("id不存在")
|
||||
}
|
||||
if task.Running {
|
||||
return errors.New("task is running")
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
task.Cancel = cancel
|
||||
task.Run(ctx)
|
||||
return nil
|
||||
}
|
||||
|
@@ -28,7 +28,14 @@ func Logger() gin.HandlerFunc {
|
||||
if user, ok := ctx.Get(constants.CTXFLG_USER_NAME); ok {
|
||||
logKv = append(logKv, "user", user)
|
||||
}
|
||||
log.Logger.Infow("GIN", logKv...)
|
||||
switch {
|
||||
case ctx.Writer.Status() >= 200 && ctx.Writer.Status() < 300:
|
||||
log.Logger.Infow("\033[102mGIN\033[0m", logKv...)
|
||||
case ctx.Writer.Status() >= 500:
|
||||
log.Logger.Infow("\033[101mGIN\033[0m", logKv...)
|
||||
default:
|
||||
log.Logger.Infow("\033[103mGIN\033[0m", logKv...)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,26 +0,0 @@
|
||||
package middle
|
||||
|
||||
import (
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func PanicMiddle() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
defer func() {
|
||||
if err := recover(); err == 0 {
|
||||
if err, ok := c.Get(constants.CTXFLG_ERR); ok {
|
||||
rErr(c, -1, err.(string), nil)
|
||||
} else {
|
||||
rErr(c, -1, "Internal error!", nil)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
c.Next()
|
||||
}
|
||||
}
|
@@ -51,7 +51,7 @@ func CheckToken() gin.HandlerFunc {
|
||||
} else {
|
||||
token = c.Query("token")
|
||||
}
|
||||
if _, err := utils.ParseToken(token); err != nil {
|
||||
if _, err := utils.VerifyToken(token); err != nil {
|
||||
rErr(c, -2, "token校验失败", err)
|
||||
return
|
||||
}
|
||||
@@ -73,8 +73,8 @@ func getUser(ctx *gin.Context) (string, error) {
|
||||
} else {
|
||||
token = ctx.Query("token")
|
||||
}
|
||||
if mc, err := utils.ParseToken(token); err == nil && mc != nil {
|
||||
return mc.UserName, nil
|
||||
if mc, err := utils.VerifyToken(token); err == nil && mc != nil {
|
||||
return mc.Username, nil
|
||||
} else {
|
||||
return "", errors.Join(errors.New("用户信息获取失败"), err)
|
||||
}
|
||||
|
@@ -89,10 +89,10 @@ type LogResp struct {
|
||||
|
||||
type ProcessLog struct {
|
||||
Id int `json:"id,omitempty" gorm:"primaryKey;autoIncrement;column:id" `
|
||||
Log string `json:"log" gorm:"column:log" type:"text"`
|
||||
Time int64 `json:"time" gorm:"column:time" type:"long"`
|
||||
Name string `json:"name" gorm:"column:name" type:"text"`
|
||||
Using string `json:"using" gorm:"column:using" type:"keyword"`
|
||||
Log string `json:"log" gorm:"column:log"`
|
||||
Time int64 `json:"time" gorm:"column:time"`
|
||||
Name string `json:"name" gorm:"column:name"`
|
||||
Using string `json:"using" gorm:"column:using"`
|
||||
}
|
||||
|
||||
func (n *ProcessLog) TableName() string {
|
||||
|
@@ -4,3 +4,11 @@ type FileStruct struct {
|
||||
Name string `json:"name"`
|
||||
IsDir bool `json:"isDir"`
|
||||
}
|
||||
|
||||
type FilePathHandlerReq struct {
|
||||
Path string `form:"path" binding:"required"`
|
||||
}
|
||||
|
||||
type FileReadHandlerReq struct {
|
||||
FilePath string `form:"filePath" binding:"required"`
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import "github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
|
||||
type Process struct {
|
||||
Uuid int `gorm:"primaryKey;autoIncrement;column:uuid" json:"uuid"`
|
||||
Name string `gorm:"column:name;uniqueIndex;type:text" json:"name"`
|
||||
Name string `gorm:"column:name;uniqueIndex;type:text" json:"name" binding:"required"`
|
||||
Cmd string `gorm:"column:args" json:"cmd"`
|
||||
Cwd string `gorm:"column:cwd" json:"cwd"`
|
||||
AutoRestart bool `gorm:"column:auto_restart" json:"autoRestart"`
|
||||
|
@@ -1,12 +1,9 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
type Task struct {
|
||||
@@ -18,7 +15,7 @@ type Task struct {
|
||||
TriggerEvent *constants.ProcessState `gorm:"column:trigger_event;" json:"triggerEvent" `
|
||||
TriggerTarget *int `gorm:"column:trigger_target;" json:"triggerTarget" `
|
||||
OperationTarget int `gorm:"column:operation_target;NOT NULL" json:"operationTarget" `
|
||||
Cron string `gorm:"column:cron;" json:"cron" `
|
||||
CronExpression string `gorm:"column:cron;" json:"cron" `
|
||||
Enable bool `gorm:"column:enable;" json:"enable" `
|
||||
ApiEnable bool `gorm:"column:api_enable;" json:"apiEnable" `
|
||||
Key *string `gorm:"column:key;" json:"key" `
|
||||
@@ -28,15 +25,6 @@ func (*Task) TableName() string {
|
||||
return "task"
|
||||
}
|
||||
|
||||
type TaskJob struct {
|
||||
Cron *cron.Cron `json:"-"`
|
||||
Task *Task `json:"task"`
|
||||
Running bool `json:"running"`
|
||||
Cancel context.CancelFunc `json:"-"`
|
||||
StartTime time.Time `json:"startTime"`
|
||||
EndTime time.Time `json:"endTime"`
|
||||
}
|
||||
|
||||
type TaskVo struct {
|
||||
Task
|
||||
ProcessName string `gorm:"column:process_name;" json:"processName"`
|
||||
|
@@ -17,3 +17,12 @@ type User struct {
|
||||
func (*User) TableName() string {
|
||||
return "users"
|
||||
}
|
||||
|
||||
type LoginHandlerReq struct {
|
||||
Account string `form:"account" binding:"required"`
|
||||
Password string `form:"password" binding:"required"`
|
||||
}
|
||||
|
||||
type DeleteUserReq struct {
|
||||
Account string `form:"account" binding:"required"`
|
||||
}
|
||||
|
@@ -14,3 +14,14 @@ type WsShare struct {
|
||||
CreateBy string `gorm:"column:create_by" json:"createBy"`
|
||||
Token string `gorm:"column:token" json:"token"`
|
||||
}
|
||||
|
||||
func (WsShare) TableName() string {
|
||||
return "ws_share"
|
||||
}
|
||||
|
||||
type WebsocketHandleReq struct {
|
||||
Uuid int `form:"uuid"`
|
||||
Cols int `form:"cols"`
|
||||
Rows int `form:"rows"`
|
||||
Token string `form:"token"`
|
||||
}
|
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository/query"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/search"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
)
|
||||
|
||||
@@ -18,7 +19,7 @@ func (l *logRepository) InsertLog(data model.ProcessLog) {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *logRepository) SearchLog(req model.GetLogReq) (result []*model.ProcessLog, total int64) {
|
||||
func (l *logRepository) SearchLog(req model.GetLogReq, logQuery []search.Query) (result []*model.ProcessLog, total int64) {
|
||||
q := query.ProcessLog.WithContext(context.TODO())
|
||||
if req.Match.Name != "" {
|
||||
q = q.Where(query.ProcessLog.Name.Eq(req.Match.Name))
|
||||
@@ -26,9 +27,16 @@ func (l *logRepository) SearchLog(req model.GetLogReq) (result []*model.ProcessL
|
||||
if req.Match.Using != "" {
|
||||
q = q.Where(query.ProcessLog.Using.Eq(req.Match.Using))
|
||||
}
|
||||
if req.Match.Log != "" {
|
||||
q = q.Where(query.ProcessLog.Log.Like("%" + req.Match.Log + "%"))
|
||||
|
||||
for _, v := range logQuery {
|
||||
switch v.Cond {
|
||||
case search.Match, search.WildCard:
|
||||
q = q.Where(query.ProcessLog.Log.Like("%" + v.Content + "%"))
|
||||
case search.NotMatch, search.NotWildCard:
|
||||
q = q.Where(query.ProcessLog.Log.NotLike("%" + v.Content + "%"))
|
||||
}
|
||||
}
|
||||
|
||||
if req.Sort == "desc" {
|
||||
q = q.Order(query.ProcessLog.Time.Desc())
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ var ProcessRepository = new(processRepository)
|
||||
|
||||
func (p *processRepository) GetAllProcessConfig() []model.Process {
|
||||
result := []model.Process{}
|
||||
|
||||
tx := db.Find(&result)
|
||||
if tx.Error != nil {
|
||||
log.Logger.Error(tx.Error)
|
||||
@@ -35,17 +34,13 @@ func (p *processRepository) GetProcessConfigByUser(username string) []model.Proc
|
||||
}
|
||||
|
||||
func (p *processRepository) UpdateProcessConfig(process model.Process) error {
|
||||
tx := db.Save(&process)
|
||||
return tx.Error
|
||||
return db.Save(&process).Error
|
||||
}
|
||||
|
||||
func (p *processRepository) AddProcessConfig(process model.Process) (int, error) {
|
||||
tx := db.Create(&process)
|
||||
if tx.Error != nil {
|
||||
log.Logger.Error(tx.Error)
|
||||
return 0, tx.Error
|
||||
}
|
||||
return process.Uuid, nil
|
||||
func (p *processRepository) AddProcessConfig(process model.Process) (id int, err error) {
|
||||
err = db.Create(&process).Error
|
||||
id = process.Uuid
|
||||
return
|
||||
}
|
||||
|
||||
func (p *processRepository) DeleteProcessConfig(uuid int) error {
|
||||
@@ -54,12 +49,7 @@ func (p *processRepository) DeleteProcessConfig(uuid int) error {
|
||||
}).Error
|
||||
}
|
||||
|
||||
func (p *processRepository) GetProcessConfigById(uuid int) model.Process {
|
||||
result := model.Process{}
|
||||
tx := db.Model(&model.Process{}).Where(&model.Process{Uuid: uuid}).First(&result)
|
||||
if tx.Error != nil {
|
||||
log.Logger.Error(tx.Error)
|
||||
return model.Process{}
|
||||
}
|
||||
return result
|
||||
func (p *processRepository) GetProcessConfigById(uuid int) (data model.Process, err error) {
|
||||
err = db.Model(&model.Process{}).Where(&model.Process{Uuid: uuid}).First(&data).Error
|
||||
return
|
||||
}
|
||||
|
@@ -1,13 +1,9 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/constants"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository/query"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type taskRepository struct{}
|
||||
@@ -41,11 +37,6 @@ func (t *taskRepository) DeleteTask(id int) (err error) {
|
||||
}
|
||||
|
||||
func (t *taskRepository) EditTask(data model.Task) (err error) {
|
||||
err = db.Model(&model.Task{}).Where(&model.Task{Id: data.Id}).First(&model.Task{}).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.Model(&model.Task{}).Where(&model.Task{Id: data.Id}).Save(data).Error
|
||||
return
|
||||
}
|
||||
|
@@ -25,20 +25,14 @@ func (u *userRepository) CreateUser(user model.User) error {
|
||||
}
|
||||
|
||||
func (u *userRepository) UpdatePassword(name string, password string) error {
|
||||
tx := db.Model(&model.User{}).Where(&model.User{Account: name}).Updates(&model.User{Password: utils.Md5(password)})
|
||||
return tx.Error
|
||||
return db.Model(&model.User{}).Where(&model.User{Account: name}).Updates(&model.User{Password: utils.Md5(password)}).Error
|
||||
}
|
||||
|
||||
func (u *userRepository) DeleteUser(name string) error {
|
||||
if err := db.Model(&model.User{}).Where(&model.User{Account: name}).First(&model.User{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
tx := db.Delete(&model.User{Account: name})
|
||||
return tx.Error
|
||||
return db.Delete(&model.User{Account: name}).Error
|
||||
}
|
||||
|
||||
func (u *userRepository) GetUserList() []model.User {
|
||||
result := []model.User{}
|
||||
func (u *userRepository) GetUserList() (result []model.User) {
|
||||
db.Find(&result)
|
||||
return result
|
||||
return
|
||||
}
|
||||
|
@@ -51,94 +51,160 @@ func pprofInit(r *gin.Engine) {
|
||||
}
|
||||
|
||||
func routePathInit(r *gin.Engine) {
|
||||
|
||||
apiGroup := r.Group("/api")
|
||||
apiGroup.Use(middle.CheckToken())
|
||||
apiGroup.Use(middle.PanicMiddle())
|
||||
// apiGroup.Use(middle.DemoMiddle())
|
||||
{
|
||||
wsGroup := apiGroup.Group("/ws")
|
||||
{
|
||||
wsGroup.GET("", middle.OprPermission(constants.OPERATION_TERMINAL), api.WsApi.WebsocketHandle)
|
||||
wsGroup.GET("/share", api.WsApi.WebsocketShareHandle)
|
||||
wsGroup.GET("", middle.OprPermission(constants.OPERATION_TERMINAL), bind(api.WsApi.WebsocketHandle, Query))
|
||||
wsGroup.GET("/share", bind(api.WsApi.WebsocketShareHandle, Query))
|
||||
}
|
||||
|
||||
processGroup := apiGroup.Group("/process")
|
||||
{
|
||||
processGroup.DELETE("", middle.OprPermission(constants.OPERATION_STOP), api.ProcApi.KillProcess)
|
||||
processGroup.GET("", api.ProcApi.GetProcessList)
|
||||
processGroup.GET("/wait", middle.ProcessWaitCond.WaitGetMiddel, api.ProcApi.GetProcessList)
|
||||
processGroup.PUT("", middle.OprPermission(constants.OPERATION_START), api.ProcApi.StartProcess)
|
||||
processGroup.PUT("/all", api.ProcApi.StartAllProcess)
|
||||
processGroup.DELETE("/all", api.ProcApi.KillAllProcess)
|
||||
processGroup.POST("/share", middle.RolePermission(constants.ROLE_ADMIN), api.ProcApi.ProcessCreateShare)
|
||||
processGroup.GET("/control", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.ProcessControl)
|
||||
processGroup.DELETE("", middle.OprPermission(constants.OPERATION_STOP), bind(api.ProcApi.KillProcess, Query))
|
||||
processGroup.GET("", bind(api.ProcApi.GetProcessList, None))
|
||||
processGroup.GET("/wait", middle.ProcessWaitCond.WaitGetMiddel, bind(api.ProcApi.GetProcessList, None))
|
||||
processGroup.PUT("", middle.OprPermission(constants.OPERATION_START), bind(api.ProcApi.StartProcess, Query))
|
||||
processGroup.PUT("/all", bind(api.ProcApi.StartAllProcess, None))
|
||||
processGroup.DELETE("/all", bind(api.ProcApi.KillAllProcess, None))
|
||||
processGroup.POST("/share", middle.RolePermission(constants.ROLE_ADMIN), bind(api.ProcApi.ProcessCreateShare, Body))
|
||||
processGroup.GET("/control", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.ProcApi.ProcessControl, Query))
|
||||
|
||||
proConfigGroup := processGroup.Group("/config")
|
||||
{
|
||||
proConfigGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.CreateNewProcess)
|
||||
proConfigGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, api.ProcApi.DeleteNewProcess)
|
||||
proConfigGroup.PUT("", middle.RolePermission(constants.ROLE_ROOT), api.ProcApi.UpdateProcessConfig)
|
||||
proConfigGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), api.ProcApi.GetProcessConfig)
|
||||
proConfigGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.ProcApi.CreateNewProcess, Body))
|
||||
proConfigGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.ProcApi.DeleteNewProcess, Query))
|
||||
proConfigGroup.PUT("", middle.RolePermission(constants.ROLE_ROOT), bind(api.ProcApi.UpdateProcessConfig, Body))
|
||||
proConfigGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), bind(api.ProcApi.GetProcessConfig, Query))
|
||||
}
|
||||
}
|
||||
|
||||
taskGroup := apiGroup.Group("/task")
|
||||
{
|
||||
taskGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.GetTaskById)
|
||||
taskGroup.GET("/all", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.GetTaskList)
|
||||
taskGroup.GET("/all/wait", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitGetMiddel, api.TaskApi.GetTaskList)
|
||||
taskGroup.POST("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.CreateTask)
|
||||
taskGroup.DELETE("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.DeleteTaskById)
|
||||
taskGroup.PUT("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.EditTask)
|
||||
taskGroup.PUT("/enable", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, api.TaskApi.EditTaskEnable)
|
||||
taskGroup.GET("/start", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.StartTask)
|
||||
taskGroup.GET("/stop", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.StopTask)
|
||||
taskGroup.POST("/key", middle.RolePermission(constants.ROLE_ADMIN), api.TaskApi.CreateTaskApiKey)
|
||||
taskGroup.GET("/api-key/:key", api.TaskApi.RunTaskByKey)
|
||||
taskGroup.GET("", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.GetTaskById, Query))
|
||||
taskGroup.GET("/all", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.GetTaskList, None))
|
||||
taskGroup.GET("/all/wait", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitGetMiddel, bind(api.TaskApi.GetTaskList, None))
|
||||
taskGroup.POST("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.CreateTask, Body))
|
||||
taskGroup.DELETE("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.DeleteTaskById, Query))
|
||||
taskGroup.PUT("", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.EditTask, Body))
|
||||
taskGroup.PUT("/enable", middle.RolePermission(constants.ROLE_ADMIN), middle.TaskWaitCond.WaitTriggerMiddel, bind(api.TaskApi.EditTaskEnable, Body))
|
||||
taskGroup.GET("/start", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.StartTask, Query))
|
||||
taskGroup.GET("/stop", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.StopTask, Query))
|
||||
taskGroup.POST("/key", middle.RolePermission(constants.ROLE_ADMIN), bind(api.TaskApi.CreateTaskApiKey, Body))
|
||||
taskGroup.GET("/api-key/:key", bind(api.TaskApi.RunTaskByKey, None))
|
||||
}
|
||||
|
||||
userGroup := apiGroup.Group("/user")
|
||||
{
|
||||
userGroup.POST("/login", api.UserApi.LoginHandler)
|
||||
userGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), api.UserApi.CreateUser)
|
||||
userGroup.PUT("/password", middle.RolePermission(constants.ROLE_USER), api.UserApi.ChangePassword)
|
||||
userGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), api.UserApi.DeleteUser)
|
||||
userGroup.GET("", middle.RolePermission(constants.ROLE_ROOT), api.UserApi.GetUserList)
|
||||
userGroup.POST("/login", bind(api.UserApi.LoginHandler, Body))
|
||||
userGroup.POST("", middle.RolePermission(constants.ROLE_ROOT), bind(api.UserApi.CreateUser, Body))
|
||||
userGroup.PUT("/password", middle.RolePermission(constants.ROLE_USER), bind(api.UserApi.ChangePassword, Body))
|
||||
userGroup.DELETE("", middle.RolePermission(constants.ROLE_ROOT), bind(api.UserApi.DeleteUser, Query))
|
||||
userGroup.GET("", middle.RolePermission(constants.ROLE_ROOT), bind(api.UserApi.GetUserList, None))
|
||||
}
|
||||
|
||||
pushGroup := apiGroup.Group("/push").Use(middle.RolePermission(constants.ROLE_ADMIN))
|
||||
{
|
||||
pushGroup.GET("/list", api.PushApi.GetPushList)
|
||||
pushGroup.GET("", api.PushApi.GetPushById)
|
||||
pushGroup.POST("", api.PushApi.AddPushConfig)
|
||||
pushGroup.PUT("", api.PushApi.UpdatePushConfig)
|
||||
pushGroup.DELETE("", api.PushApi.DeletePushConfig)
|
||||
pushGroup.GET("/list", bind(api.PushApi.GetPushList, None))
|
||||
pushGroup.GET("", bind(api.PushApi.GetPushById, Query))
|
||||
pushGroup.POST("", bind(api.PushApi.AddPushConfig, Body))
|
||||
pushGroup.PUT("", bind(api.PushApi.UpdatePushConfig, Body))
|
||||
pushGroup.DELETE("", bind(api.PushApi.DeletePushConfig, Query))
|
||||
}
|
||||
|
||||
fileGroup := apiGroup.Group("/file").Use(middle.RolePermission(constants.ROLE_ADMIN))
|
||||
{
|
||||
fileGroup.GET("/list", api.FileApi.FilePathHandler)
|
||||
fileGroup.PUT("", api.FileApi.FileWriteHandler)
|
||||
fileGroup.GET("", api.FileApi.FileReadHandler)
|
||||
fileGroup.GET("/list", bind(api.FileApi.FilePathHandler, Query))
|
||||
fileGroup.PUT("", bind(api.FileApi.FileWriteHandler, None))
|
||||
fileGroup.GET("", bind(api.FileApi.FileReadHandler, Query))
|
||||
}
|
||||
|
||||
permissionGroup := apiGroup.Group("/permission").Use(middle.RolePermission(constants.ROLE_ROOT))
|
||||
{
|
||||
permissionGroup.GET("/list", api.PermissionApi.GetPermissionList)
|
||||
permissionGroup.PUT("", middle.ProcessWaitCond.WaitTriggerMiddel, api.PermissionApi.EditPermssion)
|
||||
permissionGroup.GET("/list", bind(api.PermissionApi.GetPermissionList, Query))
|
||||
permissionGroup.PUT("", middle.ProcessWaitCond.WaitTriggerMiddel, bind(api.PermissionApi.EditPermssion, Body))
|
||||
}
|
||||
|
||||
logGroup := apiGroup.Group("/log").Use(middle.RolePermission(constants.ROLE_USER))
|
||||
{
|
||||
logGroup.POST("", api.LogApi.GetLog)
|
||||
logGroup.GET("/running", api.LogApi.GetRunningLog)
|
||||
logGroup.POST("", bind(api.LogApi.GetLog, Body))
|
||||
logGroup.GET("/running", bind(api.LogApi.GetRunningLog, None))
|
||||
}
|
||||
|
||||
configGroup := apiGroup.Group("/config").Use(middle.RolePermission(constants.ROLE_ROOT))
|
||||
{
|
||||
configGroup.GET("", api.ConfigApi.GetSystemConfiguration)
|
||||
configGroup.PUT("", api.ConfigApi.SetSystemConfiguration)
|
||||
configGroup.PUT("/es", api.ConfigApi.EsConfigReload)
|
||||
configGroup.GET("", bind(api.ConfigApi.GetSystemConfiguration, None))
|
||||
configGroup.PUT("", bind(api.ConfigApi.SetSystemConfiguration, None))
|
||||
configGroup.PUT("/log", bind(api.ConfigApi.LogConfigReload, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
None = 0
|
||||
Header = 1 << iota
|
||||
Body
|
||||
Query
|
||||
)
|
||||
|
||||
func bind[T any, R any](fn func(*gin.Context, T) R, bindOption int) func(*gin.Context) {
|
||||
return func(ctx *gin.Context) {
|
||||
var req T
|
||||
if bindOption&Body != 0 {
|
||||
if err := ctx.BindJSON(&req); err != nil {
|
||||
rErr(ctx, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if bindOption&Header != 0 {
|
||||
if err := ctx.BindHeader(&req); err != nil {
|
||||
rErr(ctx, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
if bindOption&Query != 0 {
|
||||
if err := ctx.BindQuery(&req); err != nil {
|
||||
rErr(ctx, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
result := fn(ctx, req)
|
||||
switch v := any(result).(type) {
|
||||
case error:
|
||||
if v != nil {
|
||||
rErr(ctx, v)
|
||||
return
|
||||
} else {
|
||||
ctx.JSON(200, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
})
|
||||
return
|
||||
}
|
||||
case *api.Response:
|
||||
ctx.JSON(v.StatusCode, gin.H{
|
||||
"data": v.Data,
|
||||
"msg": v.Msg,
|
||||
"code": v.Code,
|
||||
})
|
||||
return
|
||||
default:
|
||||
ctx.JSON(200, gin.H{
|
||||
"code": 0,
|
||||
"message": "success",
|
||||
"data": v,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func rErr(ctx *gin.Context, err error) {
|
||||
log.Logger.Warn(err)
|
||||
ctx.JSON(500, gin.H{
|
||||
"code": -1,
|
||||
"message": err.Error(),
|
||||
})
|
||||
}
|
||||
|
169
internal/app/search/bleve/bleve.go
Normal file
169
internal/app/search/bleve/bleve.go
Normal file
@@ -0,0 +1,169 @@
|
||||
//go:build !slim
|
||||
// +build !slim
|
||||
|
||||
package bleve
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/blevesearch/bleve/v2"
|
||||
"github.com/blevesearch/bleve/v2/search"
|
||||
_ "github.com/blevesearch/bleve/v2/search/highlight/highlighter/ansi"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
sr "github.com/lzh-1625/go_process_manager/internal/app/search"
|
||||
logger "github.com/lzh-1625/go_process_manager/log"
|
||||
gse "github.com/vcaesar/gse-bleve"
|
||||
// gse "github.com/lzh-1625/gse-bleve"
|
||||
)
|
||||
|
||||
func init() {
|
||||
sr.Register("bleve", new(bleveSearch))
|
||||
}
|
||||
|
||||
type bleveSearch struct {
|
||||
index bleve.Index
|
||||
}
|
||||
|
||||
func (b *bleveSearch) Init() error {
|
||||
opt := gse.Option{
|
||||
Dicts: "embed, zh_s",
|
||||
Stop: "",
|
||||
Opt: "search-hmm",
|
||||
Trim: "trim",
|
||||
}
|
||||
indexMapping, err := gse.NewMapping(opt)
|
||||
if err != nil {
|
||||
logger.Logger.Errorw("bleve init fail", "err", err)
|
||||
return err
|
||||
}
|
||||
mapping := bleve.NewDocumentMapping()
|
||||
log := bleve.NewTextFieldMapping()
|
||||
log.Index = true
|
||||
time := bleve.NewNumericFieldMapping()
|
||||
time.Index = true
|
||||
name := bleve.NewKeywordFieldMapping()
|
||||
name.Index = true
|
||||
using := bleve.NewKeywordFieldMapping()
|
||||
using.Index = true
|
||||
mapping.AddFieldMappingsAt("log", log)
|
||||
mapping.AddFieldMappingsAt("time", time)
|
||||
mapping.AddFieldMappingsAt("name", name)
|
||||
mapping.AddFieldMappingsAt("using", using)
|
||||
indexMapping.AddDocumentMapping("server_log_v1", mapping)
|
||||
index, err := bleve.Open("log.bleve")
|
||||
if err != nil {
|
||||
index, err = bleve.New("log.bleve", indexMapping)
|
||||
if err != nil {
|
||||
logger.Logger.Errorw("bleve init error", "err", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
b.index = index
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *bleveSearch) Insert(logContent string, processName string, using string, ts int64) {
|
||||
if err := b.index.Index(uuid.NewString(), model.ProcessLog{
|
||||
Log: logContent,
|
||||
Name: processName,
|
||||
Using: using,
|
||||
Time: ts,
|
||||
}); err != nil {
|
||||
logger.Logger.Warnw("bleve log insert failed", "err", err)
|
||||
}
|
||||
fmt.Printf("using: %v\n", using)
|
||||
}
|
||||
|
||||
func (b *bleveSearch) Search(req model.GetLogReq, filterProcessName ...string) (result model.LogResp) {
|
||||
buildQuery := bleve.NewBooleanQuery()
|
||||
for _, v := range sr.QueryStringAnalysis(req.Match.Log) {
|
||||
switch v.Cond {
|
||||
case sr.Match, sr.WildCard:
|
||||
logQuery := bleve.NewMatchQuery(v.Content)
|
||||
logQuery.SetField("log")
|
||||
buildQuery.AddMust(logQuery)
|
||||
case sr.NotMatch, sr.NotWildCard:
|
||||
logQuery := bleve.NewMatchQuery(v.Content)
|
||||
logQuery.SetField("log")
|
||||
buildQuery.AddMustNot(logQuery)
|
||||
// case sr.WildCard:
|
||||
// logQuery := bleve.NewWildcardQuery("*" + v.Content + "*")
|
||||
// logQuery.SetField("log")
|
||||
// buildQuery.AddMust(logQuery)
|
||||
// case sr.NotWildCard:
|
||||
// logQuery := bleve.NewWildcardQuery("*" + v.Content + "*")
|
||||
// logQuery.SetField("log")
|
||||
// buildQuery.AddMustNot(logQuery)
|
||||
}
|
||||
}
|
||||
if req.Match.Name != "" {
|
||||
nameQuery := bleve.NewTermQuery(req.Match.Name)
|
||||
nameQuery.SetField("name")
|
||||
buildQuery.AddMust(nameQuery)
|
||||
}
|
||||
if req.Match.Using != "" {
|
||||
usingQuery := bleve.NewWildcardQuery("*" + req.Match.Using + "*")
|
||||
usingQuery.SetField("using")
|
||||
buildQuery.AddMust(usingQuery)
|
||||
}
|
||||
if req.TimeRange.EndTime != 0 || req.TimeRange.StartTime != 0 {
|
||||
st := float64(req.TimeRange.StartTime)
|
||||
et := float64(req.TimeRange.EndTime)
|
||||
timeQuery := bleve.NewNumericRangeQuery(&st, &et)
|
||||
buildQuery.AddMust(timeQuery)
|
||||
} else {
|
||||
st := float64(0)
|
||||
et := float64(time.Now().UnixMilli())
|
||||
timeQuery := bleve.NewNumericRangeQuery(&st, &et)
|
||||
buildQuery.AddMust(timeQuery)
|
||||
}
|
||||
if len(filterProcessName) != 0 {
|
||||
for _, v := range filterProcessName {
|
||||
filterQuery := bleve.NewTermQuery(v)
|
||||
filterQuery.SetField("name")
|
||||
buildQuery.AddShould(filterQuery)
|
||||
}
|
||||
}
|
||||
sortArgs := ([]string{"-_score"})
|
||||
if req.Sort == "desc" {
|
||||
|
||||
sortArgs = ([]string{"-time"})
|
||||
}
|
||||
if req.Sort == "asc" {
|
||||
sortArgs = ([]string{"time"})
|
||||
}
|
||||
hl := bleve.HighlightRequest{}
|
||||
hl.AddField("log")
|
||||
style := "ansi"
|
||||
res, err := b.index.Search(&bleve.SearchRequest{
|
||||
Query: buildQuery,
|
||||
Fields: []string{"log", "name", "using", "time"},
|
||||
From: req.Page.From,
|
||||
Size: req.Page.Size,
|
||||
Sort: search.ParseSortOrderStrings(sortArgs),
|
||||
Highlight: &bleve.HighlightRequest{
|
||||
Style: &style,
|
||||
Fields: []string{"log"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
logger.Logger.Warnw("bleve search failed", "err", err)
|
||||
return
|
||||
}
|
||||
data := []*model.ProcessLog{}
|
||||
for _, v := range res.Hits {
|
||||
data = append(data, &model.ProcessLog{
|
||||
Log: v.Fragments["log"][0],
|
||||
Time: int64(v.Fields["time"].(float64)),
|
||||
Using: v.Fields["using"].(string),
|
||||
Name: v.Fields["name"].(string),
|
||||
})
|
||||
}
|
||||
|
||||
result.Data = data
|
||||
result.Total = int64(res.Total)
|
||||
return
|
||||
}
|
4
internal/app/search/bleve/bleve_ignore.go
Normal file
4
internal/app/search/bleve/bleve_ignore.go
Normal file
@@ -0,0 +1,4 @@
|
||||
//go:build slim
|
||||
// +build slim
|
||||
|
||||
package bleve
|
@@ -1,36 +1,31 @@
|
||||
package logic
|
||||
package es
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
sr "github.com/lzh-1625/go_process_manager/internal/app/search"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
|
||||
"github.com/olivere/elastic/v7"
|
||||
)
|
||||
|
||||
type esLogic struct {
|
||||
func init() {
|
||||
sr.Register("es", new(esSearch))
|
||||
}
|
||||
|
||||
type esSearch struct {
|
||||
esClient *elastic.Client
|
||||
}
|
||||
|
||||
var (
|
||||
EsLogic = new(esLogic)
|
||||
)
|
||||
|
||||
func (e *esLogic) InitEs() bool {
|
||||
if !config.CF.EsEnable {
|
||||
log.Logger.Debug("不使用es")
|
||||
return false
|
||||
}
|
||||
|
||||
func (e *esSearch) Init() error {
|
||||
var err error
|
||||
EsLogic.esClient, err = elastic.NewClient(
|
||||
e.esClient, err = elastic.NewClient(
|
||||
elastic.SetURL(config.CF.EsUrl),
|
||||
elastic.SetBasicAuth(config.CF.EsUsername, config.CF.EsPassword),
|
||||
elastic.SetSniff(false),
|
||||
@@ -42,15 +37,13 @@ func (e *esLogic) InitEs() bool {
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
config.CF.EsEnable = false
|
||||
log.Logger.Warnw("Failed to connect to es", "err", err)
|
||||
return false
|
||||
return err
|
||||
}
|
||||
EsLogic.CreateIndexIfNotExists(config.CF.EsIndex)
|
||||
return true
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *esLogic) Insert(logContent string, processName string, using string, ts int64) {
|
||||
func (e *esSearch) Insert(logContent string, processName string, using string, ts int64) {
|
||||
data := model.ProcessLog{
|
||||
Log: logContent,
|
||||
Name: processName,
|
||||
@@ -63,28 +56,7 @@ func (e *esLogic) Insert(logContent string, processName string, using string, ts
|
||||
}
|
||||
}
|
||||
|
||||
func (e *esLogic) CreateIndexIfNotExists(index string) error {
|
||||
|
||||
ctx := context.Background()
|
||||
exists, err := e.esClient.IndexExists(index).Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if exists {
|
||||
return nil
|
||||
}
|
||||
|
||||
info, err := e.esClient.CreateIndex(index).BodyString(e.structToJSON()).Do(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !info.Acknowledged {
|
||||
return fmt.Errorf("ES 创建索引 [%s] 失败", index)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
|
||||
func (e *esSearch) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
|
||||
// 检查 req 是否为 nil
|
||||
if req.Page.From < 0 || req.Page.Size <= 0 {
|
||||
log.Logger.Error("无效的分页请求参数")
|
||||
@@ -107,16 +79,29 @@ func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model
|
||||
if req.TimeRange.EndTime != 0 {
|
||||
queryList = append(queryList, timeRangeQuery.Lte(req.TimeRange.EndTime))
|
||||
}
|
||||
if req.Match.Log != "" {
|
||||
queryList = append(queryList, elastic.NewMatchQuery("log", req.Match.Log))
|
||||
notQuery := []elastic.Query{}
|
||||
|
||||
for _, v := range sr.QueryStringAnalysis(req.Match.Log) {
|
||||
switch v.Cond {
|
||||
case sr.Match:
|
||||
queryList = append(queryList, elastic.NewMatchQuery("log", v.Content))
|
||||
case sr.NotMatch:
|
||||
notQuery = append(notQuery, elastic.NewMatchQuery("log", v.Content))
|
||||
case sr.WildCard:
|
||||
queryList = append(queryList, elastic.NewWildcardQuery("log.keyword", "*"+v.Content+"*"))
|
||||
case sr.NotWildCard:
|
||||
notQuery = append(notQuery, elastic.NewWildcardQuery("log.keyword", "*"+v.Content+"*"))
|
||||
}
|
||||
fmt.Printf("v.Cond: %v\n", v.Cond)
|
||||
fmt.Printf("v.Content: %v\n", v.Content)
|
||||
}
|
||||
|
||||
if req.Match.Name != "" {
|
||||
queryList = append(queryList, elastic.NewMatchQuery("name", req.Match.Name))
|
||||
}
|
||||
if req.Match.Using != "" {
|
||||
queryList = append(queryList, elastic.NewMatchQuery("using", req.Match.Using))
|
||||
}
|
||||
|
||||
if len(filterProcessName) != 0 { // 过滤进程名
|
||||
shouldQueryList := []elastic.Query{}
|
||||
for _, fpn := range filterProcessName {
|
||||
@@ -129,7 +114,7 @@ func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model
|
||||
}
|
||||
|
||||
result := model.LogResp{}
|
||||
resp, err := search.Query(elastic.NewBoolQuery().Must(queryList...)).Do(context.TODO())
|
||||
resp, err := search.Query(elastic.NewBoolQuery().Must(queryList...).MustNot(notQuery...)).Highlight(elastic.NewHighlight().Field("log").PreTags("\033[43m").PostTags("\033[0m")).Do(context.TODO())
|
||||
if err != nil {
|
||||
log.Logger.Errorw("es查询失败", "err", err, "reason", resp.Error.Reason)
|
||||
return result
|
||||
@@ -140,6 +125,9 @@ func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model
|
||||
if v.Source != nil {
|
||||
var data model.ProcessLog
|
||||
if err := json.Unmarshal(v.Source, &data); err == nil {
|
||||
if len(v.Highlight) > 0 && len(v.Highlight["log"]) > 0 {
|
||||
data.Log = v.Highlight["log"][0]
|
||||
}
|
||||
result.Data = append(result.Data, &data)
|
||||
} else {
|
||||
log.Logger.Errorw("JSON 解码失败", "err", err)
|
||||
@@ -150,28 +138,3 @@ func (e *esLogic) Search(req model.GetLogReq, filterProcessName ...string) model
|
||||
result.Total = resp.TotalHits()
|
||||
return result
|
||||
}
|
||||
|
||||
// 通过反射得到mapping
|
||||
func (e *esLogic) structToJSON() string {
|
||||
typ := reflect.TypeOf(model.ProcessLog{})
|
||||
properties := make(map[string]map[string]string)
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
field := typ.Field(i)
|
||||
fieldTag := field.Tag.Get("type")
|
||||
if fieldTag != "" {
|
||||
properties[field.Tag.Get("json")] = map[string]string{
|
||||
"type": fieldTag,
|
||||
}
|
||||
}
|
||||
}
|
||||
result := map[string]interface{}{
|
||||
"mappings": map[string]interface{}{
|
||||
"properties": properties,
|
||||
},
|
||||
}
|
||||
jsonData, err := json.Marshal(result)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return string(jsonData)
|
||||
}
|
69
internal/app/search/search.go
Normal file
69
internal/app/search/search.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/log"
|
||||
)
|
||||
|
||||
type LogLogic interface {
|
||||
Search(req model.GetLogReq, filterProcessName ...string) model.LogResp
|
||||
Insert(log string, processName string, using string, ts int64)
|
||||
Init() error
|
||||
}
|
||||
|
||||
var searchImplMap map[string]LogLogic = map[string]LogLogic{}
|
||||
|
||||
func Register(name string, impl LogLogic) {
|
||||
searchImplMap[name] = impl
|
||||
}
|
||||
|
||||
func GetSearchImpl(name string) LogLogic {
|
||||
v, ok := searchImplMap[name]
|
||||
if ok {
|
||||
return v
|
||||
}
|
||||
log.Logger.Warnw("未找到对应的存储引擎,使用默认[sqlite]", "name", name)
|
||||
return searchImplMap["sqlite"]
|
||||
}
|
||||
|
||||
type Cond int
|
||||
|
||||
const (
|
||||
Match Cond = iota // ^
|
||||
WildCard // ~
|
||||
NotMatch // !^
|
||||
NotWildCard // !~
|
||||
)
|
||||
|
||||
type Query struct {
|
||||
Cond Cond
|
||||
Content string
|
||||
}
|
||||
|
||||
func QueryStringAnalysis(s string) (query []Query) {
|
||||
if strings.TrimSpace(s) == "" {
|
||||
return
|
||||
}
|
||||
strList := strings.Split(s, " ")
|
||||
for _, v := range strList {
|
||||
switch {
|
||||
case strings.HasPrefix(v, "!^"):
|
||||
query = append(query, Query{NotMatch, v[2:]})
|
||||
case strings.HasPrefix(v, "!~"):
|
||||
query = append(query, Query{NotWildCard, v[2:]})
|
||||
case strings.HasPrefix(v, "!"):
|
||||
query = append(query, Query{NotMatch, v[1:]})
|
||||
case strings.HasPrefix(v, "^"):
|
||||
query = append(query, Query{Match, v[1:]})
|
||||
case strings.HasPrefix(v, "~"):
|
||||
query = append(query, Query{WildCard, v[1:]})
|
||||
default:
|
||||
query = append(query, Query{Match, v})
|
||||
}
|
||||
}
|
||||
fmt.Printf("query: %v\n", query)
|
||||
return
|
||||
}
|
47
internal/app/search/sqlite/sqlite.go
Normal file
47
internal/app/search/sqlite/sqlite.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package sqlite
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/model"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/repository"
|
||||
"github.com/lzh-1625/go_process_manager/internal/app/search"
|
||||
)
|
||||
|
||||
func init() {
|
||||
search.Register("sqlite", new(sqliteSearch))
|
||||
}
|
||||
|
||||
type sqliteSearch struct{}
|
||||
|
||||
func (l *sqliteSearch) Search(req model.GetLogReq, filterProcessName ...string) model.LogResp {
|
||||
req.FilterName = filterProcessName
|
||||
query := search.QueryStringAnalysis(req.Match.Log)
|
||||
data, total := repository.LogRepository.SearchLog(req, query)
|
||||
for _, v := range slices.DeleteFunc(query, func(q search.Query) bool {
|
||||
return q.Cond == search.NotMatch || q.Cond == search.NotWildCard
|
||||
}) {
|
||||
for i := range data {
|
||||
data[i].Log = strings.ReplaceAll(data[i].Log, v.Content, "\033[43m"+v.Content+"\033[0m")
|
||||
}
|
||||
}
|
||||
|
||||
return model.LogResp{
|
||||
Data: data,
|
||||
Total: total,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *sqliteSearch) Insert(log string, processName string, using string, ts int64) {
|
||||
repository.LogRepository.InsertLog(model.ProcessLog{
|
||||
Log: log,
|
||||
Name: processName,
|
||||
Using: using,
|
||||
Time: ts,
|
||||
})
|
||||
}
|
||||
|
||||
func (l *sqliteSearch) Init() error {
|
||||
return nil
|
||||
}
|
51
log/log.go
51
log/log.go
@@ -5,57 +5,13 @@ import (
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
|
||||
"github.com/timandy/routine"
|
||||
"go.uber.org/zap"
|
||||
"go.uber.org/zap/zapcore"
|
||||
)
|
||||
|
||||
var Logger *logWithAdditional
|
||||
|
||||
type logWithAdditional struct {
|
||||
*zap.SugaredLogger
|
||||
threadLocal routine.ThreadLocal[[]any]
|
||||
}
|
||||
|
||||
func (l *logWithAdditional) Infow(msg string, keysAndValues ...interface{}) {
|
||||
keysAndValues = append(keysAndValues, l.threadLocal.Get()...)
|
||||
l.SugaredLogger.WithOptions(zap.AddCallerSkip(1)).Infow(msg, keysAndValues...)
|
||||
}
|
||||
|
||||
func (l *logWithAdditional) Debugw(msg string, keysAndValues ...interface{}) {
|
||||
keysAndValues = append(keysAndValues, l.threadLocal.Get()...)
|
||||
l.SugaredLogger.WithOptions(zap.AddCallerSkip(1)).Debugw(msg, keysAndValues...)
|
||||
}
|
||||
|
||||
func (l *logWithAdditional) Errorw(msg string, keysAndValues ...interface{}) {
|
||||
keysAndValues = append(keysAndValues, l.threadLocal.Get()...)
|
||||
l.SugaredLogger.WithOptions(zap.AddCallerSkip(1)).Errorw(msg, keysAndValues...)
|
||||
}
|
||||
|
||||
func (l *logWithAdditional) Warnw(msg string, keysAndValues ...interface{}) {
|
||||
keysAndValues = append(keysAndValues, l.threadLocal.Get()...)
|
||||
l.SugaredLogger.WithOptions(zap.AddCallerSkip(1)).Warnw(msg, keysAndValues...)
|
||||
}
|
||||
|
||||
func (l *logWithAdditional) AddAdditionalInfo(k, v any) {
|
||||
l.threadLocal.Set(append(l.threadLocal.Get(), k, v))
|
||||
}
|
||||
|
||||
func (l *logWithAdditional) DeleteAdditionalInfo(layer int) {
|
||||
if layer < 0 {
|
||||
l.threadLocal.Set([]any{})
|
||||
return
|
||||
}
|
||||
oldKv := l.threadLocal.Get()
|
||||
if len(oldKv) < layer*2 {
|
||||
l.threadLocal.Set([]any{})
|
||||
return
|
||||
}
|
||||
l.threadLocal.Set(oldKv[:len(oldKv)-2*layer])
|
||||
}
|
||||
var Logger *zap.SugaredLogger
|
||||
|
||||
func InitLog() {
|
||||
|
||||
encoderConfig := zapcore.EncoderConfig{
|
||||
TimeKey: "time",
|
||||
LevelKey: "level",
|
||||
@@ -89,8 +45,5 @@ func InitLog() {
|
||||
ErrorOutputPaths: []string{"stderr"},
|
||||
}
|
||||
log, _ := config.Build()
|
||||
Logger = &logWithAdditional{
|
||||
SugaredLogger: log.Sugar(),
|
||||
threadLocal: routine.NewThreadLocal[[]any](),
|
||||
}
|
||||
Logger = log.Sugar()
|
||||
}
|
||||
|
82
utils/jwt.go
82
utils/jwt.go
@@ -1,67 +1,59 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/lzh-1625/go_process_manager/config"
|
||||
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
var mySecret []byte
|
||||
|
||||
func SetSecret(secret []byte) {
|
||||
mySecret = secret
|
||||
}
|
||||
|
||||
func keyFunc(_ *jwt.Token) (i interface{}, err error) {
|
||||
return mySecret, nil
|
||||
}
|
||||
var jwtKey []byte
|
||||
|
||||
type MyClaims struct {
|
||||
UserName string `json:"user_name"`
|
||||
jwt.StandardClaims
|
||||
Username string `json:"username"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
func GenToken(UserName string) (string, error) {
|
||||
// 创建一个我们自己的声明的数据
|
||||
c := MyClaims{
|
||||
UserName,
|
||||
jwt.StandardClaims{
|
||||
ExpiresAt: time.Now().Add(
|
||||
time.Duration(config.CF.TokenExpirationTime) * time.Hour).Unix(), // 过期时间
|
||||
Issuer: "jwt", // 签发人
|
||||
func SetSecret(secret []byte) {
|
||||
jwtKey = []byte(secret)
|
||||
}
|
||||
|
||||
func GenerateToken(username string) (string, error) {
|
||||
expirationTime := time.Now().Add(3 * 24 * time.Hour)
|
||||
|
||||
claims := &MyClaims{
|
||||
Username: username,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(expirationTime),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
NotBefore: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
// 使用指定的签名方法创建签名对象
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
|
||||
return token.SignedString(mySecret)
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
|
||||
tokenString, err := token.SignedString(jwtKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tokenString, nil
|
||||
}
|
||||
|
||||
func ParseToken(tokenString string) (*MyClaims, error) {
|
||||
var mc = new(MyClaims)
|
||||
token, err := jwt.ParseWithClaims(tokenString, mc, keyFunc)
|
||||
func VerifyToken(tokenString string) (*MyClaims, error) {
|
||||
claims := &MyClaims{}
|
||||
|
||||
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) {
|
||||
return jwtKey, nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if token.Valid {
|
||||
return mc, nil
|
||||
}
|
||||
return nil, errors.New("invalid token")
|
||||
}
|
||||
|
||||
func RefreshToken(aToken, rToken string) (newAToken, newRToken string, err error) {
|
||||
if _, err = jwt.Parse(rToken, keyFunc); err != nil {
|
||||
return
|
||||
if !token.Valid {
|
||||
return nil, fmt.Errorf("invalid token")
|
||||
}
|
||||
var claims MyClaims
|
||||
_, err = jwt.ParseWithClaims(aToken, &claims, keyFunc)
|
||||
v, _ := err.(*jwt.ValidationError)
|
||||
|
||||
if v.Errors == jwt.ValidationErrorExpired {
|
||||
token, _ := GenToken(claims.UserName)
|
||||
return token, "", nil
|
||||
}
|
||||
return
|
||||
return claims, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user