Throttle metrics #26308
QuestionI am not sure if "throttle" is the right word... I have metrics being scraped at 15 seconds interval, but I only want to send metrics to the sink at 45 second granularity. In other words, I only want to keep every third scrape. I cannot change Vector ConfigVector that I do not control: sources:
scrape_metrics:
type: prometheus_scrape
endpoints:
- http://localhost/metrics
scrape_interval_secs: 15
sinks:
send_metrics:
type: vector
inputs:
- scrape_metrics
address: localhost:6000Vector that I control: sources:
receive_metrics:
type: vector
address: localhost:6000
transforms:
throttle_metrics:
type: ???
inputs:
- receive_metrics
scrape_interval_change_to_secs: 45
sinks:
write_metrics:
type: prometheus_remote_write
inputs:
- throttle_metrics
endpoint: http://localhost/insert/0/prometheus/Vector LogsNo response |
Replies: 2 comments 4 replies
|
Hi @ilinas. What you want is basically a synchronous state between events. This is not something we currently support, but there are workarounds. You can invoke external processes/access machine state such as the filesystem using the lua transform. You'd basically have to write a program that returns I spent some time and I come up with a pure Vector configuration without a lua transform, which leverages enrichment tables to keep internal state between events. Keep in mind that this is also very prone to a race condition - namely if an event comes in less than 3 seconds after another one. sources:
receive_metrics:
type: vector
address: localhost:6000
transforms:
# Memory table only accepts log events
to_log:
type: metric_to_log
inputs: [receive_metrics]
one_per_scrape:
type: dedupe
inputs: [to_log]
fields:
match: [timestamp] # first event per scrape timestamp survives
update_counter:
type: remap
inputs: [one_per_scrape]
source: |
# ?? {} handles a missing record (first get / after a state reset)
rec = get_enrichment_table_record("scrape_counter", {"key": "count"}) ?? {}
current = to_int(rec.value) ?? 0
. = { "count": current + 1 }
# This runs concurrently with the counter write. Delay ensures that the
# count gets written before we try to read it in the filter
hold:
type: delay
inputs: [receive_metrics]
delay_ms: 3000
keep_every_third:
type: filter
inputs: [hold]
condition:
type: vrl
source: |
rec = get_enrichment_table_record("scrape_counter", {"key": "count"}) ?? {}
mod(to_int(rec.value) ?? 0, 3) == 0
enrichment_tables:
scrape_counter:
type: memory
inputs: [update_counter]
ttl: 9223372036854775807 # ~292 billion years. We don't want the counter to expire.
sinks:
write_metrics:
type: prometheus_remote_write
inputs: [keep_every_third]
endpoint: http://localhost/insert/0/prometheus/There is also the sample transform, but that one will drop events randomly, not in a predictable manner like you'd like. It doesn't accept metrics so you'd also need a |
|
Thanks @thomasqueirozb. Although I was hoping for a more generic solution. I was thinking, if this was to be implemented as a proper transform, what would be the best approach? One possibility I am considering is to extend the |
Update:
Did some more digging. Looks like that lua transform runs sequentially and is able to retain state between runs. Here is a non-racy configuration that should work for your use case: