diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 940ddfc..cf798b2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,9 +16,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v4 with: - go-version: '1.20' + go-version: '1.22.5' - name: Build - run: cd src - | go mod tidy - | go build -v *.go + run: cd src && go mod tidy && go build -v diff --git a/.gitignore b/.gitignore index bd3f8bc..adb36c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1 @@ -# created by virtualenv automatically -Lib -Scripts -include -lib -local -pyvenv.cfg -share - -**/.pytest_cache/ - -*.pem -*.env - - -**/__pycache__ \ No newline at end of file +*.exe \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 98a939c..8878dcc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,4 +4,8 @@ WORKDIR /app COPY ./src /app -CMD ["go", "run", "main.go"] \ No newline at end of file +RUN go mod tidy + +RUN go build -o main main.go utils.go + +CMD ["./main"] diff --git a/src/go.mod b/src/go.mod new file mode 100644 index 0000000..366cc3b --- /dev/null +++ b/src/go.mod @@ -0,0 +1,14 @@ +module server + +go 1.22.5 + +require github.com/shirou/gopsutil v3.21.11+incompatible + +require ( + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/stretchr/testify v1.9.0 // indirect + github.com/tklauser/go-sysconf v0.3.14 // indirect + github.com/tklauser/numcpus v0.8.0 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + golang.org/x/sys v0.23.0 // indirect +) diff --git a/src/go.sum b/src/go.sum new file mode 100644 index 0000000..39f6bbe --- /dev/null +++ b/src/go.sum @@ -0,0 +1,21 @@ +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/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= +github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= +github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= +github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/main.go b/src/main.go index d184fea..3637e2a 100644 --- a/src/main.go +++ b/src/main.go @@ -5,16 +5,17 @@ import ( "net/http" ) -type healthcheckHandler struct{} - -func (h *healthcheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - w.Header().Set("content-type", "text/plain") +type metricsHandler struct { +} +func (h *metricsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Set("content-type", "application/json") switch { case r.Method == http.MethodGet: - msg := []byte("hello there") - w.WriteHeader(http.StatusOK) - w.Write(msg) + metrics := getStatus(r) + html := generateServerStatusHTML(metrics) + w.Header().Set("Content-Type", "text/html") + w.Write([]byte(html)) return default: return @@ -23,7 +24,8 @@ func (h *healthcheckHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func main() { mux := http.NewServeMux() - mux.Handle("/", &healthcheckHandler{}) + + mux.Handle("/", &metricsHandler{}) log.Fatal(http.ListenAndServe("0.0.0.0:8001", mux)) } diff --git a/src/old_code.py b/src/old_code.py deleted file mode 100644 index 87b27c6..0000000 --- a/src/old_code.py +++ /dev/null @@ -1,129 +0,0 @@ -class ServerMetrics(BaseModel): - host: str - timestamp: str - cpu_usage: str - memory_usage: str - - -def get_status(request: Request) -> ServerMetrics: - time = datetime.datetime.now(datetime.timezone.utc).isoformat() - - cpu_usage = psutil.cpu_percent() - memory_usage = psutil.virtual_memory().percent - - return ServerMetrics(host=request.client.host, timestamp=time, cpu_usage=f"{cpu_usage} %", - memory_usage=f"{memory_usage} %") - - -def format_timestamp(timestamp): - return timestamp[11:19] + " (UTC)" - - -def generate_server_status_html(metrics: ServerMetrics) -> str: - return f""" - - - - - - - - 😈️ pointless-status 😈 - - -
-
-
-
😈️ Server is running! 😈️
-
-
-
Client
-
{metrics.host}
-
-
-
Time
-
{format_timestamp(metrics.timestamp)}
-
-
-
CPU Usage
-
{metrics.cpu_usage}
-
-
-
Memory usage
-
{metrics.memory_usage}
-
-
-
- -
-
-
-
- - - """ diff --git a/src/utils.go b/src/utils.go new file mode 100644 index 0000000..da590dd --- /dev/null +++ b/src/utils.go @@ -0,0 +1,148 @@ +package main + +import ( + "fmt" + "net" + "net/http" + "time" + + "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/mem" +) + +type ServerMetrics struct { + Host string + Timestamp string + CPUUsage string + MemoryUsage string +} + +func getStatus(r *http.Request) ServerMetrics { + // Get the client IP address + ip, _, _ := net.SplitHostPort(r.RemoteAddr) + + // Get the current timestamp in ISO 8601 format + time := time.Now().UTC().Format(time.RFC3339) + + // Get CPU and Memory usage + cpuUsage, _ := cpu.Percent(0, false) + memoryUsage, _ := mem.VirtualMemory() + + return ServerMetrics{ + Host: ip, + Timestamp: time, + CPUUsage: fmt.Sprintf("%.2f %%", cpuUsage[0]), + MemoryUsage: fmt.Sprintf("%.2f %%", memoryUsage.UsedPercent), + } +} + +func formatTimestamp(timestamp string) string { + return timestamp[11:19] + " (UTC)" +} + +func generateServerStatusHTML(metrics ServerMetrics) string { + return fmt.Sprintf(` + + + + + + + 😈️ pointless-status 😈 + + +
+
+
+
😈️ Server is running! 😈️
+
+
+
Client
+
%s
+
+
+
Time
+
%s
+
+
+
CPU Usage
+
%s
+
+
+
Memory usage
+
%s
+
+
+
+
+ + + `, metrics.Host, formatTimestamp(metrics.Timestamp), metrics.CPUUsage, metrics.MemoryUsage) +}