Plugins: Remove pkg/infra/log as dependency (#115832)
* remove pkg/infra/log as dependency * add pluginslog * add slog caching
This commit is contained in:
+58
-28
@@ -2,54 +2,84 @@ package log
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"log/slog"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// loggerFactory is a function that creates a Logger given a name.
|
||||
// It can be set by calling SetLoggerFactory to use a custom logger implementation.
|
||||
var loggerFactory func(name string) Logger
|
||||
|
||||
// SetLoggerFactory sets the factory function used to create loggers.
|
||||
// This should be called during initialization to register a custom logger implementation.
|
||||
// If not set, a default slog-based logger will be used.
|
||||
func SetLoggerFactory(factory func(name string) Logger) {
|
||||
loggerFactory = factory
|
||||
}
|
||||
|
||||
var slogLogManager = &slogLoggerManager{
|
||||
cache: sync.Map{},
|
||||
}
|
||||
|
||||
func New(name string) Logger {
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: log.New(name),
|
||||
if loggerFactory != nil {
|
||||
return loggerFactory(name)
|
||||
}
|
||||
// add a caching layer since slog doesn't perform any caching itself
|
||||
return slogLogManager.getOrCreate(name)
|
||||
}
|
||||
|
||||
type grafanaInfraLogWrapper struct {
|
||||
l *log.ConcreteLogger
|
||||
type slogLoggerManager struct {
|
||||
cache sync.Map
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) New(ctx ...any) Logger {
|
||||
func (m *slogLoggerManager) getOrCreate(name string) Logger {
|
||||
if cached, ok := m.cache.Load(name); ok {
|
||||
return cached.(*slogLogger)
|
||||
}
|
||||
|
||||
logger := &slogLogger{
|
||||
logger: slog.Default().With("logger", name),
|
||||
name: name,
|
||||
}
|
||||
actual, _ := m.cache.LoadOrStore(name, logger)
|
||||
return actual.(*slogLogger)
|
||||
}
|
||||
|
||||
type slogLogger struct {
|
||||
logger *slog.Logger
|
||||
name string
|
||||
}
|
||||
|
||||
func (l *slogLogger) New(ctx ...any) Logger {
|
||||
if len(ctx) == 0 {
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: d.l.New(),
|
||||
return &slogLogger{
|
||||
logger: l.logger,
|
||||
name: l.name,
|
||||
}
|
||||
}
|
||||
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: d.l.New(ctx...),
|
||||
return &slogLogger{
|
||||
logger: l.logger.With(ctx...),
|
||||
name: l.name,
|
||||
}
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Debug(msg string, ctx ...any) {
|
||||
d.l.Debug(msg, ctx...)
|
||||
func (l *slogLogger) Debug(msg string, ctx ...any) {
|
||||
l.logger.Debug(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Info(msg string, ctx ...any) {
|
||||
d.l.Info(msg, ctx...)
|
||||
func (l *slogLogger) Info(msg string, ctx ...any) {
|
||||
l.logger.Info(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Warn(msg string, ctx ...any) {
|
||||
d.l.Warn(msg, ctx...)
|
||||
func (l *slogLogger) Warn(msg string, ctx ...any) {
|
||||
l.logger.Warn(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Error(msg string, ctx ...any) {
|
||||
d.l.Error(msg, ctx...)
|
||||
func (l *slogLogger) Error(msg string, ctx ...any) {
|
||||
l.logger.Error(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) FromContext(ctx context.Context) Logger {
|
||||
concreteInfraLogger, ok := d.l.FromContext(ctx).(*log.ConcreteLogger)
|
||||
if !ok {
|
||||
return d.New()
|
||||
}
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: concreteInfraLogger,
|
||||
}
|
||||
func (l *slogLogger) FromContext(_ context.Context) Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings"
|
||||
pluginSettings "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsettings/service"
|
||||
_ "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginslog" // Initialize plugin logger
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsources"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginsso"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore"
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package pluginslog
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
pluginslog "github.com/grafana/grafana/pkg/plugins/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register Grafana's logger implementation for pkg/plugins
|
||||
pluginslog.SetLoggerFactory(func(name string) pluginslog.Logger {
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: log.New(name),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
type grafanaInfraLogWrapper struct {
|
||||
l *log.ConcreteLogger
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) New(ctx ...any) pluginslog.Logger {
|
||||
if len(ctx) == 0 {
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: d.l.New(),
|
||||
}
|
||||
}
|
||||
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: d.l.New(ctx...),
|
||||
}
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Debug(msg string, ctx ...any) {
|
||||
d.l.Debug(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Info(msg string, ctx ...any) {
|
||||
d.l.Info(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Warn(msg string, ctx ...any) {
|
||||
d.l.Warn(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) Error(msg string, ctx ...any) {
|
||||
d.l.Error(msg, ctx...)
|
||||
}
|
||||
|
||||
func (d *grafanaInfraLogWrapper) FromContext(ctx context.Context) pluginslog.Logger {
|
||||
concreteInfraLogger, ok := d.l.FromContext(ctx).(*log.ConcreteLogger)
|
||||
if !ok {
|
||||
return d.New()
|
||||
}
|
||||
return &grafanaInfraLogWrapper{
|
||||
l: concreteInfraLogger,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user