nezha/service/singleton/api.go

270 lines
7.0 KiB
Go
Raw Normal View History

2022-05-16 23:21:27 -04:00
package singleton
2022-05-17 08:16:46 -04:00
import (
"sync"
"time"
2022-05-17 08:16:46 -04:00
"github.com/naiba/nezha/model"
"github.com/naiba/nezha/pkg/utils"
)
2022-05-16 23:21:27 -04:00
2022-05-17 22:10:35 -04:00
var (
ApiTokenList = make(map[string]*model.ApiToken)
UserIDToApiTokenList = make(map[uint64][]string)
2022-05-17 22:28:24 -04:00
ApiLock sync.RWMutex
2022-05-18 11:54:22 -04:00
ServerAPI = &ServerAPIService{}
MonitorAPI = &MonitorAPIService{}
2022-05-17 22:10:35 -04:00
)
2022-05-18 11:54:22 -04:00
type ServerAPIService struct{}
2022-05-16 23:21:27 -04:00
2022-05-17 08:16:46 -04:00
// CommonResponse 常规返回结构 包含状态码 和 状态信息
2022-05-16 23:21:27 -04:00
type CommonResponse struct {
Code int `json:"code"`
Message string `json:"message"`
}
2022-05-17 08:16:46 -04:00
type CommonServerInfo struct {
2024-07-28 01:43:28 -04:00
ID uint64 `json:"id"`
Name string `json:"name"`
Tag string `json:"tag"`
LastActive int64 `json:"last_active"`
IPV4 string `json:"ipv4"`
IPV6 string `json:"ipv6"`
ValidIP string `json:"valid_ip"`
DisplayIndex int `json:"display_index"`
2022-05-17 08:16:46 -04:00
}
// StatusResponse 服务器状态子结构 包含服务器信息与状态信息
2022-05-16 23:21:27 -04:00
type StatusResponse struct {
2022-05-17 08:16:46 -04:00
CommonServerInfo
2022-05-16 23:21:27 -04:00
Host *model.Host `json:"host"`
Status *model.HostState `json:"status"`
}
2022-05-17 08:16:46 -04:00
// ServerStatusResponse 服务器状态返回结构 包含常规返回结构 和 服务器状态子结构
2022-05-16 23:21:27 -04:00
type ServerStatusResponse struct {
CommonResponse
Result []*StatusResponse `json:"result"`
}
2022-05-17 08:16:46 -04:00
// ServerInfoResponse 服务器信息返回结构 包含常规返回结构 和 服务器信息子结构
type ServerInfoResponse struct {
CommonResponse
Result []*CommonServerInfo `json:"result"`
}
type MonitorAPIService struct {
}
type MonitorInfoResponse struct {
CommonResponse
Result []*MonitorInfo `json:"result"`
}
type MonitorInfo struct {
MonitorID uint64 `json:"monitor_id"`
ServerID uint64 `json:"server_id"`
MonitorName string `json:"monitor_name"`
ServerName string `json:"server_name"`
CreatedAt []int64 `json:"created_at"`
AvgDelay []float32 `json:"avg_delay"`
}
2022-05-17 22:10:35 -04:00
func InitAPI() {
ApiTokenList = make(map[string]*model.ApiToken)
UserIDToApiTokenList = make(map[uint64][]string)
}
2024-07-14 07:41:50 -04:00
func loadAPI() {
2022-05-17 22:10:35 -04:00
InitAPI()
var tokenList []*model.ApiToken
DB.Find(&tokenList)
for _, token := range tokenList {
ApiTokenList[token.Token] = token
UserIDToApiTokenList[token.UserID] = append(UserIDToApiTokenList[token.UserID], token.Token)
}
}
2022-05-16 23:21:27 -04:00
// GetStatusByIDList 获取传入IDList的服务器状态信息
2022-05-18 11:54:22 -04:00
func (s *ServerAPIService) GetStatusByIDList(idList []uint64) *ServerStatusResponse {
2022-05-17 08:16:46 -04:00
res := &ServerStatusResponse{}
res.Result = make([]*StatusResponse, 0)
2022-05-16 23:21:27 -04:00
ServerLock.RLock()
defer ServerLock.RUnlock()
for _, v := range idList {
2022-05-16 23:21:27 -04:00
server := ServerList[v]
if server == nil {
continue
}
2022-05-17 08:16:46 -04:00
ipv4, ipv6, validIP := utils.SplitIPAddr(server.Host.IP)
info := CommonServerInfo{
ID: server.ID,
Name: server.Name,
Tag: server.Tag,
LastActive: server.LastActive.Unix(),
IPV4: ipv4,
IPV6: ipv6,
ValidIP: validIP,
2022-05-17 08:16:46 -04:00
}
res.Result = append(res.Result, &StatusResponse{
CommonServerInfo: info,
Host: server.Host,
Status: server.State,
2022-05-16 23:21:27 -04:00
})
}
2022-05-17 08:16:46 -04:00
res.CommonResponse = CommonResponse{
Code: 0,
Message: "success",
2022-05-16 23:21:27 -04:00
}
2022-05-17 08:16:46 -04:00
return res
2022-05-16 23:21:27 -04:00
}
// GetStatusByTag 获取传入分组的所有服务器状态信息
2022-05-18 11:54:22 -04:00
func (s *ServerAPIService) GetStatusByTag(tag string) *ServerStatusResponse {
return s.GetStatusByIDList(ServerTagToIDList[tag])
2022-05-16 23:21:27 -04:00
}
// GetAllStatus 获取所有服务器状态信息
2022-05-18 11:54:22 -04:00
func (s *ServerAPIService) GetAllStatus() *ServerStatusResponse {
2022-05-17 08:16:46 -04:00
res := &ServerStatusResponse{}
res.Result = make([]*StatusResponse, 0)
2022-05-16 23:21:27 -04:00
ServerLock.RLock()
defer ServerLock.RUnlock()
for _, v := range ServerList {
host := v.Host
state := v.State
if host == nil || state == nil {
continue
}
2022-05-17 08:16:46 -04:00
ipv4, ipv6, validIP := utils.SplitIPAddr(host.IP)
info := CommonServerInfo{
2024-07-28 01:43:28 -04:00
ID: v.ID,
Name: v.Name,
Tag: v.Tag,
LastActive: v.LastActive.Unix(),
IPV4: ipv4,
IPV6: ipv6,
ValidIP: validIP,
DisplayIndex: v.DisplayIndex,
2022-05-17 08:16:46 -04:00
}
res.Result = append(res.Result, &StatusResponse{
CommonServerInfo: info,
Host: v.Host,
Status: v.State,
2022-05-16 23:21:27 -04:00
})
}
2022-05-17 08:16:46 -04:00
res.CommonResponse = CommonResponse{
Code: 0,
Message: "success",
}
return res
}
2022-05-16 23:21:27 -04:00
2022-05-17 08:16:46 -04:00
// GetListByTag 获取传入分组的所有服务器信息
2022-05-18 11:54:22 -04:00
func (s *ServerAPIService) GetListByTag(tag string) *ServerInfoResponse {
2022-05-17 08:16:46 -04:00
res := &ServerInfoResponse{}
res.Result = make([]*CommonServerInfo, 0)
ServerLock.RLock()
defer ServerLock.RUnlock()
for _, v := range ServerTagToIDList[tag] {
2022-05-17 08:16:46 -04:00
host := ServerList[v].Host
if host == nil {
continue
}
ipv4, ipv6, validIP := utils.SplitIPAddr(host.IP)
info := &CommonServerInfo{
ID: v,
Name: ServerList[v].Name,
Tag: ServerList[v].Tag,
LastActive: ServerList[v].LastActive.Unix(),
IPV4: ipv4,
IPV6: ipv6,
ValidIP: validIP,
2022-05-17 08:16:46 -04:00
}
res.Result = append(res.Result, info)
}
res.CommonResponse = CommonResponse{
Code: 0,
Message: "success",
}
return res
}
// GetAllList 获取所有服务器信息
2022-05-18 11:54:22 -04:00
func (s *ServerAPIService) GetAllList() *ServerInfoResponse {
2022-05-17 08:16:46 -04:00
res := &ServerInfoResponse{}
res.Result = make([]*CommonServerInfo, 0)
ServerLock.RLock()
defer ServerLock.RUnlock()
for _, v := range ServerList {
host := v.Host
if host == nil {
continue
}
ipv4, ipv6, validIP := utils.SplitIPAddr(host.IP)
info := &CommonServerInfo{
ID: v.ID,
Name: v.Name,
Tag: v.Tag,
LastActive: v.LastActive.Unix(),
IPV4: ipv4,
IPV6: ipv6,
ValidIP: validIP,
2022-05-17 08:16:46 -04:00
}
res.Result = append(res.Result, info)
}
res.CommonResponse = CommonResponse{
Code: 0,
Message: "success",
2022-05-16 23:21:27 -04:00
}
2022-05-17 08:16:46 -04:00
return res
2022-05-16 23:21:27 -04:00
}
func (m *MonitorAPIService) GetMonitorHistories(query map[string]any) *MonitorInfoResponse {
var (
resultMap = make(map[uint64]*MonitorInfo)
monitorHistories []*model.MonitorHistory
sortedMonitorIDs []uint64
)
res := &MonitorInfoResponse{
CommonResponse: CommonResponse{
Code: 0,
Message: "success",
},
}
if err := DB.Model(&model.MonitorHistory{}).Select("monitor_id, created_at, server_id, avg_delay").
Where(query).Where("created_at >= ?", time.Now().Add(-24*time.Hour)).Order("monitor_id, created_at").
Scan(&monitorHistories).Error; err != nil {
res.CommonResponse = CommonResponse{
Code: 500,
Message: err.Error(),
}
} else {
for _, history := range monitorHistories {
infos, ok := resultMap[history.MonitorID]
if !ok {
infos = &MonitorInfo{
MonitorID: history.MonitorID,
ServerID: history.ServerID,
MonitorName: ServiceSentinelShared.monitors[history.MonitorID].Name,
ServerName: ServerList[history.ServerID].Name,
}
resultMap[history.MonitorID] = infos
sortedMonitorIDs = append(sortedMonitorIDs, history.MonitorID)
}
infos.CreatedAt = append(infos.CreatedAt, history.CreatedAt.Truncate(time.Minute).Unix()*1000)
infos.AvgDelay = append(infos.AvgDelay, history.AvgDelay)
}
for _, monitorID := range sortedMonitorIDs {
res.Result = append(res.Result, resultMap[monitorID])
}
}
return res
}