-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.go
155 lines (148 loc) · 4.67 KB
/
index.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package main
import (
"fmt"
"net/http"
"os"
"strconv"
"strings"
"sync"
"time"
"github.com/dustin/go-humanize"
"github.com/maxsupermanhd/WebChunk/chunkStorage"
"github.com/shirou/gopsutil/host"
"github.com/shirou/gopsutil/load"
"github.com/shirou/gopsutil/mem"
)
var prevCPUIdle uint64
var prevCPUTotal uint64
var prevTime = time.Now()
var prevCPUReport string
var prevLock sync.Mutex
func indexHandler(w http.ResponseWriter, r *http.Request) {
load, _ := load.Avg()
virtmem, _ := mem.VirtualMemory()
uptime, _ := host.Uptime()
uptimetime, _ := time.ParseDuration(strconv.Itoa(int(uptime)) + "s")
prevLock.Lock()
var CPUUsage float64
var idleTicks, totalTicks float64
if time.Since(prevTime) > 1*time.Second {
CPUIdle, CPUTotal := getCPUSample()
idleTicks = float64(CPUIdle - prevCPUIdle)
totalTicks = float64(CPUTotal - prevCPUTotal)
CPUUsage = 100 * (totalTicks - idleTicks) / totalTicks
// prevCPUReport = fmt.Sprintf("%.1f%% [busy: %.2f, total: %.2f] (past %s)", CPUUsage, totalTicks-idleTicks, totalTicks, (time.Duration(time.Since(prevTime).Seconds()) * time.Second).String())
prevCPUReport = fmt.Sprintf("%.1f%% (past %s)", CPUUsage, (time.Duration(time.Since(prevTime).Seconds()) * time.Second).String())
prevTime = time.Now()
prevCPUIdle = CPUIdle
prevCPUTotal = CPUTotal
}
CPUReport := prevCPUReport
prevLock.Unlock()
var chunksCount, chunksSizeBytes uint64
type DimData struct {
Dim chunkStorage.SDim
ChunkSize string
ChunkCount uint64
CacheSize string
CacheCount int64
}
type WorldData struct {
World chunkStorage.SWorld
Dims []DimData
}
type StorageData struct {
Name string
S chunkStorage.Storage
Worlds []WorldData
Online bool
}
st := []StorageData{}
for sn, s := range storages {
worlds := []WorldData{}
if s.Driver == nil {
st = append(st, StorageData{Name: sn, S: s, Worlds: worlds, Online: false})
// log.Println("Skipping storage " + s.Name + " because driver is uninitialized")
continue
}
achunksCount, _ := s.Driver.GetChunksCount()
achunksSizeBytes, _ := s.Driver.GetChunksSize()
chunksCount += achunksCount
chunksSizeBytes += achunksSizeBytes
worldss, err := s.Driver.ListWorlds()
if err != nil {
plainmsg(w, r, plainmsgColorRed, "Error listing worlds of storage "+sn+": "+err.Error())
return
}
for _, wrld := range worldss {
wd := WorldData{World: wrld, Dims: []DimData{}}
dims, err := s.Driver.ListWorldDimensions(wrld.Name)
if err != nil {
plainmsg(w, r, plainmsgColorRed, "Error listing dimensions of world "+wrld.Name+" of storage "+sn+": "+err.Error())
return
}
for _, dim := range dims {
dimChunksCount, err := s.Driver.GetDimensionChunksCount(wrld.Name, dim.Name)
if err != nil {
plainmsg(w, r, plainmsgColorRed, "Error getting chunk count of dim "+dim.Name+" of world "+wrld.Name+" of storage "+sn+": "+err.Error())
return
}
dimChunksSize, err := s.Driver.GetDimensionChunksSize(wrld.Name, dim.Name)
if err != nil {
plainmsg(w, r, plainmsgColorRed, "Error getting chunks size of dim "+dim.Name+" of world "+wrld.Name+" of storage "+sn+": "+err.Error())
return
}
// dimCacheCount, dimCacheSize, err := getImageCacheCountSize(wrld.Name, dim.Name)
dimCacheCount, dimCacheSize, err := int64(0), 0, nil
if err != nil {
plainmsg(w, r, plainmsgColorRed, "Error getting cache size and counts of dim "+dim.Name+" of world "+wrld.Name+": "+err.Error())
return
}
wd.Dims = append(wd.Dims, DimData{
Dim: dim,
ChunkSize: humanize.Bytes(dimChunksSize),
ChunkCount: dimChunksCount,
CacheSize: humanize.Bytes(uint64(dimCacheSize)),
CacheCount: dimCacheCount,
})
}
worlds = append(worlds, wd)
}
st = append(st, StorageData{Name: sn, S: s, Worlds: worlds, Online: true})
}
chunksSize := humanize.Bytes(chunksSizeBytes)
templateRespond("index", w, r, map[string]interface{}{
"LoadAvg": load,
"VirtMem": virtmem,
"Uptime": uptimetime,
"ChunksCount": chunksCount,
"ChunksSize": chunksSize,
"CPUReport": CPUReport,
"Storages": st,
})
}
func getCPUSample() (idle, total uint64) {
contents, err := os.ReadFile("/proc/stat")
if err != nil {
return
}
lines := strings.Split(string(contents), "\n")
for _, line := range lines {
fields := strings.Fields(line)
if fields[0] == "cpu" {
numFields := len(fields)
for i := 1; i < numFields; i++ {
val, err := strconv.ParseUint(fields[i], 10, 64)
if err != nil {
fmt.Println("Error: ", i, fields[i], err)
}
total += val // tally up all the numbers to get total ticks
if i == 4 { // idle is the 5th field in the cpu line
idle = val
}
}
return
}
}
return
}