Skip to content

collector: add reusable runtime wrapper - #3661

Open
nicolastakashi wants to merge 2 commits into
prometheus:masterfrom
nicolastakashi:embeddable-runtime-foundation
Open

nicolastakashi wants to merge 2 commits into
prometheus:masterfrom
nicolastakashi:embeddable-runtime-foundation

Conversation

@nicolastakashi

@nicolastakashi nicolastakashi commented May 19, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This continues the incremental refactor to make node_exporter easier to embed outside the standalone binary.
The broader goal is to support ongoing work to make Prometheus exporters embeddable inside the Prometheus OpenTelemetry Collector distribution as native receivers, without requiring each exporter to be rewritten as an OpenTelemetry component.
This PR builds on the reusable config package by adding a runtime layer that downstream callers can construct directly from config, independent of CLI parsing and HTTP serving.
Specifically, this PR:

  • adds collector.Runtime as a reusable wrapper around NodeCollector
  • validates reusable config at runtime construction time
  • exposes embeddable APIs for:
    • collector access via Collectors()
    • registry creation via Registry()
    • enabled collector discovery via EnabledCollectors()
  • adds unit tests covering runtime construction, validation, and registry gathering

Why

Today, node_exporter collector construction is tied closely to the binary wiring. Introducing a reusable runtime layer is a small but important step toward separating:

  • binary concerns such as flags, HTTP serving, and process setup
  • reusable exporter concerns such as config validation, collector construction, and metric registry assembly
    This does not make node_exporter fully embeddable yet. In particular, collector-specific process-global configuration and state still need follow-up refactors. The intent here is to establish a reusable runtime API that future changes can build on.

Stack

This PR is part of a stacked series:

@nicolastakashi

Copy link
Copy Markdown
Contributor Author

@nicolastakashi

Copy link
Copy Markdown
Contributor Author

@ArthurSens

Copy link
Copy Markdown
Member

Anything I could do to unblock this PR? :)

@nicolastakashi
nicolastakashi force-pushed the embeddable-runtime-foundation branch from bd1a15e to e49dc09 Compare October 29, 2026 21:13
Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
Signed-off-by: Nicolas Takashi <nicolas.tcs@hotmail.com>
@nicolastakashi
nicolastakashi force-pushed the embeddable-runtime-foundation branch from e49dc09 to c9b5d35 Compare October 29, 2026 21:19
@nicolastakashi
nicolastakashi marked this pull request as ready for review October 29, 2026 21:32
@nicolastakashi

Copy link
Copy Markdown
Contributor Author

@ArthurSens PTAL

@ArthurSens ArthurSens left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good start :)

I noticed a bug with collector state still depending on global variables, which prevent us from doing something like this:

receivers:
  nodeexporter/cpu:
    scrape_interval: 10s
    exporter_config:
      collectors:
        cpu: true
        filesystem: false
        # Other collectors disabled.

  nodeexporter/filesystem:
    scrape_interval: 60s
    exporter_config:
      collectors:
        cpu: false
        filesystem: true
        # Other collectors disabled.

because both runtimes would be overriding each others enabled collectors state

Comment thread collector/runtime.go
Comment on lines +27 to +29
type Runtime struct {
collector *NodeCollector
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe the collectors' enable/disabled state also needs to be part of the runtime object so multiple runtimes don't affect each other.

Comment thread config/config.go
Comment on lines +27 to +29
WebTelemetryPath string
WebDisableExporterMetrics bool
WebMaxRequests int

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These configuration options don't seem related to configuring the metric collection, could we leave them out?

Comment thread config/config.go
WebDisableExporterMetrics bool
WebMaxRequests int
CollectorDisableDefaults bool
RuntimeGoMaxProcs int

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This one also seems unrelated to metric collection

Comment thread config/config.go
WebMaxRequests int
CollectorDisableDefaults bool
RuntimeGoMaxProcs int
EnabledCollectors []string

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Besides enabling/disabling collectors, it seems like we're missing a lot of config pieces that are specific to one single collector that also need to be here.

For example, we have --collector.textfile.directory, and this isn't present here, therefore we won't be able to configure this option whem embedding node exporter

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You can take a look at another similar PR in another exporter: prometheus/mysqld_exporter#1043

we have things like this:

type Config struct {
    Collectors            map[string]bool
    InfoSchemaProcesslist InfoSchemaProcesslistConfig
    // ...
}

type InfoSchemaProcesslistConfig struct {
    MinTime         int
    ProcessesByUser bool
    ProcessesByHost bool
}

where infoSchemaProcesslistConfig is one of many collectors in MySQL exporter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants