Skip to content

Commit 1e78388

Browse files
committed
chore(embedded/logging): improve file base logging.
- Implement size and age based log rotation - Add a flag to enable lof of accesses Signed-off-by: Stefano Scafiti <[email protected]>
1 parent 67f4b0d commit 1e78388

20 files changed

+730
-100
lines changed

cmd/immudb/command/cmd_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package immudb
1818

1919
import (
2020
"bytes"
21-
"path/filepath"
2221
"testing"
2322

2423
"github.com/stretchr/testify/require"
@@ -228,7 +227,8 @@ func TestImmudbLogFile(t *testing.T) {
228227
cmd.Flags().StringVar(&config, "config", "", "test")
229228
setupDefaults(server.DefaultOptions())
230229

231-
viper.Set("logfile", filepath.Join(t.TempDir(), "override"))
230+
viper.Set("dir", t.TempDir())
231+
viper.Set("logfile", "override")
232232

233233
cl := Commandline{}
234234

cmd/immudb/command/init.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ func (cl *Commandline) setupFlags(cmd *cobra.Command, options *server.Options) {
4848

4949
cmd.PersistentFlags().StringVar(&cl.config.CfgFn, "config", "", "config file (default path are configs or $HOME. Default filename is immudb.toml)")
5050
cmd.Flags().String("pidfile", options.Pidfile, "pid path with filename e.g. /var/run/immudb.pid")
51-
cmd.Flags().String("logfile", options.Logfile, "log path with filename e.g. /tmp/immudb/immudb.log")
51+
cmd.Flags().String("logdir", options.LogDir, "log path base dir /tmp/immudb/immulog")
52+
cmd.Flags().String("logfile", options.Logfile, "filename e.g. immudb.log")
5253
cmd.Flags().String("logformat", options.LogFormat, "log format e.g. text/json")
54+
cmd.Flags().Int("log-rotation-size", options.LogRotationSize, "maximum size a log segment can reach before being rotated")
55+
cmd.Flags().Duration("log-rotation-age", options.LogRotationAge, "maximum duration (age) of a log segment before it is rotated")
56+
cmd.Flags().Bool("log-access", options.LogAccess, "log incoming requests information (username, IP, etc...)")
5357
cmd.Flags().BoolP("mtls", "m", false, "enable mutual tls")
5458
cmd.Flags().BoolP("auth", "s", false, "enable auth")
5559
cmd.Flags().Int("max-recv-msg-size", options.MaxRecvMsgSize, "max message size in bytes the server can receive")
@@ -118,6 +122,10 @@ func setupDefaults(options *server.Options) {
118122
viper.SetDefault("replica", false)
119123
viper.SetDefault("pidfile", options.Pidfile)
120124
viper.SetDefault("logfile", options.Logfile)
125+
viper.SetDefault("logdir", options.LogDir)
126+
viper.SetDefault("log-rotation-size", options.LogRotationSize)
127+
viper.SetDefault("log-rotation-age", options.LogRotationAge)
128+
viper.SetDefault("log-access", options.LogAccess)
121129
viper.SetDefault("mtls", false)
122130
viper.SetDefault("auth", options.GetAuth())
123131
viper.SetDefault("max-recv-msg-size", options.MaxRecvMsgSize)

cmd/immudb/command/parse_options.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,12 @@ func parseOptions() (options *server.Options, err error) {
5151
}
5252

5353
pidfile := viper.GetString("pidfile")
54+
55+
logdir := viper.GetString("logdir")
5456
logfile := viper.GetString("logfile")
57+
logRotationSize := viper.GetInt("log-rotation-size")
58+
logRotationAge := viper.GetDuration("log-rotation-age")
59+
logAccess := viper.GetBool("log-access")
5560
logFormat := viper.GetString("logformat")
5661

5762
mtls := viper.GetBool("mtls")
@@ -131,7 +136,11 @@ func parseOptions() (options *server.Options, err error) {
131136
WithAddress(address).
132137
WithReplicationOptions(replicationOptions).
133138
WithPidfile(pidfile).
139+
WithLogDir(logdir).
134140
WithLogfile(logfile).
141+
WithLogRotationSize(logRotationSize).
142+
WithLogRotationAge(logRotationAge).
143+
WithLogAccess(logAccess).
135144
WithTLS(tlsConfig).
136145
WithAuth(auth).
137146
WithMaxRecvMsgSize(maxRecvMsgSize).

cmd/immudb/command/root.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ limitations under the License.
1717
package immudb
1818

1919
import (
20+
"path/filepath"
21+
2022
c "github.com/codenotary/immudb/cmd/helper"
2123
"github.com/codenotary/immudb/embedded/logger"
2224
"github.com/codenotary/immudb/pkg/server"
@@ -68,10 +70,14 @@ func (cl *Commandline) Immudb(immudbServer server.ImmuServerIf) func(*cobra.Comm
6870

6971
// initialize logger for immudb
7072
ilogger, err := logger.NewLogger(&logger.Options{
71-
Name: "immudb",
72-
LogFormat: options.LogFormat,
73-
LogFile: options.Logfile,
74-
Level: logger.LogLevelFromEnvironment(),
73+
Name: "immudb",
74+
LogFormat: options.LogFormat,
75+
LogDir: filepath.Join(options.Dir, options.LogDir),
76+
LogFile: options.Logfile,
77+
LogRotationSize: options.LogRotationSize,
78+
LogRotationAge: options.LogRotationAge,
79+
LogFileTimeFormat: logger.LogFileFormat,
80+
Level: logger.LogLevelFromEnvironment(),
7581
})
7682
if err != nil {
7783
c.QuitToStdErr(err)

embedded/logger/file.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@ import (
2323
"path/filepath"
2424
)
2525

26-
// FileLogger ...
26+
// Deprecated: FileLogger is deprecated and will be removed in a future release.
2727
type FileLogger struct {
2828
Logger *log.Logger
2929
LogLevel LogLevel
3030
out *os.File
3131
}
3232

33-
// NewFileLogger ...
33+
// Deprecated: use method NewLogger instead.
3434
func NewFileLogger(name string, file string) (logger Logger, out *os.File, err error) {
3535
out, err = setup(file)
3636
if err != nil {
@@ -60,12 +60,12 @@ func NewFileLoggerWithLevel(name string, file string, level LogLevel) (logger Lo
6060
func setup(file string) (out *os.File, err error) {
6161
if _, err = os.Stat(filepath.Dir(file)); os.IsNotExist(err) {
6262
if err = os.Mkdir(filepath.Dir(file), os.FileMode(0755)); err != nil {
63-
return nil, errors.New("Unable to create log folder")
63+
return nil, errors.New("unable to create log folder")
6464
}
6565
}
6666
out, err = os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
6767
if err != nil {
68-
return out, errors.New("Unable to create log file")
68+
return out, errors.New("unable to create log file")
6969
}
7070
return out, err
7171
}

embedded/logger/json.go

Lines changed: 6 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ limitations under the License.
1717
package logger
1818

1919
import (
20-
"bytes"
2120
"encoding"
2221
"encoding/json"
2322
"fmt"
@@ -61,7 +60,7 @@ type JsonLogger struct {
6160
timeFnc TimeFunc
6261

6362
mutex sync.Mutex
64-
writer *writer
63+
writer io.Writer
6564

6665
level int32
6766
}
@@ -77,19 +76,11 @@ func NewJSONLogger(opts *Options) (*JsonLogger, error) {
7776
output = defaultOutput
7877
}
7978

80-
if opts.LogFile != "" {
81-
out, err := setup(opts.LogFile)
82-
if err != nil {
83-
return nil, err
84-
}
85-
output = out
86-
}
87-
8879
l := &JsonLogger{
8980
name: opts.Name,
9081
timeFormat: DefaultTimeFormat,
9182
timeFnc: time.Now,
92-
writer: newWriter(output),
83+
writer: output,
9384
}
9485

9586
if opts.TimeFnc != nil {
@@ -121,14 +112,12 @@ func (l *JsonLogger) log(name string, level LogLevel, msg string, args ...interf
121112
t := l.timeFnc()
122113

123114
l.logJSON(t, name, level, msg, args...)
124-
125-
l.writer.Flush()
126115
}
127116

128117
func (l *JsonLogger) logJSON(t time.Time, name string, level LogLevel, msg string, args ...interface{}) {
129118
vals := l.getVals(t, name, level, msg)
130119

131-
if args != nil && len(args) > 0 {
120+
if len(args) > 0 {
132121
for i := 0; i < len(args); i = i + 2 {
133122
val := args[i+1]
134123
switch sv := val.(type) {
@@ -243,38 +232,8 @@ func (i *JsonLogger) Name() string {
243232

244233
// Close the logger
245234
func (i *JsonLogger) Close() error {
246-
return i.writer.Close()
247-
}
248-
249-
type writer struct {
250-
b bytes.Buffer
251-
out io.Writer
252-
}
253-
254-
func newWriter(w io.Writer) *writer {
255-
return &writer{out: w}
256-
}
257-
258-
func (w *writer) Flush() (err error) {
259-
var unwritten = w.b.Bytes()
260-
_, err = w.out.Write(unwritten)
261-
w.b.Reset()
262-
return err
263-
}
264-
265-
func (w *writer) Write(p []byte) (int, error) {
266-
return w.b.Write(p)
267-
}
268-
269-
func (w *writer) Close() error {
270-
switch t := w.out.(type) {
271-
case *os.File:
272-
err := w.Flush()
273-
if err != nil {
274-
return err
275-
}
276-
return t.Close()
277-
default:
278-
return w.Flush()
235+
if wc, ok := i.writer.(io.Closer); ok {
236+
return wc.Close()
279237
}
238+
return nil
280239
}

0 commit comments

Comments
 (0)