mirror of
https://github.com/h44z/wg-portal.git
synced 2025-04-19 00:45:17 +00:00
chore: replace logrus with standard lib log/slog
This commit is contained in:
parent
5c51573874
commit
7473132932
@ -2,12 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
@ -31,12 +30,11 @@ import (
|
||||
func main() {
|
||||
ctx := internal.SignalAwareContext(context.Background(), syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
logrus.Infof("Starting WireGuard Portal V2...")
|
||||
logrus.Infof("WireGuard Portal version: %s", internal.Version)
|
||||
slog.Info("Starting WireGuard Portal V2...", "version", internal.Version)
|
||||
|
||||
cfg, err := config.GetConfig()
|
||||
internal.AssertNoError(err)
|
||||
setupLogging(cfg)
|
||||
internal.SetupLogging(cfg.Advanced.LogLevel, cfg.Advanced.LogPretty, cfg.Advanced.LogJson)
|
||||
|
||||
cfg.LogStartupValues()
|
||||
|
||||
@ -62,7 +60,7 @@ func main() {
|
||||
case shouldExit && err == nil:
|
||||
return
|
||||
case shouldExit:
|
||||
logrus.Errorf("Failed to process program args: %v", err)
|
||||
slog.Error("Failed to process program args", "error", err)
|
||||
os.Exit(1)
|
||||
default:
|
||||
internal.AssertNoError(err)
|
||||
@ -131,41 +129,14 @@ func main() {
|
||||
go metricsServer.Run(ctx)
|
||||
go webSrv.Run(ctx, cfg.Web.ListeningAddress)
|
||||
|
||||
slog.Info("Application startup complete")
|
||||
|
||||
// wait until context gets cancelled
|
||||
<-ctx.Done()
|
||||
|
||||
logrus.Infof("Stopping WireGuard Portal")
|
||||
slog.Info("Stopping WireGuard Portal")
|
||||
|
||||
time.Sleep(5 * time.Second) // wait for (most) goroutines to finish gracefully
|
||||
|
||||
logrus.Infof("Stopped WireGuard Portal")
|
||||
}
|
||||
|
||||
func setupLogging(cfg *config.Config) {
|
||||
switch strings.ToLower(cfg.Advanced.LogLevel) {
|
||||
case "trace":
|
||||
logrus.SetLevel(logrus.TraceLevel)
|
||||
case "debug":
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
case "info", "information":
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
case "warn", "warning":
|
||||
logrus.SetLevel(logrus.WarnLevel)
|
||||
case "error":
|
||||
logrus.SetLevel(logrus.ErrorLevel)
|
||||
default:
|
||||
logrus.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
|
||||
switch {
|
||||
case cfg.Advanced.LogJson:
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{
|
||||
PrettyPrint: cfg.Advanced.LogPretty,
|
||||
})
|
||||
case cfg.Advanced.LogPretty:
|
||||
logrus.SetFormatter(&logrus.TextFormatter{
|
||||
ForceColors: true,
|
||||
DisableColors: false,
|
||||
})
|
||||
}
|
||||
slog.Info("Stopped WireGuard Portal")
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@ -13,10 +13,8 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/prometheus-community/pro-bing v0.6.1
|
||||
github.com/prometheus/client_golang v1.21.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/swaggo/swag v1.16.4
|
||||
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f
|
||||
github.com/utrack/gin-csrf v0.0.0-20190424104817-40fb8d2c8fca
|
||||
github.com/vardius/message-bus v1.1.5
|
||||
github.com/vishvananda/netlink v1.3.0
|
||||
|
5
go.sum
5
go.sum
@ -243,8 +243,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@ -261,8 +259,6 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/swaggo/swag v1.16.4 h1:clWJtd9LStiG3VeijiCfOVODP6VpHtKdQy9ELFG3s1A=
|
||||
github.com/swaggo/swag v1.16.4/go.mod h1:VBsHJRsDvfYvqoiMKnsdwhNV9LEMHgEDZcyVYX0sxPg=
|
||||
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f h1:oqdnd6OGlOUu1InG37hWcCB3a+Jy3fwjylyVboaNMwY=
|
||||
github.com/toorop/gin-logrus v0.0.0-20210225092905-2c785434f26f/go.mod h1:X3Dd1SB8Gt1V968NTzpKFjMM6O8ccta2NPC6MprOxZQ=
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
|
||||
github.com/toorop/go-dkim v0.0.0-20250226130143-9025cce95817 h1:q0hKh5a5FRkhuTb5JNfgjzpzvYLHjH0QOgPZPYnRWGA=
|
||||
github.com/toorop/go-dkim v0.0.0-20250226130143-9025cce95817/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
|
||||
@ -353,7 +349,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -4,14 +4,14 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"github.com/sirupsen/logrus"
|
||||
gormMySQL "gorm.io/driver/mysql"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/driver/sqlserver"
|
||||
"gorm.io/gorm"
|
||||
@ -32,13 +32,15 @@ type SysStat struct {
|
||||
SchemaVersion uint64 `gorm:"primaryKey,column:schema_version"`
|
||||
}
|
||||
|
||||
// GormLogger is a custom logger for Gorm, making it use logrus.
|
||||
// GormLogger is a custom logger for Gorm, making it use slog
|
||||
type GormLogger struct {
|
||||
SlowThreshold time.Duration
|
||||
SourceField string
|
||||
IgnoreErrRecordNotFound bool
|
||||
Debug bool
|
||||
Silent bool
|
||||
|
||||
prefix string
|
||||
}
|
||||
|
||||
func NewLogger(slowThreshold time.Duration, debug bool) *GormLogger {
|
||||
@ -48,6 +50,7 @@ func NewLogger(slowThreshold time.Duration, debug bool) *GormLogger {
|
||||
IgnoreErrRecordNotFound: true,
|
||||
Silent: false,
|
||||
SourceField: "src",
|
||||
prefix: "GORM-SQL: ",
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,21 +67,21 @@ func (l *GormLogger) Info(ctx context.Context, s string, args ...any) {
|
||||
if l.Silent {
|
||||
return
|
||||
}
|
||||
logrus.WithContext(ctx).Infof(s, args...)
|
||||
slog.InfoContext(ctx, l.prefix+s, args...)
|
||||
}
|
||||
|
||||
func (l *GormLogger) Warn(ctx context.Context, s string, args ...any) {
|
||||
if l.Silent {
|
||||
return
|
||||
}
|
||||
logrus.WithContext(ctx).Warnf(s, args...)
|
||||
slog.WarnContext(ctx, l.prefix+s, args...)
|
||||
}
|
||||
|
||||
func (l *GormLogger) Error(ctx context.Context, s string, args ...any) {
|
||||
if l.Silent {
|
||||
return
|
||||
}
|
||||
logrus.WithContext(ctx).Errorf(s, args...)
|
||||
slog.ErrorContext(ctx, l.prefix+s, args...)
|
||||
}
|
||||
|
||||
func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
|
||||
@ -88,26 +91,29 @@ func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (stri
|
||||
|
||||
elapsed := time.Since(begin)
|
||||
sql, rows := fc()
|
||||
fields := logrus.Fields{
|
||||
"rows": rows,
|
||||
"duration": elapsed,
|
||||
|
||||
attrs := []any{
|
||||
"rows", rows,
|
||||
"duration", elapsed,
|
||||
}
|
||||
|
||||
if l.SourceField != "" {
|
||||
fields[l.SourceField] = utils.FileWithLineNum()
|
||||
attrs = append(attrs, l.SourceField, utils.FileWithLineNum())
|
||||
}
|
||||
|
||||
if err != nil && !(errors.Is(err, gorm.ErrRecordNotFound) && l.IgnoreErrRecordNotFound) {
|
||||
fields[logrus.ErrorKey] = err
|
||||
logrus.WithContext(ctx).WithFields(fields).Errorf("%s", sql)
|
||||
attrs = append(attrs, "error", err)
|
||||
slog.ErrorContext(ctx, l.prefix+sql, attrs...)
|
||||
return
|
||||
}
|
||||
|
||||
if l.SlowThreshold != 0 && elapsed > l.SlowThreshold {
|
||||
logrus.WithContext(ctx).WithFields(fields).Warnf("%s", sql)
|
||||
slog.WarnContext(ctx, l.prefix+sql, attrs...)
|
||||
return
|
||||
}
|
||||
|
||||
if l.Debug {
|
||||
logrus.WithContext(ctx).WithFields(fields).Tracef("%s", sql)
|
||||
slog.DebugContext(ctx, l.prefix+sql, attrs...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +124,7 @@ func NewDatabase(cfg config.DatabaseConfig) (*gorm.DB, error) {
|
||||
|
||||
switch cfg.Type {
|
||||
case config.DatabaseMySQL:
|
||||
gormDb, err = gorm.Open(gormMySQL.Open(cfg.DSN), &gorm.Config{
|
||||
gormDb, err = gorm.Open(mysql.Open(cfg.DSN), &gorm.Config{
|
||||
Logger: NewLogger(cfg.SlowQueryThreshold, cfg.Debug),
|
||||
})
|
||||
if err != nil {
|
||||
@ -212,13 +218,13 @@ func (r *SqlRepo) preCheck() error {
|
||||
}
|
||||
|
||||
func (r *SqlRepo) migrate() error {
|
||||
logrus.Tracef("sysstat migration: %v", r.db.AutoMigrate(&SysStat{}))
|
||||
logrus.Tracef("user migration: %v", r.db.AutoMigrate(&domain.User{}))
|
||||
logrus.Tracef("interface migration: %v", r.db.AutoMigrate(&domain.Interface{}))
|
||||
logrus.Tracef("peer migration: %v", r.db.AutoMigrate(&domain.Peer{}))
|
||||
logrus.Tracef("peer status migration: %v", r.db.AutoMigrate(&domain.PeerStatus{}))
|
||||
logrus.Tracef("interface status migration: %v", r.db.AutoMigrate(&domain.InterfaceStatus{}))
|
||||
logrus.Tracef("audit data migration: %v", r.db.AutoMigrate(&domain.AuditEntry{}))
|
||||
slog.Debug("running migration: sys-stat", "result", r.db.AutoMigrate(&SysStat{}))
|
||||
slog.Debug("running migration: user", "result", r.db.AutoMigrate(&domain.User{}))
|
||||
slog.Debug("running migration: interface", "result", r.db.AutoMigrate(&domain.Interface{}))
|
||||
slog.Debug("running migration: peer", "result", r.db.AutoMigrate(&domain.Peer{}))
|
||||
slog.Debug("running migration: peer status", "result", r.db.AutoMigrate(&domain.PeerStatus{}))
|
||||
slog.Debug("running migration: interface status", "result", r.db.AutoMigrate(&domain.InterfaceStatus{}))
|
||||
slog.Debug("running migration: audit data", "result", r.db.AutoMigrate(&domain.AuditEntry{}))
|
||||
|
||||
existingSysStat := SysStat{}
|
||||
r.db.Where("schema_version = ?", SchemaVersion).First(&existingSysStat)
|
||||
@ -230,7 +236,7 @@ func (r *SqlRepo) migrate() error {
|
||||
if err := r.db.Create(&sysStat).Error; err != nil {
|
||||
return fmt.Errorf("failed to write sysstat entry for schema version %d: %w", SchemaVersion, err)
|
||||
}
|
||||
logrus.Debugf("sysstat entry for schema version %d written", SchemaVersion)
|
||||
slog.Debug("sys-stat entry written", "schema_version", SchemaVersion)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -3,10 +3,9 @@ package adapters
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type FilesystemRepo struct {
|
||||
@ -46,7 +45,7 @@ func (r *FilesystemRepo) WriteFile(path string, contents io.Reader) error {
|
||||
}
|
||||
defer func(file *os.File) {
|
||||
if err := file.Close(); err != nil {
|
||||
logrus.Errorf("failed to close file %s: %v", file.Name(), err)
|
||||
slog.Error("failed to close file", "file", file.Name(), "error", err)
|
||||
}
|
||||
}(file)
|
||||
|
||||
|
@ -3,13 +3,13 @@ package adapters
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promauto"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
@ -91,11 +91,11 @@ func (m *MetricsServer) Run(ctx context.Context) {
|
||||
// Run the metrics server in a goroutine
|
||||
go func() {
|
||||
if err := m.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
logrus.Errorf("metrics service on %s exited: %v", m.Addr, err)
|
||||
slog.Error("metrics service exited", "address", m.Addr, "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
logrus.Infof("started metrics service on %s", m.Addr)
|
||||
slog.Info("started metrics service", "address", m.Addr)
|
||||
|
||||
// Wait for the context to be done
|
||||
<-ctx.Done()
|
||||
@ -106,9 +106,9 @@ func (m *MetricsServer) Run(ctx context.Context) {
|
||||
|
||||
// Attempt to gracefully shut down the metrics server
|
||||
if err := m.Shutdown(shutdownCtx); err != nil {
|
||||
logrus.Errorf("metrics service on %s shutdown failed: %v", m.Addr, err)
|
||||
slog.Error("metrics service shutdown failed", "address", m.Addr, "error", err)
|
||||
} else {
|
||||
logrus.Infof("metrics service on %s shutdown gracefully", m.Addr)
|
||||
slog.Info("metrics service shutdown gracefully", "address", m.Addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,11 +3,10 @@ package adapters
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
"github.com/h44z/wg-portal/internal/domain"
|
||||
)
|
||||
@ -35,7 +34,7 @@ func (r *WgQuickRepo) ExecuteInterfaceHook(id domain.InterfaceIdentifier, hookCm
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.Tracef("interface %s: executing hook %s", id, hookCmd)
|
||||
slog.Debug("executing interface hook", "interface", id, "hook", hookCmd)
|
||||
err := r.exec(hookCmd, id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to exec hook: %w", err)
|
||||
@ -107,6 +106,8 @@ func (r *WgQuickRepo) exec(command string, interfaceId domain.InterfaceIdentifie
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to exexute shell command %s: %w", commandWithInterfaceName, err)
|
||||
}
|
||||
logrus.Tracef("executed shell command %s, with output: %s", commandWithInterfaceName, string(out))
|
||||
slog.Debug("executed shell command",
|
||||
"command", commandWithInterfaceName,
|
||||
"output", string(out))
|
||||
return nil
|
||||
}
|
||||
|
@ -7,14 +7,13 @@ import (
|
||||
"html/template"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
ginlogrus "github.com/toorop/gin-logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
@ -56,14 +55,39 @@ func NewServer(cfg *config.Config, endpoints ...ApiEndpointSetupFunc) (*Server,
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
gin.DefaultWriter = io.Discard
|
||||
s.server = gin.New()
|
||||
|
||||
if cfg.Web.RequestLogging {
|
||||
if logrus.GetLevel() == logrus.TraceLevel {
|
||||
if cfg.Advanced.LogLevel == "trace" {
|
||||
gin.SetMode(gin.DebugMode)
|
||||
s.server.Use(ginlogrus.Logger(logrus.StandardLogger()))
|
||||
} else {
|
||||
s.server.Use(ginlogrus.Logger(logrus.StandardLogger()))
|
||||
}
|
||||
s.server.Use(func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.Request.URL.Path
|
||||
raw := c.Request.URL.RawQuery
|
||||
|
||||
c.Next()
|
||||
|
||||
if raw != "" {
|
||||
path = path + "?" + raw
|
||||
}
|
||||
|
||||
latency := time.Since(start)
|
||||
status := c.Writer.Status()
|
||||
clientIP := c.ClientIP()
|
||||
method := c.Request.Method
|
||||
errorMsg := c.Errors.ByType(gin.ErrorTypePrivate).String()
|
||||
|
||||
slog.Debug("HTTP Request",
|
||||
"status", status,
|
||||
"latency", latency,
|
||||
"client", clientIP,
|
||||
"method", method,
|
||||
"path", path,
|
||||
"error", errorMsg,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
s.server.Use(gin.Recovery()).Use(func(c *gin.Context) {
|
||||
c.Writer.Header().Set("X-Served-By", hostname)
|
||||
c.Next()
|
||||
@ -112,22 +136,24 @@ func (s *Server) Run(ctx context.Context, listenAddress string) {
|
||||
err = srv.ListenAndServe()
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Infof("web service on %s exited: %v", listenAddress, err)
|
||||
slog.Info("web service exited",
|
||||
"address", listenAddress,
|
||||
"error", err)
|
||||
cancelFn()
|
||||
}
|
||||
}()
|
||||
logrus.Infof("started web service on %s", listenAddress)
|
||||
slog.Info("started web service", "address", listenAddress)
|
||||
|
||||
// Wait for the main context to end
|
||||
<-srvContext.Done()
|
||||
|
||||
logrus.Debug("web service shutting down, grace period: 5 seconds...")
|
||||
slog.Debug("web service shutting down, grace period: 5 seconds")
|
||||
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
_ = srv.Shutdown(shutdownCtx)
|
||||
|
||||
logrus.Debug("web service shut down")
|
||||
slog.Debug("web service shut down")
|
||||
}
|
||||
|
||||
func (s *Server) setupRoutes(endpoints ...ApiEndpointSetupFunc) {
|
||||
|
@ -4,9 +4,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
@ -81,7 +81,7 @@ func (a *App) Startup(ctx context.Context) error {
|
||||
|
||||
func (a *App) importNewInterfaces(ctx context.Context) error {
|
||||
if !a.Config.Core.ImportExisting {
|
||||
logrus.Trace("skipping interface import - feature disabled")
|
||||
slog.Debug("skipping interface import - feature disabled")
|
||||
return nil // feature disabled
|
||||
}
|
||||
|
||||
@ -91,14 +91,14 @@ func (a *App) importNewInterfaces(ctx context.Context) error {
|
||||
}
|
||||
|
||||
if importedCount > 0 {
|
||||
logrus.Infof("%d new interfaces imported", importedCount)
|
||||
slog.Info("new interfaces imported", "count", importedCount)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) restoreInterfaceState(ctx context.Context) error {
|
||||
if !a.Config.Core.RestoreState {
|
||||
logrus.Trace("skipping interface state restore - feature disabled")
|
||||
slog.Debug("skipping interface state restore - feature disabled")
|
||||
return nil // feature disabled
|
||||
}
|
||||
|
||||
@ -107,14 +107,14 @@ func (a *App) restoreInterfaceState(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Info("interface state restored")
|
||||
slog.Info("interface state restored")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *App) createDefaultUser(ctx context.Context) error {
|
||||
adminUserId := domain.UserIdentifier(a.Config.Core.AdminUser)
|
||||
if adminUserId == "" {
|
||||
logrus.Trace("skipping default user creation - admin user is blank")
|
||||
slog.Debug("skipping default user creation - admin user is blank")
|
||||
return nil // empty admin user - do not create
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ func (a *App) createDefaultUser(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
logrus.Trace("skipping default user creation - admin user already exists")
|
||||
slog.Debug("skipping default user creation - admin user already exists")
|
||||
return nil // admin user already exists
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ func (a *App) createDefaultUser(ctx context.Context) error {
|
||||
}
|
||||
if a.Config.Core.AdminApiToken != "" {
|
||||
if len(a.Config.Core.AdminApiToken) < 18 {
|
||||
logrus.Warnf("[SECURITY WARNING] admin API token is too short, should be at least 18 characters long")
|
||||
slog.Warn("admin API token is too short, should be at least 18 characters long")
|
||||
}
|
||||
defaultAdmin.ApiToken = a.Config.Core.AdminApiToken
|
||||
defaultAdmin.ApiTokenCreated = &now
|
||||
@ -165,7 +165,7 @@ func (a *App) createDefaultUser(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Infof("admin user %s created", admin.Identifier)
|
||||
slog.Info("admin user created", "identifier", admin.Identifier)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ package audit
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/app"
|
||||
@ -52,7 +52,7 @@ func (r *Recorder) StartBackgroundJobs(ctx context.Context) {
|
||||
// select blocks until one of the cases evaluate to true
|
||||
}
|
||||
|
||||
logrus.Tracef("registered %d audit message within the last hour", 0) // TODO: implement
|
||||
slog.Debug("audit status", "registered_messages", 0) // TODO: implement
|
||||
}
|
||||
}()
|
||||
}
|
||||
@ -77,7 +77,7 @@ func (r *Recorder) authLoginEvent(userIdentifier domain.UserIdentifier) {
|
||||
Message: fmt.Sprintf("user %s logged in", userIdentifier),
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to create audit entry for handleAuthLoginEvent: %v", err)
|
||||
slog.Error("failed to create audit entry for handleAuthLoginEvent", "error", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/app"
|
||||
@ -227,7 +227,7 @@ func (a *Authenticator) passwordAuthentication(
|
||||
rawUserInfo, err := ldapAuth.GetUserInfo(context.Background(), identifier)
|
||||
if err != nil {
|
||||
if !errors.Is(err, domain.ErrNotFound) {
|
||||
logrus.Warnf("failed to fetch ldap user info for %s: %v", identifier, err)
|
||||
slog.Warn("failed to fetch ldap user info", "identifier", identifier, "error", err)
|
||||
}
|
||||
continue // user not found / other ldap error
|
||||
}
|
||||
@ -407,8 +407,10 @@ func (a *Authenticator) registerNewUser(
|
||||
return nil, fmt.Errorf("failed to register new user: %w", err)
|
||||
}
|
||||
|
||||
logrus.Tracef("registered user %s from external authentication provider, admin user: %t",
|
||||
user.Identifier, user.IsAdmin)
|
||||
slog.Debug("registered user from external authentication provider",
|
||||
"user", user.Identifier,
|
||||
"isAdmin", user.IsAdmin,
|
||||
"provider", source)
|
||||
|
||||
return user, nil
|
||||
}
|
||||
@ -483,8 +485,10 @@ func (a *Authenticator) updateExternalUser(
|
||||
return fmt.Errorf("failed to update user: %w", err)
|
||||
}
|
||||
|
||||
logrus.Tracef("updated user %s with data from external authentication provider, admin user: %t",
|
||||
existingUser.Identifier, existingUser.IsAdmin)
|
||||
slog.Debug("updated user with data from external authentication provider",
|
||||
"user", existingUser.Identifier,
|
||||
"isAdmin", existingUser.IsAdmin,
|
||||
"provider", source)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
@ -117,7 +117,10 @@ func (l LdapAuthenticator) GetUserInfo(_ context.Context, userId domain.UserIden
|
||||
|
||||
if l.cfg.LogUserInfo {
|
||||
contents, _ := json.Marshal(users[0])
|
||||
logrus.Tracef("User info from LDAP source %s for %s: %v", l.GetName(), userId, string(contents))
|
||||
slog.Debug("LDAP user info",
|
||||
"source", l.GetName(),
|
||||
"userId", userId,
|
||||
"info", string(contents))
|
||||
}
|
||||
|
||||
return users[0], nil
|
||||
|
@ -5,10 +5,10 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
@ -111,7 +111,9 @@ func (p PlainOauthAuthenticator) GetUserInfo(
|
||||
}
|
||||
|
||||
if p.userInfoLogging {
|
||||
logrus.Tracef("User info from OAuth source %s: %v", p.name, string(contents))
|
||||
slog.Debug("OAuth user info",
|
||||
"source", p.name,
|
||||
"info", string(contents))
|
||||
}
|
||||
|
||||
return userFields, nil
|
||||
|
@ -5,9 +5,9 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
@ -106,7 +106,9 @@ func (o OidcAuthenticator) GetUserInfo(ctx context.Context, token *oauth2.Token,
|
||||
|
||||
if o.userInfoLogging {
|
||||
contents, _ := json.Marshal(tokenFields)
|
||||
logrus.Tracef("User info from OIDC source %s: %v", o.name, string(contents))
|
||||
slog.Debug("OIDC user info",
|
||||
"source", o.name,
|
||||
"info", string(contents))
|
||||
}
|
||||
|
||||
return tokenFields, nil
|
||||
|
@ -6,10 +6,10 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
"github.com/yeqown/go-qrcode/v2"
|
||||
"github.com/yeqown/go-qrcode/writer/compressed"
|
||||
@ -82,18 +82,22 @@ func (m Manager) handleInterfaceUpdatedEvent(iface *domain.Interface) {
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Debugf("handling interface updated event for %s", iface.Identifier)
|
||||
slog.Debug("handling interface updated event", "interface", iface.Identifier)
|
||||
|
||||
err := m.PersistInterfaceConfig(context.Background(), iface.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to automatically persist interface config for %s: %v", iface.Identifier, err)
|
||||
slog.Error("failed to automatically persist interface config",
|
||||
"interface", iface.Identifier,
|
||||
"error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (m Manager) handlePeerInterfaceUpdatedEvent(id domain.InterfaceIdentifier) {
|
||||
peerInterface, err := m.wg.GetInterface(context.Background(), id)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to load interface %s: %v", id, err)
|
||||
slog.Error("failed to load interface",
|
||||
"interface", id,
|
||||
"error", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -101,11 +105,13 @@ func (m Manager) handlePeerInterfaceUpdatedEvent(id domain.InterfaceIdentifier)
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Debugf("handling peer interface updated event for %s", id)
|
||||
slog.Debug("handling peer interface updated event", "interface", id)
|
||||
|
||||
err = m.PersistInterfaceConfig(context.Background(), peerInterface.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to automatically persist interface config for %s: %v", peerInterface.Identifier, err)
|
||||
slog.Error("failed to automatically persist interface config",
|
||||
"interface", peerInterface.Identifier,
|
||||
"error", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"log/slog"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
"github.com/h44z/wg-portal/internal/domain"
|
||||
@ -57,18 +56,25 @@ func (m Manager) SendPeerEmail(ctx context.Context, linkOnly bool, peers ...doma
|
||||
}
|
||||
|
||||
if peer.UserIdentifier == "" {
|
||||
logrus.Debugf("skipping peer email for %s, no user linked", peerId)
|
||||
slog.Debug("skipping peer email",
|
||||
"peer", peerId,
|
||||
"reason", "no user linked")
|
||||
continue
|
||||
}
|
||||
|
||||
user, err := m.users.GetUser(ctx, peer.UserIdentifier)
|
||||
if err != nil {
|
||||
logrus.Debugf("skipping peer email for %s, unable to fetch user: %v", peerId, err)
|
||||
slog.Debug("skipping peer email",
|
||||
"peer", peerId,
|
||||
"reason", "unable to fetch user",
|
||||
"error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
if user.Email == "" {
|
||||
logrus.Debugf("skipping peer email for %s, user has no mail address", peerId)
|
||||
slog.Debug("skipping peer email",
|
||||
"peer", peerId,
|
||||
"reason", "user has no mail address")
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,10 @@ package app
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/adapters"
|
||||
@ -50,7 +50,7 @@ func migrateFromV1(db *gorm.DB, source, typ string) error {
|
||||
return fmt.Errorf("unsupported old version, update to database version %s first: %w", latestVersion, err)
|
||||
}
|
||||
|
||||
logrus.Infof("Found valid V1 database with version: %s", lastVersion.Version)
|
||||
slog.Info("found valid V1 database", "version", lastVersion.Version)
|
||||
|
||||
if err := migrateV1Users(oldDb, db); err != nil {
|
||||
return fmt.Errorf("user migration failed: %w", err)
|
||||
@ -64,7 +64,8 @@ func migrateFromV1(db *gorm.DB, source, typ string) error {
|
||||
return fmt.Errorf("peer migration failed: %w", err)
|
||||
}
|
||||
|
||||
logrus.Infof("Migrated V1 database with version %s, please restart WireGuard Portal", lastVersion.Version)
|
||||
slog.Info("migrated V1 database successfully, please restart WireGuard Portal",
|
||||
"version", lastVersion.Version)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -126,7 +127,7 @@ func migrateV1Users(oldDb, newDb *gorm.DB) error {
|
||||
return fmt.Errorf("failed to migrate user %s: %w", oldUser.Email, err)
|
||||
}
|
||||
|
||||
logrus.Debugf(" - User %s migrated", newUser.Identifier)
|
||||
slog.Debug("user migrated successfully", "identifier", newUser.Identifier)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -220,7 +221,7 @@ func migrateV1Interfaces(oldDb, newDb *gorm.DB) error {
|
||||
return fmt.Errorf("failed to migrate device %s: %w", oldDevice.DeviceName, err)
|
||||
}
|
||||
|
||||
logrus.Debugf(" - Interface %s migrated", newInterface.Identifier)
|
||||
slog.Debug("interface migrated successfully", "identifier", newInterface.Identifier)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -319,7 +320,7 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
|
||||
return fmt.Errorf("failed to migrate dummy user %s: %w", oldPeer.Email, err)
|
||||
}
|
||||
|
||||
logrus.Debugf(" - Dummy User %s migrated", user.Identifier)
|
||||
slog.Debug("dummy user migrated successfully", "identifier", user.Identifier)
|
||||
}
|
||||
newPeer := domain.Peer{
|
||||
BaseModel: domain.BaseModel{
|
||||
@ -365,7 +366,7 @@ func migrateV1Peers(oldDb, newDb *gorm.DB) error {
|
||||
return fmt.Errorf("failed to migrate peer %s (%s): %w", oldPeer.Identifier, oldPeer.PublicKey, err)
|
||||
}
|
||||
|
||||
logrus.Debugf(" - Peer %s migrated", newPeer.Identifier)
|
||||
slog.Debug("peer migrated successfully", "identifier", newPeer.Identifier)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -3,8 +3,8 @@ package route
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
@ -67,31 +67,33 @@ func (m Manager) StartBackgroundJobs(_ context.Context) {
|
||||
}
|
||||
|
||||
func (m Manager) handleRouteUpdateEvent(srcDescription string) {
|
||||
logrus.Debugf("handling route update event: %s", srcDescription)
|
||||
slog.Debug("handling route update event", "source", srcDescription)
|
||||
|
||||
err := m.syncRoutes(context.Background())
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to synchronize routes for event %s: %v", srcDescription, err)
|
||||
slog.Error("failed to synchronize routes",
|
||||
"source", srcDescription,
|
||||
"error", err)
|
||||
}
|
||||
|
||||
logrus.Debugf("routes synchronized, event: %s", srcDescription)
|
||||
slog.Debug("routes synchronized", "source", srcDescription)
|
||||
}
|
||||
|
||||
func (m Manager) handleRouteRemoveEvent(info domain.RoutingTableInfo) {
|
||||
logrus.Debugf("handling route remove event for: %s", info.String())
|
||||
slog.Debug("handling route remove event", "info", info.String())
|
||||
|
||||
if !info.ManagementEnabled() {
|
||||
return // route management disabled
|
||||
}
|
||||
|
||||
if err := m.removeFwMarkRules(info.FwMark, info.GetRoutingTable(), netlink.FAMILY_V4); err != nil {
|
||||
logrus.Errorf("failed to remove v4 fwmark rules: %v", err)
|
||||
slog.Error("failed to remove v4 fwmark rules", "error", err)
|
||||
}
|
||||
if err := m.removeFwMarkRules(info.FwMark, info.GetRoutingTable(), netlink.FAMILY_V6); err != nil {
|
||||
logrus.Errorf("failed to remove v6 fwmark rules: %v", err)
|
||||
slog.Error("failed to remove v6 fwmark rules", "error", err)
|
||||
}
|
||||
|
||||
logrus.Debugf("routes removed, table: %s", info.String())
|
||||
slog.Debug("routes removed", "table", info.String())
|
||||
}
|
||||
|
||||
func (m Manager) syncRoutes(ctx context.Context) error {
|
||||
@ -437,14 +439,18 @@ func (m Manager) getRoutingTableAndFwMark(iface *domain.Interface, link netlink.
|
||||
if fwmark == 0 {
|
||||
// generate a new (temporary) firewall mark based on the interface index
|
||||
fwmark = uint32(m.cfg.Advanced.RouteTableOffset + link.Attrs().Index)
|
||||
logrus.Debugf("%s: using fwmark %d to handle routes", iface.Identifier, table)
|
||||
slog.Debug("using fwmark to handle routes",
|
||||
"interface", iface.Identifier,
|
||||
"fwmark", fwmark)
|
||||
|
||||
// apply the temporary fwmark to the wireguard interface
|
||||
err = m.setFwMark(iface.Identifier, int(fwmark))
|
||||
}
|
||||
if table == 0 {
|
||||
table = int(fwmark) // generate a new routing table base on interface index
|
||||
logrus.Debugf("%s: using routing table %d to handle default routes", iface.Identifier, table)
|
||||
slog.Debug("using routing table to handle default routes",
|
||||
"interface", iface.Identifier,
|
||||
"table", table)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
@ -419,7 +419,7 @@ func (m Manager) runLdapSynchronizationService(ctx context.Context) {
|
||||
go func(cfg config.LdapProvider) {
|
||||
syncInterval := cfg.SyncInterval
|
||||
if syncInterval == 0 {
|
||||
logrus.Debugf("sync disabled for LDAP server: %s", cfg.ProviderName)
|
||||
slog.Debug("sync disabled for LDAP server", "provider", cfg.ProviderName)
|
||||
return
|
||||
}
|
||||
|
||||
@ -435,7 +435,7 @@ func (m Manager) runLdapSynchronizationService(ctx context.Context) {
|
||||
|
||||
err := m.synchronizeLdapUsers(ctx, &cfg)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to synchronize LDAP users for %s: %v", cfg.ProviderName, err)
|
||||
slog.Error("failed to synchronize LDAP users", "provider", cfg.ProviderName, "error", err)
|
||||
}
|
||||
}
|
||||
}(ldapCfg)
|
||||
@ -443,7 +443,7 @@ func (m Manager) runLdapSynchronizationService(ctx context.Context) {
|
||||
}
|
||||
|
||||
func (m Manager) synchronizeLdapUsers(ctx context.Context, provider *config.LdapProvider) error {
|
||||
logrus.Tracef("starting to synchronize users for %s", provider.ProviderName)
|
||||
slog.Debug("starting to synchronize users", "provider", provider.ProviderName)
|
||||
|
||||
dn, err := ldap.ParseDN(provider.AdminGroupDN)
|
||||
if err != nil {
|
||||
@ -462,7 +462,7 @@ func (m Manager) synchronizeLdapUsers(ctx context.Context, provider *config.Ldap
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Tracef("fetched %d raw ldap users from provider %s...", len(rawUsers), provider.ProviderName)
|
||||
slog.Debug("fetched raw ldap users", "count", len(rawUsers), "provider", provider.ProviderName)
|
||||
|
||||
// Update existing LDAP users
|
||||
err = m.updateLdapUsers(ctx, provider, rawUsers, &provider.FieldMap, provider.ParsedAdminGroupDN)
|
||||
@ -504,7 +504,7 @@ func (m Manager) updateLdapUsers(
|
||||
|
||||
if existingUser == nil {
|
||||
// create new user
|
||||
logrus.Tracef("creating new user %s from provider %s...", user.Identifier, provider.ProviderName)
|
||||
slog.Debug("creating new user from provider", "user", user.Identifier, "provider", provider.ProviderName)
|
||||
|
||||
err := m.NewUser(tctx, user)
|
||||
if err != nil {
|
||||
@ -588,7 +588,7 @@ func (m Manager) disableMissingLdapUsers(
|
||||
continue
|
||||
}
|
||||
|
||||
logrus.Tracef("user %s is missing in ldap provider %s, disabling", user.Identifier, providerName)
|
||||
slog.Debug("user is missing in ldap provider, disabling", "user", user.Identifier, "provider", providerName)
|
||||
|
||||
now := time.Now()
|
||||
user.Disabled = &now
|
||||
|
@ -2,11 +2,11 @@ package wireguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
probing "github.com/prometheus-community/pro-bing"
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/app"
|
||||
@ -60,7 +60,7 @@ func (c *StatisticsCollector) startInterfaceDataFetcher(ctx context.Context) {
|
||||
|
||||
go c.collectInterfaceData(ctx)
|
||||
|
||||
logrus.Tracef("started interface data fetcher")
|
||||
slog.Debug("started interface data fetcher")
|
||||
}
|
||||
|
||||
func (c *StatisticsCollector) collectInterfaceData(ctx context.Context) {
|
||||
@ -74,14 +74,15 @@ func (c *StatisticsCollector) collectInterfaceData(ctx context.Context) {
|
||||
case <-ticker.C:
|
||||
interfaces, err := c.db.GetAllInterfaces(ctx)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to fetch all interfaces for data collection: %v", err)
|
||||
slog.Warn("failed to fetch all interfaces for data collection", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, in := range interfaces {
|
||||
physicalInterface, err := c.wg.GetInterface(ctx, in.Identifier)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to load physical interface %s for data collection: %v", in.Identifier, err)
|
||||
slog.Warn("failed to load physical interface for data collection", "interface", in.Identifier,
|
||||
"error", err)
|
||||
continue
|
||||
}
|
||||
err = c.db.UpdateInterfaceStatus(ctx, in.Identifier,
|
||||
@ -96,9 +97,9 @@ func (c *StatisticsCollector) collectInterfaceData(ctx context.Context) {
|
||||
return i, nil
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to update interface status for %s: %v", in.Identifier, err)
|
||||
slog.Warn("failed to update interface status", "interface", in.Identifier, "error", err)
|
||||
}
|
||||
logrus.Tracef("updated interface status for %s", in.Identifier)
|
||||
slog.Debug("updated interface status", "interface", in.Identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,7 +112,7 @@ func (c *StatisticsCollector) startPeerDataFetcher(ctx context.Context) {
|
||||
|
||||
go c.collectPeerData(ctx)
|
||||
|
||||
logrus.Tracef("started peer data fetcher")
|
||||
slog.Debug("started peer data fetcher")
|
||||
}
|
||||
|
||||
func (c *StatisticsCollector) collectPeerData(ctx context.Context) {
|
||||
@ -125,14 +126,14 @@ func (c *StatisticsCollector) collectPeerData(ctx context.Context) {
|
||||
case <-ticker.C:
|
||||
interfaces, err := c.db.GetAllInterfaces(ctx)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to fetch all interfaces for peer data collection: %v", err)
|
||||
slog.Warn("failed to fetch all interfaces for peer data collection", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, in := range interfaces {
|
||||
peers, err := c.wg.GetPeers(ctx, in.Identifier)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to fetch peers for data collection (interface %s): %v", in.Identifier, err)
|
||||
slog.Warn("failed to fetch peers for data collection", "interface", in.Identifier, "error", err)
|
||||
continue
|
||||
}
|
||||
for _, peer := range peers {
|
||||
@ -158,9 +159,9 @@ func (c *StatisticsCollector) collectPeerData(ctx context.Context) {
|
||||
return p, nil
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to update peer status for %s: %v", peer.Identifier, err)
|
||||
slog.Warn("failed to update peer status", "peer", peer.Identifier, "error", err)
|
||||
} else {
|
||||
logrus.Tracef("updated peer status for %s", peer.Identifier)
|
||||
slog.Debug("updated peer status", "peer", peer.Identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -221,12 +222,12 @@ func (c *StatisticsCollector) startPingWorkers(ctx context.Context) {
|
||||
go func() {
|
||||
c.pingWaitGroup.Wait()
|
||||
|
||||
logrus.Tracef("stopped ping checks")
|
||||
slog.Debug("stopped ping checks")
|
||||
}()
|
||||
|
||||
go c.enqueuePingChecks(ctx)
|
||||
|
||||
logrus.Tracef("started ping checks")
|
||||
slog.Debug("started ping checks")
|
||||
}
|
||||
|
||||
func (c *StatisticsCollector) enqueuePingChecks(ctx context.Context) {
|
||||
@ -242,14 +243,14 @@ func (c *StatisticsCollector) enqueuePingChecks(ctx context.Context) {
|
||||
case <-ticker.C:
|
||||
interfaces, err := c.db.GetAllInterfaces(ctx)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to fetch all interfaces for ping checks: %v", err)
|
||||
slog.Warn("failed to fetch all interfaces for ping checks", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, in := range interfaces {
|
||||
peers, err := c.db.GetInterfacePeers(ctx, in.Identifier)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to fetch peers for ping checks (interface %s): %v", in.Identifier, err)
|
||||
slog.Warn("failed to fetch peers for ping checks", "interface", in.Identifier, "error", err)
|
||||
continue
|
||||
}
|
||||
for _, peer := range peers {
|
||||
@ -264,7 +265,7 @@ func (c *StatisticsCollector) pingWorker(ctx context.Context) {
|
||||
defer c.pingWaitGroup.Done()
|
||||
for peer := range c.pingJobs {
|
||||
peerPingable := c.isPeerPingable(ctx, peer)
|
||||
logrus.Tracef("peer %s pingable: %t", peer.Identifier, peerPingable)
|
||||
slog.Debug("peer ping check completed", "peer", peer.Identifier, "pingable", peerPingable)
|
||||
|
||||
now := time.Now()
|
||||
err := c.db.UpdatePeerStatus(ctx, peer.Identifier,
|
||||
@ -283,9 +284,9 @@ func (c *StatisticsCollector) pingWorker(ctx context.Context) {
|
||||
return p, nil
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to update peer ping status for %s: %v", peer.Identifier, err)
|
||||
slog.Warn("failed to update peer ping status", "peer", peer.Identifier, "error", err)
|
||||
} else {
|
||||
logrus.Tracef("updated peer ping status for %s", peer.Identifier)
|
||||
slog.Debug("updated peer ping status", "peer", peer.Identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -302,7 +303,7 @@ func (c *StatisticsCollector) isPeerPingable(ctx context.Context, peer domain.Pe
|
||||
|
||||
pinger, err := probing.NewPinger(checkAddr)
|
||||
if err != nil {
|
||||
logrus.Tracef("failed to instatiate pinger for %s (%s): %v", peer.Identifier, checkAddr, err)
|
||||
slog.Debug("failed to instantiate pinger", "peer", peer.Identifier, "address", checkAddr, "error", err)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -312,7 +313,7 @@ func (c *StatisticsCollector) isPeerPingable(ctx context.Context, peer domain.Pe
|
||||
pinger.Timeout = 2 * time.Second
|
||||
err = pinger.RunWithContext(ctx) // Blocks until finished.
|
||||
if err != nil {
|
||||
logrus.Tracef("pinger for peer %s (%s) exited unexpectedly: %v", peer.Identifier, checkAddr, err)
|
||||
slog.Debug("pinger for peer exited unexpectedly", "peer", peer.Identifier, "address", checkAddr, "error", err)
|
||||
return false
|
||||
}
|
||||
stats := pinger.Statistics()
|
||||
@ -327,7 +328,7 @@ func (c *StatisticsCollector) updatePeerMetrics(ctx context.Context, status doma
|
||||
// Fetch peer data from the database
|
||||
peer, err := c.db.GetPeer(ctx, status.PeerId)
|
||||
if err != nil {
|
||||
logrus.Warnf("failed to fetch peer data for metrics %s: %v", status.PeerId, err)
|
||||
slog.Warn("failed to fetch peer data for metrics", "peer", status.PeerId, "error", err)
|
||||
return
|
||||
}
|
||||
c.ms.UpdatePeerMetrics(peer, status)
|
||||
@ -343,7 +344,7 @@ func (c *StatisticsCollector) handlePeerIdentifierChangeEvent(oldIdentifier, new
|
||||
// remove potential left-over status data
|
||||
err := c.db.DeletePeerStatus(ctx, oldIdentifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to delete old peer status for migrated peer, %s -> %s: %v",
|
||||
oldIdentifier, newIdentifier, err)
|
||||
slog.Error("failed to delete old peer status for migrated peer", "oldIdentifier", oldIdentifier,
|
||||
"newIdentifier", newIdentifier, "error", err)
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package wireguard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
evbus "github.com/vardius/message-bus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/app"
|
||||
@ -58,12 +58,12 @@ func (m Manager) handleUserCreationEvent(user *domain.User) {
|
||||
return
|
||||
}
|
||||
|
||||
logrus.Tracef("handling new user event for %s", user.Identifier)
|
||||
slog.Debug("handling new user event", "user", user.Identifier)
|
||||
|
||||
ctx := domain.SetUserInfo(context.Background(), domain.SystemAdminContextUserInfo())
|
||||
err := m.CreateDefaultPeer(ctx, user.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to create default peer for %s: %v", user.Identifier, err)
|
||||
slog.Error("failed to create default peer", "user", user.Identifier, "error", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -75,7 +75,9 @@ func (m Manager) handleUserLoginEvent(userId domain.UserIdentifier) {
|
||||
|
||||
userPeers, err := m.db.GetUserPeers(context.Background(), userId)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to retrieve existing peers for %s prior to default peer creation: %v", userId, err)
|
||||
slog.Error("failed to retrieve existing peers prior to default peer creation",
|
||||
"user", userId,
|
||||
"error", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -83,12 +85,12 @@ func (m Manager) handleUserLoginEvent(userId domain.UserIdentifier) {
|
||||
return // user already has peers, skip creation
|
||||
}
|
||||
|
||||
logrus.Tracef("handling new user login for %s", userId)
|
||||
slog.Debug("handling new user login", "user", userId)
|
||||
|
||||
ctx := domain.SetUserInfo(context.Background(), domain.SystemAdminContextUserInfo())
|
||||
err = m.CreateDefaultPeer(ctx, userId)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to create default peer for %s: %v", userId, err)
|
||||
slog.Error("failed to create default peer", "user", userId, "error", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -97,7 +99,9 @@ func (m Manager) handleUserDisabledEvent(user domain.User) {
|
||||
ctx := domain.SetUserInfo(context.Background(), domain.SystemAdminContextUserInfo())
|
||||
userPeers, err := m.db.GetUserPeers(ctx, user.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to retrieve peers for disabled user %s: %v", user.Identifier, err)
|
||||
slog.Error("failed to retrieve peers for disabled user",
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -106,15 +110,19 @@ func (m Manager) handleUserDisabledEvent(user domain.User) {
|
||||
continue // peer is already disabled
|
||||
}
|
||||
|
||||
logrus.Debugf("disabling peer %s due to user %s being disabled", peer.Identifier, user.Identifier)
|
||||
slog.Debug("disabling peer due to user being disabled",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier)
|
||||
|
||||
peer.Disabled = user.Disabled // set to user disabled timestamp
|
||||
peer.DisabledReason = domain.DisabledReasonUserDisabled
|
||||
|
||||
_, err := m.UpdatePeer(ctx, &peer)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to disable peer %s for disabled user %s: %v",
|
||||
peer.Identifier, user.Identifier, err)
|
||||
slog.Error("failed to disable peer for disabled user",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,7 +135,9 @@ func (m Manager) handleUserEnabledEvent(user domain.User) {
|
||||
ctx := domain.SetUserInfo(context.Background(), domain.SystemAdminContextUserInfo())
|
||||
userPeers, err := m.db.GetUserPeers(ctx, user.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to retrieve peers for re-enabled user %s: %v", user.Identifier, err)
|
||||
slog.Error("failed to retrieve peers for re-enabled user",
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -140,15 +150,19 @@ func (m Manager) handleUserEnabledEvent(user domain.User) {
|
||||
continue // peer was disabled for another reason
|
||||
}
|
||||
|
||||
logrus.Debugf("enabling peer %s due to user %s being enabled", peer.Identifier, user.Identifier)
|
||||
slog.Debug("enabling peer due to user being enabled",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier)
|
||||
|
||||
peer.Disabled = nil
|
||||
peer.DisabledReason = ""
|
||||
|
||||
_, err := m.UpdatePeer(ctx, &peer)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to enable peer %s for enabled user %s: %v",
|
||||
peer.Identifier, user.Identifier, err)
|
||||
slog.Error("failed to enable peer for enabled user",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
}
|
||||
}
|
||||
return
|
||||
@ -158,7 +172,9 @@ func (m Manager) handleUserDeletedEvent(user domain.User) {
|
||||
ctx := domain.SetUserInfo(context.Background(), domain.SystemAdminContextUserInfo())
|
||||
userPeers, err := m.db.GetUserPeers(ctx, user.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to retrieve peers for deleted user %s: %v", user.Identifier, err)
|
||||
slog.Error("failed to retrieve peers for deleted user",
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
return
|
||||
}
|
||||
|
||||
@ -169,14 +185,20 @@ func (m Manager) handleUserDeletedEvent(user domain.User) {
|
||||
}
|
||||
|
||||
if m.cfg.Core.DeletePeerAfterUserDeleted {
|
||||
logrus.Debugf("deleting peer %s due to user %s being deleted", peer.Identifier, user.Identifier)
|
||||
slog.Debug("deleting peer due to user being deleted",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier)
|
||||
|
||||
if err := m.DeletePeer(ctx, peer.Identifier); err != nil {
|
||||
logrus.Errorf("failed to delete peer %s for deleted user %s: %v",
|
||||
peer.Identifier, user.Identifier, err)
|
||||
slog.Error("failed to delete peer for deleted user",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
}
|
||||
} else {
|
||||
logrus.Debugf("disabling peer %s due to user %s being deleted", peer.Identifier, user.Identifier)
|
||||
slog.Debug("disabling peer due to user being deleted",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier)
|
||||
|
||||
peer.UserIdentifier = "" // remove user reference
|
||||
peer.Disabled = &deletionTime
|
||||
@ -184,8 +206,10 @@ func (m Manager) handleUserDeletedEvent(user domain.User) {
|
||||
|
||||
_, err := m.UpdatePeer(ctx, &peer)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to disable peer %s for deleted user %s: %v",
|
||||
peer.Identifier, user.Identifier, err)
|
||||
slog.Error("failed to disable peer for deleted user",
|
||||
"peer", peer.Identifier,
|
||||
"user", user.Identifier,
|
||||
"error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -206,14 +230,16 @@ func (m Manager) runExpiredPeersCheck(ctx context.Context) {
|
||||
|
||||
interfaces, err := m.db.GetAllInterfaces(ctx)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to fetch all interfaces for expiry check: %v", err)
|
||||
slog.Error("failed to fetch all interfaces for expiry check", "error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, iface := range interfaces {
|
||||
peers, err := m.db.GetInterfacePeers(ctx, iface.Identifier)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to fetch all peers from interface %s for expiry check: %v", iface.Identifier, err)
|
||||
slog.Error("failed to fetch all peers from interface for expiry check",
|
||||
"interface", iface.Identifier,
|
||||
"error", err)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -227,14 +253,14 @@ func (m Manager) checkExpiredPeers(ctx context.Context, peers []domain.Peer) {
|
||||
|
||||
for _, peer := range peers {
|
||||
if peer.IsExpired() && !peer.IsDisabled() {
|
||||
logrus.Infof("peer %s has expired, disabling...", peer.Identifier)
|
||||
slog.Info("peer has expired, disabling", "peer", peer.Identifier)
|
||||
|
||||
peer.Disabled = &now
|
||||
peer.DisabledReason = domain.DisabledReasonExpired
|
||||
|
||||
_, err := m.UpdatePeer(ctx, &peer)
|
||||
if err != nil {
|
||||
logrus.Errorf("failed to update expired peer %s: %v", peer.Identifier, err)
|
||||
slog.Error("failed to update expired peer", "peer", peer.Identifier, "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,12 +4,11 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/app"
|
||||
"github.com/h44z/wg-portal/internal/domain"
|
||||
)
|
||||
@ -130,7 +129,7 @@ func (m Manager) ImportNewInterfaces(ctx context.Context, filter ...domain.Inter
|
||||
continue
|
||||
}
|
||||
|
||||
logrus.Infof("importing new interface %s...", physicalInterface.Identifier)
|
||||
slog.Info("importing new interface", "interface", physicalInterface.Identifier)
|
||||
|
||||
physicalPeers, err := m.wg.GetPeers(ctx, physicalInterface.Identifier)
|
||||
if err != nil {
|
||||
@ -142,7 +141,7 @@ func (m Manager) ImportNewInterfaces(ctx context.Context, filter ...domain.Inter
|
||||
return 0, fmt.Errorf("import of %s failed: %w", physicalInterface.Identifier, err)
|
||||
}
|
||||
|
||||
logrus.Infof("imported new interface %s and %d peers", physicalInterface.Identifier, len(physicalPeers))
|
||||
slog.Info("imported new interface", "interface", physicalInterface.Identifier, "peers", len(physicalPeers))
|
||||
imported++
|
||||
}
|
||||
|
||||
@ -206,7 +205,7 @@ func (m Manager) RestoreInterfaceState(
|
||||
|
||||
_, err = m.wg.GetInterface(ctx, iface.Identifier)
|
||||
if err != nil && !iface.IsDisabled() {
|
||||
logrus.Debugf("creating missing interface %s...", iface.Identifier)
|
||||
slog.Debug("creating missing interface", "interface", iface.Identifier)
|
||||
|
||||
// try to create a new interface
|
||||
_, err = m.saveInterface(ctx, &iface)
|
||||
@ -224,7 +223,7 @@ func (m Manager) RestoreInterfaceState(
|
||||
return fmt.Errorf("failed to create physical interface %s: %w", iface.Identifier, err)
|
||||
}
|
||||
} else {
|
||||
logrus.Debugf("restoring interface state for %s to disabled=%t", iface.Identifier, iface.IsDisabled())
|
||||
slog.Debug("restoring interface state", "interface", iface.Identifier, "disabled", iface.IsDisabled())
|
||||
|
||||
// try to move interface to stored state
|
||||
_, err = m.saveInterface(ctx, &iface)
|
||||
|
@ -4,10 +4,9 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/app"
|
||||
"github.com/h44z/wg-portal/internal/domain"
|
||||
)
|
||||
@ -49,7 +48,9 @@ func (m Manager) CreateDefaultPeer(ctx context.Context, userId domain.UserIdenti
|
||||
}
|
||||
}
|
||||
|
||||
logrus.Infof("created %d default peers for user %s", len(newPeers), userId)
|
||||
slog.InfoContext(ctx, "created default peers for user",
|
||||
"user", userId,
|
||||
"count", len(newPeers))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type Auth struct {
|
||||
@ -77,7 +77,8 @@ func (o *OauthAdminMapping) GetAdminValueRegex() *regexp.Regexp {
|
||||
|
||||
adminRegex, err := regexp.Compile(o.AdminValueRegex)
|
||||
if err != nil {
|
||||
logrus.Fatalf("failed to compile admin_value_regex: %v", err)
|
||||
slog.Error("failed to compile admin_value_regex", "error", err)
|
||||
panic("failed to compile admin_value_regex")
|
||||
}
|
||||
o.adminValueRegex = adminRegex
|
||||
|
||||
@ -98,7 +99,8 @@ func (o *OauthAdminMapping) GetAdminGroupRegex() *regexp.Regexp {
|
||||
|
||||
groupRegex, err := regexp.Compile(o.AdminGroupRegex)
|
||||
if err != nil {
|
||||
logrus.Fatalf("failed to compile admin_group_regex: %v", err)
|
||||
slog.Error("failed to compile admin_group_regex", "error", err)
|
||||
panic("failed to compile admin_group_regex")
|
||||
}
|
||||
o.adminGroupRegex = groupRegex
|
||||
|
||||
|
@ -2,11 +2,11 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/a8m/envsubst"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
@ -65,29 +65,32 @@ type Config struct {
|
||||
|
||||
// LogStartupValues logs the startup values of the configuration in debug level
|
||||
func (c *Config) LogStartupValues() {
|
||||
logrus.Infof("Log Level: %s", c.Advanced.LogLevel)
|
||||
slog.Info("Configuration loaded!", "logLevel", c.Advanced.LogLevel)
|
||||
|
||||
logrus.Debug("WireGuard Portal Features:")
|
||||
logrus.Debugf(" - EditableKeys: %t", c.Core.EditableKeys)
|
||||
logrus.Debugf(" - CreateDefaultPeerOnCreation: %t", c.Core.CreateDefaultPeerOnCreation)
|
||||
logrus.Debugf(" - ReEnablePeerAfterUserEnable: %t", c.Core.ReEnablePeerAfterUserEnable)
|
||||
logrus.Debugf(" - DeletePeerAfterUserDeleted: %t", c.Core.DeletePeerAfterUserDeleted)
|
||||
logrus.Debugf(" - SelfProvisioningAllowed: %t", c.Core.SelfProvisioningAllowed)
|
||||
logrus.Debugf(" - ImportExisting: %t", c.Core.ImportExisting)
|
||||
logrus.Debugf(" - RestoreState: %t", c.Core.RestoreState)
|
||||
logrus.Debugf(" - UseIpV6: %t", c.Advanced.UseIpV6)
|
||||
logrus.Debugf(" - CollectInterfaceData: %t", c.Statistics.CollectInterfaceData)
|
||||
logrus.Debugf(" - CollectPeerData: %t", c.Statistics.CollectPeerData)
|
||||
logrus.Debugf(" - CollectAuditData: %t", c.Statistics.CollectAuditData)
|
||||
slog.Debug("Config Features",
|
||||
"editableKeys", c.Core.EditableKeys,
|
||||
"createDefaultPeerOnCreation", c.Core.CreateDefaultPeerOnCreation,
|
||||
"reEnablePeerAfterUserEnable", c.Core.ReEnablePeerAfterUserEnable,
|
||||
"deletePeerAfterUserDeleted", c.Core.DeletePeerAfterUserDeleted,
|
||||
"selfProvisioningAllowed", c.Core.SelfProvisioningAllowed,
|
||||
"importExisting", c.Core.ImportExisting,
|
||||
"restoreState", c.Core.RestoreState,
|
||||
"useIpV6", c.Advanced.UseIpV6,
|
||||
"collectInterfaceData", c.Statistics.CollectInterfaceData,
|
||||
"collectPeerData", c.Statistics.CollectPeerData,
|
||||
"collectAuditData", c.Statistics.CollectAuditData,
|
||||
)
|
||||
|
||||
logrus.Debug("WireGuard Portal Settings:")
|
||||
logrus.Debugf(" - ConfigStoragePath: %s", c.Advanced.ConfigStoragePath)
|
||||
logrus.Debugf(" - ExternalUrl: %s", c.Web.ExternalUrl)
|
||||
slog.Debug("Config Settings",
|
||||
"configStoragePath", c.Advanced.ConfigStoragePath,
|
||||
"externalUrl", c.Web.ExternalUrl,
|
||||
)
|
||||
|
||||
logrus.Debug("WireGuard Portal Authentication:")
|
||||
logrus.Debugf(" - OIDC Providers: %d", len(c.Auth.OpenIDConnect))
|
||||
logrus.Debugf(" - OAuth Providers: %d", len(c.Auth.OAuth))
|
||||
logrus.Debugf(" - Ldap Providers: %d", len(c.Auth.Ldap))
|
||||
slog.Debug("Config Authentication",
|
||||
"oidcProviders", len(c.Auth.OpenIDConnect),
|
||||
"oauthProviders", len(c.Auth.OAuth),
|
||||
"ldapProviders", len(c.Auth.Ldap),
|
||||
)
|
||||
}
|
||||
|
||||
// defaultConfig returns the default configuration
|
||||
@ -180,7 +183,7 @@ func loadConfigFile(cfg any, filename string) error {
|
||||
data, err := envsubst.ReadFile(filename)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
logrus.Warnf("Config file %s not found, using default values", filename)
|
||||
slog.Warn("Config file not found, using default values", "filename", filename)
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("envsubst error: %v", err)
|
||||
|
@ -3,9 +3,9 @@ package domain
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const CtxUserInfo = "userInfo"
|
||||
@ -95,7 +95,10 @@ func ValidateUserAccessRights(ctx context.Context, requiredUser UserIdentifier)
|
||||
return nil // User can access own data
|
||||
}
|
||||
|
||||
logrus.Warnf("insufficient permissions for %s (want %s), stack: %s", sessionUser.Id, requiredUser, GetStackTrace())
|
||||
slog.Warn("insufficient permissions",
|
||||
"user", sessionUser.Id,
|
||||
"requiredUser", requiredUser,
|
||||
"stack", GetStackTrace())
|
||||
return ErrNoPermission
|
||||
}
|
||||
|
||||
@ -107,6 +110,8 @@ func ValidateAdminAccessRights(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
logrus.Warnf("insufficient admin permissions for %s, stack: %s", sessionUser.Id, GetStackTrace())
|
||||
slog.Warn("insufficient admin permissions",
|
||||
"user", sessionUser.Id,
|
||||
"stack", GetStackTrace())
|
||||
return ErrNoPermission
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package domain
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"math"
|
||||
"net"
|
||||
"regexp"
|
||||
@ -9,8 +10,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal"
|
||||
)
|
||||
|
||||
@ -166,18 +165,22 @@ func (i *Interface) GetRoutingTable() int {
|
||||
numberStr := strings.ReplaceAll(routingTableStr, "0x", "")
|
||||
routingTable, err := strconv.ParseUint(numberStr, 16, 64)
|
||||
if err != nil {
|
||||
logrus.Errorf("invalid hex routing table %s: %v", routingTableStr, err)
|
||||
slog.Error("failed to parse routing table number", "table", routingTableStr, "error", err)
|
||||
return -1
|
||||
}
|
||||
if routingTable > math.MaxInt32 {
|
||||
logrus.Errorf("invalid routing table %s, too big", routingTableStr)
|
||||
slog.Error("routing table number too large", "table", routingTable, "max", math.MaxInt32)
|
||||
return -1
|
||||
}
|
||||
return int(routingTable)
|
||||
default:
|
||||
routingTable, err := strconv.Atoi(routingTableStr)
|
||||
if err != nil {
|
||||
logrus.Errorf("invalid routing table %s: %v", routingTableStr, err)
|
||||
slog.Error("failed to parse routing table number", "table", routingTableStr, "error", err)
|
||||
return -1
|
||||
}
|
||||
if routingTable > math.MaxInt32 {
|
||||
slog.Error("routing table number too large", "table", routingTable, "max", math.MaxInt32)
|
||||
return -1
|
||||
}
|
||||
return routingTable
|
||||
|
@ -3,10 +3,10 @@ package internal
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
|
||||
"github.com/go-ldap/ldap/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/h44z/wg-portal/internal/config"
|
||||
)
|
||||
@ -75,7 +75,7 @@ func LdapConnect(cfg *config.LdapProvider) (*ldap.Conn, error) {
|
||||
func LdapDisconnect(conn *ldap.Conn) {
|
||||
if conn != nil {
|
||||
if err := conn.Close(); err != nil {
|
||||
logrus.Errorf("failed to close ldap connection: %v", err)
|
||||
slog.Error("failed to close ldap connection", "error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
168
internal/logger.go
Normal file
168
internal/logger.go
Normal file
@ -0,0 +1,168 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// SetupLogging initializes the global logger with the given level and format
|
||||
func SetupLogging(level string, pretty, json bool) {
|
||||
var logLevel = new(slog.LevelVar)
|
||||
|
||||
switch strings.ToLower(level) {
|
||||
case "trace", "debug":
|
||||
logLevel.Set(slog.LevelDebug)
|
||||
case "info", "information":
|
||||
logLevel.Set(slog.LevelInfo)
|
||||
case "warn", "warning":
|
||||
logLevel.Set(slog.LevelWarn)
|
||||
case "error":
|
||||
logLevel.Set(slog.LevelError)
|
||||
default:
|
||||
logLevel.Set(slog.LevelInfo)
|
||||
}
|
||||
|
||||
opts := &slog.HandlerOptions{
|
||||
Level: logLevel,
|
||||
}
|
||||
|
||||
// send everything to stderr as suggested in https://www.gnu.org/software/libc/manual/html_node/Standard-Streams.html
|
||||
output := os.Stderr
|
||||
|
||||
var handler slog.Handler
|
||||
switch {
|
||||
case json:
|
||||
handler = slog.NewJSONHandler(output, opts)
|
||||
case pretty:
|
||||
handler = NewPrettyHandler(output, opts)
|
||||
default:
|
||||
handler = slog.NewTextHandler(output, opts)
|
||||
}
|
||||
|
||||
logger := slog.New(handler)
|
||||
|
||||
slog.SetDefault(logger)
|
||||
}
|
||||
|
||||
// PrettyHandler is a slog.Handler that formats log records in a human-readable way.
|
||||
// It mimics the behavior of the slog.Default() handler.
|
||||
type PrettyHandler struct {
|
||||
opts slog.HandlerOptions
|
||||
prefix string // preformatted group names followed by a dot
|
||||
preformat string // preformatted Attrs, with an initial space
|
||||
timeFormat string
|
||||
|
||||
mu sync.Mutex
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
// NewPrettyHandler creates a new PrettyHandler.
|
||||
func NewPrettyHandler(w io.Writer, opts *slog.HandlerOptions) *PrettyHandler {
|
||||
h := &PrettyHandler{w: w}
|
||||
if opts != nil {
|
||||
h.opts = *opts
|
||||
}
|
||||
if h.opts.ReplaceAttr == nil {
|
||||
h.opts.ReplaceAttr = func(_ []string, a slog.Attr) slog.Attr { return a }
|
||||
}
|
||||
|
||||
h.timeFormat = "2006/01/02 15:04:05"
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
// Enabled reports whether the handler handles records at the given level.
|
||||
func (h *PrettyHandler) Enabled(_ context.Context, level slog.Level) bool {
|
||||
minLevel := slog.LevelInfo
|
||||
if h.opts.Level != nil {
|
||||
minLevel = h.opts.Level.Level()
|
||||
}
|
||||
return level >= minLevel
|
||||
}
|
||||
|
||||
// WithGroup returns a new Handler with the given group appended to the handler's
|
||||
func (h *PrettyHandler) WithGroup(name string) slog.Handler {
|
||||
return &PrettyHandler{
|
||||
w: h.w,
|
||||
opts: h.opts,
|
||||
preformat: h.preformat,
|
||||
prefix: h.prefix + name + ".",
|
||||
}
|
||||
}
|
||||
|
||||
// WithAttrs returns a new Handler whose attributes consist of the handler's
|
||||
func (h *PrettyHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
var buf []byte
|
||||
for _, a := range attrs {
|
||||
buf = h.appendAttr(buf, h.prefix, a)
|
||||
}
|
||||
return &PrettyHandler{
|
||||
w: h.w,
|
||||
opts: h.opts,
|
||||
prefix: h.prefix,
|
||||
preformat: h.preformat + string(buf),
|
||||
}
|
||||
}
|
||||
|
||||
// Handle formats its argument Record as a single line of text ending in a newline.
|
||||
func (h *PrettyHandler) Handle(_ context.Context, r slog.Record) error {
|
||||
var buf []byte
|
||||
if !r.Time.IsZero() {
|
||||
buf = r.Time.AppendFormat(buf, h.timeFormat)
|
||||
buf = append(buf, ' ')
|
||||
}
|
||||
|
||||
// Make sure that each level has the same length.
|
||||
// The shortest level is "INFO", thus we add a space to the end of the level string
|
||||
levText := (r.Level.String() + " ")[0:5]
|
||||
|
||||
buf = append(buf, levText...)
|
||||
buf = append(buf, ' ')
|
||||
if h.opts.AddSource && r.PC != 0 {
|
||||
fs := runtime.CallersFrames([]uintptr{r.PC})
|
||||
f, _ := fs.Next()
|
||||
buf = append(buf, f.File...)
|
||||
buf = append(buf, ':')
|
||||
buf = strconv.AppendInt(buf, int64(f.Line), 10)
|
||||
buf = append(buf, ' ')
|
||||
}
|
||||
buf = append(buf, r.Message...)
|
||||
buf = append(buf, h.preformat...)
|
||||
r.Attrs(func(a slog.Attr) bool {
|
||||
buf = h.appendAttr(buf, h.prefix, a)
|
||||
return true
|
||||
})
|
||||
buf = append(buf, '\n')
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
_, err := h.w.Write(buf)
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *PrettyHandler) appendAttr(buf []byte, prefix string, a slog.Attr) []byte {
|
||||
if a.Equal(slog.Attr{}) {
|
||||
return buf
|
||||
}
|
||||
if a.Value.Kind() != slog.KindGroup {
|
||||
buf = append(buf, ' ')
|
||||
buf = append(buf, prefix...)
|
||||
buf = append(buf, a.Key...)
|
||||
buf = append(buf, '=')
|
||||
return fmt.Appendf(buf, "%v", a.Value.Any())
|
||||
}
|
||||
// Group
|
||||
if a.Key != "" {
|
||||
prefix += a.Key + "."
|
||||
}
|
||||
for _, a := range a.Value.Group() {
|
||||
buf = h.appendAttr(buf, prefix, a)
|
||||
}
|
||||
return buf
|
||||
}
|
@ -4,18 +4,17 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// LogClose closes the given Closer and logs any error that occurs
|
||||
func LogClose(c io.Closer) {
|
||||
if err := c.Close(); err != nil {
|
||||
logrus.Errorf("error during Close(): %v", err)
|
||||
slog.Error("error during Close()", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,11 +27,10 @@ func LogError(err error, msg ...string) {
|
||||
}
|
||||
|
||||
if len(msg) > 0 {
|
||||
logrus.Errorf("%s: %v", msg[0], err)
|
||||
return
|
||||
slog.Error(msg[0], "error", err)
|
||||
} else {
|
||||
slog.Error(err.Error())
|
||||
}
|
||||
logrus.Errorf("error: %v", err)
|
||||
|
||||
}
|
||||
|
||||
// SignalAwareContext returns a context that gets closed once a given signal is retrieved.
|
||||
|
Loading…
x
Reference in New Issue
Block a user