---
title: "pyroscope.java | Grafana Agent documentation"
description: "Learn about pyroscope.java"
---

> For a curated documentation index, see [llms.txt](/llms.txt). For the complete documentation index, see [llms-full.txt](/llms-full.txt).

# pyroscope.java

> **BETA**: This is a [beta](/docs/agent/latest/stability/#beta) component. Beta components are subject to breaking changes, and may be replaced with equivalent functionality that cover the same use case.

`pyroscope.java` continuously profiles Java processes running on the local Linux OS using [async-profiler](https://github.com/async-profiler/async-profiler).

> Note
> 
> To use the `pyroscope.java` component you must run Grafana Agent Flow as root and inside host PID namespace.

## Usage

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
pyroscope.java "LABEL" {
  targets    = TARGET_LIST
  forward_to = RECEIVER_LIST
}
```

## Arguments

The following arguments are supported:

Expand table

| Name         | Type                     | Description                                      | Default | Required |
|--------------|--------------------------|--------------------------------------------------|---------|----------|
| `targets`    | `list(map(string))`      | List of java process targets to profile.         |         | yes      |
| `forward_to` | `list(ProfilesReceiver)` | List of receivers to send collected profiles to. |         | yes      |
| `tmp_dir`    | `string`                 | Temporary directory to store async-profiler.     | `/tmp`  | no       |

## Profiling behavior

The special label `__process_pid__` *must always* be present in each target of `targets` and corresponds to the `PID` of the process to profile.

After component startup, `pyroscope.java` creates a temporary directory under `tmp_dir` and extracts the async-profiler binaries for both glibc and musl into the directory with the following layout.

![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```none
/tmp/grafana-agent-asprof-glibc-{SHA1}/bin/asprof
/tmp/grafana-agent-asprof-glibc-{SHA1}/lib/libasyncProfiler.so
/tmp/grafana-agent-asprof-musl-{SHA1}/bin/asprof
/tmp/grafana-agent-asprof-musl-{SHA1}/lib/libasyncProfiler.so
```

After process profiling startup, the component detects libc type and copies according `libAsyncProfiler.so` into the target process file system at the exact same path.

> Note
> 
> The `asprof` binary runs with root permissions. If you change the `tmp_dir` configuration to something other than `/tmp`, then you must ensure that the directory is only writable by root.

#### `targets` argument

The special `__process_pid__` label *must always* be present and corresponds to the process PID that is used for profiling.

Labels starting with a double underscore (`__`) are treated as *internal*, and are removed prior to scraping.

The special label `service_name` is required and must always be present. If it is not specified, `pyroscope.scrape` will attempt to infer it from either of the following sources, in this order:

1. `__meta_kubernetes_pod_annotation_pyroscope_io_service_name` which is a `pyroscope.io/service_name` pod annotation.
2. `__meta_kubernetes_namespace` and `__meta_kubernetes_pod_container_name`
3. `__meta_docker_container_name`
4. `__meta_dockerswarm_container_label_service_name` or `__meta_dockerswarm_service_name`

If `service_name` is not specified and could not be inferred, then it is set to `unspecified`.

## Blocks

The following blocks are supported inside the definition of `pyroscope.java`:

Expand table

| Hierarchy         | Block                                        | Description                             | Required |
|-------------------|----------------------------------------------|-----------------------------------------|----------|
| profiling\_config | [profiling\_config](#profiling_config-block) | Describes java profiling configuration. | no       |

### profiling\_config block

The `profiling_config` block describes how async-profiler is invoked.

The following arguments are supported:

Expand table

| Name          | Type       | Description                                                                                              | Default | Required |
|---------------|------------|----------------------------------------------------------------------------------------------------------|---------|----------|
| `interval`    | `duration` | How frequently to collect profiles from the targets.                                                     | “60s”   | no       |
| `cpu`         | `bool`     | A flag to enable cpu profiling, using `itimer` async-profiler event.                                     | true    | no       |
| `sample_rate` | `int`      | CPU profiling sample rate. It is converted from Hz to interval and passed as `-i` arg to async-profiler. | 100     | no       |
| `alloc`       | `string`   | Allocation profiling sampling configuration It is passed as `--alloc` arg to async-profiler.             | “512k”  | no       |
| `lock`        | `string`   | Lock profiling sampling configuration. It is passed as `--lock` arg to async-profiler.                   | “10ms”  | no       |

For more information on async-profiler configuration, see [profiler-options](https://github.com/async-profiler/async-profiler?tab=readme-ov-file#profiler-options)

## Exported fields

`pyroscope.java` does not export any fields that can be referenced by other components.

## Component health

`pyroscope.java` is only reported as unhealthy when given an invalid configuration. In those cases, exported fields retain their last healthy values.

## Debug information

`pyroscope.java` does not expose any component-specific debug information.

## Debug metrics

`pyroscope.java` does not expose any component-specific debug metrics.

## Examples

### Profile every java process on the current host

Alloy ![Copy code to clipboard](/media/images/icons/icon-copy-small-2.svg) Copy

```alloy
pyroscope.write "staging" {
  endpoint {
    url = "http://localhost:4040"
  }
}

discovery.process "all" {
  refresh_interval = "60s"
  discover_config {
    cwd = true
    exe = true
    commandline = true
    username = true
    uid = true
    container_id = true
  }
}

discovery.relabel "java" {
  targets = discovery.process.all.targets
  rule {
    action = "keep"
    regex = ".*/java$"
    source_labels = ["__meta_process_exe"]
  }
}

pyroscope.java "java" {
  targets = discovery.relabel.java.output
  forward_to = [pyroscope.write.staging.receiver]
  profiling_config {
    interval = "60s"
    alloc = "512k"
    cpu = true
    sample_rate = 100
    lock = "1ms"
  }
}
```

## Compatible components

`pyroscope.java` can accept arguments from the following components:

- Components that export [Targets](../../compatibility/#targets-exporters)
- Components that export [Pyroscope `ProfilesReceiver`](../../compatibility/#pyroscope-profilesreceiver-exporters)

> 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.
