Merge pull request #1 from flohoss/dev

Add system information
This commit is contained in:
Florian Hoss 2022-10-23 12:49:50 +02:00 committed by GitHub
commit 210af06ce1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 336 additions and 38 deletions

1
go.mod
View file

@ -4,6 +4,7 @@ go 1.19
require (
github.com/dariubs/percent v1.0.0
github.com/dustin/go-humanize v1.0.0
github.com/fsnotify/fsnotify v1.6.0
github.com/go-chi/chi/v5 v5.0.7
github.com/go-chi/cors v1.2.1

18
go.sum
View file

@ -41,7 +41,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@ -56,6 +55,8 @@ github.com/dariubs/percent v1.0.0/go.mod h1:NDZpkezJ8QqyIW/510MywB5T2KdC8v/0oTlE
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@ -81,12 +82,9 @@ github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUe
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ=
github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/spec v0.20.7 h1:1Rlu/ZrOCCob0n+JKKJAWhNWMPW8bOZRg8FJaY+0SKI=
github.com/go-openapi/spec v0.20.7/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
@ -180,7 +178,6 @@ github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamh
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
@ -188,9 +185,7 @@ github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
@ -238,8 +233,6 @@ github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a h1:kAe4YSu0O0UFn1DowN
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
github.com/swaggo/http-swagger v1.3.3 h1:Hu5Z0L9ssyBLofaama21iYaF2VbWyA8jdohaaCGpHsc=
github.com/swaggo/http-swagger v1.3.3/go.mod h1:sE+4PjD89IxMPm77FnkDz0sdO+p5lbXzrVWT6OTVVGo=
github.com/swaggo/swag v1.8.1 h1:JuARzFX1Z1njbCGz+ZytBR15TFJwF2Q7fu8puJHhQYI=
github.com/swaggo/swag v1.8.1/go.mod h1:ugemnJsPZm/kRwFUnzBlbHRd0JY9zE1M4F+uy2pAaPQ=
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
@ -301,7 +294,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -335,8 +327,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -463,8 +453,6 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -561,8 +549,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

View file

@ -3,11 +3,13 @@ package main
import (
"godash/logging"
"godash/server"
"godash/system"
"godash/weather"
)
func main() {
logging.NewGlobalLogger()
weather.NewWeather()
system.NewSystem()
server.NewServer()
}

View file

@ -9,7 +9,11 @@ import (
func (server *Server) setupRouter() {
server.Router.Get("/", launchpad)
server.Router.Route("/api", func(r chi.Router) {
r.Get("/ws", webSocket)
r.Route("/system", func(r chi.Router) {
r.Get("/static", routeStaticSystem)
r.Get("/live", routeLiveSystem)
r.Get("/ws", webSocket)
})
r.Get("/weather", getWeather)
})
server.Router.Get("/robots.txt", func(w http.ResponseWriter, r *http.Request) {

View file

@ -7,6 +7,7 @@ import (
"godash/files"
"godash/hub"
"godash/message"
"godash/system"
"godash/weather"
"net/http"
)
@ -16,6 +17,7 @@ type launchpadInformation struct {
Host string
Bookmarks []bookmark.Bookmark
Weather weather.OpenWeatherApiResponse
System system.System
}
func launchpad(w http.ResponseWriter, r *http.Request) {
@ -24,6 +26,7 @@ func launchpad(w http.ResponseWriter, r *http.Request) {
Title: "Godash",
Bookmarks: bookmark.Bookmarks,
Weather: weather.CurrentOpenWeather,
System: system.Sys,
})
}
@ -43,6 +46,38 @@ func getWeather(w http.ResponseWriter, r *http.Request) {
}
}
// @Schemes
// @Summary live system information
// @Description gets live information of the system
// @Tags system
// @Produce json
// @Success 200 {object} system.LiveInformation
// @Success 204 {object} message.Response
// @Router /system/live [get]
func routeLiveSystem(w http.ResponseWriter, r *http.Request) {
if system.Config.LiveSystem {
jsonResponse(w, system.Sys.Live, http.StatusOK)
} else {
jsonResponse(w, message.Response{Message: message.NotFound.String()}, http.StatusNoContent)
}
}
// @Schemes
// @Summary static system information
// @Description gets static information of the system
// @Tags system
// @Produce json
// @Success 200 {object} system.StaticInformation
// @Success 204 {object} message.Response
// @Router /system/static [get]
func routeStaticSystem(w http.ResponseWriter, r *http.Request) {
if system.Config.LiveSystem {
jsonResponse(w, system.Sys.Static, http.StatusOK)
} else {
jsonResponse(w, message.Response{Message: message.NotFound.String()}, http.StatusNoContent)
}
}
func webSocket(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {

View file

@ -1,21 +1,43 @@
import { select } from "https://cdn.skypack.dev/d3-selection@3";
import { timeDay } from "https://cdn.skypack.dev/d3-time@3";
const WsType = { Weather: 0, System: 1 };
const apiBase = window.location.origin + "/api";
let socket = new WebSocket(apiBase.replace("http", "ws") + "/ws");
const weatherIcon = document.getElementById("weatherIcon");
const weatherTemp = document.getElementById("weatherTemp");
const weatherDescription = document.getElementById("weatherDescription");
const weatherHumidity = document.getElementById("weatherHumidity");
const weatherSunrise = document.getElementById("weatherSunrise");
const weatherSunset = document.getElementById("weatherSunset");
let timeOut = 1;
connect();
socket.onmessage = (event) => {
const parsed = JSON.parse(event.data);
if (parsed.ws_type === WsType.Weather) {
weatherIcon.setAttribute("xlink:href", "#" + parsed.message.weather[0].icon);
weatherTemp.innerHTML = parsed.message.main.temp + " " + parsed.message.units;
weatherDescription.innerHTML = parsed.message.weather[0].description;
weatherHumidity.innerHTML = parsed.message.main.humidity + "%";
weatherSunrise.innerHTML = parsed.message.sys.str_sunrise;
weatherSunset.innerHTML = parsed.message.sys.str_sunset;
}
};
function connect() {
let ws = new WebSocket(apiBase.replace("http", "ws") + "/system/ws");
ws.onopen = () => {
console.log("WebSocket is open.");
timeOut = 1;
};
ws.onmessage = (event) => handleMessage(JSON.parse(event.data));
ws.onerror = () => ws.close();
ws.onclose = () => {
console.log("WebSocket is closed. Reconnect will be attempted in " + timeOut + " second.");
setTimeout(() => connect(), timeOut * 1000);
timeOut += 1;
};
}
function handleMessage(parsed) {
if (parsed.ws_type === WsType.Weather) replaceWeather(parsed.message);
else if (parsed.ws_type === WsType.System) replaceSystem(parsed.message);
}
function replaceWeather(parsed) {
select("#weatherIcon").attr("xlink:href", "#" + parsed.weather[0].icon);
select("#weatherTemp").text(parsed.main.temp);
select("#weatherDescription").text(parsed.weather[0].description);
select("#weatherHumidity").text(parsed.main.humidity);
select("#weatherSunrise").text(parsed.sys.str_sunrise);
select("#weatherSunset").text(parsed.sys.str_sunset);
}
function replaceSystem(parsed) {
select("#systemCpu").text(parsed.cpu.percentage);
select("#systemRamPercentage").text(parsed.ram.percentage);
select("#systemDiskPercentage").text(parsed.disk.percentage);
select("#systemUptime").text(parsed.server_uptime);
}

28
system/cpu.go Normal file
View file

@ -0,0 +1,28 @@
package system
import (
"github.com/shirou/gopsutil/v3/cpu"
"math"
"runtime"
)
func staticCpu() CPU {
var p CPU
p.Threads = runtime.NumCPU()
p.Architecture = runtime.GOARCH
c, err := cpu.Info()
if err == nil {
p.Name = c[0].ModelName
} else {
p.Name = "none detected"
}
return p
}
func (s *System) liveCpu() {
p, err := cpu.Percent(0, false)
if err != nil {
return
}
s.Live.CPU.Percentage = math.RoundToEven(p[0])
}

27
system/disk.go Normal file
View file

@ -0,0 +1,27 @@
package system
import (
"github.com/dariubs/percent"
"github.com/dustin/go-humanize"
"github.com/shirou/gopsutil/v3/disk"
"math"
)
func staticDisk() string {
d, err := disk.Usage("/")
if err != nil {
return ""
}
return humanize.IBytes(d.Total)
}
func (s *System) liveDisk() {
d, err := disk.Usage("/")
if err != nil {
return
}
used := d.Used
total := d.Total
s.Live.Disk.Value = humanize.IBytes(d.Used)
s.Live.Disk.Percentage = math.RoundToEven(percent.PercentOfFloat(float64(used), float64(total)))
}

27
system/ram.go Normal file
View file

@ -0,0 +1,27 @@
package system
import (
"github.com/dariubs/percent"
"github.com/dustin/go-humanize"
"github.com/shirou/gopsutil/v3/mem"
"math"
)
func staticRam() string {
r, err := mem.VirtualMemory()
if err != nil {
return ""
}
return humanize.IBytes(r.Total)
}
func (s *System) liveRam() {
r, err := mem.VirtualMemory()
if err != nil {
return
}
used := r.Used
total := r.Total
s.Live.Ram.Value = humanize.IBytes(r.Used)
s.Live.Ram.Percentage = math.RoundToEven(percent.PercentOfFloat(float64(used), float64(total)))
}

37
system/system.go Normal file
View file

@ -0,0 +1,37 @@
package system
import (
"github.com/sirupsen/logrus"
"godash/config"
"godash/hub"
"time"
)
var Config = SystemConfig{}
var Sys = System{}
func NewSystem() {
config.ParseViperConfig(&Config, config.AddViperConfig("system"))
if Config.LiveSystem {
Sys.Initialize()
}
}
func (s *System) UpdateLiveInformation() {
for {
s.liveCpu()
s.liveRam()
s.liveDisk()
s.uptime()
hub.LiveInformationCh <- hub.Message{WsType: hub.System, Message: s.Live}
time.Sleep(1 * time.Second)
}
}
func (s *System) Initialize() {
s.Static.CPU = staticCpu()
s.Static.Ram = staticRam()
s.Static.Disk = staticDisk()
go s.UpdateLiveInformation()
logrus.WithFields(logrus.Fields{"cpu": s.Static.CPU.Name, "arch": s.Static.CPU.Architecture}).Debug("system updated")
}

38
system/types.go Normal file
View file

@ -0,0 +1,38 @@
package system
type SystemConfig struct {
LiveSystem bool `mapstructure:"LIVE_SYSTEM"`
}
type BasicSystemInformation struct {
Value string `json:"value" validate:"required"`
Percentage float64 `json:"percentage" validate:"required"`
}
type LiveInformation struct {
CPU CpuSystemInformation `json:"cpu" validate:"required"`
Ram BasicSystemInformation `json:"ram" validate:"required"`
Disk BasicSystemInformation `json:"disk" validate:"required"`
ServerUptime uint64 `json:"server_uptime" validate:"required"`
}
type StaticInformation struct {
CPU CPU `json:"cpu" validate:"required"`
Ram string `json:"ram" validate:"required"`
Disk string `json:"disk" validate:"required"`
}
type System struct {
Live LiveInformation `json:"live" validate:"required"`
Static StaticInformation `json:"static" validate:"required"`
}
type CPU struct {
Name string `json:"name" validate:"required"`
Threads int `json:"threads" validate:"required"`
Architecture string `json:"architecture" validate:"required"`
}
type CpuSystemInformation struct {
Percentage float64 `json:"percentage" validate:"required"`
}

14
system/uptime.go Normal file
View file

@ -0,0 +1,14 @@
package system
import (
"github.com/shirou/gopsutil/v3/host"
)
func (s *System) uptime() {
i, err := host.Info()
if err != nil {
return
}
// returns uptime in milliseconds
s.Live.ServerUptime = i.Uptime * 1000
}

View file

@ -32,6 +32,35 @@
{{ define "content" }}{{ end }}
{{ define "systemIcons" }}
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
<symbol id="cpu" viewBox="0 0 512 512">
<path
fill="currentColor"
d="M176 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64c-35.3 0-64 28.7-64 64H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H64v56H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H64v56H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H64c0 35.3 28.7 64 64 64v40c0 13.3 10.7 24 24 24s24-10.7 24-24V448h56v40c0 13.3 10.7 24 24 24s24-10.7 24-24V448h56v40c0 13.3 10.7 24 24 24s24-10.7 24-24V448c35.3 0 64-28.7 64-64h40c13.3 0 24-10.7 24-24s-10.7-24-24-24H448V280h40c13.3 0 24-10.7 24-24s-10.7-24-24-24H448V176h40c13.3 0 24-10.7 24-24s-10.7-24-24-24H448c0-35.3-28.7-64-64-64V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H280V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H176V24zM160 128H352c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32zm192 32H160V352H352V160z"
/>
</symbol>
<symbol id="ram" viewBox="0 0 576 512">
<path
fill="currentColor"
d="M64 64C28.7 64 0 92.7 0 128v7.4c0 6.8 4.4 12.6 10.1 16.3C23.3 160.3 32 175.1 32 192s-8.7 31.7-21.9 40.3C4.4 236 0 241.8 0 248.6V320H576V248.6c0-6.8-4.4-12.6-10.1-16.3C552.7 223.7 544 208.9 544 192s8.7-31.7 21.9-40.3c5.7-3.7 10.1-9.5 10.1-16.3V128c0-35.3-28.7-64-64-64H64zM576 352H0v64c0 17.7 14.3 32 32 32H80V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h96V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h96V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h96V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h48c17.7 0 32-14.3 32-32V352zM192 160v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32z"
/>
</symbol>
<symbol id="disk" viewBox="0 0 512 512">
<path
fill="currentColor"
d="M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V280.4c-17-15.2-39.4-24.4-64-24.4H64c-24.6 0-47 9.2-64 24.4V96zM64 288H448c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V352c0-35.3 28.7-64 64-64zM320 416c17.7 0 32-14.3 32-32s-14.3-32-32-32s-32 14.3-32 32s14.3 32 32 32zm128-32c0-17.7-14.3-32-32-32s-32 14.3-32 32s14.3 32 32 32s32-14.3 32-32z"
/>
</symbol>
<symbol id="power" viewBox="0 0 512 512">
<path
fill="currentColor"
d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V256c0 17.7 14.3 32 32 32s32-14.3 32-32V32zM143.5 120.6c13.6-11.3 15.4-31.5 4.1-45.1s-31.5-15.4-45.1-4.1C49.7 115.4 16 181.8 16 256c0 132.5 107.5 240 240 240s240-107.5 240-240c0-74.2-33.8-140.6-86.6-184.6c-13.6-11.3-33.8-9.4-45.1 4.1s-9.4 33.8 4.1 45.1c38.9 32.3 63.5 81 63.5 135.4c0 97.2-78.8 176-176 176s-176-78.8-176-176c0-54.4 24.7-103.1 63.5-135.4z"
/>
</symbol>
</svg>
{{ end }}
{{ define "weatherIcons" }}
<svg xmlns="http://www.w3.org/2000/svg" style="display: none">
<symbol id="01d" viewBox="0 0 16 16">

View file

@ -5,7 +5,9 @@
{{ end }}
{{ define "content" }}
{{ template "systemIcons" . }}
{{ template "weatherIcons" . }}
{{ if .Weather.Name }}
<div class="flex items-center mb-6 md:mb-10 select-none">
<svg class="w-20 h-20 md:w-14 md:h-14 mr-5">
@ -14,15 +16,15 @@
{{ end }}
</svg>
<div class="flex flex-col md:flex-row">
<div class="text-4xl font-bold mr-8" id="weatherTemp">{{ .Weather.Main.Temp }} {{ .Weather.Units }}</div>
<div class="text-4xl font-bold mr-8"><span id="weatherTemp">{{ .Weather.Main.Temp }}</span> {{ .Weather.Units }}</div>
<div class="flex flex-col md:flex-row mt-1 text-sm text-slate-700 dark:text-slate-300">
<div class="flex items-center md:mr-5">
<svg width="14" height="14" class="mr-2">
<use xlink:href="#quote"></use>
</svg>
<div id="weatherDescription">
<div>
{{ range .Weather.Weather }}
{{ .Description }}
<div id="weatherDescription">{{ .Description }}</div>
{{ end }}
</div>
</div>
@ -30,7 +32,7 @@
<svg width="14" height="14" class="mr-2">
<use xlink:href="#humidity"></use>
</svg>
<div id="weatherHumidity">{{ .Weather.Main.Humidity }}%</div>
<span id="weatherHumidity">{{ .Weather.Main.Humidity }}</span>%
</div>
<div class="hidden lg:flex items-center">
<div class="flex items-center md:mr-5">
@ -71,4 +73,48 @@
</a>
{{ end }}
</div>
{{ if .System.Static.CPU.Name }}
<div class="grid grid-cols-4 gap-5 mt-6 md:mt-10 select-none">
<div class="flex items-center justify-between">
<div class="flex items-center">
<svg width="20" height="20" class="mr-3">
<use xlink:href="#cpu"></use>
</svg>
<div class="mr-2">CPU</div>
<div class="text-sm text-slate-700 dark:text-slate-300 bg-slate-300 dark:bg-slate-700 rounded px-1">{{ .System.Static.CPU.Name }}</div>
</div>
<div class="text-xl font-bold"><span id="systemCpu">{{ .System.Live.CPU.Percentage }}</span>%</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<svg width="20" height="20" class="mr-3">
<use xlink:href="#ram"></use>
</svg>
<div class="mr-2">RAM</div>
<div class="text-sm text-slate-700 dark:text-slate-300 bg-slate-300 dark:bg-slate-700 rounded px-1">{{ .System.Static.Ram }}</div>
</div>
<div class="text-xl font-bold"><span id="systemRamPercentage">{{ .System.Live.Ram.Percentage }}</span>%</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<svg width="20" height="20" class="mr-3">
<use xlink:href="#disk"></use>
</svg>
<div class="mr-2">Disk</div>
<div class="text-sm text-slate-700 dark:text-slate-300 bg-slate-300 dark:bg-slate-700 rounded px-1">{{ .System.Static.Disk }}</div>
</div>
<div class="text-xl font-bold"><span id="systemDiskPercentage">{{ .System.Live.Disk.Percentage }}</span>%</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<svg width="20" height="20" class="mr-3">
<use xlink:href="#power"></use>
</svg>
<div class="mr-2">Uptime</div>
</div>
<div class="text-xl font-bold"><span id="systemUptime">{{ .System.Live.ServerUptime }}</span></div>
</div>
</div>
{{ end }}
{{ end }}