diff --git a/pkg/plugins/manager/loader/finder/finder.go b/pkg/plugins/manager/loader/finder/finder.go index bbe58e730c3..e8f0bbccd87 100644 --- a/pkg/plugins/manager/loader/finder/finder.go +++ b/pkg/plugins/manager/loader/finder/finder.go @@ -12,14 +12,13 @@ import ( "github.com/grafana/grafana/pkg/util" ) -var logger = log.New("plugin.finder") - type Finder struct { cfg *setting.Cfg + log log.Logger } func New(cfg *setting.Cfg) Finder { - return Finder{cfg: cfg} + return Finder{cfg: cfg, log: log.New("plugin.finder")} } func (f *Finder) Find(pluginDirs []string) ([]string, error) { @@ -28,10 +27,10 @@ func (f *Finder) Find(pluginDirs []string) ([]string, error) { for _, dir := range pluginDirs { exists, err := fs.Exists(dir) if err != nil { - logger.Warn("Error occurred when checking if plugin directory exists", "dir", dir, "err", err) + f.log.Warn("Error occurred when checking if plugin directory exists", "dir", dir, "err", err) } if !exists { - logger.Warn("Skipping finding plugins as directory does not exist", "dir", dir) + f.log.Warn("Skipping finding plugins as directory does not exist", "dir", dir) continue } @@ -76,11 +75,11 @@ func (f *Finder) getPluginJSONPaths(dir string) ([]string, error) { return nil }); err != nil { if errors.Is(err, os.ErrNotExist) { - logger.Debug("Couldn't scan directory since it doesn't exist", "pluginDir", dir, "err", err) + f.log.Debug("Couldn't scan directory since it doesn't exist", "pluginDir", dir, "err", err) return []string{}, nil } if errors.Is(err, os.ErrPermission) { - logger.Debug("Couldn't scan directory due to lack of permissions", "pluginDir", dir, "err", err) + f.log.Debug("Couldn't scan directory due to lack of permissions", "pluginDir", dir, "err", err) return []string{}, nil } diff --git a/pkg/plugins/manager/loader/initializer/initializer.go b/pkg/plugins/manager/loader/initializer/initializer.go index 4f9db49169d..ee7993158fc 100644 --- a/pkg/plugins/manager/loader/initializer/initializer.go +++ b/pkg/plugins/manager/loader/initializer/initializer.go @@ -23,17 +23,17 @@ import ( "github.com/grafana/grafana/pkg/util" ) -var logger = log.New("plugin.initializer") - type Initializer struct { cfg *setting.Cfg license models.Licensing + log log.Logger } func New(cfg *setting.Cfg, license models.Licensing) Initializer { return Initializer{ cfg: cfg, license: license, + log: log.New("plugin.initializer"), } } @@ -80,7 +80,7 @@ func (i *Initializer) Initialize(p *plugins.Plugin) error { } } - pluginLog := logger.New("pluginID", p.ID) + pluginLog := i.log.New("pluginID", p.ID) p.SetLogger(pluginLog) if p.Backend { @@ -123,7 +123,7 @@ func (i *Initializer) InitializeWithFactory(p *plugins.Plugin, factory backendpl } p.RegisterClient(f) } else { - logger.Warn("Could not initialize core plugin process", "pluginID", p.ID) + i.log.Warn("Could not initialize core plugin process", "pluginID", p.ID) return fmt.Errorf("could not initialize plugin %s", p.ID) } diff --git a/pkg/plugins/manager/loader/initializer/initializer_test.go b/pkg/plugins/manager/loader/initializer/initializer_test.go index 8e93158a3fb..65c575e4a51 100644 --- a/pkg/plugins/manager/loader/initializer/initializer_test.go +++ b/pkg/plugins/manager/loader/initializer/initializer_test.go @@ -5,6 +5,7 @@ import ( "path/filepath" "testing" + "github.com/inconshreveable/log15" "github.com/stretchr/testify/assert" "github.com/grafana/grafana/pkg/infra/log" @@ -37,6 +38,7 @@ func TestInitializer_Initialize(t *testing.T) { i := &Initializer{ cfg: setting.NewCfg(), + log: &fakeLogger{}, } err := i.Initialize(p) @@ -71,6 +73,7 @@ func TestInitializer_Initialize(t *testing.T) { i := &Initializer{ cfg: setting.NewCfg(), + log: fakeLogger{}, } err := i.Initialize(p) @@ -117,6 +120,7 @@ func TestInitializer_Initialize(t *testing.T) { cfg: &setting.Cfg{ AppSubURL: "appSubURL", }, + log: fakeLogger{}, } err := i.Initialize(p) @@ -163,6 +167,7 @@ func TestInitializer_InitializeWithFactory(t *testing.T) { cfg: &setting.Cfg{ AppSubURL: "appSubURL", }, + log: fakeLogger{}, } factoryInvoked := false @@ -202,6 +207,7 @@ func TestInitializer_InitializeWithFactory(t *testing.T) { cfg: &setting.Cfg{ AppSubURL: "appSubURL", }, + log: fakeLogger{}, } err := i.InitializeWithFactory(p, nil) @@ -236,6 +242,7 @@ func TestInitializer_envVars(t *testing.T) { }, }, license: licensing, + log: fakeLogger{}, } envVars := i.envVars(p) @@ -252,6 +259,7 @@ func TestInitializer_setPathsBasedOnApp(t *testing.T) { t.Run("When setting paths based on core plugin on Windows", func(t *testing.T) { i := &Initializer{ cfg: setting.NewCfg(), + log: fakeLogger{}, } child := &plugins.Plugin{ @@ -347,3 +355,15 @@ func (t *testLicensingService) Environment() map[string]string { type testPlugin struct { backendplugin.Plugin } + +type fakeLogger struct { + log.Logger +} + +func (f fakeLogger) New(_ ...interface{}) log15.Logger { + return fakeLogger{} +} + +func (f fakeLogger) Warn(_ string, _ ...interface{}) { + +} diff --git a/pkg/plugins/manager/loader/loader.go b/pkg/plugins/manager/loader/loader.go index 6a532743ee5..f04bff52ec1 100644 --- a/pkg/plugins/manager/loader/loader.go +++ b/pkg/plugins/manager/loader/loader.go @@ -21,7 +21,6 @@ import ( ) var ( - logger = log.New("plugin.loader") ErrInvalidPluginJSON = errors.New("did not find valid type or id properties in plugin.json") ErrInvalidPluginJSONFilePath = errors.New("invalid plugin.json filepath was provided") ) @@ -33,6 +32,7 @@ type Loader struct { pluginFinder finder.Finder pluginInitializer initializer.Initializer signatureValidator signature.Validator + log log.Logger errs map[string]*plugins.SignatureError } @@ -48,13 +48,14 @@ func New(license models.Licensing, cfg *setting.Cfg, authorizer plugins.PluginLo pluginInitializer: initializer.New(cfg, license), signatureValidator: signature.NewValidator(authorizer), errs: make(map[string]*plugins.SignatureError), + log: log.New("plugin.loader"), } } func (l *Loader) Load(paths []string, ignore map[string]struct{}) ([]*plugins.Plugin, error) { pluginJSONPaths, err := l.pluginFinder.Find(paths) if err != nil { - logger.Error("plugin finder encountered an error", "err", err) + l.log.Error("plugin finder encountered an error", "err", err) } return l.loadPlugins(pluginJSONPaths, ignore) @@ -63,7 +64,7 @@ func (l *Loader) Load(paths []string, ignore map[string]struct{}) ([]*plugins.Pl func (l *Loader) LoadWithFactory(path string, factory backendplugin.PluginFactoryFunc) (*plugins.Plugin, error) { p, err := l.load(path, map[string]struct{}{}) if err != nil { - logger.Error("failed to load core plugin", "err", err) + l.log.Error("failed to load core plugin", "err", err) return nil, err } @@ -75,7 +76,7 @@ func (l *Loader) LoadWithFactory(path string, factory backendplugin.PluginFactor func (l *Loader) load(path string, ignore map[string]struct{}) (*plugins.Plugin, error) { pluginJSONPaths, err := l.pluginFinder.Find([]string{path}) if err != nil { - logger.Error("failed to find plugin", "err", err) + l.log.Error("failed to find plugin", "err", err) return nil, err } @@ -98,24 +99,24 @@ func (l *Loader) loadPlugins(pluginJSONPaths []string, existingPlugins map[strin for _, pluginJSONPath := range pluginJSONPaths { plugin, err := l.readPluginJSON(pluginJSONPath) if err != nil { - logger.Warn("Skipping plugin loading as it's plugin.json is invalid", "id", plugin.ID) + l.log.Warn("Skipping plugin loading as it's plugin.json is invalid", "id", plugin.ID) continue } pluginJSONAbsPath, err := filepath.Abs(pluginJSONPath) if err != nil { - logger.Warn("Skipping plugin loading as full plugin.json path could not be calculated", "id", plugin.ID) + l.log.Warn("Skipping plugin loading as full plugin.json path could not be calculated", "id", plugin.ID) continue } if _, dupe := foundPlugins[filepath.Dir(pluginJSONAbsPath)]; dupe { - logger.Warn("Skipping plugin loading as it's a duplicate", "id", plugin.ID) + l.log.Warn("Skipping plugin loading as it's a duplicate", "id", plugin.ID) continue } foundPlugins[filepath.Dir(pluginJSONAbsPath)] = plugin } - foundPlugins.stripDuplicates(existingPlugins) + foundPlugins.stripDuplicates(existingPlugins, l.log) // calculate initial signature state loadedPlugins := make(map[string]*plugins.Plugin) @@ -126,9 +127,9 @@ func (l *Loader) loadPlugins(pluginJSONPaths []string, existingPlugins map[strin Class: l.pluginClass(pluginDir), } - sig, err := signature.Calculate(logger, plugin) + sig, err := signature.Calculate(l.log, plugin) if err != nil { - logger.Warn("Could not calculate plugin signature state", "pluginID", plugin.ID, "err", err) + l.log.Warn("Could not calculate plugin signature state", "pluginID", plugin.ID, "err", err) continue } plugin.Signature = sig.Status @@ -163,7 +164,7 @@ func (l *Loader) loadPlugins(pluginJSONPaths []string, existingPlugins map[strin for _, plugin := range loadedPlugins { signingError := l.signatureValidator.Validate(plugin) if signingError != nil { - logger.Warn("Skipping loading plugin due to problem with signature", + l.log.Warn("Skipping loading plugin due to problem with signature", "pluginID", plugin.ID, "status", signingError.SignatureStatus) plugin.SignatureError = signingError l.errs[plugin.ID] = signingError @@ -180,7 +181,7 @@ func (l *Loader) loadPlugins(pluginJSONPaths []string, existingPlugins map[strin if exists, err := fs.Exists(module); err != nil { return nil, err } else if !exists { - logger.Warn("Plugin missing module.js", + l.log.Warn("Plugin missing module.js", "pluginID", plugin.ID, "warning", "Missing module.js, If you loaded this plugin from git, make sure to compile it.", "path", module) @@ -201,7 +202,7 @@ func (l *Loader) loadPlugins(pluginJSONPaths []string, existingPlugins map[strin } func (l *Loader) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error) { - logger.Debug("Loading plugin", "path", pluginJSONPath) + l.log.Debug("Loading plugin", "path", pluginJSONPath) if !strings.EqualFold(filepath.Ext(pluginJSONPath), ".json") { return plugins.JSONData{}, ErrInvalidPluginJSONFilePath @@ -221,7 +222,7 @@ func (l *Loader) readPluginJSON(pluginJSONPath string) (plugins.JSONData, error) } if err := reader.Close(); err != nil { - logger.Warn("Failed to close JSON file", "path", pluginJSONPath, "err", err) + l.log.Warn("Failed to close JSON file", "path", pluginJSONPath, "err", err) } if err := validatePluginJSON(plugin); err != nil { @@ -283,11 +284,11 @@ func (l *Loader) pluginClass(pluginDir string) plugins.Class { type foundPlugins map[string]plugins.JSONData // stripDuplicates will strip duplicate plugins or plugins that already exist -func (f *foundPlugins) stripDuplicates(existingPlugins map[string]struct{}) { +func (f *foundPlugins) stripDuplicates(existingPlugins map[string]struct{}, log log.Logger) { pluginsByID := make(map[string]struct{}) for path, scannedPlugin := range *f { if _, existing := existingPlugins[scannedPlugin.ID]; existing { - logger.Debug("Skipping plugin as it's already installed", "plugin", scannedPlugin.ID) + log.Debug("Skipping plugin as it's already installed", "plugin", scannedPlugin.ID) delete(*f, path) continue } diff --git a/pkg/plugins/manager/loader/loader_test.go b/pkg/plugins/manager/loader/loader_test.go index 9afc6fc748c..dbd75caa2a8 100644 --- a/pkg/plugins/manager/loader/loader_test.go +++ b/pkg/plugins/manager/loader/loader_test.go @@ -12,6 +12,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/stretchr/testify/assert" + "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins/manager/loader/finder" "github.com/grafana/grafana/pkg/plugins/manager/loader/initializer" @@ -887,6 +888,7 @@ func newLoader(cfg *setting.Cfg) *Loader { pluginInitializer: initializer.New(cfg, &fakeLicensingService{}), signatureValidator: signature.NewValidator(&signature.UnsignedPluginAuthorizer{Cfg: cfg}), errs: make(map[string]*plugins.SignatureError), + log: &fakeLogger{}, } } @@ -916,7 +918,7 @@ func (t *fakeLicensingService) ContentDeliveryPrefix() string { return "" } -func (t *fakeLicensingService) LicenseURL(showAdminLicensingPage bool) string { +func (t *fakeLicensingService) LicenseURL(_ bool) string { return "" } @@ -927,3 +929,19 @@ func (t *fakeLicensingService) HasValidLicense() bool { func (t *fakeLicensingService) Environment() map[string]string { return map[string]string{"GF_ENTERPRISE_LICENSE_TEXT": t.tokenRaw} } + +type fakeLogger struct { + log.Logger +} + +func (fl fakeLogger) Info(_ string, _ ...interface{}) { + +} + +func (fl fakeLogger) Debug(_ string, _ ...interface{}) { + +} + +func (fl fakeLogger) Warn(_ string, _ ...interface{}) { + +} diff --git a/pkg/plugins/manager/signature/signature.go b/pkg/plugins/manager/signature/signature.go index ea227e190a1..c1acd6c8c73 100644 --- a/pkg/plugins/manager/signature/signature.go +++ b/pkg/plugins/manager/signature/signature.go @@ -5,37 +5,37 @@ import ( "github.com/grafana/grafana/pkg/plugins" ) -var logger = log.New("plugin.signature.validator") - type Validator struct { authorizer plugins.PluginLoaderAuthorizer + log log.Logger } func NewValidator(authorizer plugins.PluginLoaderAuthorizer) Validator { return Validator{ authorizer: authorizer, + log: log.New("plugin.signature.validator"), } } func (s *Validator) Validate(plugin *plugins.Plugin) *plugins.SignatureError { if plugin.Signature == plugins.SignatureValid { - logger.Debug("Plugin has valid signature", "id", plugin.ID) + s.log.Debug("Plugin has valid signature", "id", plugin.ID) return nil } // If a plugin is nested within another, create links to each other to inherit signature details if plugin.Parent != nil { if plugin.IsCorePlugin() || plugin.Signature == plugins.SignatureInternal { - logger.Debug("Not setting descendant plugin's signature to that of root since it's core or internal", + s.log.Debug("Not setting descendant plugin's signature to that of root since it's core or internal", "plugin", plugin.ID, "signature", plugin.Signature, "isCore", plugin.IsCorePlugin) } else { - logger.Debug("Setting descendant plugin's signature to that of root", "plugin", plugin.ID, + s.log.Debug("Setting descendant plugin's signature to that of root", "plugin", plugin.ID, "root", plugin.Parent.ID, "signature", plugin.Signature, "rootSignature", plugin.Parent.Signature) plugin.Signature = plugin.Parent.Signature plugin.SignatureType = plugin.Parent.SignatureType plugin.SignatureOrg = plugin.Parent.SignatureOrg if plugin.Signature == plugins.SignatureValid { - logger.Debug("Plugin has valid signature (inherited from root)", "id", plugin.ID) + s.log.Debug("Plugin has valid signature (inherited from root)", "id", plugin.ID) return nil } } @@ -48,28 +48,28 @@ func (s *Validator) Validate(plugin *plugins.Plugin) *plugins.SignatureError { switch plugin.Signature { case plugins.SignatureUnsigned: if authorized := s.authorizer.CanLoadPlugin(plugin); !authorized { - logger.Debug("Plugin is unsigned", "pluginID", plugin.ID) + s.log.Debug("Plugin is unsigned", "pluginID", plugin.ID) return &plugins.SignatureError{ PluginID: plugin.ID, SignatureStatus: plugins.SignatureUnsigned, } } - logger.Warn("Permitting unsigned plugin. This is not recommended", "pluginID", plugin.ID, "pluginDir", plugin.PluginDir) + s.log.Warn("Permitting unsigned plugin. This is not recommended", "pluginID", plugin.ID, "pluginDir", plugin.PluginDir) return nil case plugins.SignatureInvalid: - logger.Debug("Plugin has an invalid signature", "pluginID", plugin.ID) + s.log.Debug("Plugin has an invalid signature", "pluginID", plugin.ID) return &plugins.SignatureError{ PluginID: plugin.ID, SignatureStatus: plugins.SignatureInvalid, } case plugins.SignatureModified: - logger.Debug("Plugin has a modified signature", "pluginID", plugin.ID) + s.log.Debug("Plugin has a modified signature", "pluginID", plugin.ID) return &plugins.SignatureError{ PluginID: plugin.ID, SignatureStatus: plugins.SignatureModified, } default: - logger.Debug("Plugin has an unrecognized plugin signature state", "pluginID", plugin.ID, "signature", + s.log.Debug("Plugin has an unrecognized plugin signature state", "pluginID", plugin.ID, "signature", plugin.Signature) return &plugins.SignatureError{ PluginID: plugin.ID,