pyroscope.scrape
pyroscope.scrape collects pprof performance profiles for a given set of HTTP targets.
pyroscope.scrape mimics the scraping behavior of prometheus.scrape.
Similarly to how Prometheus scrapes metrics via HTTP, pyroscope.scrape collects profiles via HTTP requests.
Unlike Prometheus, which usually only scrapes one /metrics endpoint per target, pyroscope.scrape may need to scrape multiple endpoints for the same target.
This is because the component scrapes different profile types from different endpoints.
For example, the component may scrape mutex profiles from a /debug/pprof/delta_mutex HTTP endpoint, and memory consumption from a /debug/pprof/allocs HTTP endpoint.
You can configure the profile paths, protocol scheme, scrape interval, scrape timeout, query parameters, and any other settings within pyroscope.scrape.
The pyroscope.scrape component regards a scrape as successful if it responded with an HTTP 200 OK status code and returned the body of a valid pprof profile.
If a scrape request fails, the debug UI for pyroscope.scrape shows:
- Detailed information about the failure.
- The time of the last successful scrape.
- The labels last used for scraping.
The component can forward the scraped performance profiles to components such as pyroscope.write through the forward_to argument.
You can specify multiple pyroscope.scrape components by giving them different labels.
Usage
pyroscope.scrape "<LABEL>" {
targets = <TARGET_LIST>
forward_to = <RECEIVER_LIST>
}Arguments
pyroscope.scrape starts a scrape job to scrape all of the input targets.
The component can start multiple scrape jobs for a single input target when it scrapes multiple profile types.
You can use the following arguments with pyroscope.scrape:
You can provide at most one of the following:
authorizationblockbasic_authblockbearer_token_fileargumentbearer_tokenargumentoauth2block
Any omitted arguments take on their default values.
If you pass conflicting arguments, for example, configuring both bearer_token and bearer_token_file, then pyroscope.scrape fails to start and reports an error.
no_proxy can contain IPs, CIDR notations, and domain names. IP and domain names can contain port numbers.
proxy_url must be configured if no_proxy is configured.
proxy_from_environment uses the environment variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY (or the lowercase versions thereof).
Requests use the proxy from the environment variable matching their scheme, unless excluded by NO_PROXY.
proxy_url and no_proxy must not be configured if proxy_from_environment is configured.
proxy_connect_header should only be configured if proxy_url or proxy_from_environment are configured.
job_name
The job_name argument defaults to the component’s unique identifier.
For example, the job_name of pyroscope.scrape "local" { ... } is "pyroscope.scrape.local".
targets
You can define the list of targets statically, dynamically, or as a combination of both.
The following special labels can change the behavior of pyroscope.scrape:
__address__is the special label that must always be present and corresponds to the<host>:<port>that’s used for the scrape request.__name__is the special label that indicates which profile type the component collects.__profile_path__is the special label that holds the path to the profile endpoint on the target (for example, “/debug/pprof/allocs”).__profile_path_prefix__is the special label that holds an optional prefix to prepend to the profile path (for example,"/mimir-prometheus").service_nameis a required label that identifies the service you profile.
The component treats labels that start with a double underscore as internal and removes them before scraping.
Every profile carries a service_name label.
You can set it on the target yourself.
If you don’t, pyroscope.scrape adds the label and infers a value from the following sources, in this order:
__meta_kubernetes_pod_annotation_pyroscope_io_service_namewhich is apyroscope.io/service_namePod annotation.__meta_kubernetes_namespaceand__meta_kubernetes_pod_container_name__meta_docker_container_name__meta_dockerswarm_container_label_service_nameor__meta_dockerswarm_service_name
When you don’t set service_name and the component can’t infer a value, it uses unspecified.
The component injects the following labels into the scraped profiles so that you can link them to a scrape target:
Alloy only sets otel.scope.name and otel.scope.version if they aren’t already present on the scraped profile.
otel.scope.version is only set when otel.scope.name matches the default value.
scrape_interval
The scrape_interval typically refers to the frequency with which Alloy collects performance profiles from the monitored targets.
It represents the time interval between consecutive scrapes or data collection events.
This parameter is important for controlling the trade-off between resource usage and the freshness of the collected data.
If scrape_interval is short:
- Advantages:
- The component loses fewer profiles if the scraped application crashes.
- Disadvantages:
- Greater consumption of CPU, memory, and network resources during scrapes and remote writes.
- The backend database (Pyroscope) consumes more storage space.
If scrape_interval is long:
- Advantages:
- Lower resource consumption.
- Disadvantages:
- The component loses more profiles if the scraped application crashes.
- If you set the delta argument to
true, the batch size of each remote write to Pyroscope may be bigger. You may need to tune the Pyroscope database with higher limits. - If you set the delta argument to
true, you run a larger risk of reaching the HTTP server timeouts of the scraped application.
For example, consider this situation:
- You configure
pyroscope.scrapewith ascrape_intervalof"60s". - The scraped application runs an HTTP server with a timeout of 30 seconds.
- Any scrape HTTP requests where you set the delta argument to
truefail, because they attempt to run for 59 seconds.
Blocks
You can use the following blocks with pyroscope.scrape:
No valid configuration blocks found.
Any omitted blocks take on their default values.
For example, if you don’t specify profile.mutex in the configuration, the component uses the defaults documented in profile.mutex.
authorization
credential and credentials_file are mutually exclusive, and only one can be provided inside an authorization block.
Warning
Using
credentials_filecauses the file to be read on every outgoing request. Use thelocal.filecomponent with thecredentialsattribute instead to avoid unnecessary reads.
basic_auth
When you use password_file, the file is read on every outgoing request that uses basic authentication.
password and password_file are mutually exclusive, and only one can be provided inside a basic_auth block.
Note
High scrape or write rates create repeated file reads when you use
password_file. You can use thelocal.filecomponent to read the password file and provide the content to thepasswordattribute. This avoids repeated file reads becauselocal.filemonitors the file and reads when it changes.
clustering
When Alloy is using clustering, and you set enabled to true, this pyroscope.scrape component instance opts in to participating in the cluster to distribute scrape load between all cluster nodes.
Clustering causes the set of targets to be locally filtered down to a unique subset per node, where each node is roughly assigned the same number of targets. If the state of the cluster changes, such as when a node joins, the cluster recalculates the subset of targets to scrape per node.
When you enable clustering mode, all Alloy instances participating in the cluster must use the same configuration file and have access to the same service discovery APIs.
If Alloy is not running in clustered mode, this block is a no-op.
oauth2
client_secret and client_secret_file are mutually exclusive, and only one can be provided inside an oauth2 block.
Warning
Using
client_secret_filecauses the file to be read on every outgoing request. Use thelocal.filecomponent with theclient_secretattribute instead to avoid unnecessary reads.
The oauth2 block may also contain a separate tls_config sub-block.
no_proxy can contain IPs, CIDR notations, and domain names. IP and domain names can contain port numbers.
proxy_url must be configured if no_proxy is configured.
proxy_from_environment uses the environment variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY (or the lowercase versions thereof).
Requests use the proxy from the environment variable matching their scheme, unless excluded by NO_PROXY.
proxy_url and no_proxy must not be configured if proxy_from_environment is configured.
proxy_connect_header should only be configured if proxy_url or proxy_from_environment are configured.
profiling_config
The profiling_config block configures the profiling settings when scraping targets.
You can use the following arguments with the profiling_config block:
profile.block
The profile.block block collects profiles on process blocking.
You can use the following arguments with the profile.block block:
For more information about the delta argument, see the delta argument section.
profile.custom
The profile.custom block collects profiles from custom endpoints.
You must give each block a label:
profile.custom "<PROFILE_TYPE>" {
enabled = true
path = "<PROFILE_PATH>"
}You can specify multiple profile.custom blocks.
Labels assigned to profile.custom blocks must be unique across the component.
You can use the following arguments with the profile.custom block:
When the delta argument is true, a seconds query parameter is automatically added to requests.
The seconds used is equal to scrape_interval - 1.
profile.fgprof
The profile.fgprof block collects profiles from an fgprof endpoint.
You can use the following arguments with the profile.fgprof block:
For more information about the delta argument, see the delta argument section.
profile.godeltaprof_block
The profile.godeltaprof_block block collects profiles from the godeltaprof block endpoint. The target computes the delta.
You can use the following arguments with the profile.godeltaprof_block block:
profile.godeltaprof_memory
The profile.godeltaprof_memory block collects profiles from the godeltaprof memory endpoint. The target computes the delta.
You can use the following arguments with the profile.godeltaprof_memory block:
profile.godeltaprof_mutex
The profile.godeltaprof_mutex block collects profiles from the godeltaprof mutex endpoint.
The target computes the delta.
You can use the following arguments with the profile.godeltaprof_mutex block:
profile.goroutine
The profile.goroutine block collects profiles on the number of goroutines.
You can use the following arguments with the profile.goroutine block:
Refer to delta argument for more information about the delta argument.
profile.memory
The profile.memory block collects profiles on memory consumption.
You can use the following arguments with the profile.memory block:
Refer to delta argument for more information about the delta argument.
profile.mutex
The profile.mutex block collects profiles on mutexes.
You can use the following arguments with the profile.mutex block:
Refer to delta argument for more information about the delta argument.
profile.process_cpu
The profile.process_cpu block collects profiles on CPU consumption for the process.
You can use the following arguments with the profile.process_cpu block:
For more information about the delta argument, see the delta argument section.
tls_config
The following pairs of arguments are mutually exclusive and can’t both be set simultaneously:
ca_pemandca_filecert_pemandcert_filekey_pemandkey_file
When configuring client authentication, both the client certificate (using cert_pem or cert_file) and the client key (using key_pem or key_file) must be provided.
When min_version isn’t provided, the minimum acceptable TLS version is inherited from Go’s default minimum version, TLS 1.2.
If min_version is provided, it must be set to one of the following strings:
"TLS10"(TLS 1.0)"TLS11"(TLS 1.1)"TLS12"(TLS 1.2)"TLS13"(TLS 1.3)
Caution
If you set
insecure_skip_verifytotrue, you disable verification of the server’s certificate chain and hostname. Alloy accepts any certificate the server presents, including expired, self-signed, or invalid certificates.You can use
insecure_skip_verifyfor local development, self-signed certificates, or endpoints that use a private CA outside the system trust store. If the hostname doesn’t match the certificate, setserver_nameinstead ofinsecure_skip_verify. In production, useca_fileorca_pemto trust a private CA instead ofinsecure_skip_verify.Set
insecure_skip_verifytotrueonly in isolated development or testing environments where you don’t transmit sensitive data. Remove the setting before you deploy to production.
Common configuration
The following configuration applies across the profile types described in Blocks.
delta argument
When the delta argument is false, the pprof HTTP query is instantaneous.
When the delta argument is true:
- The pprof HTTP query runs for a certain amount of time.
- A
secondsparameter is automatically added to the HTTP request. - The default value for the
secondsquery parameter isscrape_interval - 1. If you setdelta_profiling_duration, thensecondstakes the same value asdelta_profiling_duration. However, thedelta_profiling_durationcan’t be larger thanscrape_interval. For example, if you setscrape_intervalto"15s", thensecondsdefaults to14sIf you setdelta_profiling_durationto16s, then you must setscrape_intervalto at least17s. If the HTTP endpoint is/debug/pprof/profile, then the HTTP query becomes/debug/pprof/profile?seconds=14
Exported fields
pyroscope.scrape doesn’t export any fields.
Component health
pyroscope.scrape is only reported as unhealthy if given an invalid configuration.
In those cases, exported fields retain their last healthy values.
Debug information
pyroscope.scrape reports the status of the last scrape for each configured scrape job on the component’s debug endpoint.
Debug metrics
The following Prometheus metrics are exposed:
Examples
The following examples show how to scrape profiles from static and dynamically discovered targets, and how to enable and disable specific profile types.
Default endpoints of static targets
The following example sets up a scrape job of a statically configured list of targets - Alloy itself and Pyroscope.
The component sends the scraped profiles to pyroscope.write, which remote writes them to a Pyroscope database.
pyroscope.scrape "local" {
targets = [
{"__address__" = "localhost:4040", "service_name"="pyroscope"},
{"__address__" = "localhost:12345", "service_name"="alloy"},
]
forward_to = [pyroscope.write.local.receiver]
}
pyroscope.write "local" {
endpoint {
url = "http://pyroscope:4040"
}
}The component scrapes these endpoints every 15 seconds:
http://localhost:4040/debug/pprof/allocs
http://localhost:4040/debug/pprof/block
http://localhost:4040/debug/pprof/goroutine
http://localhost:4040/debug/pprof/mutex
http://localhost:4040/debug/pprof/profile?seconds=14
http://localhost:12345/debug/pprof/allocs
http://localhost:12345/debug/pprof/block
http://localhost:12345/debug/pprof/goroutine
http://localhost:12345/debug/pprof/mutex
http://localhost:12345/debug/pprof/profile?seconds=14The component adds seconds=14 to the /debug/pprof/profile endpoint, because:
- The
deltaargument of theprofile.process_cpublock istrueby default. scrape_intervalis"15s"by default.
The component doesn’t scrape the /debug/fgprof endpoint, because the enabled argument of the profile.fgprof block is false by default.
Default endpoints of dynamic targets
discovery.http "dynamic_targets" {
url = "https://example.com/scrape_targets"
refresh_interval = "15s"
}
pyroscope.scrape "local" {
targets = [discovery.http.dynamic_targets.targets]
forward_to = [pyroscope.write.local.receiver]
}
pyroscope.write "local" {
endpoint {
url = "http://pyroscope:4040"
}
}Default endpoints of static and dynamic targets
discovery.http "dynamic_targets" {
url = "https://example.com/scrape_targets"
refresh_interval = "15s"
}
pyroscope.scrape "local" {
targets = array.concat([
{"__address__" = "localhost:4040", "service_name"="pyroscope"},
{"__address__" = "localhost:12345", "service_name"="alloy"},
], discovery.http.dynamic_targets.targets)
forward_to = [pyroscope.write.local.receiver]
}
pyroscope.write "local" {
endpoint {
url = "http://pyroscope:4040"
}
}Enable and disable profiles
pyroscope.scrape "local" {
targets = [
{"__address__" = "localhost:12345", "service_name"="alloy"},
]
profiling_config {
profile.fgprof {
enabled = true
}
profile.block {
enabled = false
}
profile.mutex {
enabled = false
}
}
forward_to = [pyroscope.write.local.receiver]
}The component scrapes these endpoints every 15 seconds:
http://localhost:12345/debug/pprof/allocs
http://localhost:12345/debug/pprof/goroutine
http://localhost:12345/debug/pprof/profile?seconds=14
http://localhost:12345/debug/fgprof?seconds=14These endpoints are NOT scraped because they’re explicitly disabled:
http://localhost:12345/debug/pprof/block
http://localhost:12345/debug/pprof/mutexCompatible components
pyroscope.scrape can accept arguments from the following components:
- Components that export Targets
- Components that export Pyroscope
ProfilesReceiver
Note
Connecting some components may not be sensible or components may require further configuration to make the connection work correctly. Refer to the linked documentation for more details.


