diff --git a/web/html/xui/index.html b/web/html/xui/index.html
index 1a5e4d89..851031fc 100644
--- a/web/html/xui/index.html
+++ b/web/html/xui/index.html
@@ -42,7 +42,7 @@
:stroke-color="status.cpu.color"
:class="themeSwitcher.darkCardClass"
:percent="status.cpu.percent">
-
CPU
+ CPU ([[ status.cpuCount ]]core)
{{ i18n "pages.index.operationHours" }}:
- [[ formatSecond(status.uptime) ]]
+ xray
+ [[ formatSecond(status.appStats.uptime) ]]
+ os
{{ i18n "pages.index.operationHoursDesc" }}
+ [[ formatSecond(status.uptime) ]]
@@ -131,7 +134,36 @@
- tcp / udp {{ i18n "pages.index.connectionCount" }}: [[ status.tcpCount ]] / [[ status.udpCount ]]
+ {{ i18n "usage"}}:
+ Memory [[ sizeFormat(status.appStats.mem) ]] -
+ Threads [[ status.appStats.threads ]]
+
+
+
+
+
+ Host: [[ status.hostInfo.hostname ]] -
+ IPv4:
+
+
+ [[ status.hostInfo.ipv4 ]]
+
+
+
+
+ IPv6:
+
+
+ [[ status.hostInfo.ipv6 ]]
+
+
+
+
+
+
+
+
+ {{ i18n "pages.index.connectionCount" }}: tcp: [[ status.tcpCount ]] udp: [[ status.udpCount ]]
{{ i18n "pages.index.connectionCountDesc" }}
@@ -315,6 +347,7 @@
class Status {
constructor(data) {
this.cpu = new CurTotal(0, 0);
+ this.cpuCount = 0;
this.disk = new CurTotal(0, 0);
this.loads = [0, 0, 0];
this.mem = new CurTotal(0, 0);
@@ -324,12 +357,16 @@
this.tcpCount = 0;
this.udpCount = 0;
this.uptime = 0;
+ this.appUptime = 0;
+ this.appStats = {threads: 0, mem: 0, uptime: 0};
+ this.hostInfo = {hostname:"", ipv4: "", ipv6: ""};
this.xray = {state: State.Stop, errorMsg: "", version: "", color: ""};
if (data == null) {
return;
}
this.cpu = new CurTotal(data.cpu, 100);
+ this.cpuCount = data.cpuCount;
this.disk = new CurTotal(data.disk.current, data.disk.total);
this.loads = data.loads.map(load => toFixed(load, 2));
this.mem = new CurTotal(data.mem.current, data.mem.total);
@@ -339,6 +376,9 @@
this.tcpCount = data.tcpCount;
this.udpCount = data.udpCount;
this.uptime = data.uptime;
+ this.appUptime = data.appUptime;
+ this.appStats = data.appStats;
+ this.hostInfo = data.hostInfo;
this.xray = data.xray;
switch (this.xray.state) {
case State.Running:
diff --git a/web/service/server.go b/web/service/server.go
index 1d4fd08c..09f51bf0 100644
--- a/web/service/server.go
+++ b/web/service/server.go
@@ -39,9 +39,10 @@ const (
)
type Status struct {
- T time.Time `json:"-"`
- Cpu float64 `json:"cpu"`
- Mem struct {
+ T time.Time `json:"-"`
+ Cpu float64 `json:"cpu"`
+ CpuCount int `json:"cpuCount"`
+ Mem struct {
Current uint64 `json:"current"`
Total uint64 `json:"total"`
} `json:"mem"`
@@ -70,6 +71,16 @@ type Status struct {
Sent uint64 `json:"sent"`
Recv uint64 `json:"recv"`
} `json:"netTraffic"`
+ AppStats struct {
+ Threads uint32 `json:"threads"`
+ Mem uint64 `json:"mem"`
+ Uptime uint64 `json:"uptime"`
+ } `json:"appStats"`
+ HostInfo struct {
+ HostName string `json:"hostname"`
+ Ipv4 string `json:"ipv4"`
+ Ipv6 string `json:"ipv6"`
+ } `json:"hostInfo"`
}
type Release struct {
@@ -176,6 +187,36 @@ func (s *ServerService) GetStatus(lastStatus *Status) *Status {
}
status.Xray.Version = s.xrayService.GetXrayVersion()
+ var rtm runtime.MemStats
+ runtime.ReadMemStats(&rtm)
+
+ status.AppStats.Mem = rtm.Sys
+ status.AppStats.Threads = uint32(runtime.NumGoroutine())
+ status.CpuCount = runtime.NumCPU()
+ if p.IsRunning() {
+ status.AppStats.Uptime = p.GetUptime()
+ } else {
+ status.AppStats.Uptime = 0
+ }
+
+ status.HostInfo.HostName, _ = os.Hostname()
+
+ // get ip address
+ netInterfaces, _ := net.Interfaces()
+ for i := 0; i < len(netInterfaces); i++ {
+ if len(netInterfaces[i].Flags) > 2 && netInterfaces[i].Flags[0] == "up" && netInterfaces[i].Flags[1] != "loopback" {
+ addrs := netInterfaces[i].Addrs
+
+ for _, address := range addrs {
+ if strings.Contains(address.Addr, ".") {
+ status.HostInfo.Ipv4 += address.Addr + " "
+ } else if address.Addr[0:6] != "fe80::" {
+ status.HostInfo.Ipv6 += address.Addr + " "
+ }
+ }
+ }
+ }
+
return status
}
diff --git a/xray/process.go b/xray/process.go
index ae8e7019..c72cd080 100644
--- a/xray/process.go
+++ b/xray/process.go
@@ -12,6 +12,7 @@ import (
"runtime"
"strings"
"syscall"
+ "time"
"x-ui/config"
"x-ui/util/common"
@@ -58,16 +59,18 @@ type process struct {
version string
apiPort int
- config *Config
- lines *queue.Queue
- exitErr error
+ config *Config
+ lines *queue.Queue
+ exitErr error
+ startTime time.Time
}
func newProcess(config *Config) *process {
return &process{
- version: "Unknown",
- config: config,
- lines: queue.New(100),
+ version: "Unknown",
+ config: config,
+ lines: queue.New(100),
+ startTime: time.Now(),
}
}
@@ -111,6 +114,10 @@ func (p *Process) GetConfig() *Config {
return p.config
}
+func (p *Process) GetUptime() uint64 {
+ return uint64(time.Since(p.startTime).Seconds())
+}
+
func (p *process) refreshAPIPort() {
for _, inbound := range p.config.InboundConfigs {
if inbound.Tag == "api" {