Improve logging. TODO: Switch to slog.
This commit is contained in:
parent
2b4d1e5488
commit
0407672a23
5 changed files with 136 additions and 5 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@ client/calls/
|
|||
/gordio
|
||||
/calls
|
||||
Session.vim
|
||||
*.log
|
||||
|
|
|
@ -14,3 +14,10 @@ auth:
|
|||
"localhost": true
|
||||
listen: ':3050'
|
||||
public: true
|
||||
log:
|
||||
# level logs at or above the specified level
|
||||
# levels are trace, debug, info, warn, error, fatal, panic
|
||||
# an entry without a file: property indicates stderr
|
||||
- level: debug
|
||||
- level: error
|
||||
file: error.log
|
||||
|
|
|
@ -9,11 +9,12 @@ import (
|
|||
)
|
||||
|
||||
type Config struct {
|
||||
DB DB `yaml:"db"`
|
||||
CORS CORS `yaml:"cors"`
|
||||
Auth Auth `yaml:"auth"`
|
||||
Listen string `yaml:"listen"`
|
||||
Public bool `yaml:"public"`
|
||||
DB DB `yaml:"db"`
|
||||
CORS CORS `yaml:"cors"`
|
||||
Auth Auth `yaml:"auth"`
|
||||
Log []Logger `yaml:"log"`
|
||||
Listen string `yaml:"listen"`
|
||||
Public bool `yaml:"public"`
|
||||
|
||||
configPath string
|
||||
}
|
||||
|
@ -33,6 +34,11 @@ type DB struct {
|
|||
Driver string `yaml:"driver"`
|
||||
}
|
||||
|
||||
type Logger struct {
|
||||
File *string `yaml:"file"`
|
||||
Level *string `yaml:"level"`
|
||||
}
|
||||
|
||||
func New(cmd *cobra.Command) *Config {
|
||||
c := &Config{}
|
||||
cmd.PersistentFlags().StringVarP(&c.configPath, "config", "c", "config.yaml", "configuration file")
|
||||
|
|
110
pkg/gordio/server/logging.go
Normal file
110
pkg/gordio/server/logging.go
Normal file
|
@ -0,0 +1,110 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"dynatron.me/x/stillbox/pkg/gordio/config"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
const (
|
||||
LOGPERM fs.FileMode = 0600
|
||||
)
|
||||
|
||||
type Logger struct {
|
||||
console io.Writer
|
||||
writers []io.Writer
|
||||
hup chan os.Signal
|
||||
}
|
||||
|
||||
func NewLogger(cfg *config.Config) (*Logger, error) {
|
||||
l := &Logger{
|
||||
console: &zerolog.ConsoleWriter{Out: os.Stderr},
|
||||
}
|
||||
l.hup = make(chan os.Signal, 1)
|
||||
go func() {
|
||||
for sig := range l.hup {
|
||||
log.Logger = log.Output(l.console)
|
||||
log.Info().Msgf("received %s, closing and reopening logfiles", sig)
|
||||
l.Close()
|
||||
err := l.OpenLogs(cfg)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("error reopening logs")
|
||||
continue
|
||||
}
|
||||
|
||||
log.Logger = log.Output(zerolog.MultiLevelWriter(l.writers...))
|
||||
}
|
||||
}()
|
||||
|
||||
signal.Notify(l.hup, syscall.SIGHUP)
|
||||
|
||||
err := l.OpenLogs(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Logger = log.Output(zerolog.MultiLevelWriter(l.writers...))
|
||||
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (l *Logger) Close() {
|
||||
for _, lg := range l.writers {
|
||||
if _, isConsole := lg.(*zerolog.ConsoleWriter); isConsole {
|
||||
continue
|
||||
}
|
||||
|
||||
if cl, isCloser := lg.(io.Closer); isCloser {
|
||||
err := cl.Close()
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("closing writer")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
l.writers = nil
|
||||
}
|
||||
|
||||
func (l *Logger) OpenLogs(cfg *config.Config) error {
|
||||
l.writers = make([]io.Writer, 0, len(cfg.Log))
|
||||
for _, lc := range cfg.Log {
|
||||
level := zerolog.TraceLevel
|
||||
if lc.Level != nil {
|
||||
var err error
|
||||
|
||||
level, err = zerolog.ParseLevel(*lc.Level)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
w := &zerolog.FilteredLevelWriter{
|
||||
Level: level,
|
||||
}
|
||||
|
||||
switch lc.File {
|
||||
case nil:
|
||||
w.Writer = &zerolog.LevelWriterAdapter{Writer: l.console}
|
||||
default:
|
||||
f, err := os.OpenFile(*lc.File, os.O_WRONLY|os.O_CREATE, LOGPERM)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Writer = &zerolog.LevelWriterAdapter{
|
||||
Writer: f,
|
||||
}
|
||||
}
|
||||
|
||||
l.writers = append(l.writers, w)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -23,9 +23,15 @@ type Server struct {
|
|||
sources sources.Sources
|
||||
sinks sinks.Sinks
|
||||
nex *nexus.Nexus
|
||||
logger *Logger
|
||||
}
|
||||
|
||||
func New(cfg *config.Config) (*Server, error) {
|
||||
logger, err := NewLogger(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db, err := database.NewClient(cfg.DB)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -39,6 +45,7 @@ func New(cfg *config.Config) (*Server, error) {
|
|||
db: db,
|
||||
r: r,
|
||||
nex: nexus.New(),
|
||||
logger: logger,
|
||||
}
|
||||
|
||||
srv.sinks.Register("database", sinks.NewDatabaseSink(srv.db), true)
|
||||
|
|
Loading…
Reference in a new issue