summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/client.go39
-rw-r--r--client/fsm.go4
-rw-r--r--exports/exports.go14
-rw-r--r--i18nerr/i18nerr.go8
-rw-r--r--internal/api/api.go10
-rw-r--r--internal/config/config.go4
-rw-r--r--internal/config/v2/convert.go2
-rw-r--r--internal/config/v2/v2.go6
-rw-r--r--internal/discovery/discovery.go24
-rw-r--r--internal/discovery/manager.go5
-rw-r--r--internal/failover/monitor.go19
-rw-r--r--internal/log/log.go140
-rw-r--r--internal/server/custom.go4
-rw-r--r--internal/server/institute.go4
-rw-r--r--internal/server/secureinternet.go4
15 files changed, 90 insertions, 197 deletions
diff --git a/client/client.go b/client/client.go
index 6c905ca..ea5b2b9 100644
--- a/client/client.go
+++ b/client/client.go
@@ -6,6 +6,8 @@ package client
import (
"context"
"errors"
+ "log/slog"
+ "os"
"sync"
"time"
@@ -46,6 +48,9 @@ type Client struct {
// tokenCacher
tokCacher TokenCacher
+ // logf is the log file
+ logf *os.File
+
// cfg is the config
cfg *config.Config
@@ -101,7 +106,7 @@ func (c *Client) goTransition(id fsm.StateID) error {
return i18nerr.WrapInternal(err, "state transition error")
}
if !handled {
- log.Logger.Debugf("transition not handled by the client to internal state: '%s'", GetStateName(id))
+ slog.Debug("transition not handled by the client to internal state", "state", GetStateName(id))
}
return nil
}
@@ -126,14 +131,16 @@ func New(name string, version string, directory string, stateCallback func(FSMSt
}
// Initialize the logger
- lvl := log.LevelInfo
+ lvl := slog.LevelInfo
if debug {
- lvl = log.LevelDebug
+ lvl = slog.LevelDebug
}
- if err = log.Logger.Init(lvl, directory); err != nil {
+ logf, err := log.Init(lvl, directory)
+ if err != nil {
return nil, i18nerr.WrapInternalf(err, "The log file with directory: '%s' failed to initialize", directory)
}
+ c.logf = logf
// set client name
c.Name = name
@@ -207,7 +214,7 @@ func (c *Client) AuthDone(id string, t srvtypes.Type) {
}
_, err = c.FSM.GoTransition(StateMain)
if err != nil {
- log.Logger.Debugf("unhandled auth done main transition: %v", err)
+ slog.Debug("unhandled auth done transition", "error", err)
}
c.TrySave()
}
@@ -222,7 +229,7 @@ func (c *Client) TokensUpdated(id string, t srvtypes.Type, tok eduoauth.Token) {
// Set the memory
err := c.tokCacher.Set(id, t, tok)
if err != nil {
- log.Logger.Warningf("failed to set tokens into cache with error: %v", err)
+ slog.Warn("failed to set tokens in cache", "error", err)
}
if c.TokenSetter == nil {
@@ -256,11 +263,13 @@ func (c *Client) Deregister() {
// Move the state machine back
_, err := c.FSM.GoTransition(StateDeregistered)
if err != nil {
- log.Logger.Debugf("failed deregistered transition: %v", err)
+ slog.Debug("failed deregistered transition", "error", err)
}
// Close the log file
- _ = log.Logger.Close()
+ if c.logf != nil {
+ _ = c.logf.Close()
+ }
release()
// Empty out the state
@@ -316,14 +325,14 @@ func (c *Client) locationCallback(ck *cookie.Cookie, orgID string) error {
// TrySave tries to save the internal state file
// If an error occurs it logs it
func (c *Client) TrySave() {
- log.Logger.Debugf("saving state file")
+ slog.Debug("saving state file")
if c.cfg == nil {
- log.Logger.Warningf("no state file to save")
+ slog.Warn("no state file to save")
return
}
err := c.cfg.Save()
if err != nil {
- log.Logger.Warningf("failed to save state file: %v", err)
+ slog.Warn("failed to save state file", "error", err)
}
}
@@ -429,12 +438,12 @@ func (c *Client) GetConfig(ck *cookie.Cookie, identifier string, _type srvtypes.
}
err = c.GettingConfig()
if err != nil {
- log.Logger.Debugf("failed getting config transition: %v", err)
+ slog.Debug("failed getting config transition", "error", err)
}
tok, err := c.retrieveTokens(identifier, _type)
if err != nil {
- log.Logger.Debugf("no tokens found for server: '%s', with error: '%v'", identifier, err)
+ slog.Debug("no tokens found for server", "server", identifier, "error", err)
}
ctx := ck.Context()
@@ -443,7 +452,7 @@ func (c *Client) GetConfig(ck *cookie.Cookie, identifier string, _type srvtypes.
// make sure the servers are fetched fresh
_, _, dserverr := disco.Servers(ctx)
if dserverr != nil {
- log.Logger.Warningf("failed to fetch server discovery when getting config: %v", dserverr)
+ slog.Warn("failed to fetch server discovery when getting config", "error", dserverr)
}
release()
}
@@ -457,7 +466,7 @@ func (c *Client) GetConfig(ck *cookie.Cookie, identifier string, _type srvtypes.
// make sure the organizations are fetched if they need an update
_, _, dorgerr := disco.Organizations(ctx)
if dorgerr != nil {
- log.Logger.Warningf("failed to fetch organization discovery when getting config: %v", dorgerr)
+ slog.Warn("failed to fetch organization discovery when getting config", "error", dorgerr)
}
release()
srv, err = c.Servers.GetSecure(ctx, identifier, c.discoMan, tok, startup)
diff --git a/client/fsm.go b/client/fsm.go
index d22f947..6fffc8a 100644
--- a/client/fsm.go
+++ b/client/fsm.go
@@ -2,10 +2,10 @@ package client
import (
"fmt"
+ "log/slog"
"codeberg.org/eduVPN/eduvpn-common/i18nerr"
"codeberg.org/eduVPN/eduvpn-common/internal/fsm"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
)
type (
@@ -182,7 +182,7 @@ func (c *Client) SetState(state FSMStateID) error {
if err != nil {
// self-transitions are only debug errors
if c.FSM.InState(state) {
- log.Logger.Debugf("attempt an invalid self-transition: %s", c.FSM.GetStateName(state))
+ slog.Debug("attempt at an invalid self-transition", "transition", c.FSM.GetStateName(state))
return nil
}
return i18nerr.WrapInternalf(err, "Failed internal state transition requested by the client from: '%s' to '%s'", GetStateName(curr), GetStateName(state))
diff --git a/exports/exports.go b/exports/exports.go
index 448883b..880101a 100644
--- a/exports/exports.go
+++ b/exports/exports.go
@@ -1,5 +1,3 @@
-// package main implements the main exported API to be used by other languages
-//
// Some notes:
//
// - Errors are returned as JSON c strings. The JSON type is defined in `types/error/error.go Error`. Free them using `FreeString`. Same is the case for other string types, you should also free them. The errors are always localized
@@ -23,12 +21,12 @@ import (
"context"
"encoding/json"
"fmt"
+ "log/slog"
"runtime/cgo"
"unsafe"
"codeberg.org/eduVPN/eduvpn-common/client"
"codeberg.org/eduVPN/eduvpn-common/i18nerr"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/types/cookie"
errtypes "codeberg.org/eduVPN/eduvpn-common/types/error"
srvtypes "codeberg.org/eduVPN/eduvpn-common/types/server"
@@ -84,7 +82,7 @@ func stateCallback(
newStateC := C.int(newState)
d, err := getReturnData(data)
if err != nil {
- log.Logger.Errorf("failed to get return data: %v", err)
+ slog.Error("cgo failed to get return data", "error", err)
return false
}
dataC := C.CString(d)
@@ -982,7 +980,7 @@ func SetTokenHandler(getter C.TokenGetter, setter C.TokenSetter) *C.char {
state.TokenSetter = func(sid string, stype srvtypes.Type, t srvtypes.Tokens) {
tJSON, err := getReturnData(t)
if err != nil {
- log.Logger.Warningf("failed to get tokens for setting tokens in exports: %v", err)
+ slog.Warn("cgo failed to get tokens in setting tokens callback", "error", err)
return
}
c1 := C.CString(sid)
@@ -1004,20 +1002,20 @@ func SetTokenHandler(getter C.TokenGetter, setter C.TokenSetter) *C.char {
// get null pointer index as unmarshalling wants it without
null := bytes.IndexByte(d, 0)
if null < 0 {
- log.Logger.Warningf("output buffer is not NULL terminated")
+ slog.Warn("cgo output buffer in token getter is not null terminated")
return nil
}
// no data found
if null == 0 {
- log.Logger.Debugf("empty string returned when getting tokens")
+ slog.Warn("cgo empty string returned in token getter")
return nil
}
var gotT srvtypes.Tokens
err := json.Unmarshal(d[:null], &gotT)
if err != nil {
- log.Logger.Warningf("failed to get JSON data for getting tokens in exports: %v", err)
+ slog.Warn("cgo failed to get JSON data in token getter", "error", err)
return nil
}
return &gotT
diff --git a/i18nerr/i18nerr.go b/i18nerr/i18nerr.go
index 438b135..f16cf08 100644
--- a/i18nerr/i18nerr.go
+++ b/i18nerr/i18nerr.go
@@ -5,10 +5,10 @@ import (
"context"
"errors"
"fmt"
+ "log/slog"
"sync"
"codeberg.org/eduVPN/eduvpn-common/internal/http"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"golang.org/x/text/language"
"golang.org/x/text/message"
@@ -102,12 +102,12 @@ func (e *Error) Unwrap() error {
func printerOrNew(tag language.Tag) *message.Printer {
v, ok := printers.Load(tag)
if !ok {
- log.Logger.Debugf("i18n: could not load printer with tag: '%v' from map", tag)
+ slog.Debug("i18n could not load printer from map", "tag", tag)
return message.NewPrinter(tag)
}
p, ok := v.(*message.Printer)
if !ok {
- log.Logger.Debugf("i18n: could not load printer with tag: '%v' as the type is not correct: '%T'", tag, p)
+ slog.Debug("i18n could not load printer from map with incorrect type", "tag", tag, "type", fmt.Sprintf("%T", p))
return message.NewPrinter(tag)
}
return p
@@ -165,7 +165,7 @@ func WrapInternalf(err error, disp string, args ...any) *Error {
// initializeLangs initializes the printers from the default catalog into the sync map
// we cannot do this in init() because this is too early
func inititializeLangs() {
- log.Logger.Debugf("i18n: initializing languages...")
+ slog.Debug("i18n initializing languages")
for _, t := range message.DefaultCatalog.Languages() {
printers.Store(t, message.NewPrinter(t))
}
diff --git a/internal/api/api.go b/internal/api/api.go
index 4ee82b0..c34a0b0 100644
--- a/internal/api/api.go
+++ b/internal/api/api.go
@@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"fmt"
+ "log/slog"
"net/http"
"net/url"
"time"
@@ -16,7 +17,6 @@ import (
"codeberg.org/eduVPN/eduvpn-common/internal/api/endpoints"
"codeberg.org/eduVPN/eduvpn-common/internal/api/profiles"
httpw "codeberg.org/eduVPN/eduvpn-common/internal/http"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/internal/wireguard"
"codeberg.org/eduVPN/eduvpn-common/types/protocol"
"codeberg.org/eduVPN/eduvpn-common/types/server"
@@ -186,7 +186,7 @@ func (a *API) authorizedRetry(ctx context.Context, method string, endpoint strin
// Only retry authorized if we get an HTTP 401
// TODO: Can the OAuth client handle this instead?
if errors.As(err, &statErr) && statErr.Status == 401 {
- log.Logger.Debugf("Got a 401 error after HTTP method: %s, endpoint: %s. Marking token as expired...", method, endpoint)
+ slog.Debug("Got a HTTP 401. Marking tokens as expired...", "HTTP method", method, "endpoint", endpoint)
// Mark the token as expired and retry, so we trigger the refresh flow
a.oauth.SetTokenExpired()
h, body, err = a.authorized(ctx, method, endpoint, opts)
@@ -196,7 +196,7 @@ func (a *API) authorizedRetry(ctx context.Context, method string, endpoint strin
if err != nil && errors.As(err, &tErr) {
// Mark the token as invalid and retry, so we trigger the authorization flow
a.oauth.SetTokenRenew()
- log.Logger.Debugf("the tokens were invalid, trying again...")
+ slog.Debug("The tokens were invalid, trying again...")
if autherr := a.authorize(ctx); autherr != nil {
return nil, nil, autherr
}
@@ -376,12 +376,12 @@ type OAuthLogger struct{}
// Logf logs a message with parameters
func (ol *OAuthLogger) Logf(msg string, params ...any) {
- log.Logger.Debugf(msg, params...)
+ slog.Debug("OAuth log", "log", fmt.Sprintf(msg, params...))
}
// Log logs a message
func (ol *OAuthLogger) Log(msg string) {
- log.Logger.Debugf("%s", msg)
+ slog.Debug("OAuth log", "log", msg)
}
func init() {
diff --git a/internal/config/config.go b/internal/config/config.go
index 9e924c1..06da9b3 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -4,6 +4,7 @@ package config
import (
"encoding/json"
+ "log/slog"
"os"
"path"
@@ -11,7 +12,6 @@ import (
"codeberg.org/eduVPN/eduvpn-common/internal/config/v1"
"codeberg.org/eduVPN/eduvpn-common/internal/config/v2"
"codeberg.org/eduVPN/eduvpn-common/internal/discovery"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/internal/util"
)
@@ -91,7 +91,7 @@ func NewFromDirectory(dir string) *Config {
}
err := cfg.Load()
if err != nil {
- log.Logger.Debugf("failed to load configuration: %v", err)
+ slog.Debug("failed to load configuration", "error", err)
}
if cfg.V2 == nil {
cfg.V2 = &v2.V2{}
diff --git a/internal/config/v2/convert.go b/internal/config/v2/convert.go
index f50ffaf..675d274 100644
--- a/internal/config/v2/convert.go
+++ b/internal/config/v2/convert.go
@@ -1,11 +1,11 @@
package v2
import (
+ "maps"
"time"
"codeberg.org/eduVPN/eduvpn-common/internal/config/v1"
"codeberg.org/eduVPN/eduvpn-common/types/server"
- "maps"
)
func v1AuthTime(st time.Time, ost time.Time) time.Time {
diff --git a/internal/config/v2/v2.go b/internal/config/v2/v2.go
index d23d26d..7851cb8 100644
--- a/internal/config/v2/v2.go
+++ b/internal/config/v2/v2.go
@@ -4,11 +4,11 @@ package v2
import (
"errors"
"fmt"
+ "log/slog"
"net/url"
"time"
"codeberg.org/eduVPN/eduvpn-common/internal/discovery"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/types/server"
)
@@ -215,7 +215,7 @@ func convertCustom(u string) server.Server {
dn := u
pu, err := url.Parse(u)
if err != nil {
- log.Logger.Errorf("failed to parse server hostname: %v", err)
+ slog.Error("failed to parse server hostname", "error", err)
} else {
dn = pu.Hostname()
}
@@ -272,7 +272,7 @@ func (cfg *V2) PublicList(disco *discovery.Discovery) *server.List {
g.Profiles = v.Profiles
ret.Custom = append(ret.Custom, g)
default:
- log.Logger.Errorf("no such server type in list: '%v'", k.T)
+ slog.Error("no such server type in list", "type", k.T)
continue
}
}
diff --git a/internal/discovery/discovery.go b/internal/discovery/discovery.go
index 3fcb68c..81163f8 100644
--- a/internal/discovery/discovery.go
+++ b/internal/discovery/discovery.go
@@ -6,12 +6,12 @@ import (
"encoding/json"
"errors"
"fmt"
+ "log/slog"
"net/http"
"time"
httpw "codeberg.org/eduVPN/eduvpn-common/internal/http"
"codeberg.org/eduVPN/eduvpn-common/internal/levenshtein"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/internal/verify"
discotypes "codeberg.org/eduVPN/eduvpn-common/types/discovery"
)
@@ -129,13 +129,13 @@ func (discovery *Discovery) file(ctx context.Context, jsonFile string, previousV
if lms != "" {
lm, err := http.ParseTime(lms)
if err != nil {
- log.Logger.Warningf("failed to parse 'Last-Modified' header: %v", err)
+ slog.Warn("failed to parse 'Last-Modified' header", "error", err)
} else {
newUpdate = lm
- log.Logger.Debugf("got 'Last-Modified' header: %v", lm)
+ slog.Debug("got 'Last-Modified' header", "value", lm)
}
} else {
- log.Logger.Warningf("no 'Last-Modified' header found")
+ slog.Warn("no 'Last-Modified' header found")
}
// Get signature
@@ -339,22 +339,22 @@ func (discovery *Discovery) Organizations(ctx context.Context) (*Organizations,
statErr := &httpw.StatusError{}
if errors.As(err, &statErr) {
if statErr.Status != 304 {
- log.Logger.Warningf("failed to get fresh organizations: %v", err)
+ slog.Warn("failed to get fresh organization", "error", err)
} else {
discovery.OrganizationList.Timestamp = time.Now()
- log.Logger.Debugf("got 304 for discovery, organization_list.json not modified")
+ slog.Debug("got HTTP 304 for discovery, organization_list.json is not modified")
err = nil
}
}
// Return previous with an error
orgs, perr := discovery.previousOrganizations()
if perr != nil {
- log.Logger.Warningf("failed to get previous discovery organizations: %v", perr)
+ slog.Warn("failed to get previous discovery organizations", "error", perr)
}
return orgs, false, err
}
if len(jsonDecode.List) == 0 {
- log.Logger.Warningf("fresh organization list is empty")
+ slog.Warn("fresh organization list is empty")
} else {
discovery.OrganizationList = jsonDecode
}
@@ -379,22 +379,22 @@ func (discovery *Discovery) Servers(ctx context.Context) (*Servers, bool, error)
statErr := &httpw.StatusError{}
if errors.As(err, &statErr) {
if statErr.Status != 304 {
- log.Logger.Warningf("failed to get fresh servers: %v", err)
+ slog.Warn("failed to get fresh servers", "error", err)
} else {
discovery.ServerList.Timestamp = time.Now()
- log.Logger.Debugf("got 304 for discovery, server_list.json not modified")
+ slog.Debug("got HTTP 304 for discovery, server_list.json is not modified")
err = nil
}
}
// Return previous with an error
srvs, perr := discovery.previousServers()
if perr != nil {
- log.Logger.Warningf("failed to get previous discovery servers: %v", perr)
+ slog.Warn("failed to get previous discovery server", "error", perr)
}
return srvs, false, err
}
if len(jsonDecode.List) == 0 {
- log.Logger.Warningf("fresh server list is empty")
+ slog.Warn("fresh server list is empty")
} else {
discovery.ServerList = jsonDecode
}
diff --git a/internal/discovery/manager.go b/internal/discovery/manager.go
index 6a78486..134525b 100644
--- a/internal/discovery/manager.go
+++ b/internal/discovery/manager.go
@@ -2,9 +2,8 @@ package discovery
import (
"context"
+ "log/slog"
"sync"
-
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
)
// Manager is the discovery struct that is cached
@@ -68,7 +67,7 @@ func (m *Manager) Startup(ctx context.Context, cb func()) {
m.lock(false)
discoCopy, err := m.disco.Copy()
if err != nil {
- log.Logger.Warningf("internal error, failed to clone discovery, %v", err)
+ slog.Warn("failed to clone discovery", "error", err)
return
}
m.unlock(false)
diff --git a/internal/failover/monitor.go b/internal/failover/monitor.go
index a29c711..5efdbd0 100644
--- a/internal/failover/monitor.go
+++ b/internal/failover/monitor.go
@@ -3,9 +3,8 @@ package failover
import (
"context"
"fmt"
+ "log/slog"
"time"
-
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
)
type sender interface {
@@ -44,7 +43,7 @@ func (m *DroppedConMon) dropped(startBytes int64) (bool, error) {
if err != nil {
return false, err
}
- log.Logger.Debugf("[Failover] Alive check, current Rx bytes: %d, start Rx bytes: %d", b, startBytes)
+ slog.Debug("Failover alive check", "rx bytes", b, "start bytes", startBytes)
return b <= startBytes, nil
}
@@ -71,17 +70,17 @@ func (m *DroppedConMon) Start(ctx context.Context, gateway string, mtuSize int)
// Send a ping and wait for max 2 seconds
// If we have then increased Rx bytes we return early
if err = p.Send(1); err != nil {
- log.Logger.Debugf("[Failover] First ping failed, exiting...")
+ slog.Debug("Failover first ping failed, exiting...")
return false, err
}
- log.Logger.Debugf("[Failover] Now we are doing alive check")
+ slog.Debug("Failover doing alive check")
// Read the pong, if we got the echo reply then everything is fine, early return
if err = p.Read(time.Now().Add(m.pInterval)); err == nil {
- log.Logger.Debugf("[Failover] Got early pong, exiting...")
+ slog.Debug("Failover got early pong, exiting...")
return false, err
}
- log.Logger.Debugf("[Failover] Error reading pong: %v", err)
+ slog.Debug("Failover error reading pong", "error", err)
// Create a new ticker that executes our ping function every 'interval' seconds
// It starts immediately and stops when we reach the end
@@ -89,15 +88,15 @@ func (m *DroppedConMon) Start(ctx context.Context, gateway string, mtuSize int)
defer ticker.Stop()
// Otherwise send n pings, without waiting for pong and then check if dropped
- log.Logger.Debugf("[Failover] Starting by sending pings and not waiting for pong...")
+ slog.Debug("Failover started by sending pings and not waiting for a pong...")
// Loop until the max drop counter
// We begin with 2 as this is used as the sequence number for ping
// and we have already sent a ping
for s := 2; s <= m.pDropped; s++ {
- log.Logger.Debugf("[Failover] Sending ping: %d, with size: %d", s, mtuSize)
+ slog.Debug("Failover sending ping", "ping", s, "size", mtuSize)
// Send a ping and return if an error occurs
if err := p.Send(s); err != nil {
- log.Logger.Debugf("[Failover] A ping failed, exiting...")
+ slog.Debug("Failover ping failed, exiting...")
return false, err
}
// Wait for the next tick to continue
diff --git a/internal/log/log.go b/internal/log/log.go
index e47a743..d4a9bf5 100644
--- a/internal/log/log.go
+++ b/internal/log/log.go
@@ -4,146 +4,34 @@ package log
import (
"fmt"
"io"
- "log"
+ "log/slog"
"os"
"path"
"codeberg.org/eduVPN/eduvpn-common/internal/util"
)
-// FileLogger defines the type of logger that this package implements
-// As the name suggests, it saves the log to a file.
-type FileLogger struct {
- // Level indicates which maximum level this logger actually forwards to the file
- Level Level
-
- // file represents a pointer to the open log file
- file *os.File
-}
-
-// Logger is the global logger instance
-var Logger *FileLogger
-
-// Level is the level of log, e.g. debug
-type Level int8
-
-const (
- // LevelNotSet indicates level not set, not allowed.
- LevelNotSet Level = iota
-
- // LevelDebug indicates that the message is not an error but is there for debugging.
- LevelDebug
-
- // LevelInfo indicates that the message is not an error but is there for additional information.
- LevelInfo
-
- // LevelWarning indicates only a warning, the app still functions.
- LevelWarning
-
- // LevelError indicates a generic error, the app still functions but some functionality might not work.
- LevelError
-
- // LevelFatal indicates a fatal error, the app cannot function correctly when such an error occurs.
- LevelFatal
-)
-
-// String returns the string of each level.
-func (e Level) String() string {
- switch e {
- case LevelNotSet:
- return "NOTSET"
- case LevelDebug:
- return "DEBUG"
- case LevelInfo:
- return "INFO"
- case LevelWarning:
- return "WARNING"
- case LevelError:
- return "ERROR"
- case LevelFatal:
- return "FATAL"
- default:
- return "UNKNOWN"
- }
-}
-
-// Init initializes the logger by forwarding a max level 'level' and a directory 'directory' where the log should be stored
-// If the logger cannot be initialized, for example an error in opening the log file, an error is returned.
-func (logger *FileLogger) Init(lvl Level, dir string) error {
+// Init initializes the logger by setting a max level 'level' and a directory 'directory' where the log should be stored
+// internally, it uses slog, so any package just imports slog
+func Init(lvl slog.Level, dir string) (*os.File, error) {
err := util.EnsureDirectory(dir)
if err != nil {
- return err
+ return nil, err
}
+ name := path.Join(dir, "log")
f, err := os.OpenFile(
- logger.filename(dir),
+ name,
os.O_RDWR|os.O_CREATE|os.O_APPEND,
0o666,
)
if err != nil {
- return fmt.Errorf("failed creating log: %w", err)
+ return nil, fmt.Errorf("failed creating log: %w", err)
}
multi := io.MultiWriter(os.Stdout, f)
- log.SetOutput(multi)
- logger.file = f
- logger.Level = lvl
- return nil
-}
-
-// Inherit logs an error with a message and params using the error level verbosity of the error.
-// The message is always prefixed with the error.
-func (logger *FileLogger) Inherit(err error, msg string) {
- if err == nil {
- return
- }
- s := "%s %s"
- logger.Errorf(s, err.Error(), msg)
-}
-
-// Debugf logs a message with parameters as level LevelDebug.
-func (logger *FileLogger) Debugf(msg string, params ...any) {
- logger.log(LevelDebug, msg, params...)
-}
-
-// Infof logs a message with parameters as level LevelInfo.
-func (logger *FileLogger) Infof(msg string, params ...any) {
- logger.log(LevelInfo, msg, params...)
-}
-
-// Warningf logs a message with parameters as level LevelWarning.
-func (logger *FileLogger) Warningf(msg string, params ...any) {
- logger.log(LevelWarning, msg, params...)
-}
-
-// Errorf logs a message with parameters as level LevelError.
-func (logger *FileLogger) Errorf(msg string, params ...any) {
- logger.log(LevelError, msg, params...)
-}
-
-// Fatalf logs a message with parameters as level LevelFatal.
-func (logger *FileLogger) Fatalf(msg string, params ...any) {
- logger.log(LevelFatal, msg, params...)
-}
-
-// Close closes the logger by closing the internal file.
-func (logger *FileLogger) Close() error {
- return logger.file.Close()
-}
-
-// filename returns the filename of the logger by returning the full path as a string.
-func (logger *FileLogger) filename(directory string) string {
- return path.Join(directory, "log")
-}
-
-// log logs as level 'level' a message 'msg' with parameters 'params'.
-func (logger *FileLogger) log(lvl Level, msg string, params ...any) {
- if lvl >= logger.Level && logger.Level != LevelNotSet {
- fMsg := fmt.Sprintf(msg, params...)
- f := fmt.Sprintf("- Go - %s - %s", lvl.String(), fMsg)
- // To log file
- log.Println(f)
- }
-}
-
-func init() {
- Logger = &FileLogger{}
+ handler := slog.NewTextHandler(multi, &slog.HandlerOptions{
+ Level: lvl,
+ })
+ logger := slog.New(handler)
+ slog.SetDefault(logger)
+ return f, nil
}
diff --git a/internal/server/custom.go b/internal/server/custom.go
index fe240e7..0940084 100644
--- a/internal/server/custom.go
+++ b/internal/server/custom.go
@@ -2,11 +2,11 @@ package server
import (
"context"
+ "log/slog"
"time"
"codeberg.org/eduVPN/eduvpn-common/internal/api"
"codeberg.org/eduVPN/eduvpn-common/internal/config/v2"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/types/server"
"github.com/jwijenbergh/eduoauth-go"
)
@@ -45,7 +45,7 @@ func (s *Servers) AddCustom(ctx context.Context, id string, ot *int64) error {
// authorization has failed, remove the server again
rerr := s.config.RemoveServer(id, server.TypeCustom)
if rerr != nil {
- log.Logger.Warningf("could not remove custom server: '%s' after failing authorization: %v", id, rerr)
+ slog.Warn("could not remove custom server after failing authorization", "server", id, "error", rerr)
}
return err
}
diff --git a/internal/server/institute.go b/internal/server/institute.go
index 8948443..348e895 100644
--- a/internal/server/institute.go
+++ b/internal/server/institute.go
@@ -2,12 +2,12 @@ package server
import (
"context"
+ "log/slog"
"time"
"codeberg.org/eduVPN/eduvpn-common/internal/api"
"codeberg.org/eduVPN/eduvpn-common/internal/config/v2"
"codeberg.org/eduVPN/eduvpn-common/internal/discovery"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/types/server"
"github.com/jwijenbergh/eduoauth-go"
)
@@ -57,7 +57,7 @@ func (s *Servers) AddInstitute(ctx context.Context, discom *discovery.Manager, i
// authorization has failed, remove the server again
rerr := s.config.RemoveServer(dsrv.BaseURL, server.TypeInstituteAccess)
if rerr != nil {
- log.Logger.Warningf("could not remove institute access server: '%s' after failing authorization: %v", dsrv.BaseURL, rerr)
+ slog.Warn("Could not remove institute access server after failing authorization", "server", dsrv.BaseURL, "error", rerr)
}
return err
}
diff --git a/internal/server/secureinternet.go b/internal/server/secureinternet.go
index 1b786ed..f97cef1 100644
--- a/internal/server/secureinternet.go
+++ b/internal/server/secureinternet.go
@@ -3,12 +3,12 @@ package server
import (
"context"
"errors"
+ "log/slog"
"time"
"codeberg.org/eduVPN/eduvpn-common/internal/api"
"codeberg.org/eduVPN/eduvpn-common/internal/config/v2"
"codeberg.org/eduVPN/eduvpn-common/internal/discovery"
- "codeberg.org/eduVPN/eduvpn-common/internal/log"
"codeberg.org/eduVPN/eduvpn-common/internal/util"
"codeberg.org/eduVPN/eduvpn-common/types/server"
"github.com/jwijenbergh/eduoauth-go"
@@ -76,7 +76,7 @@ func (s *Servers) AddSecure(ctx context.Context, discom *discovery.Manager, orgI
// authorization has failed, remove the server again
rerr := s.config.RemoveServer(orgID, server.TypeSecureInternet)
if rerr != nil {
- log.Logger.Warningf("could not remove secure internet server: '%s' after failing authorization: %v", orgID, rerr)
+ slog.Warn("could not remove secure internet server after failing authorization", "server", orgID, "error", rerr)
}
return err
}