diff options
| -rw-r--r-- | client/client.go | 28 | ||||
| -rw-r--r-- | client/client_test.go | 6 | ||||
| -rw-r--r-- | cmd/eduvpn-cli/main.go | 1 | ||||
| -rw-r--r-- | exports/exports.go | 1 | ||||
| -rw-r--r-- | internal/log/log.go | 22 |
5 files changed, 42 insertions, 16 deletions
diff --git a/client/client.go b/client/client.go index d986fa6..e3f40aa 100644 --- a/client/client.go +++ b/client/client.go @@ -50,6 +50,17 @@ func CalculateGateway(cidr string) (string, error) { return ret.String(), nil } +// Logger is used by Client to control its logging. Client uses slog for all +// logging which can be configured by implementations of this interface. +type Logger interface { + // Init initializes the logging through slog. The given directory can + // be used to store the log files. + Init(dir string) (*slog.Logger, error) + // Close is called after logging has ended and should release all + // resources from Init. + Close() error +} + // Client is the main struct for the VPN client. type Client struct { // The name of the client @@ -70,8 +81,8 @@ type Client struct { // tokenCacher tokCacher TokenCacher - // logr is the log file rotater - logr *log.FileRotater + // logr is the logger + logr Logger // cfg is the config cfg *config.Config @@ -137,10 +148,10 @@ func (c *Client) goTransition(id fsm.StateID) error { // - name: the name of the client // - directory: the directory where the config files are stored. Absolute or relative // - stateCallback: the callback function for the FSM that takes two states (old and new) and the data as an interface -// - debug: whether or not we want to enable debugging +// - logger: the logger interface to use, if nil the default logger is used which logs to files in directory // // It returns an error if initialization failed, for example when discovery cannot be obtained and when there are no servers. -func New(name string, version string, directory string, stateCallback func(FSMStateID, FSMStateID, any) bool) (c *Client, err error) { +func New(name string, version string, directory string, stateCallback func(FSMStateID, FSMStateID, any) bool, logger Logger) (c *Client, err error) { // We create the client by filling fields one by one c = &Client{} @@ -152,11 +163,16 @@ func New(name string, version string, directory string, stateCallback func(FSMSt return nil, i18nerr.NewInternalf("The client registered with an invalid version: '%v'", version) } - logr, err := log.Init(slog.LevelDebug, directory) + // Initialize provided logger or use default + if logger == nil { + logger = &log.Logger{} + } + c.logr = logger + slogger, err := c.logr.Init(directory) if err != nil { return nil, i18nerr.WrapInternalf(err, "The log file with directory: '%s' failed to initialize", directory) } - c.logr = logr + slog.SetDefault(slogger) // set client name c.Name = name diff --git a/client/client_test.go b/client/client_test.go index 3ae5775..372c6c3 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -169,6 +169,7 @@ func TestServer(t *testing.T) { go stateCallback(ck, oldState, newState, data) return true }, + nil, ) if err != nil { t.Fatalf("Creating client error: %v", err) @@ -216,6 +217,7 @@ func TestTokenExpired(t *testing.T) { go stateCallback(ck, oldState, newState, data) return true }, + nil, ) if err != nil { t.Fatalf("Creating client error: %v", err) @@ -274,6 +276,7 @@ func TestInvalidProfileCorrected(t *testing.T) { go stateCallback(ck, oldState, newState, data) return true }, + nil, ) if err != nil { t.Fatalf("Creating client error: %v", err) @@ -330,6 +333,7 @@ func TestConfigStartup(t *testing.T) { go stateCallback(ck, oldState, newState, data) return true }, + nil, ) if err != nil { t.Fatalf("Creating client error: %v", err) @@ -390,6 +394,7 @@ func TestPreferTCP(t *testing.T) { go stateCallback(ck, oldState, newState, data) return true }, + nil, ) if err != nil { t.Fatalf("Creating client error: %v", err) @@ -453,6 +458,7 @@ func TestInvalidClientID(t *testing.T) { func(_ FSMStateID, _ FSMStateID, _ any) bool { return true }, + nil, ) if v { if err != nil { diff --git a/cmd/eduvpn-cli/main.go b/cmd/eduvpn-cli/main.go index d0457b5..2a8ffc1 100644 --- a/cmd/eduvpn-cli/main.go +++ b/cmd/eduvpn-cli/main.go @@ -154,6 +154,7 @@ func printConfig(url string, cc string, srvType srvtypes.Type, prof string) erro stateCallback(oldState, newState, data, prof, dir) return true }, + nil, ) if err != nil { return err diff --git a/exports/exports.go b/exports/exports.go index 3ef6781..05a77c2 100644 --- a/exports/exports.go +++ b/exports/exports.go @@ -163,6 +163,7 @@ func Register( func(oldState client.FSMStateID, newState client.FSMStateID, data interface{}) bool { return stateCallback(cb, oldState, newState, data) }, + nil, ) // Only update the state if we get no error if err == nil { diff --git a/internal/log/log.go b/internal/log/log.go index 6a48ad7..91eaed8 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -9,12 +9,11 @@ import ( "path" ) -// 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 -// This can be done as this function sets the logger as the default logger in slog -// It returns the log file and the error -// This log file should be closed at the end -func Init(lvl slog.Level, dir string) (*FileRotater, error) { +type Logger struct { + fr *FileRotater +} + +func (l *Logger) Init(dir string) (*slog.Logger, error) { err := os.MkdirAll(dir, 0o700) if err != nil { return nil, err @@ -25,11 +24,14 @@ func Init(lvl slog.Level, dir string) (*FileRotater, error) { if err != nil { return nil, fmt.Errorf("failed creating log rotater: %w", err) } + l.fr = fr multi := io.MultiWriter(os.Stdout, fr) handler := slog.NewTextHandler(multi, &slog.HandlerOptions{ - Level: lvl, + Level: slog.LevelDebug, }) - logger := slog.New(handler) - slog.SetDefault(logger) - return fr, nil + return slog.New(handler), nil +} + +func (l *Logger) Close() error { + return l.fr.Close() } |
