github.com/grafana/pyroscope@v1.18.0/docs/sources/configure-client/language-sdks/java.md (about)

     1  ---
     2  title: "Java"
     3  menuTitle: "Java"
     4  description: "Instrumenting Java applications for continuous profiling."
     5  weight: 30
     6  aliases:
     7    - /docs/phlare/latest/configure-client/language-sdks/java
     8  ---
     9  
    10  # Java
    11  
    12  The Java Profiler, integrated with Pyroscope, offers a comprehensive solution for performance analysis in Java applications.
    13  It provides real-time insights, enabling developers to understand and optimize their Java codebase effectively.
    14  This tool is crucial for improving application responsiveness, reducing resource consumption, and ensuring top-notch performance in Java environments.
    15  
    16  {{< admonition type="note" >}}
    17  Refer to [Available profiling types](https://grafana.com/docs/pyroscope/<PYROSCOPE_VERSION>/configure-client/profile-types/) for a list of profile types supported by each language.
    18  {{< /admonition >}}
    19  
    20  ## Before you begin
    21  
    22  To capture and analyze profiling data, you need either a hosted Pyroscope OSS server or a hosted [Pyroscope instance with Grafana Cloud Profiles](/products/cloud/profiles-for-continuous-profiling/) (requires a free Grafana Cloud account).
    23  
    24  The Pyroscope server can be a local server for development or a remote server for production use.
    25  
    26  ## Add Java profiling to your application
    27  
    28  Java integration is distributed as a single jar file (`pyroscope.jar`) or a Maven package.
    29  Supported platforms include:
    30  
    31  * Linux on x64
    32  * Linux on ARM64
    33  * MacOS on x64
    34  * MacOS on ARM64
    35  
    36  Visit the GitHub [releases](https://github.com/pyroscope-io/pyroscope-java/releases) page to download the latest version of `pyroscope.jar`.
    37  
    38  The latest release is also available on [Maven Central](https://search.maven.org/artifact/io.pyroscope/agent).
    39  
    40  ## Configure the Java client
    41  
    42  You can start Pyroscope either from your application's code or attach it as javaagent.
    43  
    44  ### Start Pyroscope from app's Java code
    45  
    46  First, add the Pyroscope dependency:
    47  
    48  {{< code >}}
    49  
    50  ```maven
    51  <dependency>
    52    <groupId>io.pyroscope</groupId>
    53    <artifactId>agent</artifactId>
    54    <version>2.1.2</version>
    55  </dependency>
    56  ```
    57  
    58  ```gradle
    59  implementation("io.pyroscope:agent:2.1.2")
    60  ```
    61  
    62  {{< /code >}}
    63  
    64  Add the following code to your application:
    65  
    66  {{< code >}}
    67  
    68  ```java
    69  PyroscopeAgent.start(
    70    new Config.Builder()
    71      .setApplicationName("ride-sharing-app-java")
    72      .setProfilingEvent(EventType.ITIMER)
    73      .setFormat(Format.JFR)
    74      .setServerAddress("http://pyroscope-server:4040")
    75      .build()
    76  );
    77  ```
    78  
    79  ```spring
    80  import io.pyroscope.javaagent.PyroscopeAgent;
    81  import io.pyroscope.javaagent.config.Config;
    82  import io.pyroscope.javaagent.EventType;
    83  import io.pyroscope.http.Format;
    84  
    85  @PostConstruct
    86  public void init() {
    87  
    88      PyroscopeAgent.start(
    89      new Config.Builder()
    90          .setApplicationName("ride-sharing-app-java")
    91          .setProfilingEvent(EventType.ITIMER)
    92          .setFormat(Format.JFR)
    93          .setServerAddress("http://pyroscope-server:4040")
    94          // Optionally, if authentication is enabled, specify the API key.
    95          // .setBasicAuthUser("<User>")
    96          // .setBasicAuthPassword("<Password>")
    97          // Optionally, if you'd like to set allocation threshold to register events, in bytes. '0' registers all events
    98          // .setProfilingAlloc("0")
    99          .build()
   100      );
   101  }
   102  ```
   103  
   104  {{< /code >}}
   105  
   106  
   107  You can also optionally replace some Pyroscope components:
   108  ```java
   109  PyroscopeAgent.start(
   110    new PyroscopeAgent.Options.Builder(config)
   111      .setExporter(snapshot -> {
   112        // Your custom export/upload logic may go here
   113        // It is invoked every 10 seconds by default with snapshot of
   114        // profiling data
   115      })
   116      .setLogger((l, msg, args) -> {
   117        // Your custom logging may go here
   118        // Pyroscope does not depend on any logging library
   119        System.out.printf((msg) + "%n", args);
   120      })
   121      .setScheduler(profiler -> {
   122        // Your custom profiling schedule logic may go here
   123      })
   124      .build()
   125  );
   126  ```
   127  
   128  ### Start Pyroscope as `javaagent`
   129  
   130  To start profiling a Java application, run your application with `pyroscope.jar` `javaagent`:
   131  
   132  ```shell
   133  export PYROSCOPE_APPLICATION_NAME=my.java.app
   134  export PYROSCOPE_SERVER_ADDRESS=http://pyroscope-server:4040
   135  
   136  java -javaagent:pyroscope.jar -jar app.jar
   137  ```
   138  
   139  ### Add profiling labels to Java applications
   140  
   141  You can add dynamic tags (labels) to the profiling data. These tags can filter the data in the UI.
   142  
   143  Add labels dynamically:
   144  ```java
   145  Pyroscope.LabelsWrapper.run(new LabelsSet("controller", "slow_controller"), () -> {
   146    slowCode();
   147  });
   148  ```
   149  
   150  You can also add static tags (labels) to the profiling data:
   151  
   152  ```java
   153  Pyroscope.setStaticLabels(Map.of("region", System.getenv("REGION")));
   154  // or with Config.Builder if you start pyroscope with PyroscopeAgent.start
   155  PyroscopeAgent.start(new Config.Builder()
   156      .setLabels(mapOf("region", System.getenv("REGION")))
   157      // ...
   158      .build()
   159  );
   160  ```
   161  
   162  ### Configuration options
   163  
   164  When you start Pyroscope as `javaagent` or obtain configuration by `Config.build()`, Pyroscope searches
   165  for configuration in multiple sources: system properties, environment variables, and `pyroscope.properties`.
   166  Property keys have the same names as environment variables, but are in lowercase and underscores (`_`) are replaced with periods (`.`). For example, `PYROSCOPE_FORMAT` becomes `pyroscope.format`
   167  
   168  The Java integration supports JFR format to be able to support multiple events (JFR is the only output format that supports [multiple events in `async-profiler`](https://github.com/jvm-profiling-tools/async-profiler#multiple-events)). There are several environment variables that define how multiple event configuration works:
   169  
   170  | Flag                                        | Description                                                                                                                                                                                                                                                                                                                                                                                                                      |
   171  |---------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
   172  | `PYROSCOPE_AGENT_ENABLED`                   | Enables the agent. The default is `true`.                                                                                                                                                                                                                                                                                                                                                                                        |
   173  | `PYROSCOPE_APPLICATION_NAME`                | Sets the application name. If not provided, a generated name will be used.                                                                                                                                                                                                                                                                                                                                                       |
   174  | `PYROSCOPE_PROFILING_INTERVAL`              | Sets the profiling sampling interval for CPU profiling. The default is `10ms`.                                                                                                                                                                                                                                                                                                                                                   |
   175  | `PYROSCOPE_FORMAT`                          | Sets the profiler output format. The default is `collapsed`, but in order to support multiple formats it must be set to `jfr`.                                                                                                                                                                                                                                                                                                   |
   176  | `PYROSCOPE_PROFILER_EVENT`                  | Sets the profiler event. With JFR format enabled, this event refers to one of the possible CPU profiling events: `itimer`, `cpu`, `wall`. The default is `itimer`.                                                                                                                                                                                                                                                               |
   177  | `PYROSCOPE_PROFILER_ALLOC`                  | Sets the threshold to register allocation events, in bytes (equivalent to `--alloc=` in `async-profiler`). The default value is `""` - empty string, which means that allocation profiling is disabled. Setting it to `0` will register every event, causing significant CPU and network overhead, making it not suitable for production environments. We recommend setting a starting value of 512k and adjusting it as needed. |
   178  | `PYROSCOPE_PROFILER_LOCK`                   | Sets the threshold to register lock events, in nanoseconds (equivalent to `--lock=` in `async-profiler`). The default value is `""` - empty string, which means that lock profiling is disabled. Setting it to `0` will register every event, causing significant CPU and network overhead, making it not suitable for production environments. We recommend setting a starting value of 10ms and adjusting it as needed.        |
   179  | `PYROSCOPE_UPLOAD_INTERVAL`                 | Sets the interval for uploading profiling data. The default is `10s`.                                                                                                                                                                                                                                                                                                                                                            |
   180  | `PYROSCOPE_JAVA_STACK_DEPTH_MAX`            | Sets the maximum stack depth. The default is `2048`.                                                                                                                                                                                                                                                                                                                                                                             |
   181  | `PYROSCOPE_SERVER_ADDRESS`                  | Address of the Pyroscope server. The default is `http://localhost:4040`                                                                                                                                                                                                                                                                                                                                                          |
   182  | `PYROSCOPE_CONFIGURATION_FILE`              | Sets an additional properties configuration file. The default value is `pyroscope.properties`.                                                                                                                                                                                                                                                                                                                                   |
   183  | `PYROSCOPE_BASIC_AUTH_USER`                 | HTTP Basic authentication username. The default value is `""` - empty string, no authentication.                                                                                                                                                                                                                                                                                                                                 |
   184  | `PYROSCOPE_BASIC_AUTH_PASSWORD`             | HTTP Basic authentication password. The default value is `""` - empty string, no authentication.                                                                                                                                                                                                                                                                                                                                 |
   185  | `PYROSCOPE_TENANT_ID`                       | pyroscope tenant ID, passed as X-Scope-OrgID http header. The default value is `""` - empty string, no tenant ID.                                                                                                                                                                                                                                                                                                                |
   186  | `PYROSCOPE_HTTP_HEADERS`                    | Extra HTTP headers in JSON format, for example: `{"X-Header": "Value"}`. The default value is `{}` - no extra headers.                                                                                                                                                                                                                                                                                                           |
   187  | `PYROSCOPE_LABELS`                          | Sets static labels in the form of comma separated `key=value` pairs. The default value is `""` - empty string, no labels.                                                                                                                                                                                                                                                                                                        |
   188  | `PYROSCOPE_LOG_LEVEL`                       | Determines the level of verbosity for Pyroscope's logger. Available options include `debug`, `info`, `warn`, and `error`. The default value is set to `info`.                                                                                                                                                                                                                                                                    |
   189  | `PYROSCOPE_PUSH_QUEUE_CAPACITY`             | Specifies the size of the ingestion queue that temporarily stores profiling data in memory during network outages. The default value is set to 8.                                                                                                                                                                                                                                                                                |
   190  | `PYROSCOPE_INGEST_MAX_TRIES`                | Sets the maximum number of times to retry an ingestion API call in the event of failure. A value of `-1` indicates that the retries will continue indefinitely. The default value is set to `8`.                                                                                                                                                                                                                                 |
   191  | `PYROSCOPE_EXPORT_COMPRESSION_LEVEL_JFR`    | Sets the level of GZIP compression applied to uploaded JFR files. This option accepts values of `NO_COMPRESSION`, `BEST_SPEED`, `BEST_COMPRESSION`, and `DEFAULT_COMPRESSION`.                                                                                                                                                                                                                                                   |
   192  | `PYROSCOPE_EXPORT_COMPRESSION_LEVEL_LABELS` | Operates similarly to `PYROSCOPE_EXPORT_COMPRESSION_LEVEL_JFR`, but applies to the dynamic labels part. The default value is set to `BEST_SPEED`.                                                                                                                                                                                                                                                                                |
   193  | `PYROSCOPE_ALLOC_LIVE`                      | Retain allocation samples with live objects only (objects that have not been collected by the end of profiling session). Useful for finding Java heap memory leaks. The default value is `false`                                                                                                                                                                                                                                 |
   194  | `PYROSCOPE_GC_BEFORE_DUMP`                  | A boolean value that executes a `System.gc()` command before dumping the profile when set to `true`. This option may be useful for live profiling, but is disabled by default.                                                                                                                                                                                                                                                   |
   195  
   196  ## Send data to Pyroscope OSS or Grafana Cloud Profiles
   197  
   198  Add the following code to your application:
   199  ```java
   200  PyroscopeAgent.start(
   201      new Config.Builder()
   202          .setApplicationName("test-java-app")
   203          .setProfilingEvent(EventType.ITIMER)
   204          .setFormat(Format.JFR)
   205          .setServerAddress("<URL>")
   206          // Set these if using Grafana Cloud:
   207          .setBasicAuthUser("<User>")
   208          .setBasicAuthPassword("<Password>")
   209          // Optional Pyroscope tenant ID (only needed if using multi-tenancy). Not needed for Grafana cloud.
   210          // .setTenantID("<TenantID>")
   211          .build()
   212  );
   213  ```
   214  
   215  To configure the Java SDK to send data to Pyroscope, replace the `<URL>` placeholder with the appropriate server URL. This could be the Grafana Cloud URL or your own custom Pyroscope server URL.
   216  
   217  If you need to send data to Grafana Cloud, you'll have to configure HTTP Basic authentication. Replace `<User>` with your Grafana Cloud stack user and `<Password>` with your Grafana Cloud API key.
   218  
   219  If your Pyroscope server has multi-tenancy enabled, you'll need to configure a tenant ID. Replace `<TenantID>` with your Pyroscope tenant ID.
   220  
   221  ### Locate the URL, user, and password in Grafana Cloud Profiles
   222  
   223  [//]: # 'Shared content for URl location in Grafana Cloud Profiles'
   224  [//]: # 'This content is located in /pyroscope/docs/sources/shared/locate-url-pw-user-cloud-profiles.md'
   225  
   226  {{< docs/shared source="pyroscope" lookup="locate-url-pw-user-cloud-profiles.md" version="latest" >}}
   227  
   228  ### Example configurations
   229  
   230  The following configuration sets application name, Pyroscope format, profiling interval, event, and lock.
   231  This example is an excerpt from the [`rideshare` Dockerfile](https://github.com/grafana/pyroscope/blob/main/examples/language-sdk-instrumentation/java/rideshare/Dockerfile#L24-L34) available in the Pyroscope repository.
   232  
   233  ```
   234  ENV PYROSCOPE_APPLICATION_NAME=rideshare.java.push.app
   235  ENV PYROSCOPE_FORMAT=jfr
   236  ENV PYROSCOPE_PROFILING_INTERVAL=10ms
   237  ENV PYROSCOPE_PROFILER_EVENT=itimer
   238  ENV PYROSCOPE_PROFILER_LOCK=10ms
   239  ```
   240  
   241  This configuration excerpt enables allocation and lock profiling:
   242  
   243  ```
   244  PYROSCOPE_PROFILER_ALLOC=512k
   245  PYROSCOPE_PROFILER_LOCK=10ms
   246  ```
   247  
   248  ## Java profiling examples
   249  
   250  Check out the following resources to learn more about Java profiling:
   251  - [Java examples](https://github.com/grafana/pyroscope/tree/main/examples/language-sdk-instrumentation/java/rideshare)
   252  - [Java Demo](https://play.grafana.org/a/grafana-pyroscope-app/single?query=process_cpu%3Acpu%3Ananoseconds%3Acpu%3Ananoseconds%7Bservice_name%3D%22pyroscope-rideshare-java%22%7D&from=now-1h&until=now) showing Java example with tags