7 changed files with 541 additions and 5 deletions
@ -0,0 +1,79 @@ |
|||||
|
package core |
||||
|
|
||||
|
import ( |
||||
|
"encoding/base64" |
||||
|
"fmt" |
||||
|
"scagnet/util" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/shirou/gopsutil/v3/cpu" |
||||
|
"github.com/shirou/gopsutil/v3/disk" |
||||
|
"github.com/shirou/gopsutil/v3/mem" |
||||
|
"github.com/shirou/gopsutil/v3/process" |
||||
|
"go.uber.org/zap" |
||||
|
"google.golang.org/protobuf/proto" |
||||
|
) |
||||
|
|
||||
|
// 服务器状态检测
|
||||
|
type SysMonitor struct{} |
||||
|
|
||||
|
// 服务器信息
|
||||
|
func (f *SysMonitor) GetSysInfo(args *Args, replay *string) error { |
||||
|
logger := util.NewProductionLogger() |
||||
|
defer logger.Sync() |
||||
|
|
||||
|
// 磁盘容量信息
|
||||
|
diskInfo, err := disk.Usage("/") |
||||
|
if err != nil { |
||||
|
logger.Error("获取磁盘信息失败", zap.Error(err)) |
||||
|
return |
||||
|
} |
||||
|
// 磁盘空间占用
|
||||
|
hdtval := fmt.Sprintf("%.2f GB", float64(diskInfo.Total)/1024/1024/1024) |
||||
|
hduval := fmt.Sprintf("%.2f GB", float64(diskInfo.Used)/1024/1024/1024) |
||||
|
|
||||
|
// 获取CPU占用率 (需要等待1秒来计算)
|
||||
|
cpuPercent, err := cpu.Percent(time.Second, false) |
||||
|
if err != nil { |
||||
|
logger.Error("获取CPU信息失败", zap.Error(err)) |
||||
|
return err |
||||
|
} |
||||
|
cpuinfo := fmt.Sprintf(" %.2f%%", cpuPercent[0]) |
||||
|
|
||||
|
// 获取内存占用信息
|
||||
|
memInfo, err := mem.VirtualMemory() |
||||
|
if err != nil { |
||||
|
logger.Error("获取内存信息失败", zap.Error(err)) |
||||
|
return err |
||||
|
|
||||
|
} |
||||
|
// 获取系统进程信息 (只获取前5个进程)
|
||||
|
processes, err := process.Processes() |
||||
|
if err != nil { |
||||
|
logger.Error("获取进程信息失败", zap.Error(err)) |
||||
|
return err |
||||
|
} |
||||
|
// 统计运行中的进程数量
|
||||
|
procnum := int32(len(processes)) |
||||
|
|
||||
|
//生成proto的内容
|
||||
|
hdinfo, err := proto.Marshal(&pb.Hdinfo{ |
||||
|
Hdstat: fmt.Sprintf("%v / %v", hduval, hdtval), |
||||
|
Procout: fmt.Sprintf(" %d", procnum), |
||||
|
Cpustat: cpuinfo, |
||||
|
Memstat: fmt.Sprintf(" %.2f%%", memInfo.UsedPercent), |
||||
|
Netstat: fmt.Sprintf(" %.2f MB", float64(netIO[0].BytesRecv)/1024/1024), |
||||
|
}) |
||||
|
if err != nil { |
||||
|
logger.Error("生成proto内容失败", zap.Error(err)) |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
// ver:0821
|
||||
|
// 输出proto
|
||||
|
encdata := base64.StdEncoding.EncodeToString(hdinfo) |
||||
|
*replay = encdata |
||||
|
|
||||
|
// 服务器状态检测
|
||||
|
return nil |
||||
|
} |
||||
@ -0,0 +1,375 @@ |
|||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
|
// versions:
|
||||
|
// protoc-gen-go v1.36.6
|
||||
|
// protoc v6.30.2
|
||||
|
// source: scinfo.proto
|
||||
|
|
||||
|
package pb |
||||
|
|
||||
|
import ( |
||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
|
reflect "reflect" |
||||
|
sync "sync" |
||||
|
unsafe "unsafe" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) |
||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) |
||||
|
) |
||||
|
|
||||
|
// 服务信息
|
||||
|
type ServiceInfo struct { |
||||
|
state protoimpl.MessageState `protogen:"open.v1"` |
||||
|
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` |
||||
|
Scname string `protobuf:"bytes,2,opt,name=scname,proto3" json:"scname,omitempty"` |
||||
|
Addr string `protobuf:"bytes,3,opt,name=addr,proto3" json:"addr,omitempty"` |
||||
|
Port string `protobuf:"bytes,4,opt,name=port,proto3" json:"port,omitempty"` |
||||
|
Token string `protobuf:"bytes,5,opt,name=token,proto3" json:"token,omitempty"` |
||||
|
Status int32 `protobuf:"varint,6,opt,name=status,proto3" json:"status,omitempty"` |
||||
|
unknownFields protoimpl.UnknownFields |
||||
|
sizeCache protoimpl.SizeCache |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) Reset() { |
||||
|
*x = ServiceInfo{} |
||||
|
mi := &file_scinfo_proto_msgTypes[0] |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) String() string { |
||||
|
return protoimpl.X.MessageStringOf(x) |
||||
|
} |
||||
|
|
||||
|
func (*ServiceInfo) ProtoMessage() {} |
||||
|
|
||||
|
func (x *ServiceInfo) ProtoReflect() protoreflect.Message { |
||||
|
mi := &file_scinfo_proto_msgTypes[0] |
||||
|
if x != nil { |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
if ms.LoadMessageInfo() == nil { |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
return ms |
||||
|
} |
||||
|
return mi.MessageOf(x) |
||||
|
} |
||||
|
|
||||
|
// Deprecated: Use ServiceInfo.ProtoReflect.Descriptor instead.
|
||||
|
func (*ServiceInfo) Descriptor() ([]byte, []int) { |
||||
|
return file_scinfo_proto_rawDescGZIP(), []int{0} |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) GetId() string { |
||||
|
if x != nil { |
||||
|
return x.Id |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) GetScname() string { |
||||
|
if x != nil { |
||||
|
return x.Scname |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) GetAddr() string { |
||||
|
if x != nil { |
||||
|
return x.Addr |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) GetPort() string { |
||||
|
if x != nil { |
||||
|
return x.Port |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) GetToken() string { |
||||
|
if x != nil { |
||||
|
return x.Token |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *ServiceInfo) GetStatus() int32 { |
||||
|
if x != nil { |
||||
|
return x.Status |
||||
|
} |
||||
|
return 0 |
||||
|
} |
||||
|
|
||||
|
// 目录下的文件信息
|
||||
|
type FileInfo struct { |
||||
|
state protoimpl.MessageState `protogen:"open.v1"` |
||||
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` |
||||
|
Size string `protobuf:"bytes,2,opt,name=size,proto3" json:"size,omitempty"` |
||||
|
ModTime string `protobuf:"bytes,3,opt,name=modTime,proto3" json:"modTime,omitempty"` |
||||
|
unknownFields protoimpl.UnknownFields |
||||
|
sizeCache protoimpl.SizeCache |
||||
|
} |
||||
|
|
||||
|
func (x *FileInfo) Reset() { |
||||
|
*x = FileInfo{} |
||||
|
mi := &file_scinfo_proto_msgTypes[1] |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
|
||||
|
func (x *FileInfo) String() string { |
||||
|
return protoimpl.X.MessageStringOf(x) |
||||
|
} |
||||
|
|
||||
|
func (*FileInfo) ProtoMessage() {} |
||||
|
|
||||
|
func (x *FileInfo) ProtoReflect() protoreflect.Message { |
||||
|
mi := &file_scinfo_proto_msgTypes[1] |
||||
|
if x != nil { |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
if ms.LoadMessageInfo() == nil { |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
return ms |
||||
|
} |
||||
|
return mi.MessageOf(x) |
||||
|
} |
||||
|
|
||||
|
// Deprecated: Use FileInfo.ProtoReflect.Descriptor instead.
|
||||
|
func (*FileInfo) Descriptor() ([]byte, []int) { |
||||
|
return file_scinfo_proto_rawDescGZIP(), []int{1} |
||||
|
} |
||||
|
|
||||
|
func (x *FileInfo) GetName() string { |
||||
|
if x != nil { |
||||
|
return x.Name |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *FileInfo) GetSize() string { |
||||
|
if x != nil { |
||||
|
return x.Size |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *FileInfo) GetModTime() string { |
||||
|
if x != nil { |
||||
|
return x.ModTime |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
// 代码内容
|
||||
|
type CodeContent struct { |
||||
|
state protoimpl.MessageState `protogen:"open.v1"` |
||||
|
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` |
||||
|
Content []byte `protobuf:"bytes,2,opt,name=content,proto3" json:"content,omitempty"` |
||||
|
unknownFields protoimpl.UnknownFields |
||||
|
sizeCache protoimpl.SizeCache |
||||
|
} |
||||
|
|
||||
|
func (x *CodeContent) Reset() { |
||||
|
*x = CodeContent{} |
||||
|
mi := &file_scinfo_proto_msgTypes[2] |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
|
||||
|
func (x *CodeContent) String() string { |
||||
|
return protoimpl.X.MessageStringOf(x) |
||||
|
} |
||||
|
|
||||
|
func (*CodeContent) ProtoMessage() {} |
||||
|
|
||||
|
func (x *CodeContent) ProtoReflect() protoreflect.Message { |
||||
|
mi := &file_scinfo_proto_msgTypes[2] |
||||
|
if x != nil { |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
if ms.LoadMessageInfo() == nil { |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
return ms |
||||
|
} |
||||
|
return mi.MessageOf(x) |
||||
|
} |
||||
|
|
||||
|
// Deprecated: Use CodeContent.ProtoReflect.Descriptor instead.
|
||||
|
func (*CodeContent) Descriptor() ([]byte, []int) { |
||||
|
return file_scinfo_proto_rawDescGZIP(), []int{2} |
||||
|
} |
||||
|
|
||||
|
func (x *CodeContent) GetName() string { |
||||
|
if x != nil { |
||||
|
return x.Name |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *CodeContent) GetContent() []byte { |
||||
|
if x != nil { |
||||
|
return x.Content |
||||
|
} |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
// 服务器磁盘占用,cpu 内存
|
||||
|
type Hdinfo struct { |
||||
|
state protoimpl.MessageState `protogen:"open.v1"` |
||||
|
Hdstat string `protobuf:"bytes,1,opt,name=hdstat,proto3" json:"hdstat,omitempty"` |
||||
|
Procout string `protobuf:"bytes,2,opt,name=procout,proto3" json:"procout,omitempty"` |
||||
|
Cpustat string `protobuf:"bytes,3,opt,name=cpustat,proto3" json:"cpustat,omitempty"` |
||||
|
Memstat string `protobuf:"bytes,4,opt,name=memstat,proto3" json:"memstat,omitempty"` |
||||
|
Netstat string `protobuf:"bytes,5,opt,name=netstat,proto3" json:"netstat,omitempty"` |
||||
|
unknownFields protoimpl.UnknownFields |
||||
|
sizeCache protoimpl.SizeCache |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) Reset() { |
||||
|
*x = Hdinfo{} |
||||
|
mi := &file_scinfo_proto_msgTypes[3] |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) String() string { |
||||
|
return protoimpl.X.MessageStringOf(x) |
||||
|
} |
||||
|
|
||||
|
func (*Hdinfo) ProtoMessage() {} |
||||
|
|
||||
|
func (x *Hdinfo) ProtoReflect() protoreflect.Message { |
||||
|
mi := &file_scinfo_proto_msgTypes[3] |
||||
|
if x != nil { |
||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) |
||||
|
if ms.LoadMessageInfo() == nil { |
||||
|
ms.StoreMessageInfo(mi) |
||||
|
} |
||||
|
return ms |
||||
|
} |
||||
|
return mi.MessageOf(x) |
||||
|
} |
||||
|
|
||||
|
// Deprecated: Use Hdinfo.ProtoReflect.Descriptor instead.
|
||||
|
func (*Hdinfo) Descriptor() ([]byte, []int) { |
||||
|
return file_scinfo_proto_rawDescGZIP(), []int{3} |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) GetHdstat() string { |
||||
|
if x != nil { |
||||
|
return x.Hdstat |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) GetProcout() string { |
||||
|
if x != nil { |
||||
|
return x.Procout |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) GetCpustat() string { |
||||
|
if x != nil { |
||||
|
return x.Cpustat |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) GetMemstat() string { |
||||
|
if x != nil { |
||||
|
return x.Memstat |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
func (x *Hdinfo) GetNetstat() string { |
||||
|
if x != nil { |
||||
|
return x.Netstat |
||||
|
} |
||||
|
return "" |
||||
|
} |
||||
|
|
||||
|
var File_scinfo_proto protoreflect.FileDescriptor |
||||
|
|
||||
|
const file_scinfo_proto_rawDesc = "" + |
||||
|
"\n" + |
||||
|
"\fscinfo.proto\"\x8b\x01\n" + |
||||
|
"\vServiceInfo\x12\x0e\n" + |
||||
|
"\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" + |
||||
|
"\x06scname\x18\x02 \x01(\tR\x06scname\x12\x12\n" + |
||||
|
"\x04addr\x18\x03 \x01(\tR\x04addr\x12\x12\n" + |
||||
|
"\x04port\x18\x04 \x01(\tR\x04port\x12\x14\n" + |
||||
|
"\x05token\x18\x05 \x01(\tR\x05token\x12\x16\n" + |
||||
|
"\x06status\x18\x06 \x01(\x05R\x06status\"L\n" + |
||||
|
"\bFileInfo\x12\x12\n" + |
||||
|
"\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + |
||||
|
"\x04size\x18\x02 \x01(\tR\x04size\x12\x18\n" + |
||||
|
"\amodTime\x18\x03 \x01(\tR\amodTime\";\n" + |
||||
|
"\vCodeContent\x12\x12\n" + |
||||
|
"\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" + |
||||
|
"\acontent\x18\x02 \x01(\fR\acontent\"\x88\x01\n" + |
||||
|
"\x06Hdinfo\x12\x16\n" + |
||||
|
"\x06hdstat\x18\x01 \x01(\tR\x06hdstat\x12\x18\n" + |
||||
|
"\aprocout\x18\x02 \x01(\tR\aprocout\x12\x18\n" + |
||||
|
"\acpustat\x18\x03 \x01(\tR\acpustat\x12\x18\n" + |
||||
|
"\amemstat\x18\x04 \x01(\tR\amemstat\x12\x18\n" + |
||||
|
"\anetstat\x18\x05 \x01(\tR\anetstatB\x06Z\x04./pbb\x06proto3" |
||||
|
|
||||
|
var ( |
||||
|
file_scinfo_proto_rawDescOnce sync.Once |
||||
|
file_scinfo_proto_rawDescData []byte |
||||
|
) |
||||
|
|
||||
|
func file_scinfo_proto_rawDescGZIP() []byte { |
||||
|
file_scinfo_proto_rawDescOnce.Do(func() { |
||||
|
file_scinfo_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_scinfo_proto_rawDesc), len(file_scinfo_proto_rawDesc))) |
||||
|
}) |
||||
|
return file_scinfo_proto_rawDescData |
||||
|
} |
||||
|
|
||||
|
var file_scinfo_proto_msgTypes = make([]protoimpl.MessageInfo, 4) |
||||
|
var file_scinfo_proto_goTypes = []any{ |
||||
|
(*ServiceInfo)(nil), // 0: ServiceInfo
|
||||
|
(*FileInfo)(nil), // 1: FileInfo
|
||||
|
(*CodeContent)(nil), // 2: CodeContent
|
||||
|
(*Hdinfo)(nil), // 3: Hdinfo
|
||||
|
} |
||||
|
var file_scinfo_proto_depIdxs = []int32{ |
||||
|
0, // [0:0] is the sub-list for method output_type
|
||||
|
0, // [0:0] is the sub-list for method input_type
|
||||
|
0, // [0:0] is the sub-list for extension type_name
|
||||
|
0, // [0:0] is the sub-list for extension extendee
|
||||
|
0, // [0:0] is the sub-list for field type_name
|
||||
|
} |
||||
|
|
||||
|
func init() { file_scinfo_proto_init() } |
||||
|
func file_scinfo_proto_init() { |
||||
|
if File_scinfo_proto != nil { |
||||
|
return |
||||
|
} |
||||
|
type x struct{} |
||||
|
out := protoimpl.TypeBuilder{ |
||||
|
File: protoimpl.DescBuilder{ |
||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), |
||||
|
RawDescriptor: unsafe.Slice(unsafe.StringData(file_scinfo_proto_rawDesc), len(file_scinfo_proto_rawDesc)), |
||||
|
NumEnums: 0, |
||||
|
NumMessages: 4, |
||||
|
NumExtensions: 0, |
||||
|
NumServices: 0, |
||||
|
}, |
||||
|
GoTypes: file_scinfo_proto_goTypes, |
||||
|
DependencyIndexes: file_scinfo_proto_depIdxs, |
||||
|
MessageInfos: file_scinfo_proto_msgTypes, |
||||
|
}.Build() |
||||
|
File_scinfo_proto = out.File |
||||
|
file_scinfo_proto_goTypes = nil |
||||
|
file_scinfo_proto_depIdxs = nil |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
syntax = "proto3"; |
||||
|
option go_package = "./pb"; |
||||
|
|
||||
|
// 服务信息 |
||||
|
message ServiceInfo { |
||||
|
string id = 1; |
||||
|
string scname = 2; |
||||
|
string addr = 3; |
||||
|
string port = 4; |
||||
|
string token = 5; |
||||
|
int32 status=6; |
||||
|
} |
||||
|
|
||||
|
// 目录下的文件信息 |
||||
|
message FileInfo { |
||||
|
string name = 1; |
||||
|
string size = 2; |
||||
|
string modTime = 3; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 代码内容 |
||||
|
message CodeContent { |
||||
|
string name = 1; |
||||
|
bytes content = 2; |
||||
|
} |
||||
|
|
||||
|
// 服务器磁盘占用,cpu 内存 |
||||
|
message Hdinfo{ |
||||
|
string hdstat=1; |
||||
|
string procout=2; |
||||
|
string cpustat=3; |
||||
|
string memstat=4; |
||||
|
string netstat=5; |
||||
|
} |
||||
@ -1,3 +1,5 @@ |
|||||
## 说明 |
## 说明 |
||||
|
|
||||
封装后的程序运行在linux服务器,客户端通过json_rpc方式访问。 |
封装后的程序运行在linux服务器,客户端通过json_rpc方式访问。 |
||||
|
|
||||
|
1、定时发送服务器的空间信息,磁盘信息,cpu信息,内存信息。 |
||||
|
|||||
Loading…
Reference in new issue