Skip to content

feat(go.d/prometheus): add relabeling engine#22660

Draft
ilyam8 wants to merge 2 commits into
netdata:masterfrom
ilyam8:feat/prometheus-relabeling
Draft

feat(go.d/prometheus): add relabeling engine#22660
ilyam8 wants to merge 2 commits into
netdata:masterfrom
ilyam8:feat/prometheus-relabeling

Conversation

@ilyam8
Copy link
Copy Markdown
Member

@ilyam8 ilyam8 commented Jun 8, 2026

Test Plan

Fixes: #22636

Additional Information
For users: How does this change affect me?

Summary by cubic

Adds a per-sample transform hook for Prometheus metric relabeling and replaces the old streaming API. Scrape() behavior stays the same, while ScrapeWithTransform(ctx, transform) adds context cancellation and safe in-place label edits.

  • New Features

    • Added ScrapeWithTransform(ctx, SampleTransform); runs before family assembly. nil transform behaves like Scrape().
    • Threaded context.Context into HTTP fetch via req.WithContext.
    • Parser owns labels only when a transform is provided, enabling in-place mutation without extra allocs otherwise.
    • Removed legacy ScrapeStream/parseToStream; tests consolidated and benchmarks updated.
  • Migration

    • Replace ScrapeStream usage with ScrapeWithTransform(ctx, transform). Return (sample, true, nil) to keep, (_, false, nil) to drop, or an error to abort.
    • If you relied on HELP callbacks, read HELP from the returned metric families.

Written for commit 1bfb64b. Summary will update on new commits.

Review in cubic

ilyam8 added 2 commits June 8, 2026 12:29
ScrapeStream now takes a context.Context and threads it into the HTTP request
via req.WithContext, so a streaming consumer can cancel or deadline a scrape.
The method had no callers, so the signature change is contained.

Scrape() and ScrapeSeries() keep their signatures and pass context.Background()
to the shared fetch helper, so their behavior is unchanged.
Add a per-sample transform hook for Prometheus-style metric relabeling and remove
the unused ScrapeStream callback API it supersedes.

- type SampleTransform func(Sample) (Sample, bool, error): keep (optionally mutated
  -- rewrite Name or mutate Labels in place), drop, or abort the scrape.
- ScrapeWithTransform(ctx, transform) (MetricFamilies, error) on the Prometheus
  interface; Scrape() is now ScrapeWithTransform(ctx, nil), so both share one
  assembly path.
- parseToMetricFamilies(text, transform): with a transform it sets ownLabels=true so
  the transform can mutate each sample's labels safely; with nil it keeps the
  no-allocation fast path. The transform runs before the assembler.
- Remove ScrapeStream + parseToStream (no production callers); stream.go held only
  ScrapeStream, so it is removed; the exposition-order/deferral caveat moves to
  ScrapeWithTransform's doc.
- Consolidate the parser tests into parse_test.go (stream_test.go no longer maps to a
  distinct surface); the parser benchmark measures the transform path.
@github-actions github-actions Bot added area/collectors Everything related to data collection collectors/go.d area/go labels Jun 8, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 9 files

Confidence score: 4/5

  • This PR appears safe to merge with minimal risk: the only reported issue is moderate severity (5/10) and does not indicate a likely functional break for normal scrape behavior.
  • In src/go/pkg/prometheus/client.go, fetch() ignores cancellation in the file-read branch, so a canceled context may continue a file scrape instead of stopping promptly, which can affect responsiveness under cancellation/timeouts.
  • Pay close attention to src/go/pkg/prometheus/client.go - ensure context cancellation is honored in the file-read path to avoid non-interruptible scrapes.
Architecture diagram
sequenceDiagram
    participant Client as Consumer Code
    participant Prom as Prometheus
    participant Fetch as HTTP/File Fetcher
    participant Parser as PromTextParser
    participant Xform as SampleTransform (callback)
    participant Asm as Assembler

    Note over Client,Asm: NEW: ScrapeWithTransform replaces ScrapeStream

    alt Happy Path – No Transform
        Client->>Prom: Scrape()
        Prom->>Prom: delegates to ScrapeWithTransform(ctx.Background(), nil)
        Note over Prom,Fetch: CHANGED: fetch now accepts context
        Prom->>Fetch: fetch(ctx, buf)
        alt HTTP URL
            Fetch->>Fetch: req = req.WithContext(ctx)
            Fetch->>Fetch: HTTP GET
        else File Path
            Fetch->>Fetch: file read
        end
        Fetch-->>Prom: raw bytes
        Prom->>Parser: parseToMetricFamilies(text, nil)
        Note over Parser: ownLabels = false
        Parser->>Asm: applySample (copies labels)
        Asm-->>Parser: MetricFamilies
        Parser-->>Prom: MetricFamilies
        Prom-->>Client: MetricFamilies
    else Happy Path – With Transform
        Client->>Prom: ScrapeWithTransform(ctx, transform)
        Prom->>Fetch: fetch(ctx, buf)
        Fetch-->>Prom: raw bytes
        Prom->>Parser: parseToMetricFamilies(text, transform)
        Note over Parser: ownLabels = true
        loop Each Sample in Exposition Order
            Parser->>Xform: transform(sample)
            alt Keep
                Xform-->>Parser: (mutated sample, true, nil)
                Parser->>Asm: applySample(kept sample)
            else Drop
                Xform-->>Parser: (_, false, nil)
                Note over Parser: sample dropped
            else Error
                Xform-->>Parser: (_, false, error)
                Note over Parser: abort scrape
                Parser->>Prom: error
                Prom-->>Client: error
            end
        end
        Asm-->>Parser: MetricFamilies (only kept samples)
        Parser-->>Prom: MetricFamilies
        Prom-->>Client: MetricFamilies
    end

    Note over Client,Asm: REMOVED: ScrapeStream(onHelp, onSample) – now inline in transform

    opt Context Cancellation
        Fetch->>Fetch: request cancelled by ctx
        Fetch-->>Prom: HTTP error
        Prom-->>Client: error
    end
Loading

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/go/pkg/prometheus/client.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/collectors Everything related to data collection area/go collectors/go.d

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Add Prometheus-compatible metric relabeling to the go.d Prometheus collector

1 participant