展示监控信息

This commit is contained in:
奶爸 2019-12-09 23:45:23 +08:00
parent bfe6d48927
commit 8d791d91c1
9 changed files with 157 additions and 84 deletions

View File

@ -29,11 +29,13 @@ var (
Run: run,
}
clientID string
server string
clientSecret string
debug bool
)
func main() {
rootCmd.PersistentFlags().StringVarP(&server, "server", "s", "localhost:5555", "客户端ID")
rootCmd.PersistentFlags().StringVarP(&clientID, "id", "i", "", "客户端ID")
rootCmd.PersistentFlags().StringVarP(&clientSecret, "secret", "p", "", "客户端Secret")
rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "开启Debug")
@ -48,7 +50,6 @@ var reporting bool
var client pb.NezhaServiceClient
var ctx = context.Background()
var delayWhenError = time.Second * 10
var delayWhenReport = time.Second
func run(cmd *cobra.Command, args []string) {
dao.Conf = &model.Config{
@ -67,7 +68,7 @@ func run(cmd *cobra.Command, args []string) {
log.Println("Try to reconnect ...")
}
for {
conn, err = grpc.Dial(":5555", grpc.WithInsecure(), grpc.WithPerRPCCredentials(&auth))
conn, err = grpc.Dial(server, grpc.WithInsecure(), grpc.WithPerRPCCredentials(&auth))
if err != nil {
log.Printf("grpc.Dial err: %v", err)
retry()
@ -121,12 +122,12 @@ func reportState() {
defer log.Printf("reportState exit %v %v => %v", endReport, time.Now(), err)
for {
if endReport.After(time.Now()) {
_, err = client.ReportState(ctx, monitor.GetState(0).PB())
monitor.TrackNetworkSpeed()
_, err = client.ReportState(ctx, monitor.GetState(1).PB())
if err != nil {
log.Printf("reportState error %v", err)
time.Sleep(delayWhenError)
}
}
time.Sleep(delayWhenReport)
}
}

View File

@ -24,12 +24,18 @@ func ServeWeb() {
"tf": func(t time.Time) string {
return t.Format("2006年1月2号")
},
"stf": func(s uint64) string {
return time.Unix(int64(s), 0).Format("2006年1月2号 15:04")
},
"fs": func() string {
if !dao.Conf.Debug {
return ""
}
return fmt.Sprintf("%d", time.Now().UnixNano())
},
"sf": func(duration uint64) string {
return time.Duration(time.Duration(duration) * time.Second).String()
},
"bf": func(b uint64) string {
return bytefmt.ByteSize(b)
},

View File

@ -10,44 +10,53 @@ const (
// State ..
type State struct {
CPU float64
MemTotal uint64
MemUsed uint64
SwapTotal uint64
SwapUsed uint64
DiskTotal uint64
DiskUsed uint64
NetIn uint64
NetOut uint64
CPU float64
MemTotal uint64
MemUsed uint64
SwapTotal uint64
SwapUsed uint64
DiskTotal uint64
DiskUsed uint64
NetInTransfer uint64
NetOutTransfer uint64
NetInSpeed uint64
NetOutSpeed uint64
Uptime uint64
}
// PB ..
func (s *State) PB() *pb.State {
return &pb.State{
Cpu: s.CPU,
MemTotal: s.MemTotal,
MemUsed: s.MemUsed,
SwapTotal: s.SwapTotal,
SwapUsed: s.SwapUsed,
DiskTotal: s.DiskTotal,
DiskUsed: s.DiskUsed,
NetIn: s.NetIn,
NetOut: s.NetOut,
Cpu: s.CPU,
MemTotal: s.MemTotal,
MemUsed: s.MemUsed,
SwapTotal: s.SwapTotal,
SwapUsed: s.SwapUsed,
DiskTotal: s.DiskTotal,
DiskUsed: s.DiskUsed,
NetInTransfer: s.NetInTransfer,
NetOutTransfer: s.NetOutTransfer,
NetInSpeed: s.NetInSpeed,
NetOutSpeed: s.NetOutSpeed,
Uptime: s.Uptime,
}
}
// PB2State ..
func PB2State(s *pb.State) State {
return State{
CPU: s.GetCpu(),
MemTotal: s.GetMemTotal(),
MemUsed: s.GetMemUsed(),
SwapTotal: s.GetSwapTotal(),
SwapUsed: s.GetSwapUsed(),
DiskTotal: s.GetDiskTotal(),
DiskUsed: s.GetDiskUsed(),
NetIn: s.GetNetIn(),
NetOut: s.GetNetOut(),
CPU: s.GetCpu(),
MemTotal: s.GetMemTotal(),
MemUsed: s.GetMemUsed(),
SwapTotal: s.GetSwapTotal(),
SwapUsed: s.GetSwapUsed(),
DiskTotal: s.GetDiskTotal(),
DiskUsed: s.GetDiskUsed(),
NetInTransfer: s.GetNetInTransfer(),
NetOutTransfer: s.GetNetOutTransfer(),
NetInSpeed: s.GetNetInSpeed(),
NetOutSpeed: s.GetNetOutSpeed(),
Uptime: s.GetUptime(),
}
}
@ -58,8 +67,7 @@ type Host struct {
CPU []string
Arch string
Virtualization string
Uptime string
BootTime string
BootTime uint64
IP string
CountryCode string
Version string
@ -73,7 +81,6 @@ func (h *Host) PB() *pb.Host {
Cpu: h.CPU,
Arch: h.Arch,
Virtualization: h.Virtualization,
Uptime: h.Uptime,
BootTime: h.BootTime,
Ip: h.IP,
CountryCode: h.CountryCode,
@ -89,7 +96,6 @@ func PB2Host(h *pb.Host) Host {
CPU: h.GetCpu(),
Arch: h.GetArch(),
Virtualization: h.GetVirtualization(),
Uptime: h.GetUptime(),
BootTime: h.GetBootTime(),
IP: h.GetIp(),
CountryCode: h.GetCountryCode(),

View File

@ -13,6 +13,7 @@ import (
// CommonEnvironment ..
func CommonEnvironment(c *gin.Context, data map[string]interface{}) gin.H {
data["MatchedPath"] = c.MustGet("MatchedPath")
data["Version"] = dao.Version
// 站点标题
if t, has := data["Title"]; !has {
data["Title"] = dao.Conf.Site.Brand

View File

@ -14,11 +14,10 @@ message Host {
repeated string cpu = 3;
string arch = 4;
string virtualization = 5;
string uptime = 6;
string boot_time = 7;
string ip = 8;
string country_code = 9;
string version = 10;
uint64 boot_time = 6;
string ip = 7;
string country_code = 8;
string version = 9;
}
message State {
@ -29,8 +28,11 @@ message State {
uint64 swap_used = 5;
uint64 disk_total = 6;
uint64 disk_used = 7;
uint64 net_in = 8;
uint64 net_out = 9;
uint64 net_in_transfer = 8;
uint64 net_out_transfer = 9;
uint64 net_in_speed = 10;
uint64 net_out_speed = 11;
uint64 uptime = 12;
}
message Receipt{

View File

@ -1,7 +1,7 @@
{{define "common/footer"}}
<div class="ui inverted vertical footer segment">
<div class="ui center aligned text container">
本系统由 <a href="https://github.com/p14yground/nezha" target="_blank">哪吒面板</a> 强力驱动
本系统由 <a href="https://github.com/p14yground/nezha" target="_blank">哪吒面板</a>(v{{.Version}}) 强力驱动
</div>
</div>
<script src="https://cdnjs.loli.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

View File

@ -11,8 +11,14 @@
class="{{$server.Host.CountryCode}} flag"></i>{{end}}{{$server.Name}}
<i data-html="
<div class='content'>
{{$server.Host}}
{{$server.State}}
系统:{{$server.Host.Platform}}-{{$server.Host.PlatformVersion}} [{{if $server.Host.Virtualization}}{{$server.Host.Virtualization}}:{{end}}{{$server.Host.Arch}}]<br>
CPU{{$server.Host.CPU}}<br>
硬盘:{{$server.State.DiskUsed|bf}}/{{$server.State.DiskTotal|bf}}<br>
内存:{{$server.State.MemUsed|bf}}/{{$server.State.MemTotal|bf}}<br>
交换:{{$server.State.SwapUsed|bf}}/{{$server.State.SwapTotal|bf}}<br>
流量:<i class='arrow alternate circle down outline icon'></i>{{$server.State.NetInTransfer|bf}} <i class='arrow alternate circle up outline icon'></i>{{$server.State.NetOutTransfer|bf}}<br>
启动:{{$server.Host.BootTime|stf}}<br>
版本v{{$server.Host.Version}}<br>
</div>" class="yellow info circle icon"></i>
</div>
<div class="description">
@ -25,15 +31,6 @@
</div>
</div>
</div>
<div class="three wide column">硬盘</div>
<div class="thirteen wide column">
<div class="ui active progress" data-value="{{$server.State.DiskUsed}}"
data-total="{{$server.State.DiskTotal}}">
<div class="bar">
<div class="progress"></div>
</div>
</div>
</div>
<div class="three wide column">内存</div>
<div class="thirteen wide column">
<div class="ui active progress" data-value="{{$server.State.MemUsed}}"
@ -43,10 +40,33 @@
</div>
</div>
</div>
<div class="three wide column">交换</div>
<div class="thirteen wide column">
<div class="ui active progress" data-value="{{$server.State.SwapUsed}}"
data-total="{{$server.State.SwapTotal}}">
<div class="bar">
<div class="progress"></div>
</div>
</div>
</div>
<div class="three wide column">网络</div>
<div class="thirteen wide column">
<i class="arrow alternate circle down outline icon"></i>{{$server.State.NetIn|bf}}
<i class="arrow alternate circle up outline icon"></i>{{$server.State.NetOut|bf}}
<i
class="arrow alternate circle down outline icon"></i>{{$server.State.NetInSpeed|bf}}/s
<i class="arrow alternate circle up outline icon"></i>{{$server.State.NetOutSpeed|bf}}/s
</div>
<div class="three wide column">硬盘</div>
<div class="thirteen wide column">
<div class="ui active progress" data-value="{{$server.State.DiskUsed}}"
data-total="{{$server.State.DiskTotal}}">
<div class="bar">
<div class="progress"></div>
</div>
</div>
</div>
<div class="three wide column">在线</div>
<div class="thirteen wide column">
<i class="clock icon"></i>{{$server.State.Uptime|sf}}
</div>
</div>
</div>

View File

@ -26,3 +26,6 @@ var ServerList map[string]*model.Server
// ServerLock ..
var ServerLock sync.RWMutex
// Version ..
var Version = "debug"

View File

@ -15,6 +15,7 @@ import (
"github.com/shirou/gopsutil/net"
"github.com/p14yground/nezha/model"
"github.com/p14yground/nezha/service/dao"
)
type ipDotSbGeoIP struct {
@ -22,6 +23,8 @@ type ipDotSbGeoIP struct {
IP string
}
var netInSpeed, netOutSpeed, netInTransfer, netOutTransfer, lastUpdate uint64
// GetHost ..
func GetHost() *model.Host {
hi, _ := host.Info()
@ -46,49 +49,80 @@ func GetHost() *model.Host {
CPU: cpus,
Arch: hi.KernelArch,
Virtualization: hi.VirtualizationSystem,
Uptime: fmt.Sprintf("%v", hi.Uptime),
BootTime: fmt.Sprintf("%v", hi.BootTime),
BootTime: hi.BootTime,
IP: ip.IP,
CountryCode: strings.ToLower(ip.CountryCode),
Version: dao.Version,
}
}
// GetState ..
func GetState(delay uint64) *model.State {
func GetState(delay int64) *model.State {
hi, _ := host.Info()
// Memory
mv, _ := mem.VirtualMemory()
ms, _ := mem.SwapMemory()
// Disk
var diskTotal, diskUsed uint64
dparts, _ := disk.Partitions(true)
for _, part := range dparts {
u, _ := disk.Usage(part.Mountpoint)
diskTotal += u.Total
diskUsed += u.Used
}
// CPU
var cpuPercent float64
cp, err := cpu.Percent(time.Second*time.Duration(delay), false)
if err == nil {
cpuPercent = cp[0]
}
// Disk
var diskTotal, diskUsed uint64
dparts, _ := disk.Partitions(true)
var lastDevice string
for _, part := range dparts {
u, _ := disk.Usage(part.Mountpoint)
if lastDevice != part.Device {
diskTotal += u.Total
lastDevice = part.Device
}
diskUsed += u.Used
}
}
// Network
var netIn, netOut uint64
nc, err := net.IOCounters(false)
if err == nil {
netIn = nc[0].BytesRecv
netOut = nc[0].BytesSent
}
return &model.State{
CPU: cpuPercent,
MemTotal: mv.Total,
MemUsed: mv.Used,
SwapTotal: ms.Total,
SwapUsed: ms.Used,
DiskTotal: diskTotal,
DiskUsed: diskUsed,
NetIn: netIn,
NetOut: netOut,
CPU: cpuPercent,
MemTotal: mv.Total,
MemUsed: mv.Used,
SwapTotal: ms.Total,
SwapUsed: ms.Used,
DiskTotal: diskTotal,
DiskUsed: diskUsed,
NetInTransfer: netInTransfer,
NetOutTransfer: netOutTransfer,
NetInSpeed: netInSpeed,
NetOutSpeed: netOutSpeed,
Uptime: hi.Uptime,
}
}
// TrackNetworkSpeed ..
func TrackNetworkSpeed() {
var innerNetInTransfer, innerNetOutTransfer uint64
nc, err := net.IOCounters(true)
if err == nil {
for i := 0; i < len(nc); i++ {
if strings.HasPrefix(nc[i].Name, "e") {
innerNetInTransfer += nc[i].BytesRecv
innerNetOutTransfer += nc[i].BytesSent
}
}
if netInTransfer == 0 {
netInTransfer = innerNetInTransfer
}
if netOutTransfer == 0 {
netOutTransfer = innerNetOutTransfer
}
diff := uint64(time.Now().Unix())
if lastUpdate == 0 {
lastUpdate = diff
return
}
diff -= lastUpdate
if diff > 0 {
netInSpeed = (innerNetInTransfer - netInTransfer) / diff
netOutSpeed = (innerNetOutTransfer - netOutTransfer) / diff
}
}
}