Merge branch 'dev' of github.com:naiba/nezha-v1 into dev

This commit is contained in:
naiba 2024-11-22 23:57:48 +08:00
commit 58cc8aa5df
16 changed files with 425 additions and 306 deletions

View File

@ -107,25 +107,20 @@ func batchDeleteServer(c *gin.Context) (any, error) {
return nil, newGormError("%v", err) return nil, newGormError("%v", err)
} }
singleton.ServerLock.Lock() singleton.AlertsLock.Lock()
for i := 0; i < len(servers); i++ { for _, sid := range servers {
id := servers[i] for _, alert := range singleton.Alerts {
delete(singleton.ServerList, id) if singleton.AlertsCycleTransferStatsStore[alert.ID] != nil {
delete(singleton.AlertsCycleTransferStatsStore[alert.ID].ServerName, sid)
singleton.AlertsLock.Lock() delete(singleton.AlertsCycleTransferStatsStore[alert.ID].Transfer, sid)
for i := 0; i < len(singleton.Alerts); i++ { delete(singleton.AlertsCycleTransferStatsStore[alert.ID].NextUpdate, sid)
if singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID] != nil {
delete(singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID].ServerName, id)
delete(singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID].Transfer, id)
delete(singleton.AlertsCycleTransferStatsStore[singleton.Alerts[i].ID].NextUpdate, id)
} }
} }
singleton.AlertsLock.Unlock() singleton.DB.Unscoped().Delete(&model.Transfer{}, "server_id = ?", sid)
singleton.DB.Unscoped().Delete(&model.Transfer{}, "server_id = ?", id)
} }
singleton.ServerLock.Unlock() singleton.AlertsLock.Unlock()
singleton.OnServerDelete(servers)
singleton.ReSortServer() singleton.ReSortServer()
return nil, nil return nil, nil

View File

@ -109,14 +109,12 @@ func getServerStat(c *gin.Context, withPublicNote bool) ([]byte, error) {
var servers []model.StreamServer var servers []model.StreamServer
for i := 0; i < len(serverList); i++ { for i := 0; i < len(serverList); i++ {
server := serverList[i] server := serverList[i]
host := *server.Host
host.IP = ""
servers = append(servers, model.StreamServer{ servers = append(servers, model.StreamServer{
ID: server.ID, ID: server.ID,
Name: server.Name, Name: server.Name,
PublicNote: utils.IfOr(withPublicNote, server.PublicNote, ""), PublicNote: utils.IfOr(withPublicNote, server.PublicNote, ""),
DisplayIndex: server.DisplayIndex, DisplayIndex: server.DisplayIndex,
Host: &host, Host: server.Host,
State: server.State, State: server.State,
LastActive: server.LastActive, LastActive: server.LastActive,
}) })

1
go.mod
View File

@ -7,6 +7,7 @@ toolchain go1.23.1
require ( require (
github.com/appleboy/gin-jwt/v2 v2.10.0 github.com/appleboy/gin-jwt/v2 v2.10.0
github.com/chai2010/gettext-go v1.0.3 github.com/chai2010/gettext-go v1.0.3
github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0
github.com/gin-contrib/pprof v1.4.0 github.com/gin-contrib/pprof v1.4.0
github.com/gin-gonic/gin v1.10.0 github.com/gin-gonic/gin v1.10.0
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.1

2
go.sum
View File

@ -24,6 +24,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0 h1:aYo8nnk3ojoQkP5iErif5Xxv0Mo0Ga/FR5+ffl/7+Nk=
github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0/go.mod h1:8AuBTZBRSFqEYBPYULd+NN474/zZBLP+6WeT5S9xlAc=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=

View File

@ -1,6 +1,8 @@
package model package model
import ( import (
"fmt"
pb "github.com/naiba/nezha/proto" pb "github.com/naiba/nezha/proto"
) )
@ -105,8 +107,6 @@ type Host struct {
Arch string `json:"arch,omitempty"` Arch string `json:"arch,omitempty"`
Virtualization string `json:"virtualization,omitempty"` Virtualization string `json:"virtualization,omitempty"`
BootTime uint64 `json:"boot_time,omitempty"` BootTime uint64 `json:"boot_time,omitempty"`
IP string `json:"ip,omitempty"`
CountryCode string `json:"country_code,omitempty"`
Version string `json:"version,omitempty"` Version string `json:"version,omitempty"`
GPU []string `json:"gpu,omitempty"` GPU []string `json:"gpu,omitempty"`
} }
@ -122,8 +122,6 @@ func (h *Host) PB() *pb.Host {
Arch: h.Arch, Arch: h.Arch,
Virtualization: h.Virtualization, Virtualization: h.Virtualization,
BootTime: h.BootTime, BootTime: h.BootTime,
Ip: h.IP,
CountryCode: h.CountryCode,
Version: h.Version, Version: h.Version,
Gpu: h.GPU, Gpu: h.GPU,
} }
@ -140,9 +138,36 @@ func PB2Host(h *pb.Host) Host {
Arch: h.GetArch(), Arch: h.GetArch(),
Virtualization: h.GetVirtualization(), Virtualization: h.GetVirtualization(),
BootTime: h.GetBootTime(), BootTime: h.GetBootTime(),
IP: h.GetIp(),
CountryCode: h.GetCountryCode(),
Version: h.GetVersion(), Version: h.GetVersion(),
GPU: h.GetGpu(), GPU: h.GetGpu(),
} }
} }
type IP struct {
IPv4Addr string `json:"ipv4_addr,omitempty"`
IPv6Addr string `json:"ipv6_addr,omitempty"`
}
func (p *IP) Join() string {
if p.IPv4Addr != "" && p.IPv6Addr != "" {
return fmt.Sprintf("%s/%s", p.IPv4Addr, p.IPv6Addr)
} else if p.IPv4Addr != "" {
return p.IPv4Addr
}
return p.IPv6Addr
}
type GeoIP struct {
IP IP `json:"ip,omitempty"`
CountryCode string `json:"country_code,omitempty"`
}
func PB2GeoIP(p *pb.GeoIP) GeoIP {
pbIP := p.GetIp()
return GeoIP{
IP: IP{
IPv4Addr: pbIP.GetIpv4(),
IPv6Addr: pbIP.GetIpv6(),
},
}
}

View File

