Repository navigation
Conversation
New module external/prometheus with PrometheusReporter, a Storm V2 StormReporter which serves the metrics of each worker over HTTP for Prometheus to scrape. Storm only ships Console, CSV, JMX and Graphite reporters for the topology metrics; with JMX or Graphite the dimensions end up flattened in the metric names and have to be mapped back to labels with regular expressions. Storm passes its reporters a MetricRegistryProvider, which gives the metrics of each task with their dimensions. These become the labels topology, host, port, component, task and stream, so a metric reported by several tasks ends up in a single family: - a scoped metric such as fetcher_counter.status_200 becomes fetcher_counter with scope="status_200" - a gauge whose value is a map, such as status.count, becomes status_count with a key label per entry - Storm's own metrics such as __ack-count-spout:default become storm_ack_count with source_component and stream labels; the .m1_rate gauges registered next to Storm's counters are skipped Counters and meters are exposed as counters, histograms and timers as summaries with a _max and a _mean gauge, timers in seconds. Each worker listens on its port plus port.offset (1000 by default), using the worker.port system property set by the supervisor. In local mode the workers share a single endpoint on the port given by port, 9400 by default. The JVM metrics are exposed too unless jvm.metrics is false. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
Author
|
@rzo1 move upstream to Apache Storm instead? |
Contributor
Yes, adding it upstream make sense. Think all can benefit from it. |
Contributor
Author
|
done in apache/storm#9158 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
StormCrawler can register its metrics with the Storm V2 API (
stormcrawler.metrics.version: "v2"or"both"), but Storm only ships Console, CSV, JMX and Graphite reporters for them. Storm'sstorm-metrics-prometheusmodule only pushes the Nimbus cluster summary metrics to a Pushgateway. With JMX or Graphite, the dimensions end up flattened in names likestorm.worker.<topology>.<host>.<component>.<task>.<port>-fetcher_counter.status_200, which have to be mapped back to labels with regular expressions.This adds a new module,
external/prometheus, withPrometheusReporter, a V2StormReporterwhich serves the metrics of each worker over HTTP for Prometheus to scrape.How it works
Storm passes its reporters a
MetricRegistryProvider, whosegetTaskMetrics()gives the metrics of each task under their short name along with the task's dimensions. These become labels directly (topology,host,port,component,task,stream), so a metric reported by several tasks ends up in a single family, without any name parsing:fetcher_counter.status_200) become the familyfetcher_counterwith ascopelabel. Only the first dot separates the scope, sofetcher_counter.robots.fetchedhasscope="robots.fetched".status.countfromStatusMetricsBolt, become a family named after the whole metric (status_count) with akeylabel per entry.__ack-count-spout:default) becomestorm_ack_countwithsource_componentandstreamlabels. The.m1_rategauges Storm registers next to its counters are skipped, since Prometheus computes rates from the counters._maxand a_meangauge. Timers are converted to seconds.Configuration
Each worker listens on its port plus
port.offset(7700 for a worker on 6700), using theworker.portsystem property set by the supervisor, so Prometheus scrapes one target per slot. In local mode, where the worker port is unknown, the workers share a single endpoint onport(9400 by default). The JVM metrics (memory, GC, threads,process_start_time_seconds) are exposed as well unlessjvm.metricsis false, and the usual Stormfilterapplies. See the module's README.Testing
PrometheusReporterTeststarts a realStormMetricRegistry, registers a metric of each type (including a map gauge and one of Storm's rate counters), scrapes the HTTP endpoint and checks the samples.Known limitations
_sum; use the_meangauge instead.ack-count,process-latency...), which holds for all of Storm's current ones.memory{scope="heap.used"}. The JVM metrics cover the same ground.cache.hitsandcache.missesfromAbstractStatusUpdaterBoltare reset on read, which is fixed separately in AbstractStatusUpdaterBolt: report cache hits/misses with a counter, not reset-on-read gauges #2229.🤖 Generated with Claude Code