Replace zap with slog

This commit is contained in:
Florian Hoss 2023-10-26 11:42:14 +02:00
parent 4e7dc40144
commit 9afd3953e6
10 changed files with 67 additions and 115 deletions

View file

@ -2,29 +2,31 @@ package main
import ( import (
"fmt" "fmt"
"log" "log/slog"
"net/http" "net/http"
"os"
"gitlab.unjx.de/flohoss/godash/internal/controller" "gitlab.unjx.de/flohoss/godash/internal/controller"
"gitlab.unjx.de/flohoss/godash/internal/env" "gitlab.unjx.de/flohoss/godash/internal/env"
"gitlab.unjx.de/flohoss/godash/internal/logging" "gitlab.unjx.de/flohoss/godash/internal/logger"
"gitlab.unjx.de/flohoss/godash/internal/router" "gitlab.unjx.de/flohoss/godash/internal/router"
"go.uber.org/zap"
) )
func main() { func main() {
env, err := env.Parse() env, err := env.Parse()
if err != nil { if err != nil {
log.Fatal(err) slog.Error("cannot parse environment variables", "err", err)
os.Exit(1)
} }
zap.ReplaceGlobals(logging.CreateLogger(env.LogLevel)) slog.SetDefault(logger.NewLogger(env.LogLevel))
r := router.InitRouter() r := router.InitRouter()
c := controller.NewController(env) c := controller.NewController(env)
router.SetupRoutes(r, c) router.SetupRoutes(r, c)
zap.L().Info("starting server", zap.String("url", fmt.Sprintf("http://localhost:%d", env.Port))) slog.Info("starting server", "url", fmt.Sprintf("http://localhost:%d", env.Port))
if err := r.Start(fmt.Sprintf(":%d", env.Port)); err != http.ErrServerClosed { if err := r.Start(fmt.Sprintf(":%d", env.Port)); err != http.ErrServerClosed {
zap.L().Fatal("cannot start server", zap.Error(err)) slog.Error("cannot start server", "err", err)
os.Exit(1)
} }
} }

3
go.mod
View file

