Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: switch to slog for logging #253

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 14 additions & 16 deletions cmd/adder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,22 +86,14 @@ func main() {
// Configure logging
logging.Configure()
logger := logging.GetLogger()
// Sync logger on exit
defer func() {
if err := logger.Sync(); err != nil {
// We don't actually care about the error here, but we have to do something
// to appease the linter
return
}
}()

// Start debug listener
if cfg.Debug.ListenPort > 0 {
logger.Infof(
logger.Info(fmt.Sprintf(
"starting debug listener on %s:%d",
cfg.Debug.ListenAddress,
cfg.Debug.ListenPort,
)
))
go func() {
err := http.ListenAndServe(
fmt.Sprintf(
Expand All @@ -112,7 +104,8 @@ func main() {
nil,
)
if err != nil {
logger.Fatalf("failed to start debug listener: %s", err)
logger.Error(fmt.Sprintf("failed to start debug listener: %s", err))
os.Exit(1)
}
}()
}
Expand All @@ -129,7 +122,8 @@ func main() {
// Configure input
input := plugin.GetPlugin(plugin.PluginTypeInput, cfg.Input)
if input == nil {
logger.Fatalf("unknown input: %s", cfg.Input)
logger.Error(fmt.Sprintf("unknown input: %s", cfg.Input))
os.Exit(1)
}
pipe.AddInput(input)

Expand All @@ -142,7 +136,8 @@ func main() {
// Configure output
output := plugin.GetPlugin(plugin.PluginTypeOutput, cfg.Output)
if output == nil {
logger.Fatalf("unknown output: %s", cfg.Output)
logger.Error(fmt.Sprintf("unknown output: %s", cfg.Output))
os.Exit(1)
}
// Check if output plugin implements APIRouteRegistrar
if registrar, ok := interface{}(output).(api.APIRouteRegistrar); ok {
Expand All @@ -152,15 +147,18 @@ func main() {

// Start API after plugins are configured
if err := apiInstance.Start(); err != nil {
logger.Fatalf("failed to start API: %s", err)
logger.Error(fmt.Sprintf("failed to start API: %s", err))
os.Exit(1)
}

// Start pipeline and wait for error
if err := pipe.Start(); err != nil {
logger.Fatalf("failed to start pipeline: %s", err)
logger.Error(fmt.Sprintf("failed to start pipeline: %s", err))
os.Exit(1)
}
err, ok := <-pipe.ErrorChan()
if ok {
logger.Fatalf("pipeline failed: %s", err)
logger.Error(fmt.Sprintf("pipeline failed: %s", err))
os.Exit(1)
}
}
4 changes: 3 additions & 1 deletion fcm/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"os"

"github.com/blinklabs-io/adder/internal/logging"
)
Expand Down Expand Up @@ -45,7 +46,8 @@ func WithNotification(title string, body string) MessageOption {

func NewMessage(token string, opts ...MessageOption) *Message {
if token == "" {
logging.GetLogger().Fatalf("Token is mandatory for FCM message")
logging.GetLogger().Error("Token is mandatory for FCM message")
os.Exit(1)
}

msg := &Message{
Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ require (
github.com/swaggo/gin-swagger v1.6.0
github.com/swaggo/swag v1.16.3
go.uber.org/automaxprocs v1.5.3
go.uber.org/zap v1.27.0
golang.org/x/oauth2 v0.23.0
gopkg.in/yaml.v2 v2.4.0
)
Expand Down Expand Up @@ -62,7 +61,6 @@ require (
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/utxorpc/go-codegen v0.9.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.uber.org/multierr v1.10.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/crypto v0.27.0 // indirect
golang.org/x/net v0.25.0 // indirect
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,6 @@ go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
Expand Down
18 changes: 9 additions & 9 deletions input/chainsync/chainsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ func (c *ChainSync) setupConnection() error {
return err
}
if c.logger != nil {
c.logger.Infof("connected to node at %s", c.dialAddress)
c.logger.Info(fmt.Sprintf("connected to node at %s", c.dialAddress))
}
// Start async error handler
go func() {
Expand All @@ -225,18 +225,18 @@ func (c *ChainSync) setupConnection() error {
if c.autoReconnect {
c.autoReconnectDelay = 0
if c.logger != nil {
c.logger.Infof(
c.logger.Info(fmt.Sprintf(
"reconnecting to %s due to error: %s",
c.dialAddress,
err,
)
))
}
for {
if c.autoReconnectDelay > 0 {
c.logger.Infof(
c.logger.Info(fmt.Sprintf(
"waiting %s to reconnect",
c.autoReconnectDelay,
)
))
time.Sleep(c.autoReconnectDelay)
// Double current reconnect delay up to maximum
c.autoReconnectDelay = min(
Expand All @@ -250,10 +250,10 @@ func (c *ChainSync) setupConnection() error {
// Shutdown current connection
if err := c.oConn.Close(); err != nil {
if c.logger != nil {
c.logger.Warnf(
c.logger.Warn(fmt.Sprintf(
"failed to properly close connection: %s",
err,
)
))
}
}
// Set the intersect points from the cursor cache
Expand All @@ -263,11 +263,11 @@ func (c *ChainSync) setupConnection() error {
// Restart the connection
if err := c.Start(); err != nil {
if c.logger != nil {
c.logger.Infof(
c.logger.Info(fmt.Sprintf(
"reconnecting to %s due to error: %s",
c.dialAddress,
err,
)
))
}
continue
}
Expand Down
72 changes: 31 additions & 41 deletions internal/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,59 +15,49 @@
package logging

import (
"log"
"log/slog"
"os"
"time"

"github.com/blinklabs-io/adder/internal/config"

"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

type Logger = zap.SugaredLogger

var globalLogger *Logger
var globalLogger *slog.Logger

func Configure() {
cfg := config.GetConfig()
// Build our custom logging config
loggerConfig := zap.NewProductionConfig()
// Change timestamp key name
loggerConfig.EncoderConfig.TimeKey = "timestamp"
// Use a human readable time format
loggerConfig.EncoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout(
time.RFC3339,
)

// Set level
if cfg.Logging.Level != "" {
level, err := zapcore.ParseLevel(cfg.Logging.Level)
if err != nil {
log.Fatalf("error configuring logger: %s", err)
}
loggerConfig.Level.SetLevel(level)
var level slog.Level
switch cfg.Logging.Level {
case "debug":
level = slog.LevelDebug
case "info":
level = slog.LevelInfo
case "warn":
level = slog.LevelWarn
case "error":
level = slog.LevelError
default:
level = slog.LevelInfo
}

// Create the logger
l, err := loggerConfig.Build()
if err != nil {
log.Fatal(err)
}
handler := slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
if a.Key == slog.TimeKey {
// Format the time attribute to use RFC3339 or your custom format
// Rename the time key to timestamp
return slog.String("timestamp", a.Value.Time().Format(time.RFC3339))
}
return a
},
Level: level,
})
globalLogger = slog.New(handler).With("component", "main")

// Store the "sugared" version of the logger
globalLogger = l.Sugar()
}

func GetLogger() *zap.SugaredLogger {
func GetLogger() *slog.Logger {
if globalLogger == nil {
Configure()
}
return globalLogger
}

func GetDesugaredLogger() *zap.Logger {
return globalLogger.Desugar()
}

func GetAccessLogger() *zap.Logger {
return globalLogger.Desugar().
With(zap.String("type", "access")).
WithOptions(zap.WithCaller(false))
}
27 changes: 13 additions & 14 deletions output/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package log

import (
"log/slog"

"github.com/blinklabs-io/adder/event"
"github.com/blinklabs-io/adder/internal/logging"
"github.com/blinklabs-io/adder/plugin"
Expand All @@ -24,7 +26,7 @@ type LogOutput struct {
errorChan chan error
eventChan chan event.Event
logger plugin.Logger
outputLogger *logging.Logger
outputLogger *slog.Logger
level string
}

Expand All @@ -40,16 +42,13 @@ func New(options ...LogOptionFunc) *LogOutput {
if l.logger == nil {
l.logger = logging.GetLogger()
}
// Determine if we can use the provided logger or need our own
// This is necessary because this plugin uses logger functions that aren't part
// of the plugin.Logger interface
switch v := l.logger.(type) {
case *logging.Logger:
l.outputLogger = v
default:
l.outputLogger = logging.GetLogger()

// Use the provided *slog.Logger if available, otherwise fall back to global logger
if providedLogger, ok := l.logger.(*slog.Logger); ok {
l.outputLogger = providedLogger.With("type", "event")
} else {
l.outputLogger = logging.GetLogger().With("type", "event")
}
l.outputLogger = l.outputLogger.With("type", "event")
return l
}

Expand All @@ -64,14 +63,14 @@ func (l *LogOutput) Start() error {
}
switch l.level {
case "info":
l.outputLogger.Infow("", "event", evt)
l.outputLogger.Info("", "event", evt)
case "warn":
l.outputLogger.Warnw("", "event", evt)
l.outputLogger.Warn("", "event", evt)
case "error":
l.outputLogger.Errorw("", "event", evt)
l.outputLogger.Error("", "event", evt)
default:
// Use INFO level if log level isn't recognized
l.outputLogger.Infow("", "event", evt)
l.outputLogger.Info("", "event", evt)
}
}
}()
Expand Down
Loading