Skip to content

Commit

Permalink
Update log management
Browse files Browse the repository at this point in the history
  • Loading branch information
tr4cks committed May 17, 2024
1 parent 17befe2 commit e744bd9
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 15 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/linde12/gowol v0.0.0-20180926075039-797e4d01634c
github.com/mitchellh/mapstructure v1.5.0
github.com/prometheus-community/pro-bing v0.4.0
github.com/rs/zerolog v1.32.0
github.com/spf13/cobra v1.8.0
gopkg.in/yaml.v3 v3.0.1
)
Expand All @@ -27,6 +28,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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=
Expand All @@ -25,6 +26,7 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx
github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
Expand All @@ -41,6 +43,10 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
github.com/linde12/gowol v0.0.0-20180926075039-797e4d01634c h1:QRJTb9zWXQL+yUajUqbp+VLtN+DQaYRloOxNwylsuVc=
github.com/linde12/gowol v0.0.0-20180926075039-797e4d01634c/go.mod h1:YeHfx3xIWda3noSterlj6d3+PdRRCTRox269+zhLmbM=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
Expand All @@ -52,10 +58,14 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/prometheus-community/pro-bing v0.4.0 h1:YMbv+i08gQz97OZZBwLyvmmQEEzyfyrrjEaAchdy3R4=
github.com/prometheus-community/pro-bing v0.4.0/go.mod h1:b7wRYZtCcPmt4Sz319BykUU241rWLe1VFXyiyWK/dH4=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
Expand Down Expand Up @@ -86,8 +96,10 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
Expand Down
72 changes: 62 additions & 10 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"encoding/json"
"fmt"
"html/template"
"io"
"io/fs"
"log"
"net/http"
"os"
"path"
"strings"
"time"

"github.com/rs/zerolog"
"github.com/tr4cks/power/modules"
"github.com/tr4cks/power/modules/ilo"
"github.com/tr4cks/power/modules/wakeonlan"
Expand Down Expand Up @@ -121,24 +123,74 @@ var templateFS embed.FS
//go:embed static
var staticFS embed.FS

// loggers
var (
ginLogger zerolog.Logger
mainLogger zerolog.Logger
)

func configureLoggers() {
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
var outputWriter io.Writer = os.Stderr
if gin.Mode() != "release" {
outputWriter = zerolog.ConsoleWriter{Out: os.Stderr}
}
logger := zerolog.New(outputWriter).With().Timestamp().Logger()
ginLogger = logger.With().Str("scope", "gin").Logger()
mainLogger = logger.With().Str("scope", "main").Logger()
}

func loggerWithZerolog(logger *zerolog.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()
path := c.Request.URL.Path
raw := c.Request.URL.RawQuery

c.Next()

latency := time.Since(start)

if raw != "" {
path = path + "?" + raw
}

errorMessage := c.Errors.ByType(gin.ErrorTypePrivate).String()
event := logger.Info()
if errorMessage != "" {
event = logger.Error()
}

event.
Str("client_ip", c.ClientIP()).
Str("method", c.Request.Method).
Str("path", path).
Int("status", c.Writer.Status()).
Int("size", c.Writer.Size()).
Dur("latency", latency).
Msg(errorMessage)
}
}

func runServer(config *Config, module modules.Module) {
// Configure Gin
router := gin.Default()
router := gin.New()
router.Use(loggerWithZerolog(&ginLogger))
router.Use(gin.Recovery())
router.SetTrustedProxies(nil)
html := template.Must(template.ParseFS(templateFS, "index.html"))
router.SetHTMLTemplate(html)

// Logging
logErr := log.New(os.Stderr, "[ERR] ", log.LstdFlags|log.Lshortfile)
configureLoggers()

// Serve static folder
staticSubtreeFS, err := fs.Sub(staticFS, "static")
if err != nil {
log.Fatal(err)
mainLogger.Fatal().Err(err)
}
router.StaticFS("/static", http.FS(staticSubtreeFS))

withServerState := router.Group("/", ServerStateMiddleware(module, logErr))
withServerState := router.Group("/", ServerStateMiddleware(module, &mainLogger))
{
// GET index.html
withServerState.GET("/", func(c *gin.Context) {
Expand All @@ -156,7 +208,7 @@ func runServer(config *Config, module modules.Module) {
if c.GetBool("power") {
err := module.PowerOff()
if err != nil {
logErr.Printf("Server shutdown error: %s", err)
mainLogger.Error().Err(err).Msg("Server shutdown error")
c.HTML(http.StatusOK, "index.html", gin.H{
"power": c.GetBool("power"),
"led": c.GetBool("led"),
Expand All @@ -167,7 +219,7 @@ func runServer(config *Config, module modules.Module) {
} else {
err := module.PowerOn()
if err != nil {
logErr.Printf("Server power-up error: %s", err)
mainLogger.Error().Err(err).Msg("Server power-up error")
c.HTML(http.StatusOK, "index.html", gin.H{
"power": c.GetBool("power"),
"led": c.GetBool("led"),
Expand All @@ -187,7 +239,7 @@ func runServer(config *Config, module modules.Module) {
err := module.PowerOn()

if err != nil {
logErr.Printf("Server power-up error: %s", err)
mainLogger.Error().Err(err).Msg("Server power-up error")
c.JSON(http.StatusInternalServerError, gin.H{
"status": "ko",
"error": "a problem occurred during server startup",
Expand All @@ -204,7 +256,7 @@ func runServer(config *Config, module modules.Module) {
err := module.PowerOff()

if err != nil {
logErr.Printf("Server shutdown error: %s", err)
mainLogger.Error().Err(err).Msg("Server shutdown error")
c.JSON(http.StatusInternalServerError, gin.H{
"status": "ko",
"error": "a problem occurred during server shutdown",
Expand All @@ -217,7 +269,7 @@ func runServer(config *Config, module modules.Module) {
})
})

api.GET("/state", ServerStateMiddleware(module, logErr), func(c *gin.Context) {
api.GET("/state", ServerStateMiddleware(module, &mainLogger), func(c *gin.Context) {
c.JSON(200, gin.H{
"power": c.GetBool("power"),
"led": c.GetBool("led"),
Expand Down
9 changes: 4 additions & 5 deletions middleware.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package main

import (
"log"

"github.com/rs/zerolog"
"github.com/tr4cks/power/modules"

"github.com/gin-gonic/gin"
)

func ServerStateMiddleware(module modules.Module, logErr *log.Logger) gin.HandlerFunc {
func ServerStateMiddleware(module modules.Module, logger *zerolog.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
powerState, ledState := module.State()

if powerState.Err != nil {
logErr.Printf("Failed to retrieve POWER state: %s", powerState.Err)
logger.Error().Err(powerState.Err).Msg("Failed to retrieve POWER state")
}
if ledState.Err != nil {
logErr.Printf("Failed to retrieve LED state: %s", ledState.Err)
logger.Error().Err(ledState.Err).Msg("Failed to retrieve LED state")
}

c.Set("power", powerState.Value)
Expand Down

0 comments on commit e744bd9

Please sign in to comment.