@ -9,11 +9,11 @@ require (
github.com/fsnotify/fsnotify v1.7.0 github.com/fsnotify/fsnotify v1.7.0
github.com/go-playground/validator/v10 v10.15.5 github.com/go-playground/validator/v10 v10.15.5
github.com/labstack/echo/v4 v4.11.2 github.com/labstack/echo/v4 v4.11.2
github.com/lmittmann/tint v1.0.2
github.com/r3labs/sse/v2 v2.10.0 github.com/r3labs/sse/v2 v2.10.0
github.com/shirou/gopsutil/v3 v3.23.9 github.com/shirou/gopsutil/v3 v3.23.9
github.com/stretchr/testify v1.8.4 github.com/stretchr/testify v1.8.4
github.com/unjx-de/go-folder v1.0.7 github.com/unjx-de/go-folder v1.0.7
go.uber.org/zap v1.26.0
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
) )
@ -46,7 +46,6 @@ require (
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/crypto v0.14.0 // indirect golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect golang.org/x/sys v0.13.0 // indirect

8
go.sum
View file

@ -54,6 +54,8 @@ github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
github.com/lmittmann/tint v1.0.2 h1:9XZ+JvEzjvd3VNVugYqo3j+dl0NRju8k9FquAusJExM=
github.com/lmittmann/tint v1.0.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed h1:036IscGBfJsFIgJQzlui7nK1Ncm0tp2ktmPj8xO4N/0= github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed h1:036IscGBfJsFIgJQzlui7nK1Ncm0tp2ktmPj8xO4N/0=
github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k=
@ -116,12 +118,6 @@ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=

View file

@ -2,12 +2,12 @@ package bookmarks
import ( import (
"io" "io"
"log/slog"
"os" "os"
"strings" "strings"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
folderCreate "github.com/unjx-de/go-folder" folderCreate "github.com/unjx-de/go-folder"
"go.uber.org/zap"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@ -29,44 +29,45 @@ func (c *Config) createFolderStructure() {
folders := []string{StorageDir, IconsDir} folders := []string{StorageDir, IconsDir}
err := folderCreate.CreateFolders(folders, 0755) err := folderCreate.CreateFolders(folders, 0755)
if err != nil { if err != nil {
zap.L().Fatal("cannot create folder", zap.Error(err)) slog.Error("cannot create folder", "err", err)
os.Exit(1)
} }
zap.L().Debug("folders created", zap.Strings("folders", folders)) slog.Debug("folders created", "folders", folders)
} }
func (c *Config) copyDefaultConfigIfNotExisting() { func (c *Config) copyDefaultConfigIfNotExisting() {
_, err := os.Open(StorageDir + configFile) _, err := os.Open(StorageDir + configFile)
if err != nil { if err != nil {
zap.L().Debug(configFile + " not existing, creating...") slog.Debug(configFile + " not existing, creating...")
source, _ := os.Open(bookmarksFolder + configFile) source, _ := os.Open(bookmarksFolder + configFile)
defer source.Close() defer source.Close()
destination, err := os.Create(StorageDir + configFile) destination, err := os.Create(StorageDir + configFile)
if err != nil { if err != nil {
zap.L().Error(err.Error()) slog.Error(err.Error())
return return
} }
defer destination.Close() defer destination.Close()
_, err = io.Copy(destination, source) _, err = io.Copy(destination, source)
if err != nil { if err != nil {
zap.L().Error(err.Error()) slog.Error(err.Error())
return return
} }
zap.L().Debug(configFile + " created") slog.Debug(configFile + " created")
} else { } else {
zap.L().Debug(configFile + " existing, skipping creation") slog.Debug(configFile + " existing, skipping creation")
} }
} }
func (c *Config) readBookmarksFile() []byte { func (c *Config) readBookmarksFile() []byte {
file, err := os.Open(StorageDir + configFile) file, err := os.Open(StorageDir + configFile)
if err != nil { if err != nil {
zap.L().Error(err.Error()) slog.Error(err.Error())
return nil return nil
} }
defer file.Close() defer file.Close()
byteValue, err := io.ReadAll(file) byteValue, err := io.ReadAll(file)
if err != nil { if err != nil {
zap.L().Error(err.Error()) slog.Error(err.Error())
return nil return nil
} }
return byteValue return byteValue
@ -86,7 +87,7 @@ func (c *Config) parseBookmarks() {
byteValue := c.readBookmarksFile() byteValue := c.readBookmarksFile()
err := yaml.Unmarshal(byteValue, &c.Parsed) err := yaml.Unmarshal(byteValue, &c.Parsed)
if err != nil { if err != nil {
zap.L().Error(err.Error()) slog.Error(err.Error())
return return
} }
c.replaceIconString() c.replaceIconString()
@ -95,7 +96,7 @@ func (c *Config) parseBookmarks() {
func (c *Config) watchBookmarks() { func (c *Config) watchBookmarks() {
watcher, err := fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
zap.L().Error(err.Error()) slog.Error(err.Error())
} }
defer watcher.Close() defer watcher.Close()
done := make(chan bool) done := make(chan bool)
@ -103,17 +104,18 @@ func (c *Config) watchBookmarks() {
go func() { go func() {
for { for {
select { select {
case _ = <-watcher.Events: case <-watcher.Events:
c.parseBookmarks() c.parseBookmarks()
zap.L().Debug("bookmarks changed", zap.Int("applications", len(c.Parsed.Applications)), zap.Int("links", len(c.Parsed.Links))) slog.Debug("bookmarks changed", "applications", len(c.Parsed.Applications), "links", len(c.Parsed.Links))
case err := <-watcher.Errors: case err := <-watcher.Errors:
zap.L().Error(err.Error()) slog.Error(err.Error())
} }
} }
}() }()
if err := watcher.Add(StorageDir + configFile); err != nil { if err := watcher.Add(StorageDir + configFile); err != nil {
zap.L().Fatal("cannot add watcher") slog.Error("cannot add watcher")
os.Exit(1)
} }
<-done <-done
} }

25
internal/logger/logger.go Normal file
View file

@ -0,0 +1,25 @@
package logger
import (
"log/slog"
"os"
"time"
"github.com/lmittmann/tint"
)
func NewLogger(logLevel string) *slog.Logger {
w := os.Stderr
lvl := new(slog.Level)
level := slog.LevelInfo
err := lvl.UnmarshalText([]byte(logLevel))
if err == nil {
level = *lvl
}
return slog.New(tint.NewHandler(w, &tint.Options{
Level: &level,
TimeFormat: time.Kitchen,
}))
}

View file

@ -1,44 +0,0 @@
package logging
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func TestInfoLogger(t *testing.T) {
level := "info"
log := CreateLogger(level)
defer log.Sync()
assert.NotEmpty(t, log, "Logger should not be nil")
assert.Equal(t, log.Level().String(), level, fmt.Sprintf("Level should be %s", level))
}
func TestWarnLogger(t *testing.T) {
level := "warn"
log := CreateLogger(level)
defer log.Sync()
assert.NotEmpty(t, log, "Logger should not be nil")
assert.Equal(t, log.Level().String(), level, fmt.Sprintf("Level should be %s", level))
}
func TestDebugLogger(t *testing.T) {
level := "debug"
log := CreateLogger(level)
defer log.Sync()
assert.NotEmpty(t, log, "Logger should not be nil")
assert.Equal(t, log.Level().String(), level, fmt.Sprintf("Level should be %s", level))
}
func TestInvalidLogger(t *testing.T) {
level := "invalid"
log := CreateLogger(level)
defer log.Sync()
assert.NotEmpty(t, log, "Logger should not be nil")
assert.Equal(t, log.Level().String(), "info", "Level should be info")
}

View file

@ -1,33 +0,0 @@
package logging
import (
"time"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func CreateLogger(logLevel string) *zap.Logger {
encoderCfg := zap.NewProductionEncoderConfig()
encoderCfg.TimeKey = "time"
encoderCfg.EncodeTime = zapcore.TimeEncoderOfLayout(time.StampMilli)
level := zap.NewAtomicLevelAt(zap.InfoLevel)
zapLevel, err := zap.ParseAtomicLevel(logLevel)
if err == nil {
level = zapLevel
}
config := zap.Config{
Level: level,
Development: false,
DisableCaller: false,
DisableStacktrace: false,
Sampling: nil,
Encoding: "json",
EncoderConfig: encoderCfg,
OutputPaths: []string{"stdout"},
ErrorOutputPaths: []string{"stderr"},
}
return zap.Must(config.Build())
}

View file

@ -2,6 +2,7 @@ package router
import ( import (
"net/http" "net/http"
"strings"
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware" "github.com/labstack/echo/v4/middleware"
@ -16,7 +17,11 @@ func InitRouter() *echo.Echo {
e.Pre(middleware.RemoveTrailingSlash()) e.Pre(middleware.RemoveTrailingSlash())
e.Use(middleware.Recover()) e.Use(middleware.Recover())
e.Use(middleware.Gzip()) e.Use(middleware.GzipWithConfig(middleware.GzipConfig{
Skipper: func(c echo.Context) bool {
return strings.Contains(c.Path(), "sse")
},
}))
e.Renderer = initTemplates() e.Renderer = initTemplates()

View file

@ -2,10 +2,10 @@ package system
import ( import (
"encoding/json" "encoding/json"
"log/slog"
"time" "time"
"github.com/r3labs/sse/v2" "github.com/r3labs/sse/v2"
"go.uber.org/zap"
) )
func NewSystemService(enabled bool, sse *sse.Server) *System { func NewSystemService(enabled bool, sse *sse.Server) *System {
@ -35,5 +35,5 @@ func (c *Config) Initialize() {
c.System.Static.Ram = staticRam() c.System.Static.Ram = staticRam()
c.System.Static.Disk = staticDisk() c.System.Static.Disk = staticDisk()
go c.UpdateLiveInformation() go c.UpdateLiveInformation()
zap.L().Debug("system updated", zap.String("cpu", c.System.Static.CPU.Name), zap.String("arch", c.System.Static.Host.Architecture)) slog.Debug("system updated", "cpu", c.System.Static.CPU.Name, "arch", c.System.Static.Host.Architecture)
} }

View file

@ -4,13 +4,13 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log/slog"
"math" "math"
"net/http" "net/http"
"time" "time"
"github.com/caarlos0/env/v8" "github.com/caarlos0/env/v8"
"github.com/r3labs/sse/v2" "github.com/r3labs/sse/v2"
"go.uber.org/zap"
) )
func NewWeatherService(sse *sse.Server) *Weather { func NewWeatherService(sse *sse.Server) *Weather {
@ -58,15 +58,15 @@ func (w *Weather) updateWeather(interval time.Duration) {
w.config.Units, w.config.Units,
w.config.Lang)) w.config.Lang))
if err != nil || resp.StatusCode != 200 { if err != nil || resp.StatusCode != 200 {
zap.L().Error("weather cannot be updated, please check WEATHER_KEY") slog.Error("weather cannot be updated, please check WEATHER_KEY")
} else { } else {
body, _ := io.ReadAll(resp.Body) body, _ := io.ReadAll(resp.Body)
err = json.Unmarshal(body, &weatherResponse) err = json.Unmarshal(body, &weatherResponse)
if err != nil { if err != nil {
zap.L().Error("weather cannot be processed") slog.Error("weather cannot be processed")
} else { } else {
w.copyWeatherValues(&weatherResponse) w.copyWeatherValues(&weatherResponse)
zap.L().Debug("weather updated", zap.Float64("temp", w.CurrentWeather.Temp)) slog.Debug("weather updated", "temp", w.CurrentWeather.Temp)
} }
resp.Body.Close() resp.Body.Close()
json, _ := json.Marshal(w.CurrentWeather) json, _ := json.Marshal(w.CurrentWeather)