├── pkg ├── geoip │ ├── geoip.db │ └── geoip.go ├── ddns │ ├── dummy │ │ └── dummy.go │ ├── ddns_test.go │ └── webhook │ │ └── webhook_test.go ├── oidc │ ├── cloudflare │ │ └── cloudflare.go │ └── general │ │ └── general.go ├── utils │ ├── hfs.go │ ├── gjson.go │ ├── request_wrapper.go │ ├── http.go │ ├── utils_test.go │ ├── utils.go │ └── jsonx.go ├── mygin │ ├── preferred_theme.go │ ├── error.go │ ├── view_password.go │ ├── mygin.go │ └── auth.go ├── websocketx │ └── safe_conn.go └── grpcx │ └── io_stream_wrapper.go ├── resource ├── template │ ├── theme-default │ │ ├── README.md │ │ ├── theme.json │ │ ├── footer.html │ │ ├── viewpassword.html │ │ ├── header.html │ │ └── menu.html │ ├── component │ │ ├── confirm.html │ │ ├── api.html │ │ ├── nat.html │ │ ├── rule.html │ │ ├── notification.html │ │ ├── cron.html │ │ ├── ddns.html │ │ └── monitor.html │ ├── dashboard-default │ │ ├── redirect.html │ │ ├── error.html │ │ ├── login.html │ │ ├── nat.html │ │ ├── ddns.html │ │ ├── monitor.html │ │ ├── api.html │ │ ├── cron.html │ │ └── terminal.html │ └── common │ │ ├── footer.html │ │ ├── header.html │ │ └── menu.html └── static │ ├── favicon.ico │ ├── webfonts │ ├── fa-thin-100.ttf │ ├── fa-brands-400.ttf │ ├── fa-brands-400.woff │ ├── fa-duotone-900.ttf │ ├── fa-light-300.ttf │ ├── fa-light-300.woff │ ├── fa-light-300.woff2 │ ├── fa-regular-400.ttf │ ├── fa-solid-900.ttf │ ├── fa-solid-900.woff │ ├── fa-solid-900.woff2 │ ├── fa-thin-100.woff │ ├── fa-thin-100.woff2 │ ├── fa-brands-400.woff2 │ ├── fa-duotone-900.woff │ ├── fa-duotone-900.woff2 │ ├── fa-regular-400.woff │ ├── fa-regular-400.woff2 │ ├── fa-sharp-thin-100.woff2 │ ├── fa-v4compatibility.ttf │ ├── fa-duotone-thin-100.woff2 │ ├── fa-sharp-light-300.woff2 │ ├── fa-sharp-solid-900.woff2 │ ├── fa-v4compatibility.woff2 │ ├── fa-duotone-light-300.woff2 │ ├── fa-duotone-regular-400.woff2 │ ├── fa-sharp-regular-400.woff2 │ ├── fa-sharp-duotone-light-300.woff2 │ ├── fa-sharp-duotone-solid-900.woff2 │ ├── fa-sharp-duotone-thin-100.woff2 │ └── fa-sharp-duotone-regular-400.woff2 │ ├── mixin.js │ └── file.js ├── .gitattributes ├── proto.sh ├── script ├── proto.sh ├── docker-compose.yaml ├── entrypoint-simple.sh ├── server-agent.service ├── server-dash.service ├── dash-config.yaml ├── build-for-docker.sh ├── com.serverstatus.agent.plist ├── entrypoint.sh ├── run-with-prebuilt.sh ├── server-agent.openrc ├── verify-build.sh ├── config.yml ├── test-entrypoint.sh └── fix-permissions.sh ├── model ├── nat.go ├── api_token.go ├── transfer.go ├── api.go ├── common.go ├── server_test.go ├── monitor_history.go ├── cron.go ├── user.go ├── ddns.go ├── server.go ├── alertrule.go ├── host.go └── monitor.go ├── .github ├── workflows │ ├── sync-code.yml │ └── test.yml └── FUNDING.yml ├── .gitignore ├── k8s ├── ingress.yaml └── deployment.yaml ├── .dockerignore ├── service └── singleton │ ├── l10n.go │ └── nat.go ├── Dockerfile.minimal ├── .goreleaser.yml ├── proto └── server.proto ├── Dockerfile ├── docs └── migration.md ├── Dockerfile.debug ├── cmd ├── dashboard │ └── controller │ │ └── guest_page.go └── migrate │ └── main.go ├── README.md ├── go.mod └── db └── access_optimizer.go /pkg/geoip/geoip.db: -------------------------------------------------------------------------------- 1 | stub -------------------------------------------------------------------------------- /resource/template/theme-default/README.md: -------------------------------------------------------------------------------- 1 | # 默认主题 -------------------------------------------------------------------------------- /resource/template/theme-default/theme.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Default" 3 | } 4 | -------------------------------------------------------------------------------- /resource/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/favicon.ico -------------------------------------------------------------------------------- /resource/static/webfonts/fa-thin-100.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-thin-100.ttf -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | resource/** linguist-vendored 2 | resource/static/* !linguist-vendored 3 | resource/template/dashboard/* !linguist-vendored -------------------------------------------------------------------------------- /resource/static/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /resource/static/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /resource/static/webfonts/fa-duotone-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-duotone-900.ttf -------------------------------------------------------------------------------- /resource/static/webfonts/fa-light-300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-light-300.ttf -------------------------------------------------------------------------------- /resource/static/webfonts/fa-light-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-light-300.woff -------------------------------------------------------------------------------- /resource/static/webfonts/fa-light-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-light-300.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /resource/static/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /resource/static/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /resource/static/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-thin-100.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-thin-100.woff -------------------------------------------------------------------------------- /resource/static/webfonts/fa-thin-100.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-thin-100.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-duotone-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-duotone-900.woff -------------------------------------------------------------------------------- /resource/static/webfonts/fa-duotone-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-duotone-900.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /resource/static/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /proto.sh: -------------------------------------------------------------------------------- 1 | protoc --go-grpc_out="require_unimplemented_servers=false:." --go_out="." proto/*.proto 2 | rm -rf ../agent/proto 3 | cp -r proto ../agent -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-thin-100.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-thin-100.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-v4compatibility.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-v4compatibility.ttf -------------------------------------------------------------------------------- /resource/static/webfonts/fa-duotone-thin-100.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-duotone-thin-100.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-light-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-light-300.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-solid-900.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-v4compatibility.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-v4compatibility.woff2 -------------------------------------------------------------------------------- /script/proto.sh: -------------------------------------------------------------------------------- 1 | protoc --go-grpc_out="require_unimplemented_servers=false:." --go_out="." proto/*.proto 2 | rm -rf ../agent/proto 3 | cp -r proto ../agent -------------------------------------------------------------------------------- /resource/static/webfonts/fa-duotone-light-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-duotone-light-300.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-duotone-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-duotone-regular-400.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-regular-400.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-duotone-light-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-duotone-light-300.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-duotone-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-duotone-solid-900.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-duotone-thin-100.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-duotone-thin-100.woff2 -------------------------------------------------------------------------------- /resource/static/webfonts/fa-sharp-duotone-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xOS/ServerStatus/HEAD/resource/static/webfonts/fa-sharp-duotone-regular-400.woff2 -------------------------------------------------------------------------------- /model/nat.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type NAT struct { 4 | Common 5 | Name string 6 | ServerID uint64 7 | Host string 8 | Domain string `gorm:"unique"` 9 | } 10 | -------------------------------------------------------------------------------- /model/api_token.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type ApiToken struct { 4 | Common 5 | UserID uint64 `json:"user_id"` 6 | Token string `json:"token"` 7 | Note string `json:"note"` 8 | } 9 | -------------------------------------------------------------------------------- /model/transfer.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type Transfer struct { 4 | Common 5 | ServerID uint64 `gorm:"index" json:"server_id"` 6 | In uint64 `json:"in"` 7 | Out uint64 `json:"out"` 8 | } -------------------------------------------------------------------------------- /pkg/ddns/dummy/dummy.go: -------------------------------------------------------------------------------- 1 | package dummy 2 | 3 | import ( 4 | "context" 5 | 6 | "github.com/libdns/libdns" 7 | ) 8 | 9 | // Internal use 10 | type Provider struct { 11 | } 12 | 13 | func (provider *Provider) SetRecords(ctx context.Context, zone string, 14 | recs []libdns.Record) ([]libdns.Record, error) { 15 | return recs, nil 16 | } 17 | -------------------------------------------------------------------------------- /.github/workflows/sync-code.yml: -------------------------------------------------------------------------------- 1 | name: Sync 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | 7 | jobs: 8 | sync-to-gitee: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: adambirds/sync-github-to-gitlab-action@v1.1.0 13 | with: 14 | destination_repository: git@gitee.com:Ten/ServerStatus.git 15 | destination_branch_name: master 16 | destination_ssh_key: ${{ secrets.GITEE_SSH_KEY }} 17 | -------------------------------------------------------------------------------- /model/api.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | type ServiceItemResponse struct { 4 | Monitor *Monitor 5 | CurrentUp uint64 6 | CurrentDown uint64 7 | TotalUp uint64 8 | TotalDown uint64 9 | Delay *[30]float32 10 | Up *[30]int 11 | Down *[30]int 12 | } 13 | 14 | func (r ServiceItemResponse) TotalUptime() float32 { 15 | if r.TotalUp+r.TotalDown == 0 { 16 | return 0 17 | } 18 | return float32(r.TotalUp) / (float32(r.TotalUp + r.TotalDown)) * 100 19 | } 20 | -------------------------------------------------------------------------------- /resource/template/component/confirm.html: -------------------------------------------------------------------------------- 1 | {{define "component/confirm"}} 2 |
12 | {{end}} -------------------------------------------------------------------------------- /script/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.3" 2 | 3 | services: 4 | dashboard: 5 | image: image_url 6 | restart: always 7 | volumes: 8 | - ./data:/dashboard/data 9 | - ./static-custom/static:/dashboard/resource/static/custom:ro 10 | - ./theme-custom/template:/dashboard/resource/template/theme-custom:ro 11 | - ./dashboard-custom/template:/dashboard/resource/template/dashboard-custom:ro 12 | ports: 13 | - site_port:site_port 14 | - grpc_port:grpc_port -------------------------------------------------------------------------------- /resource/template/dashboard-default/redirect.html: -------------------------------------------------------------------------------- 1 | {{define "dashboard-default/redirect"}} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |If you are not redirected, please click here.
14 | 15 | 16 | 17 | 18 | {{end}} -------------------------------------------------------------------------------- /pkg/oidc/cloudflare/cloudflare.go: -------------------------------------------------------------------------------- 1 | package cloudflare 2 | 3 | import ( 4 | "github.com/xos/serverstatus/model" 5 | "github.com/xos/serverstatus/service/singleton" 6 | ) 7 | 8 | type UserInfo struct { 9 | Sub string `json:"sub"` 10 | Email string `json:"email"` 11 | Name string `json:"name"` 12 | Groups []string `json:"groups"` 13 | } 14 | 15 | func (u UserInfo) MapToServerUser() model.User { 16 | var user model.User 17 | singleton.DB.Where("login = ?", u.Sub).First(&user) 18 | user.Login = u.Sub 19 | user.Email = u.Email 20 | user.Name = u.Name 21 | return user 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | *.pprof 14 | .idea 15 | /data 16 | /dist 17 | .DS_Store 18 | /main 19 | /cmd/agent/main 20 | /cmd/dashboard/main 21 | /config.yml 22 | /resource/template/theme-custom 23 | /resource/static/theme-custom 24 | server 25 | scripts/monitor_goroutines.sh 26 | FIXES_APPLIED.md 27 | debug_monitor.sh 28 | .claude 29 | sqlite.db 30 | config 31 | heap.txt 32 | gp.txt 33 | fullgoroutinestackdump.txt 34 | tp.txt 35 | -------------------------------------------------------------------------------- /model/common.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "time" 5 | 6 | "gorm.io/gorm" 7 | ) 8 | 9 | const CtxKeyAuthorizedUser = "ckau" 10 | const CtxKeyViewPasswordVerified = "ckvpv" 11 | const CtxKeyPreferredTheme = "ckpt" 12 | const CacheKeyOauth2State = "p:a:state" 13 | 14 | type Common struct { 15 | ID uint64 `gorm:"primaryKey"` 16 | CreatedAt time.Time `gorm:"index;<-:create"` 17 | UpdatedAt time.Time `gorm:"autoUpdateTime"` 18 | DeletedAt gorm.DeletedAt `gorm:"index"` 19 | } 20 | 21 | type Response struct { 22 | Code int `json:"code,omitempty"` 23 | Message string `json:"message,omitempty"` 24 | Result interface{} `json:"result,omitempty"` 25 | } -------------------------------------------------------------------------------- /pkg/utils/hfs.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "embed" 5 | "io/fs" 6 | "os" 7 | ) 8 | 9 | // HybridFS combines embed.FS and os.DirFS. 10 | type HybridFS struct { 11 | embedFS, dir fs.FS 12 | } 13 | 14 | func NewHybridFS(embed embed.FS, subDir string, localDir string) (*HybridFS, error) { 15 | subFS, err := fs.Sub(embed, subDir) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | return &HybridFS{ 21 | embedFS: subFS, 22 | dir: os.DirFS(localDir), 23 | }, nil 24 | } 25 | 26 | func (hfs *HybridFS) Open(name string) (fs.File, error) { 27 | // Ensure embed files are not replaced 28 | if file, err := hfs.embedFS.Open(name); err == nil { 29 | return file, nil 30 | } 31 | 32 | return hfs.dir.Open(name) 33 | } 34 | -------------------------------------------------------------------------------- /model/server_test.go: -------------------------------------------------------------------------------- 1 | package model 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/xos/serverstatus/pkg/utils" 7 | ) 8 | 9 | func TestServerMarshal(t *testing.T) { 10 | patterns := []string{ 11 | "asd > asd", 12 | "asd \" asd", 13 | "asd } asd", 14 | } 15 | 16 | for i := 0; i < len(patterns); i++ { 17 | server := Server{ 18 | Name: patterns[i], 19 | Tag: patterns[i], 20 | } 21 | serverStr := string(server.MarshalForDashboard()) 22 | var serverRestore Server 23 | if utils.Json.Unmarshal([]byte(serverStr), &serverRestore) != nil { 24 | t.Fatalf("Error: %s", serverStr) 25 | } 26 | if server.Name != serverRestore.Name { 27 | t.Fatalf("Expected %s, but got %s", server.Name, serverRestore.Name) 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /resource/template/dashboard-default/error.html: -------------------------------------------------------------------------------- 1 | {{define "dashboard-default/error"}} 2 | {{template "common/header" .}} 3 |