Monitoring JVM Metrics with ClickStack

[Edit this page](https://github.com/ClickHouse/clickhouse-docs/blob/main/docs/use-cases/observability/clickstack/ingesting-data/integration-examples/jvm-metrics.md)

TL;DR

Monitor JVM applications in ClickStack using the OpenTelemetry Java agent. Includes a demo dataset and pre-built dashboard.

## Integration with existing JVM application[​](#existing-jvm "Direct link to Integration with existing JVM application")

This section covers configuring your existing JVM application to send metrics to ClickStack using the OpenTelemetry Java agent.

If you would like to test the integration before configuring your production setup, you can test with our demo dataset in the [demo dataset section](#demo-dataset).

##### Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- ClickStack instance running
- Existing Java application (Java 8+)
- Access to modify JVM startup arguments

Get ClickStack API key

#### Get ClickStack API key[​](#get-api-key "Direct link to Get ClickStack API key")

The OpenTelemetry Java agent sends data to ClickStack's OTLP endpoint, which requires authentication.

1. Open HyperDX at your ClickStack URL (e.g., <http://localhost:8080>)
2. Create an account or log in if needed
3. Navigate to **Team Settings → API Keys**
4. Copy your **Ingestion API Key**

Download OpenTelemetry Java agent

#### Download OpenTelemetry Java agent[​](#download-agent "Direct link to Download OpenTelemetry Java agent")

Download the OpenTelemetry Java agent JAR file:

```
curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.22.0/opentelemetry-javaagent.jar
```

This downloads the agent to your current directory. You can place it wherever makes sense for your deployment (e.g., `/opt/opentelemetry/` or alongside your application JAR).

Configure JVM startup arguments

#### Configure JVM startup arguments[​](#configure-jvm "Direct link to Configure JVM startup arguments")

Add the Java agent to your JVM startup command. The agent automatically collects JVM metrics and sends them to ClickStack.

##### Option 1: Command line flags[​](#command-line-flags "Direct link to Option 1: Command line flags")

```
java -javaagent:opentelemetry-javaagent.jar \
  -Dotel.service.name=my-java-app \
  -Dotel.exporter.otlp.endpoint=http://localhost:4318 \
  -Dotel.exporter.otlp.protocol=http/protobuf \
  -Dotel.exporter.otlp.headers="authorization=YOUR_API_KEY" \
  -Dotel.metrics.exporter=otlp \
  -Dotel.logs.exporter=none \
  -Dotel.traces.exporter=none \
  -jar my-application.jar
```

**Replace the following:**

- `opentelemetry-javaagent.jar` → Full path to the agent JAR (e.g., `/opt/opentelemetry/opentelemetry-javaagent.jar`)
- `my-java-app` → A meaningful name for your service (e.g., `payment-service`, `user-api`)
- `YOUR_API_KEY` → Your ClickStack API key from the command above
- `my-application.jar` → Your application's JAR file name
- `http://localhost:4318` → Your ClickStack endpoint (use `localhost:4318` if ClickStack runs on the same machine, otherwise use `http://your-clickstack-host:4318`)

##### Option 2: Environment variables[​](#env-vars "Direct link to Option 2: Environment variables")

Alternatively, use environment variables:

```
export JAVA_TOOL_OPTIONS="-javaagent:opentelemetry-javaagent.jar"
export OTEL_SERVICE_NAME="my-java-app"
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_EXPORTER_OTLP_HEADERS="authorization=YOUR_API_KEY"
export OTEL_METRICS_EXPORTER="otlp"
export OTEL_LOGS_EXPORTER="none"
export OTEL_TRACES_EXPORTER="none"

java -jar my-application.jar
```

**Replace the following:**

- `opentelemetry-javaagent.jar` → Full path to the agent JAR
- `my-java-app` → Your service name
- `YOUR_API_KEY` → Your ClickStack API key
- `http://localhost:4318` → Your ClickStack endpoint
- `my-application.jar` → Your application's JAR file name

Tip

The OpenTelemetry Java agent automatically collects these JVM metrics:

- **Memory**: `jvm.memory.used`, `jvm.memory.limit`, `jvm.memory.committed`, `jvm.memory.used_after_last_gc`
- **Garbage Collection**: `jvm.gc.duration`
- **Threads**: `jvm.thread.count`
- **Classes**: `jvm.class.count`, `jvm.class.loaded`, `jvm.class.unloaded`
- **CPU**: `jvm.cpu.time`, `jvm.cpu.count`

Verify metrics in HyperDX

#### Verify metrics in HyperDX[​](#verifying-metrics "Direct link to Verify metrics in HyperDX")

Once your application is running with the agent, verify metrics are flowing to ClickStack:

1. Open HyperDX at <http://localhost:8080> (or your ClickStack URL)
2. Navigate to **Chart Explorer**
3. Search for metrics starting with `jvm.` (e.g., `jvm.memory.used`, `jvm.gc.duration`, `jvm.thread.count`)

## Demo dataset[​](#demo-dataset "Direct link to Demo dataset")

For users who want to test the JVM metrics integration before instrumenting their applications, we provide a sample dataset with pre-generated metrics showing realistic JVM behavior from a medium-sized microservice with steady moderate traffic.

Download the sample dataset

#### Download the sample dataset[​](#download-sample "Direct link to Download the sample dataset")

```
# Download gauge metrics (memory, threads, CPU, classes)
curl -O https://datasets-documentation.s3.eu-west-3.amazonaws.com/clickstack-integrations/jvm/jvm-metrics-gauge.jsonl

# Download sum metrics (GC events)
curl -O https://datasets-documentation.s3.eu-west-3.amazonaws.com/clickstack-integrations/jvm/jvm-metrics-sum.jsonl
```

The dataset includes 24 hours of JVM metrics showing:

- Heap memory growth with periodic garbage collection events
- Thread count variations
- Realistic GC pause times
- Class loading activity
- CPU utilization patterns

Start ClickStack

#### Start ClickStack[​](#start-clickstack "Direct link to Start ClickStack")

If you don't already have ClickStack running:

```
docker run -d --name clickstack \
  -p 8080:8080 -p 4317:4317 -p 4318:4318 \
  clickhouse/clickstack-all-in-one:latest
```

Wait a few moments for ClickStack to fully start up.

Import the demo dataset

#### Import the demo dataset[​](#import-demo-data "Direct link to Import the demo dataset")

```
# Import gauge metrics (memory, threads, CPU, classes)
docker exec -i clickstack clickhouse-client --query="
  INSERT INTO default.otel_metrics_gauge FORMAT JSONEachRow
" < jvm-metrics-gauge.jsonl

# Import sum metrics (GC events)
docker exec -i clickstack clickhouse-client --query="
  INSERT INTO default.otel_metrics_sum FORMAT JSONEachRow
" < jvm-metrics-sum.jsonl
```

This imports the metrics directly into ClickStack's metrics tables.

Verify the demo data

#### Verify the demo data[​](#verify-demo-metrics "Direct link to Verify the demo data")

Once imported:

1. Open HyperDX at <http://localhost:8080> and log in (create an account if needed)
2. Navigate to the Search view and set source to **Metrics**
3. Set the time range to **2025-12-06 14:00:00 - 2025-12-09 14:00:00**
4. Search for `jvm.memory.used` or `jvm.gc.duration`

You should see metrics for the demo service.

Timezone Display

HyperDX displays timestamps in your browser's local timezone. The demo data spans **2025-12-07 14:00:00 - 2025-12-08 14:00:00 (UTC)**. Set your time range to **2025-12-06 14:00:00 - 2025-12-09 14:00:00** to ensure you see the demo metrics regardless of your location. Once you see the metrics, you can narrow the range to a 24-hour period for clearer visualizations.

## Dashboards and visualization[​](#dashboards "Direct link to Dashboards and visualization")

To help you monitor JVM applications with ClickStack, we provide a pre-built dashboard with essential visualizations for JVM metrics.

Download the dashboard configuration

#### [Download](/docs/examples/jvm-metrics-dashboard.json) the dashboard configuration[​](#download "Direct link to download")

Import the pre-built dashboard

#### Import the pre-built dashboard[​](#import-dashboard "Direct link to Import the pre-built dashboard")

1. Open HyperDX and navigate to the Dashboards section
2. Click **Import Dashboard** in the upper right corner under the ellipses