@ -193,7 +193,7 @@ func (ns *NotificationServerBundle) replaceParamsInString(str string, message st
str = strings.ReplaceAll(str, "#SERVER.UDPCONNCOUNT#", mod(fmt.Sprintf("%d", ns.Server.State.UdpConnCount))) str = strings.ReplaceAll(str, "#SERVER.UDPCONNCOUNT#", mod(fmt.Sprintf("%d", ns.Server.State.UdpConnCount)))
var ipv4, ipv6, validIP string var ipv4, ipv6, validIP string
ipList := strings.Split(ns.Server.Host.IP, "/") ipList := strings.Split(ns.Server.GeoIP.IP.Join(), "/")
if len(ipList) > 1 { if len(ipList) > 1 {
// 双栈 // 双栈
ipv4 = ipList[0] ipv4 = ipList[0]
@ -201,7 +201,7 @@ func (ns *NotificationServerBundle) replaceParamsInString(str string, message st
validIP = ipv4 validIP = ipv4
} else if len(ipList) == 1 { } else if len(ipList) == 1 {
// 仅ipv4|ipv6 // 仅ipv4|ipv6
if strings.Contains(ipList[0], ":") { if strings.IndexByte(ipList[0], ':') != -1 {
ipv6 = ipList[0] ipv6 = ipList[0]
validIP = ipv6 validIP = ipv6
} else { } else {

View File

@ -49,8 +49,6 @@ func execCase(t *testing.T, item testSt) {
Arch: "", Arch: "",
Virtualization: "", Virtualization: "",
BootTime: 0, BootTime: 0,
IP: "1.1.1.1",
CountryCode: "",
Version: "", Version: "",
}, },
State: &HostState{ State: &HostState{
@ -70,6 +68,12 @@ func execCase(t *testing.T, item testSt) {
UdpConnCount: 0, UdpConnCount: 0,
ProcessCount: 0, ProcessCount: 0,
}, },
GeoIP: &GeoIP{
IP: IP{
IPv4Addr: "1.1.1.1",
},
CountryCode: "",
},
LastActive: time.Time{}, LastActive: time.Time{},
TaskClose: nil, TaskClose: nil,
TaskStream: nil, TaskStream: nil,

View File

@ -27,6 +27,7 @@ type Server struct {
Host *Host `gorm:"-" json:"host,omitempty"` Host *Host `gorm:"-" json:"host,omitempty"`
State *HostState `gorm:"-" json:"state,omitempty"` State *HostState `gorm:"-" json:"state,omitempty"`
GeoIP *GeoIP `gorm:"-" json:"geoip,omitempty"`
LastActive time.Time `gorm:"-" json:"last_active,omitempty"` LastActive time.Time `gorm:"-" json:"last_active,omitempty"`
TaskClose chan error `gorm:"-" json:"-"` TaskClose chan error `gorm:"-" json:"-"`
@ -40,6 +41,7 @@ type Server struct {
func (s *Server) CopyFromRunningServer(old *Server) { func (s *Server) CopyFromRunningServer(old *Server) {
s.Host = old.Host s.Host = old.Host
s.State = old.State s.State = old.State
s.GeoIP = old.GeoIP
s.LastActive = old.LastActive s.LastActive = old.LastActive
s.TaskClose = old.TaskClose s.TaskClose = old.TaskClose
s.TaskCloseLock = old.TaskCloseLock s.TaskCloseLock = old.TaskCloseLock

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"net" "net"
"strings" "strings"
"sync"
maxminddb "github.com/oschwald/maxminddb-golang" maxminddb "github.com/oschwald/maxminddb-golang"
) )
@ -12,6 +13,16 @@ import (
//go:embed geoip.db //go:embed geoip.db
var db []byte var db []byte
var (
dbOnce = sync.OnceValues(func() (*maxminddb.Reader, error) {
db, err := maxminddb.FromBytes(db)
if err != nil {
return nil, err
}
return db, nil
})
)
type IPInfo struct { type IPInfo struct {
Country string `maxminddb:"country"` Country string `maxminddb:"country"`
CountryName string `maxminddb:"country_name"` CountryName string `maxminddb:"country_name"`
@ -20,11 +31,10 @@ type IPInfo struct {
} }
func Lookup(ip net.IP) (string, error) { func Lookup(ip net.IP) (string, error) {
db, err := maxminddb.FromBytes(db) db, err := dbOnce()
if err != nil { if err != nil {
return "", err return "", err
} }
defer db.Close()
var record IPInfo var record IPInfo
err = db.Lookup(ip, &record) err = db.Lookup(ip, &record)

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.34.1 // protoc-gen-go v1.34.1
// protoc v5.28.2 // protoc v5.28.3
// source: proto/nezha.proto // source: proto/nezha.proto
package proto package proto
@ -34,10 +34,8 @@ type Host struct {
Arch string `protobuf:"bytes,7,opt,name=arch,proto3" json:"arch,omitempty"` Arch string `protobuf:"bytes,7,opt,name=arch,proto3" json:"arch,omitempty"`
Virtualization string `protobuf:"bytes,8,opt,name=virtualization,proto3" json:"virtualization,omitempty"` Virtualization string `protobuf:"bytes,8,opt,name=virtualization,proto3" json:"virtualization,omitempty"`
BootTime uint64 `protobuf:"varint,9,opt,name=boot_time,json=bootTime,proto3" json:"boot_time,omitempty"` BootTime uint64 `protobuf:"varint,9,opt,name=boot_time,json=bootTime,proto3" json:"boot_time,omitempty"`
Ip string `protobuf:"bytes,10,opt,name=ip,proto3" json:"ip,omitempty"` Version string `protobuf:"bytes,10,opt,name=version,proto3" json:"version,omitempty"`
CountryCode string `protobuf:"bytes,11,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` // deprecated Gpu []string `protobuf:"bytes,11,rep,name=gpu,proto3" json:"gpu,omitempty"`
Version string `protobuf:"bytes,12,opt,name=version,proto3" json:"version,omitempty"`
Gpu []string `protobuf:"bytes,13,rep,name=gpu,proto3" json:"gpu,omitempty"`
} }
func (x *Host) Reset() { func (x *Host) Reset() {
@ -135,20 +133,6 @@ func (x *Host) GetBootTime() uint64 {
return 0 return 0
} }
func (x *Host) GetIp() string {
if x != nil {
return x.Ip
}
return ""
}
func (x *Host) GetCountryCode() string {
if x != nil {
return x.CountryCode
}
return ""
}
func (x *Host) GetVersion() string { func (x *Host) GetVersion() string {
if x != nil { if x != nil {
return x.Version return x.Version
@ -169,22 +153,22 @@ type State struct {
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Cpu float64 `protobuf:"fixed64,1,opt,name=cpu,proto3" json:"cpu,omitempty"` Cpu float64 `protobuf:"fixed64,1,opt,name=cpu,proto3" json:"cpu,omitempty"`
MemUsed uint64 `protobuf:"varint,3,opt,name=mem_used,json=memUsed,proto3" json:"mem_used,omitempty"` MemUsed uint64 `protobuf:"varint,2,opt,name=mem_used,json=memUsed,proto3" json:"mem_used,omitempty"`
SwapUsed uint64 `protobuf:"varint,4,opt,name=swap_used,json=swapUsed,proto3" json:"swap_used,omitempty"` SwapUsed uint64 `protobuf:"varint,3,opt,name=swap_used,json=swapUsed,proto3" json:"swap_used,omitempty"`
DiskUsed uint64 `protobuf:"varint,5,opt,name=disk_used,json=diskUsed,proto3" json:"disk_used,omitempty"` DiskUsed uint64 `protobuf:"varint,4,opt,name=disk_used,json=diskUsed,proto3" json:"disk_used,omitempty"`
NetInTransfer uint64 `protobuf:"varint,6,opt,name=net_in_transfer,json=netInTransfer,proto3" json:"net_in_transfer,omitempty"` NetInTransfer uint64 `protobuf:"varint,5,opt,name=net_in_transfer,json=netInTransfer,proto3" json:"net_in_transfer,omitempty"`
NetOutTransfer uint64 `protobuf:"varint,7,opt,name=net_out_transfer,json=netOutTransfer,proto3" json:"net_out_transfer,omitempty"` NetOutTransfer uint64 `protobuf:"varint,6,opt,name=net_out_transfer,json=netOutTransfer,proto3" json:"net_out_transfer,omitempty"`
NetInSpeed uint64 `protobuf:"varint,8,opt,name=net_in_speed,json=netInSpeed,proto3" json:"net_in_speed,omitempty"` NetInSpeed uint64 `protobuf:"varint,7,opt,name=net_in_speed,json=netInSpeed,proto3" json:"net_in_speed,omitempty"`
NetOutSpeed uint64 `protobuf:"varint,9,opt,name=net_out_speed,json=netOutSpeed,proto3" json:"net_out_speed,omitempty"` NetOutSpeed uint64 `protobuf:"varint,8,opt,name=net_out_speed,json=netOutSpeed,proto3" json:"net_out_speed,omitempty"`
Uptime uint64 `protobuf:"varint,10,opt,name=uptime,proto3" json:"uptime,omitempty"` Uptime uint64 `protobuf:"varint,9,opt,name=uptime,proto3" json:"uptime,omitempty"`
Load1 float64 `protobuf:"fixed64,11,opt,name=load1,proto3" json:"load1,omitempty"` Load1 float64 `protobuf:"fixed64,10,opt,name=load1,proto3" json:"load1,omitempty"`
Load5 float64 `protobuf:"fixed64,12,opt,name=load5,proto3" json:"load5,omitempty"` Load5 float64 `protobuf:"fixed64,11,opt,name=load5,proto3" json:"load5,omitempty"`
Load15 float64 `protobuf:"fixed64,13,opt,name=load15,proto3" json:"load15,omitempty"` Load15 float64 `protobuf:"fixed64,12,opt,name=load15,proto3" json:"load15,omitempty"`
TcpConnCount uint64 `protobuf:"varint,14,opt,name=tcp_conn_count,json=tcpConnCount,proto3" json:"tcp_conn_count,omitempty"` TcpConnCount uint64 `protobuf:"varint,13,opt,name=tcp_conn_count,json=tcpConnCount,proto3" json:"tcp_conn_count,omitempty"`
UdpConnCount uint64 `protobuf:"varint,15,opt,name=udp_conn_count,json=udpConnCount,proto3" json:"udp_conn_count,omitempty"` UdpConnCount uint64 `protobuf:"varint,14,opt,name=udp_conn_count,json=udpConnCount,proto3" json:"udp_conn_count,omitempty"`
ProcessCount uint64 `protobuf:"varint,16,opt,name=process_count,json=processCount,proto3" json:"process_count,omitempty"` ProcessCount uint64 `protobuf:"varint,15,opt,name=process_count,json=processCount,proto3" json:"process_count,omitempty"`
Temperatures []*State_SensorTemperature `protobuf:"bytes,17,rep,name=temperatures,proto3" json:"temperatures,omitempty"` Temperatures []*State_SensorTemperature `protobuf:"bytes,16,rep,name=temperatures,proto3" json:"temperatures,omitempty"`
Gpu []float64 `protobuf:"fixed64,18,rep,packed,name=gpu,proto3" json:"gpu,omitempty"` Gpu []float64 `protobuf:"fixed64,17,rep,packed,name=gpu,proto3" json:"gpu,omitempty"`
} }
func (x *State) Reset() { func (x *State) Reset() {
@ -634,8 +618,9 @@ type GeoIP struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` Use6 bool `protobuf:"varint,1,opt,name=use6,proto3" json:"use6,omitempty"`
CountryCode string `protobuf:"bytes,2,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"` Ip *IP `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"`
CountryCode string `protobuf:"bytes,3,opt,name=country_code,json=countryCode,proto3" json:"country_code,omitempty"`
} }
func (x *GeoIP) Reset() { func (x *GeoIP) Reset() {
@ -670,11 +655,18 @@ func (*GeoIP) Descriptor() ([]byte, []int) {
return file_proto_nezha_proto_rawDescGZIP(), []int{7} return file_proto_nezha_proto_rawDescGZIP(), []int{7}
} }
func (x *GeoIP) GetIp() string { func (x *GeoIP) GetUse6() bool {
if x != nil {
return x.Use6
}
return false
}
func (x *GeoIP) GetIp() *IP {
if x != nil { if x != nil {
return x.Ip return x.Ip
} }
return "" return nil
} }
func (x *GeoIP) GetCountryCode() string { func (x *GeoIP) GetCountryCode() string {
@ -684,11 +676,66 @@ func (x *GeoIP) GetCountryCode() string {
return "" return ""
} }
type IP struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Ipv4 string `protobuf:"bytes,1,opt,name=ipv4,proto3" json:"ipv4,omitempty"`
Ipv6 string `protobuf:"bytes,2,opt,name=ipv6,proto3" json:"ipv6,omitempty"`
}
func (x *IP) Reset() {
*x = IP{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_nezha_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *IP) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*IP) ProtoMessage() {}
func (x *IP) ProtoReflect() protoreflect.Message {
mi := &file_proto_nezha_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use IP.ProtoReflect.Descriptor instead.
func (*IP) Descriptor() ([]byte, []int) {
return file_proto_nezha_proto_rawDescGZIP(), []int{8}
}
func (x *IP) GetIpv4() string {
if x != nil {
return x.Ipv4
}
return ""
}
func (x *IP) GetIpv6() string {
if x != nil {
return x.Ipv6
}
return ""
}
var File_proto_nezha_proto protoreflect.FileDescriptor var File_proto_nezha_proto protoreflect.FileDescriptor
var file_proto_nezha_proto_rawDesc = []byte{ var file_proto_nezha_proto_rawDesc = []byte{
0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x65, 0x7a, 0x68, 0x61, 0x2e, 0x70, 0x72, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6e, 0x65, 0x7a, 0x68, 0x61, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf2, 0x02, 0x0a, 0x04, 0x48, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x02, 0x0a, 0x04, 0x48,
0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x6f, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12,
0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x29, 0x0a, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73,
@ -706,93 +753,95 @@ var file_proto_nezha_proto_rawDesc = []byte{
0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x76, 0x69, 0x72, 0x74, 0x75, 0x61, 0x6c, 0x69, 0x7a, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x6f, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x62, 0x6f, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28,
0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x70,
0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x75, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x67, 0x70, 0x75, 0x22, 0xa9, 0x04, 0x0a,
0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x01, 0x20,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x10, 0x0a, 0x01, 0x28, 0x01, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x65, 0x6d, 0x5f,
0x03, 0x67, 0x70, 0x75, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x67, 0x70, 0x75, 0x22, 0x75, 0x73, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x55,
0xa9, 0x04, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x75, 0x73, 0x65, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x55, 0x73, 0x65, 0x64,
0x65, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x04, 0x20,
0x65, 0x6d, 0x55, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x77, 0x61, 0x70, 0x5f, 0x75, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a,
0x73, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x77, 0x61, 0x70, 0x55, 0x0f, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x69, 0x73, 0x6b, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x54, 0x72, 0x61,
0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x64, 0x69, 0x73, 0x6b, 0x55, 0x73, 0x65, 0x64, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74,
0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52,
0x66, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x0e, 0x6e, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12,
0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x12, 0x28, 0x0a, 0x10, 0x6e, 0x65, 0x74, 0x5f, 0x20, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18,
0x6f, 0x75, 0x74, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x53, 0x70, 0x65, 0x65,
0x28, 0x04, 0x52, 0x0e, 0x6e, 0x65, 0x74, 0x4f, 0x75, 0x74, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x73, 0x70, 0x65,
0x65, 0x72, 0x12, 0x20, 0x0a, 0x0c, 0x6e, 0x65, 0x74, 0x5f, 0x69, 0x6e, 0x5f, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x4f, 0x75, 0x74,
0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x6e, 0x65, 0x74, 0x49, 0x6e, 0x53, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x18,
0x70, 0x65, 0x65, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x74, 0x5f, 0x6f, 0x75, 0x74, 0x5f, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a,
0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x74, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x31, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x6f,
0x4f, 0x75, 0x74, 0x53, 0x70, 0x65, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x70, 0x74, 0x69, 0x61, 0x64, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x18, 0x0b, 0x20, 0x01,
0x6d, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x75, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x12, 0x16, 0x0a, 0x06, 0x6c, 0x6f, 0x61,
0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x31, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x01, 0x52, 0x64, 0x31, 0x35, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x6c, 0x6f, 0x61, 0x64, 0x31,
0x05, 0x6c, 0x6f, 0x61, 0x64, 0x31, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x18, 0x35, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x63, 0x6f,
0x0c, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x6c, 0x6f, 0x61, 0x64, 0x35, 0x12, 0x16, 0x0a, 0x06, 0x75, 0x6e, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x74, 0x63, 0x70, 0x43, 0x6f,
0x6c, 0x6f, 0x61, 0x64, 0x31, 0x35, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x01, 0x52, 0x06, 0x6c, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x64, 0x70, 0x5f, 0x63,
0x61, 0x64, 0x31, 0x35, 0x12, 0x24, 0x0a, 0x0e, 0x74, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x6f, 0x6e, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52,
0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x74, 0x63, 0x0c, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x23, 0x0a,
0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x75, 0x64, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f,
0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x6f, 0x75,
0x28, 0x04, 0x52, 0x0c, 0x75, 0x64, 0x70, 0x43, 0x6f, 0x6e, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72,
0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x54, 0x65, 0x6d,
0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x42, 0x0a, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72,
0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x70, 0x75, 0x18, 0x11, 0x20,
0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x03, 0x28, 0x01, 0x52, 0x03, 0x67, 0x70, 0x75, 0x22, 0x4f, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x74,
0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x52, 0x0c, 0x74, 0x65, 0x6d, 0x65, 0x5f, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74,
0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x70, 0x75, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
0x18, 0x12, 0x20, 0x03, 0x28, 0x01, 0x52, 0x03, 0x67, 0x70, 0x75, 0x22, 0x4f, 0x0a, 0x17, 0x53, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65,
0x74, 0x61, 0x74, 0x65, 0x5f, 0x53, 0x65, 0x6e, 0x73, 0x6f, 0x72, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x74, 0x65,
0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3e, 0x0a, 0x04, 0x54, 0x61, 0x73,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x65, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69,
0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52,
0x0b, 0x74, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65, 0x22, 0x3e, 0x0a, 0x04, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20,
0x54, 0x61, 0x73, 0x6b, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7a, 0x0a, 0x0a, 0x54, 0x61, 0x73,
0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x28, 0x04, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18,
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7a, 0x0a, 0x0a, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64,
0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x61,
0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73,
0x0a, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x64, 0x66, 0x75, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x65,
0x65, 0x6c, 0x61, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x21, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74,
0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x75, 0x63, 0x63, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08,
0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x75, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x22, 0x22, 0x0a, 0x0c, 0x49, 0x4f, 0x53, 0x74,
0x63, 0x63, 0x65, 0x73, 0x73, 0x66, 0x75, 0x6c, 0x22, 0x21, 0x0a, 0x07, 0x52, 0x65, 0x63, 0x65, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61,
0x69, 0x70, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x18, 0x01, 0x20, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x59, 0x0a, 0x05,
0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x64, 0x22, 0x22, 0x0a, 0x0c, 0x49, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x36, 0x18, 0x01, 0x20,
0x4f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x01, 0x28, 0x08, 0x52, 0x04, 0x75, 0x73, 0x65, 0x36, 0x12, 0x19, 0x0a, 0x02, 0x69, 0x70, 0x18,
0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x50,
0x3a, 0x0a, 0x05, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x70, 0x18, 0x01, 0x52, 0x02, 0x69, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x5f,
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x70, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x75, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x2c, 0x0a, 0x02, 0x49, 0x50, 0x12, 0x12, 0x0a,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x32, 0xbf, 0x02, 0x0a, 0x0c, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76,
0x4e, 0x65, 0x7a, 0x68, 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x11, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x36, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x04, 0x69, 0x70, 0x76, 0x36, 0x32, 0xbf, 0x02, 0x0a, 0x0c, 0x4e, 0x65, 0x7a, 0x68, 0x61, 0x53,
0x65, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x33, 0x0a, 0x11, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74,
0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0c, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x10, 0x52,
0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12,
0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x31,
0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x11, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a,
0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x74, 0x22,
0x00, 0x12, 0x31, 0x0a, 0x10, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x79, 0x73, 0x74, 0x65, 0x00, 0x12, 0x2b, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x61, 0x73, 0x6b,
0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x6f, 0x12, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x1a, 0x0b, 0x2e,
0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3a,
0x70, 0x74, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x61, 0x0a, 0x08, 0x49, 0x4f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f,
0x73, 0x6b, 0x12, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x74, 0x6f, 0x2e, 0x49, 0x4f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x1a,
0x65, 0x73, 0x75, 0x6c, 0x74, 0x1a, 0x0e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x4f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,
0x63, 0x65, 0x69, 0x70, 0x74, 0x22, 0x00, 0x12, 0x2b, 0x0a, 0x0b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x44, 0x61, 0x74, 0x61, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2b, 0x0a, 0x0b, 0x52, 0x65,
0x73, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x12, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x48, 0x70, 0x6f, 0x72, 0x74, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x73, 0x74, 0x1a, 0x0b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x6f, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x1a, 0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x22, 0x00, 0x30, 0x01, 0x12, 0x3a, 0x0a, 0x08, 0x49, 0x4f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x2f, 0x70, 0x72, 0x6f,
0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x4f, 0x53, 0x74, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6d, 0x44, 0x61, 0x74, 0x61, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x4f,
0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x61, 0x74, 0x61, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01,
0x12, 0x2b, 0x0a, 0x0b, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x12,
0x0c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x1a, 0x0c, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x6f, 0x49, 0x50, 0x22, 0x00, 0x42, 0x09, 0x5a,
0x07, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
@ -807,7 +856,7 @@ func file_proto_nezha_proto_rawDescGZIP() []byte {
return file_proto_nezha_proto_rawDescData return file_proto_nezha_proto_rawDescData
} }
var file_proto_nezha_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_proto_nezha_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_proto_nezha_proto_goTypes = []interface{}{ var file_proto_nezha_proto_goTypes = []interface{}{
(*Host)(nil), // 0: proto.Host (*Host)(nil), // 0: proto.Host
(*State)(nil), // 1: proto.State (*State)(nil), // 1: proto.State
@ -817,26 +866,28 @@ var file_proto_nezha_proto_goTypes = []interface{}{
(*Receipt)(nil), // 5: proto.Receipt (*Receipt)(nil), // 5: proto.Receipt
(*IOStreamData)(nil), // 6: proto.IOStreamData (*IOStreamData)(nil), // 6: proto.IOStreamData
(*GeoIP)(nil), // 7: proto.GeoIP (*GeoIP)(nil), // 7: proto.GeoIP
(*IP)(nil), // 8: proto.IP
} }
var file_proto_nezha_proto_depIdxs = []int32{ var file_proto_nezha_proto_depIdxs = []int32{
2, // 0: proto.State.temperatures:type_name -> proto.State_SensorTemperature 2, // 0: proto.State.temperatures:type_name -> proto.State_SensorTemperature
1, // 1: proto.NezhaService.ReportSystemState:input_type -> proto.State 8, // 1: proto.GeoIP.ip:type_name -> proto.IP
0, // 2: proto.NezhaService.ReportSystemInfo:input_type -> proto.Host 1, // 2: proto.NezhaService.ReportSystemState:input_type -> proto.State
4, // 3: proto.NezhaService.ReportTask:input_type -> proto.TaskResult 0, // 3: proto.NezhaService.ReportSystemInfo:input_type -> proto.Host
0, // 4: proto.NezhaService.RequestTask:input_type -> proto.Host 4, // 4: proto.NezhaService.ReportTask:input_type -> proto.TaskResult
6, // 5: proto.NezhaService.IOStream:input_type -> proto.IOStreamData 0, // 5: proto.NezhaService.RequestTask:input_type -> proto.Host
7, // 6: proto.NezhaService.LookupGeoIP:input_type -> proto.GeoIP 6, // 6: proto.NezhaService.IOStream:input_type -> proto.IOStreamData
5, // 7: proto.NezhaService.ReportSystemState:output_type -> proto.Receipt 7, // 7: proto.NezhaService.ReportGeoIP:input_type -> proto.GeoIP
5, // 8: proto.NezhaService.ReportSystemInfo:output_type -> proto.Receipt 5, // 8: proto.NezhaService.ReportSystemState:output_type -> proto.Receipt
5, // 9: proto.NezhaService.ReportTask:output_type -> proto.Receipt 5, // 9: proto.NezhaService.ReportSystemInfo:output_type -> proto.Receipt
3, // 10: proto.NezhaService.RequestTask:output_type -> proto.Task 5, // 10: proto.NezhaService.ReportTask:output_type -> proto.Receipt
6, // 11: proto.NezhaService.IOStream:output_type -> proto.IOStreamData 3, // 11: proto.NezhaService.RequestTask:output_type -> proto.Task
7, // 12: proto.NezhaService.LookupGeoIP:output_type -> proto.GeoIP 6, // 12: proto.NezhaService.IOStream:output_type -> proto.IOStreamData
7, // [7:13] is the sub-list for method output_type 7, // 13: proto.NezhaService.ReportGeoIP:output_type -> proto.GeoIP
1, // [1:7] is the sub-list for method input_type 8, // [8:14] is the sub-list for method output_type
1, // [1:1] is the sub-list for extension type_name 2, // [2:8] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension extendee 2, // [2:2] is the sub-list for extension type_name
0, // [0:1] is the sub-list for field type_name 2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
} }
func init() { file_proto_nezha_proto_init() } func init() { file_proto_nezha_proto_init() }
@ -941,6 +992,18 @@ func file_proto_nezha_proto_init() {
return nil return nil
} }
} }
file_proto_nezha_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*IP); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
} }
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
@ -948,7 +1011,7 @@ func file_proto_nezha_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_nezha_proto_rawDesc, RawDescriptor: file_proto_nezha_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 8, NumMessages: 9,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },

View File

@ -4,78 +4,78 @@ option go_package = "./proto";
package proto; package proto;
service NezhaService { service NezhaService {
rpc ReportSystemState(State)returns(Receipt){} rpc ReportSystemState(State) returns (Receipt) {}
rpc ReportSystemInfo(Host)returns(Receipt){} rpc ReportSystemInfo(Host) returns (Receipt) {}
rpc ReportTask(TaskResult)returns(Receipt){} rpc ReportTask(TaskResult) returns (Receipt) {}
rpc RequestTask(Host)returns(stream Task){} rpc RequestTask(Host) returns (stream Task) {}
rpc IOStream(stream IOStreamData)returns(stream IOStreamData){} rpc IOStream(stream IOStreamData) returns (stream IOStreamData) {}
rpc LookupGeoIP(GeoIP)returns(GeoIP){} rpc ReportGeoIP(GeoIP) returns (GeoIP) {}
} }
message Host { message Host {
string platform = 1; string platform = 1;
string platform_version = 2; string platform_version = 2;
repeated string cpu = 3; repeated string cpu = 3;
uint64 mem_total = 4; uint64 mem_total = 4;
uint64 disk_total = 5; uint64 disk_total = 5;
uint64 swap_total = 6; uint64 swap_total = 6;
string arch = 7; string arch = 7;
string virtualization = 8; string virtualization = 8;
uint64 boot_time = 9; uint64 boot_time = 9;
string ip = 10; string version = 10;
string country_code = 11; // deprecated repeated string gpu = 11;
string version = 12;
repeated string gpu = 13;
} }
message State { message State {
double cpu = 1; double cpu = 1;
uint64 mem_used = 3; uint64 mem_used = 2;
uint64 swap_used = 4; uint64 swap_used = 3;
uint64 disk_used = 5; uint64 disk_used = 4;
uint64 net_in_transfer = 6; uint64 net_in_transfer = 5;
uint64 net_out_transfer = 7; uint64 net_out_transfer = 6;
uint64 net_in_speed = 8; uint64 net_in_speed = 7;
uint64 net_out_speed = 9; uint64 net_out_speed = 8;
uint64 uptime = 10; uint64 uptime = 9;
double load1 = 11; double load1 = 10;
double load5 = 12; double load5 = 11;
double load15 = 13; double load15 = 12;
uint64 tcp_conn_count = 14; uint64 tcp_conn_count = 13;
uint64 udp_conn_count = 15; uint64 udp_conn_count = 14;
uint64 process_count = 16; uint64 process_count = 15;
repeated State_SensorTemperature temperatures = 17; repeated State_SensorTemperature temperatures = 16;
repeated double gpu = 18; repeated double gpu = 17;
} }
message State_SensorTemperature { message State_SensorTemperature {
string name = 1; string name = 1;
double temperature = 2; double temperature = 2;
} }
message Task { message Task {
uint64 id = 1; uint64 id = 1;
uint64 type = 2; uint64 type = 2;
string data = 3; string data = 3;
} }
message TaskResult { message TaskResult {
uint64 id = 1; uint64 id = 1;
uint64 type = 2; uint64 type = 2;
float delay = 3; float delay = 3;
string data = 4; string data = 4;
bool successful = 5; bool successful = 5;
} }
message Receipt{ message Receipt { bool proced = 1; }
bool proced = 1;
}
message IOStreamData { message IOStreamData { bytes data = 1; }
bytes data = 1;
}
message GeoIP { message GeoIP {
string ip = 1; bool use6 = 1;
string country_code = 2; IP ip = 2;
} string country_code = 3;
}
message IP {
string ipv4 = 1;
string ipv6 = 2;
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT. // Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions: // versions:
// - protoc-gen-go-grpc v1.5.1 // - protoc-gen-go-grpc v1.5.1
// - protoc v5.28.2 // - protoc v5.28.3
// source: proto/nezha.proto // source: proto/nezha.proto
package proto package proto
@ -24,7 +24,7 @@ const (
NezhaService_ReportTask_FullMethodName = "/proto.NezhaService/ReportTask" NezhaService_ReportTask_FullMethodName = "/proto.NezhaService/ReportTask"
NezhaService_RequestTask_FullMethodName = "/proto.NezhaService/RequestTask" NezhaService_RequestTask_FullMethodName = "/proto.NezhaService/RequestTask"
NezhaService_IOStream_FullMethodName = "/proto.NezhaService/IOStream" NezhaService_IOStream_FullMethodName = "/proto.NezhaService/IOStream"
NezhaService_LookupGeoIP_FullMethodName = "/proto.NezhaService/LookupGeoIP" NezhaService_ReportGeoIP_FullMethodName = "/proto.NezhaService/ReportGeoIP"
) )
// NezhaServiceClient is the client API for NezhaService service. // NezhaServiceClient is the client API for NezhaService service.
@ -36,7 +36,7 @@ type NezhaServiceClient interface {
ReportTask(ctx context.Context, in *TaskResult, opts ...grpc.CallOption) (*Receipt, error) ReportTask(ctx context.Context, in *TaskResult, opts ...grpc.CallOption) (*Receipt, error)
RequestTask(ctx context.Context, in *Host, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Task], error) RequestTask(ctx context.Context, in *Host, opts ...grpc.CallOption) (grpc.ServerStreamingClient[Task], error)
IOStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[IOStreamData, IOStreamData], error) IOStream(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[IOStreamData, IOStreamData], error)
LookupGeoIP(ctx context.Context, in *GeoIP, opts ...grpc.CallOption) (*GeoIP, error) ReportGeoIP(ctx context.Context, in *GeoIP, opts ...grpc.CallOption) (*GeoIP, error)
} }
type nezhaServiceClient struct { type nezhaServiceClient struct {
@ -109,10 +109,10 @@ func (c *nezhaServiceClient) IOStream(ctx context.Context, opts ...grpc.CallOpti
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type NezhaService_IOStreamClient = grpc.BidiStreamingClient[IOStreamData, IOStreamData] type NezhaService_IOStreamClient = grpc.BidiStreamingClient[IOStreamData, IOStreamData]
func (c *nezhaServiceClient) LookupGeoIP(ctx context.Context, in *GeoIP, opts ...grpc.CallOption) (*GeoIP, error) { func (c *nezhaServiceClient) ReportGeoIP(ctx context.Context, in *GeoIP, opts ...grpc.CallOption) (*GeoIP, error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(GeoIP) out := new(GeoIP)
err := c.cc.Invoke(ctx, NezhaService_LookupGeoIP_FullMethodName, in, out, cOpts...) err := c.cc.Invoke(ctx, NezhaService_ReportGeoIP_FullMethodName, in, out, cOpts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -128,7 +128,7 @@ type NezhaServiceServer interface {
ReportTask(context.Context, *TaskResult) (*Receipt, error) ReportTask(context.Context, *TaskResult) (*Receipt, error)
RequestTask(*Host, grpc.ServerStreamingServer[Task]) error RequestTask(*Host, grpc.ServerStreamingServer[Task]) error
IOStream(grpc.BidiStreamingServer[IOStreamData, IOStreamData]) error IOStream(grpc.BidiStreamingServer[IOStreamData, IOStreamData]) error
LookupGeoIP(context.Context, *GeoIP) (*GeoIP, error) ReportGeoIP(context.Context, *GeoIP) (*GeoIP, error)
} }
// UnimplementedNezhaServiceServer should be embedded to have // UnimplementedNezhaServiceServer should be embedded to have
@ -153,8 +153,8 @@ func (UnimplementedNezhaServiceServer) RequestTask(*Host, grpc.ServerStreamingSe
func (UnimplementedNezhaServiceServer) IOStream(grpc.BidiStreamingServer[IOStreamData, IOStreamData]) error { func (UnimplementedNezhaServiceServer) IOStream(grpc.BidiStreamingServer[IOStreamData, IOStreamData]) error {
return status.Errorf(codes.Unimplemented, "method IOStream not implemented") return status.Errorf(codes.Unimplemented, "method IOStream not implemented")
} }
func (UnimplementedNezhaServiceServer) LookupGeoIP(context.Context, *GeoIP) (*GeoIP, error) { func (UnimplementedNezhaServiceServer) ReportGeoIP(context.Context, *GeoIP) (*GeoIP, error) {
return nil, status.Errorf(codes.Unimplemented, "method LookupGeoIP not implemented") return nil, status.Errorf(codes.Unimplemented, "method ReportGeoIP not implemented")
} }
func (UnimplementedNezhaServiceServer) testEmbeddedByValue() {} func (UnimplementedNezhaServiceServer) testEmbeddedByValue() {}
@ -248,20 +248,20 @@ func _NezhaService_IOStream_Handler(srv interface{}, stream grpc.ServerStream) e
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type NezhaService_IOStreamServer = grpc.BidiStreamingServer[IOStreamData, IOStreamData] type NezhaService_IOStreamServer = grpc.BidiStreamingServer[IOStreamData, IOStreamData]
func _NezhaService_LookupGeoIP_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { func _NezhaService_ReportGeoIP_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GeoIP) in := new(GeoIP)
if err := dec(in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
if interceptor == nil { if interceptor == nil {
return srv.(NezhaServiceServer).LookupGeoIP(ctx, in) return srv.(NezhaServiceServer).ReportGeoIP(ctx, in)
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: NezhaService_LookupGeoIP_FullMethodName, FullMethod: NezhaService_ReportGeoIP_FullMethodName,
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(NezhaServiceServer).LookupGeoIP(ctx, req.(*GeoIP)) return srv.(NezhaServiceServer).ReportGeoIP(ctx, req.(*GeoIP))
} }
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
@ -286,8 +286,8 @@ var NezhaService_ServiceDesc = grpc.ServiceDesc{
Handler: _NezhaService_ReportTask_Handler, Handler: _NezhaService_ReportTask_Handler,
}, },
{ {
MethodName: "LookupGeoIP", MethodName: "ReportGeoIP",
Handler: _NezhaService_LookupGeoIP_Handler, Handler: _NezhaService_ReportGeoIP_Handler,
}, },
}, },
Streams: []grpc.StreamDesc{ Streams: []grpc.StreamDesc{

View File

@ -4,11 +4,12 @@ import (
"context" "context"
"sync" "sync"
petname "github.com/dustinkirkland/golang-petname"
"github.com/hashicorp/go-uuid"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"github.com/hashicorp/go-uuid"
"github.com/naiba/nezha/model" "github.com/naiba/nezha/model"
"github.com/naiba/nezha/service/singleton" "github.com/naiba/nezha/service/singleton"
) )
@ -30,7 +31,7 @@ func (a *authHandler) Check(ctx context.Context) (uint64, error) {
} }
if clientSecret != singleton.Conf.AgentSecretKey { if clientSecret != singleton.Conf.AgentSecretKey {
return 0, status.Errorf(codes.Unauthenticated, "客户端认证失败") return 0, status.Error(codes.Unauthenticated, "客户端认证失败")
} }
var clientUUID string var clientUUID string
@ -39,22 +40,25 @@ func (a *authHandler) Check(ctx context.Context) (uint64, error) {
} }
if _, err := uuid.ParseUUID(clientUUID); err != nil { if _, err := uuid.ParseUUID(clientUUID); err != nil {
return 0, status.Errorf(codes.Unauthenticated, "客户端 UUID 不合法") return 0, status.Error(codes.Unauthenticated, "客户端 UUID 不合法")
} }
singleton.ServerLock.RLock() singleton.ServerLock.RLock()
defer singleton.ServerLock.RUnlock() defer singleton.ServerLock.RUnlock()
clientID, hasID := singleton.ServerUUIDToID[clientUUID] clientID, hasID := singleton.ServerUUIDToID[clientUUID]
if !hasID { if !hasID {
s := model.Server{UUID: clientUUID} s := model.Server{UUID: clientUUID, Name: petname.Generate(2, "-")}
if err := singleton.DB.Create(&s).Error; err != nil { if err := singleton.DB.Create(&s).Error; err != nil {
return 0, status.Errorf(codes.Unauthenticated, err.Error()) return 0, status.Error(codes.Unauthenticated, err.Error())
} }
s.Host = &model.Host{} s.Host = &model.Host{}
s.State = &model.HostState{} s.State = &model.HostState{}
s.TaskCloseLock = new(sync.Mutex) s.TaskCloseLock = new(sync.Mutex)
// generate a random silly server name
singleton.ServerList[s.ID] = &s singleton.ServerList[s.ID] = &s
singleton.ServerUUIDToID[clientUUID] = s.ID singleton.ServerUUIDToID[clientUUID] = s.ID
singleton.ReSortServer()
clientID = s.ID clientID = s.ID
} }

View File

@ -9,9 +9,8 @@ import (
"time" "time"
"github.com/naiba/nezha/pkg/ddns" "github.com/naiba/nezha/pkg/ddns"
"github.com/naiba/nezha/pkg/geoip" geoipx "github.com/naiba/nezha/pkg/geoip"
"github.com/naiba/nezha/pkg/grpcx" "github.com/naiba/nezha/pkg/grpcx"
"github.com/naiba/nezha/pkg/utils"
"github.com/jinzhu/copier" "github.com/jinzhu/copier"
@ -126,40 +125,6 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
singleton.ServerLock.RLock() singleton.ServerLock.RLock()
defer singleton.ServerLock.RUnlock() defer singleton.ServerLock.RUnlock()
// 检查并更新DDNS
if singleton.ServerList[clientID].EnableDDNS && host.IP != "" &&
(singleton.ServerList[clientID].Host == nil || singleton.ServerList[clientID].Host.IP != host.IP) {
ipv4, ipv6, _ := utils.SplitIPAddr(host.IP)
providers, err := singleton.GetDDNSProvidersFromProfiles(singleton.ServerList[clientID].DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6})
if err == nil {
for _, provider := range providers {
go func(provider *ddns.Provider) {
provider.UpdateDomain(context.Background())
}(provider)
}
} else {
log.Printf("NEZHA>> 获取DDNS配置时发生错误: %v", err)
}
}
// 发送IP变动通知
if singleton.ServerList[clientID].Host != nil && singleton.Conf.EnableIPChangeNotification &&
((singleton.Conf.Cover == model.ConfigCoverAll && !singleton.Conf.IgnoredIPNotificationServerIDs[clientID]) ||
(singleton.Conf.Cover == model.ConfigCoverIgnoreAll && singleton.Conf.IgnoredIPNotificationServerIDs[clientID])) &&
singleton.ServerList[clientID].Host.IP != "" &&
host.IP != "" &&
singleton.ServerList[clientID].Host.IP != host.IP {
singleton.SendNotification(singleton.Conf.IPChangeNotificationGroupID,
fmt.Sprintf(
"[%s] %s, %s => %s",
singleton.Localizer.T("IP Changed"),
singleton.ServerList[clientID].Name, singleton.IPDesensitize(singleton.ServerList[clientID].Host.IP),
singleton.IPDesensitize(host.IP),
),
nil)
}
/** /**
* 这里的 singleton 中的数据都是关机前的旧数据 * 这里的 singleton 中的数据都是关机前的旧数据
* agent 重启时bootTime 变大agent 端会先上报 host 信息然后上报 state 信息 * agent 重启时bootTime 变大agent 端会先上报 host 信息然后上报 state 信息
@ -170,11 +135,6 @@ func (s *NezhaHandler) ReportSystemInfo(c context.Context, r *pb.Host) (*pb.Rece
singleton.ServerList[clientID].PrevTransferOutSnapshot = singleton.ServerList[clientID].PrevTransferOutSnapshot - int64(singleton.ServerList[clientID].State.NetOutTransfer) singleton.ServerList[clientID].PrevTransferOutSnapshot = singleton.ServerList[clientID].PrevTransferOutSnapshot - int64(singleton.ServerList[clientID].State.NetOutTransfer)
} }
// 不要冲掉国家码
if singleton.ServerList[clientID].Host != nil {
host.CountryCode = singleton.ServerList[clientID].Host.CountryCode
}
singleton.ServerList[clientID].Host = &host singleton.ServerList[clientID].Host = &host
return &pb.Receipt{Proced: true}, nil return &pb.Receipt{Proced: true}, nil
} }
@ -204,28 +164,73 @@ func (s *NezhaHandler) IOStream(stream pb.NezhaService_IOStreamServer) error {
return nil return nil
} }
func (s *NezhaHandler) LookupGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, error) { func (s *NezhaHandler) ReportGeoIP(c context.Context, r *pb.GeoIP) (*pb.GeoIP, error) {
var clientID uint64 var clientID uint64
var err error var err error
if clientID, err = s.Auth.Check(c); err != nil { if clientID, err = s.Auth.Check(c); err != nil {
return nil, err return nil, err
} }
// 根据内置数据库查询 IP 地理位置 geoip := model.PB2GeoIP(r)
ip := r.GetIp() joinedIP := geoip.IP.Join()
netIP := net.ParseIP(ip) use6 := r.GetUse6()
location, err := geoip.Lookup(netIP)
if err != nil { singleton.ServerLock.RLock()
return nil, err // 检查并更新DDNS
if singleton.ServerList[clientID].EnableDDNS && joinedIP != "" &&
(singleton.ServerList[clientID].GeoIP == nil || singleton.ServerList[clientID].GeoIP.IP != geoip.IP) {
ipv4 := geoip.IP.IPv4Addr
ipv6 := geoip.IP.IPv6Addr
providers, err := singleton.GetDDNSProvidersFromProfiles(singleton.ServerList[clientID].DDNSProfiles, &ddns.IP{Ipv4Addr: ipv4, Ipv6Addr: ipv6})
if err == nil {
for _, provider := range providers {
go func(provider *ddns.Provider) {
provider.UpdateDomain(context.Background())
}(provider)
}
} else {
log.Printf("NEZHA>> 获取DDNS配置时发生错误: %v", err)
}
} }
// 发送IP变动通知
if singleton.ServerList[clientID].GeoIP != nil && singleton.Conf.EnableIPChangeNotification &&
((singleton.Conf.Cover == model.ConfigCoverAll && !singleton.Conf.IgnoredIPNotificationServerIDs[clientID]) ||
(singleton.Conf.Cover == model.ConfigCoverIgnoreAll && singleton.Conf.IgnoredIPNotificationServerIDs[clientID])) &&
singleton.ServerList[clientID].GeoIP.IP.Join() != "" &&
joinedIP != "" &&
singleton.ServerList[clientID].GeoIP.IP != geoip.IP {
singleton.SendNotification(singleton.Conf.IPChangeNotificationGroupID,
fmt.Sprintf(
"[%s] %s, %s => %s",
singleton.Localizer.T("IP Changed"),
singleton.ServerList[clientID].Name, singleton.IPDesensitize(singleton.ServerList[clientID].GeoIP.IP.Join()),
singleton.IPDesensitize(joinedIP),
),
nil)
}
singleton.ServerLock.RUnlock()
// 根据内置数据库查询 IP 地理位置
var ip string
if geoip.IP.IPv6Addr != "" && (use6 || geoip.IP.IPv4Addr == "") {
ip = geoip.IP.IPv6Addr
} else {
ip = geoip.IP.IPv4Addr
}
netIP := net.ParseIP(ip)
location, err := geoipx.Lookup(netIP)
if err != nil {
log.Printf("NEZHA>> geoip.Lookup: %v", err)
}
geoip.CountryCode = location
// 将地区码写入到 Host // 将地区码写入到 Host
singleton.ServerLock.RLock() singleton.ServerLock.Lock()
defer singleton.ServerLock.RUnlock() defer singleton.ServerLock.Unlock()
if singleton.ServerList[clientID].Host == nil { singleton.ServerList[clientID].GeoIP = &geoip
return nil, fmt.Errorf("host not found")
}
singleton.ServerList[clientID].Host.CountryCode = location
return &pb.GeoIP{Ip: ip, CountryCode: location}, nil return &pb.GeoIP{Ip: nil, CountryCode: location}, err
} }

View File

@ -157,7 +157,7 @@ func checkStatus() {
if alert.TriggerMode == model.ModeAlwaysTrigger || alertsPrevState[alert.ID][server.ID] != _RuleCheckFail { if alert.TriggerMode == model.ModeAlwaysTrigger || alertsPrevState[alert.ID][server.ID] != _RuleCheckFail {
alertsPrevState[alert.ID][server.ID] = _RuleCheckFail alertsPrevState[alert.ID][server.ID] = _RuleCheckFail
message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.T("Incident"), message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.T("Incident"),
server.Name, IPDesensitize(server.Host.IP), alert.Name) server.Name, IPDesensitize(server.GeoIP.IP.Join()), alert.Name)
go SendTriggerTasks(alert.FailTriggerTasks, curServer.ID) go SendTriggerTasks(alert.FailTriggerTasks, curServer.ID)
go SendNotification(alert.NotificationGroupID, message, NotificationMuteLabel.ServerIncident(server.ID, alert.ID), &curServer) go SendNotification(alert.NotificationGroupID, message, NotificationMuteLabel.ServerIncident(server.ID, alert.ID), &curServer)
// 清除恢复通知的静音缓存 // 清除恢复通知的静音缓存
@ -167,7 +167,7 @@ func checkStatus() {
// 本次通过检查但上一次的状态为失败,则发送恢复通知 // 本次通过检查但上一次的状态为失败,则发送恢复通知
if alertsPrevState[alert.ID][server.ID] == _RuleCheckFail { if alertsPrevState[alert.ID][server.ID] == _RuleCheckFail {
message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.T("Resolved"), message := fmt.Sprintf("[%s] %s(%s) %s", Localizer.T("Resolved"),
server.Name, IPDesensitize(server.Host.IP), alert.Name) server.Name, IPDesensitize(server.GeoIP.IP.Join()), alert.Name)
go SendTriggerTasks(alert.RecoverTriggerTasks, curServer.ID) go SendTriggerTasks(alert.RecoverTriggerTasks, curServer.ID)
go SendNotification(alert.NotificationGroupID, message, NotificationMuteLabel.ServerIncidentResolved(server.ID, alert.ID), &curServer) go SendNotification(alert.NotificationGroupID, message, NotificationMuteLabel.ServerIncidentResolved(server.ID, alert.ID), &curServer)
// 清除失败通知的静音缓存 // 清除失败通知的静音缓存

View File

@ -68,3 +68,13 @@ func ReSortServer() {
return SortedServerListForGuest[i].DisplayIndex > SortedServerListForGuest[j].DisplayIndex return SortedServerListForGuest[i].DisplayIndex > SortedServerListForGuest[j].DisplayIndex
}) })
} }
func OnServerDelete(sid []uint64) {
ServerLock.Lock()
defer ServerLock.Unlock()
for _, id := range sid {
serverUUID := ServerList[id].UUID
delete(ServerUUIDToID, serverUUID)
delete(ServerList, id)
}
}