From 876ecb29c8e90a8b5721d5a7937a30837bd97a6c Mon Sep 17 00:00:00 2001 From: Deluan Date: Mon, 22 Dec 2025 15:30:55 -0500 Subject: [PATCH] feat(plugins): enhance plugin logging and set User-Agent header Signed-off-by: Deluan --- consts/consts.go | 2 ++ core/artwork/sources.go | 1 + plugins/examples/wikimedia/README.md | 22 +++++++++++----------- plugins/manager.go | 9 +++++++-- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/consts/consts.go b/consts/consts.go index fbb2c9429..2d342f909 100644 --- a/consts/consts.go +++ b/consts/consts.go @@ -150,6 +150,8 @@ var ( } ) +var HTTPUserAgent = "Navidrome" + "/" + Version + var ( VariousArtists = "Various Artists" // TODO This will be dynamic when using disambiguation diff --git a/core/artwork/sources.go b/core/artwork/sources.go index 4250a373b..ba0767c07 100644 --- a/core/artwork/sources.go +++ b/core/artwork/sources.go @@ -182,6 +182,7 @@ func fromAlbumExternalSource(ctx context.Context, al model.Album, provider exter func fromURL(ctx context.Context, imageUrl *url.URL) (io.ReadCloser, string, error) { hc := http.Client{Timeout: 5 * time.Second} req, _ := http.NewRequestWithContext(ctx, http.MethodGet, imageUrl.String(), nil) + req.Header.Set("User-Agent", consts.HTTPUserAgent) resp, err := hc.Do(req) if err != nil { return nil, "", err diff --git a/plugins/examples/wikimedia/README.md b/plugins/examples/wikimedia/README.md index 47db0a8e3..ae78fd467 100644 --- a/plugins/examples/wikimedia/README.md +++ b/plugins/examples/wikimedia/README.md @@ -117,20 +117,20 @@ Expected output: ## API Endpoints Used -| Service | Endpoint | Purpose | -|---------|----------|---------| -| Wikidata | `https://query.wikidata.org/sparql` | SPARQL queries for Wikipedia URLs and images | -| DBpedia | `https://dbpedia.org/sparql` | Fallback SPARQL queries for Wikipedia URLs and short bios | -| Wikipedia | `https://en.wikipedia.org/w/api.php` | MediaWiki API for article extracts | +| Service | Endpoint | Purpose | +|-----------|--------------------------------------|-----------------------------------------------------------| +| Wikidata | `https://query.wikidata.org/sparql` | SPARQL queries for Wikipedia URLs and images | +| DBpedia | `https://dbpedia.org/sparql` | Fallback SPARQL queries for Wikipedia URLs and short bios | +| Wikipedia | `https://en.wikipedia.org/w/api.php` | MediaWiki API for article extracts | ## Implemented Functions -| Function | Description | -|----------|-------------| -| `nd_manifest` | Returns plugin manifest with HTTP permissions | -| `nd_get_artist_url` | Returns Wikipedia URL for an artist | -| `nd_get_artist_biography` | Returns artist biography from Wikipedia | -| `nd_get_artist_images` | Returns artist image URLs from Wikidata | +| Function | Description | +|---------------------------|-----------------------------------------------| +| `nd_manifest` | Returns plugin manifest with HTTP permissions | +| `nd_get_artist_url` | Returns Wikipedia URL for an artist | +| `nd_get_artist_biography` | Returns artist biography from Wikipedia | +| `nd_get_artist_images` | Returns artist image URLs from Wikidata | ## License diff --git a/plugins/manager.go b/plugins/manager.go index 075e10a88..d96dd6193 100644 --- a/plugins/manager.go +++ b/plugins/manager.go @@ -449,6 +449,8 @@ func (m *Manager) ReloadPlugin(name string) error { // callPluginFunction is a helper to call a plugin function with input and output types. // It handles JSON marshalling/unmarshalling and error checking. func callPluginFunction[I any, O any](ctx context.Context, plugin *pluginInstance, funcName string, input I) (O, error) { + start := time.Now() + var result O // Create plugin instance @@ -467,9 +469,10 @@ func callPluginFunction[I any, O any](ctx context.Context, plugin *pluginInstanc return result, fmt.Errorf("failed to marshal input: %w", err) } + startCall := time.Now() exit, output, err := p.Call(funcName, inputBytes) if err != nil { - log.Debug(ctx, "Plugin call failed", "p", plugin.name, "function", funcName, err) + log.Trace(ctx, "Plugin call failed", "p", plugin.name, "function", funcName, "pluginDuration", time.Since(startCall), "navidromeDuration", startCall.Sub(start), err) return result, fmt.Errorf("plugin call failed: %w", err) } if exit != 0 { @@ -478,8 +481,10 @@ func callPluginFunction[I any, O any](ctx context.Context, plugin *pluginInstanc err = json.Unmarshal(output, &result) if err != nil { - log.Debug(ctx, "Plugin call failed", "p", plugin.name, "function", funcName, err) + log.Trace(ctx, "Plugin call failed", "p", plugin.name, "function", funcName, "pluginDuration", time.Since(startCall), "navidromeDuration", startCall.Sub(start), err) } + + log.Trace(ctx, "Plugin call succeeded", "p", plugin.name, "function", funcName, "pluginDuration", time.Since(startCall), "navidromeDuration", startCall.Sub(start)) return result, err }