diff --git a/logger/context.go b/logger/context.go index 6cb6b65f..848b9bca 100644 --- a/logger/context.go +++ b/logger/context.go @@ -4,6 +4,17 @@ import "context" type loggerKey struct{} +// MustContext returns logger from passed context or DefaultLogger if empty +func MustContext(ctx context.Context) Logger { + if ctx == nil { + return DefaultLogger + } + if l, ok := ctx.Value(loggerKey{}).(Logger); ok && l != nil { + return l + } + return DefaultLogger +} + // FromContext returns logger from passed context func FromContext(ctx context.Context) (Logger, bool) { if ctx == nil { diff --git a/logger/options.go b/logger/options.go index 3138892d..cd3b9f26 100644 --- a/logger/options.go +++ b/logger/options.go @@ -6,6 +6,8 @@ import ( "log/slog" "os" "time" + + "go.unistack.org/micro/v3/meter" ) // Option func signature @@ -45,6 +47,8 @@ type Options struct { Level Level // TimeFunc used to obtain current time TimeFunc func() time.Time + // Meter used to count logs for specific level + Meter meter.Meter } // NewOptions creates new options struct @@ -58,6 +62,7 @@ func NewOptions(opts ...Option) Options { ContextAttrFuncs: DefaultContextAttrFuncs, AddSource: true, TimeFunc: time.Now, + Meter: meter.DefaultMeter, } WithMicroKeys()(&options) diff --git a/logger/slog/slog.go b/logger/slog/slog.go index 3c699cff..76a7e1bb 100644 --- a/logger/slog/slog.go +++ b/logger/slog/slog.go @@ -11,6 +11,7 @@ import ( "sync" "go.unistack.org/micro/v3/logger" + "go.unistack.org/micro/v3/semconv" "go.unistack.org/micro/v3/tracer" ) @@ -150,6 +151,7 @@ func (s *slogLogger) Init(opts ...logger.Option) error { } func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() if !s.V(lvl) { return } @@ -189,6 +191,7 @@ func (s *slogLogger) Log(ctx context.Context, lvl logger.Level, attrs ...interfa } func (s *slogLogger) Logf(ctx context.Context, lvl logger.Level, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", lvl.String()).Inc() if !s.V(lvl) { return } @@ -228,6 +231,7 @@ func (s *slogLogger) Logf(ctx context.Context, lvl logger.Level, msg string, att } func (s *slogLogger) Info(ctx context.Context, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.InfoLevel.String()).Inc() if !s.V(logger.InfoLevel) { return } @@ -249,6 +253,7 @@ func (s *slogLogger) Info(ctx context.Context, attrs ...interface{}) { } func (s *slogLogger) Infof(ctx context.Context, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.InfoLevel.String()).Inc() if !s.V(logger.InfoLevel) { return } @@ -270,6 +275,7 @@ func (s *slogLogger) Infof(ctx context.Context, msg string, attrs ...interface{} } func (s *slogLogger) Debug(ctx context.Context, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.DebugLevel.String()).Inc() if !s.V(logger.DebugLevel) { return } @@ -291,6 +297,7 @@ func (s *slogLogger) Debug(ctx context.Context, attrs ...interface{}) { } func (s *slogLogger) Debugf(ctx context.Context, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.DebugLevel.String()).Inc() if !s.V(logger.DebugLevel) { return } @@ -312,6 +319,7 @@ func (s *slogLogger) Debugf(ctx context.Context, msg string, attrs ...interface{ } func (s *slogLogger) Trace(ctx context.Context, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.TraceLevel.String()).Inc() if !s.V(logger.TraceLevel) { return } @@ -333,6 +341,7 @@ func (s *slogLogger) Trace(ctx context.Context, attrs ...interface{}) { } func (s *slogLogger) Tracef(ctx context.Context, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.TraceLevel.String()).Inc() if !s.V(logger.TraceLevel) { return } @@ -354,6 +363,7 @@ func (s *slogLogger) Tracef(ctx context.Context, msg string, attrs ...interface{ } func (s *slogLogger) Error(ctx context.Context, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.ErrorLevel.String()).Inc() if !s.V(logger.ErrorLevel) { return } @@ -393,6 +403,7 @@ func (s *slogLogger) Error(ctx context.Context, attrs ...interface{}) { } func (s *slogLogger) Errorf(ctx context.Context, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.ErrorLevel.String()).Inc() if !s.V(logger.ErrorLevel) { return } @@ -432,6 +443,7 @@ func (s *slogLogger) Errorf(ctx context.Context, msg string, attrs ...interface{ } func (s *slogLogger) Fatal(ctx context.Context, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.FatalLevel.String()).Inc() if !s.V(logger.FatalLevel) { return } @@ -454,6 +466,7 @@ func (s *slogLogger) Fatal(ctx context.Context, attrs ...interface{}) { } func (s *slogLogger) Fatalf(ctx context.Context, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.FatalLevel.String()).Inc() if !s.V(logger.FatalLevel) { return } @@ -476,6 +489,7 @@ func (s *slogLogger) Fatalf(ctx context.Context, msg string, attrs ...interface{ } func (s *slogLogger) Warn(ctx context.Context, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.WarnLevel.String()).Inc() if !s.V(logger.WarnLevel) { return } @@ -497,6 +511,7 @@ func (s *slogLogger) Warn(ctx context.Context, attrs ...interface{}) { } func (s *slogLogger) Warnf(ctx context.Context, msg string, attrs ...interface{}) { + s.opts.Meter.Counter(semconv.LoggerMessageTotal, "level", logger.WarnLevel.String()).Inc() if !s.V(logger.WarnLevel) { return } diff --git a/meter/options.go b/meter/options.go index 14bcfc69..79ef2a11 100644 --- a/meter/options.go +++ b/meter/options.go @@ -2,8 +2,6 @@ package meter import ( "context" - - "go.unistack.org/micro/v3/logger" ) // Option powers the configuration for metrics implementations: @@ -11,8 +9,6 @@ type Option func(*Options) // Options for metrics implementations type Options struct { - // Logger used for logging - Logger logger.Logger // Context holds external options Context context.Context // Name holds the meter name @@ -39,7 +35,6 @@ func NewOptions(opt ...Option) Options { Address: DefaultAddress, Path: DefaultPath, Context: context.Background(), - Logger: logger.DefaultLogger, MetricPrefix: DefaultMetricPrefix, LabelPrefix: DefaultLabelPrefix, } @@ -95,13 +90,6 @@ func TimingObjectives(value map[float64]float64) Option { } */ -// Logger sets the logger -func Logger(l logger.Logger) Option { - return func(o *Options) { - o.Logger = l - } -} - // Labels sets the meter labels func Labels(ls ...string) Option { return func(o *Options) { diff --git a/semconv/logger.go b/semconv/logger.go new file mode 100644 index 00000000..88ef668f --- /dev/null +++ b/semconv/logger.go @@ -0,0 +1,4 @@ +package semconv + +// LoggerMessageTotal specifies meter metric name for logger messages +var LoggerMessageTotal = "logger_message_total"