|
| 1 | +--- |
| 2 | +slug: /use-cases/observability/clickstack/integrations/jvm-metrics |
| 3 | +title: 'Monitoring JVM Metrics with ClickStack' |
| 4 | +sidebar_label: 'JVM Metrics' |
| 5 | +pagination_prev: null |
| 6 | +pagination_next: null |
| 7 | +description: 'Monitoring JVM with ClickStack' |
| 8 | +doc_type: 'guide' |
| 9 | +--- |
| 10 | + |
| 11 | +import Image from '@theme/IdealImage'; |
| 12 | +import api_key from '@site/static/images/clickstack/api-key.png'; |
| 13 | + |
| 14 | +# Monitoring JVM Metrics with ClickStack {#jvm-clickstack} |
| 15 | + |
| 16 | +:::note[TL;DR] |
| 17 | +This guide shows you how to monitor JVM applications with ClickStack using the OpenTelemetry Java agent to collect metrics. You'll learn how to: |
| 18 | +- Attach the OpenTelemetry Java agent to your JVM application |
| 19 | +- Configure the agent to send metrics to ClickStack via OTLP |
| 20 | +- Use a pre-built dashboard to visualize heap memory, garbage collection, threads, and CPU |
| 21 | + |
| 22 | +A demo dataset with sample metrics is available if you want to test the integration before instrumenting your production applications. |
| 23 | + |
| 24 | +Time Required: 5-10 minutes |
| 25 | +::: |
| 26 | + |
| 27 | +## Integration with existing JVM application {#existing-jvm} |
| 28 | + |
| 29 | +This section covers configuring your existing JVM application to send metrics to ClickStack using the OpenTelemetry Java agent. |
| 30 | + |
| 31 | +If you would like to test the integration before configuring your production setup, you can test with our demo dataset in the [following section](/use-cases/observability/clickstack/integrations/jvm#demo-dataset). |
| 32 | + |
| 33 | +##### Prerequisites {#prerequisites} |
| 34 | +- ClickStack instance running |
| 35 | +- Existing Java application (Java 8+) |
| 36 | +- Access to modify JVM startup arguments |
| 37 | + |
| 38 | +<VerticalStepper headerLevel="h4"> |
| 39 | + |
| 40 | +#### Get ClickStack API key {#get-api-key} |
| 41 | + |
| 42 | +The OpenTelemetry Java agent sends data to ClickStack's OTLP endpoint, which requires authentication. |
| 43 | + |
| 44 | +1. Open HyperDX at your ClickStack URL (e.g., http://localhost:8080) |
| 45 | +2. Create an account or log in if needed |
| 46 | +3. Navigate to **Team Settings → API Keys** |
| 47 | +4. Copy your **Ingestion API Key** |
| 48 | + |
| 49 | +<Image img={api_key} alt="ClickStack API Key"/> |
| 50 | + |
| 51 | +#### Download OpenTelemetry Java agent {#download-agent} |
| 52 | + |
| 53 | +Download the OpenTelemetry Java agent JAR file: |
| 54 | + |
| 55 | +```bash |
| 56 | +curl -L -O https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.22.0/opentelemetry-javaagent.jar |
| 57 | +``` |
| 58 | + |
| 59 | +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). |
| 60 | + |
| 61 | +#### Configure JVM startup arguments {#configure-jvm} |
| 62 | + |
| 63 | +Add the Java agent to your JVM startup command. The agent automatically collects JVM metrics and sends them to ClickStack. |
| 64 | + |
| 65 | +##### Option 1: Command line flags {#command-line-flags} |
| 66 | + |
| 67 | +```bash |
| 68 | +java -javaagent:opentelemetry-javaagent.jar \ |
| 69 | + -Dotel.service.name=my-java-app \ |
| 70 | + -Dotel.exporter.otlp.endpoint=http://localhost:4318 \ |
| 71 | + -Dotel.exporter.otlp.protocol=http/protobuf \ |
| 72 | + -Dotel.exporter.otlp.headers="authorization=YOUR_API_KEY" \ |
| 73 | + -Dotel.metrics.exporter=otlp \ |
| 74 | + -Dotel.logs.exporter=none \ |
| 75 | + -Dotel.traces.exporter=none \ |
| 76 | + -jar my-application.jar |
| 77 | +``` |
| 78 | + |
| 79 | +**Replace the following:** |
| 80 | +- `opentelemetry-javaagent.jar` → Full path to the agent JAR (e.g., `/opt/opentelemetry/opentelemetry-javaagent.jar`) |
| 81 | +- `my-java-app` → A meaningful name for your service (e.g., `payment-service`, `user-api`) |
| 82 | +- `YOUR_API_KEY` → Your ClickStack API key from the command above |
| 83 | +- `my-application.jar` → Your application's JAR file name |
| 84 | +- `http://localhost:4318` → Your ClickStack endpoint (use `localhost:4318` if ClickStack runs on the same machine, otherwise use `http://your-clickstack-host:4318`) |
| 85 | + |
| 86 | +##### Option 2: Environment variables {#env-vars} |
| 87 | + |
| 88 | +Alternatively, use environment variables: |
| 89 | + |
| 90 | +```bash |
| 91 | +export JAVA_TOOL_OPTIONS="-javaagent:opentelemetry-javaagent.jar" |
| 92 | +export OTEL_SERVICE_NAME="my-java-app" |
| 93 | +export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318" |
| 94 | +export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" |
| 95 | +export OTEL_EXPORTER_OTLP_HEADERS="authorization=YOUR_API_KEY" |
| 96 | +export OTEL_METRICS_EXPORTER="otlp" |
| 97 | +export OTEL_LOGS_EXPORTER="none" |
| 98 | +export OTEL_TRACES_EXPORTER="none" |
| 99 | + |
| 100 | +java -jar my-application.jar |
| 101 | +``` |
| 102 | + |
| 103 | +**Replace the following:** |
| 104 | +- `opentelemetry-javaagent.jar` → Full path to the agent JAR |
| 105 | +- `my-java-app` → Your service name |
| 106 | +- `YOUR_API_KEY` → Your ClickStack API key |
| 107 | +- `http://localhost:4318` → Your ClickStack endpoint |
| 108 | +- `my-application.jar` → Your application's JAR file name |
| 109 | + |
| 110 | +:::tip |
| 111 | +The OpenTelemetry Java agent automatically collects these JVM metrics: |
| 112 | +- **Memory**: `jvm.memory.used`, `jvm.memory.limit`, `jvm.memory.committed`, `jvm.memory.used_after_last_gc` |
| 113 | +- **Garbage Collection**: `jvm.gc.duration` |
| 114 | +- **Threads**: `jvm.thread.count` |
| 115 | +- **Classes**: `jvm.class.count`, `jvm.class.loaded`, `jvm.class.unloaded` |
| 116 | +- **CPU**: `jvm.cpu.time`, `jvm.cpu.count` |
| 117 | +::: |
| 118 | + |
| 119 | +#### Verify metrics in HyperDX {#verifying-metrics} |
| 120 | + |
| 121 | +Once your application is running with the agent, verify metrics are flowing to ClickStack: |
| 122 | + |
| 123 | +1. Open HyperDX at http://localhost:8080 (or your ClickStack URL) |
| 124 | +2. Navigate to **Chart Explorer** |
| 125 | +3. Search for metrics starting with `jvm.` (e.g., `jvm.memory.used`, `jvm.gc.duration`, `jvm.thread.count`) |
| 126 | + |
| 127 | +</VerticalStepper> |
| 128 | + |
| 129 | +## Demo dataset {#demo-dataset} |
| 130 | + |
| 131 | +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. |
| 132 | + |
| 133 | +<VerticalStepper headerLevel="h4"> |
| 134 | + |
| 135 | +#### Download the sample dataset {#download-sample} |
| 136 | + |
| 137 | +```bash |
| 138 | +curl -O https://datasets-documentation.s3.eu-west-3.amazonaws.com/clickstack-integrations/jvm-metrics.jsonl |
| 139 | +``` |
| 140 | + |
| 141 | +The dataset includes 24 hours of JVM metrics showing: |
| 142 | +- Heap memory growth with periodic garbage collection events |
| 143 | +- Thread count variations |
| 144 | +- Realistic GC pause times |
| 145 | +- Class loading activity |
| 146 | +- CPU utilization patterns |
| 147 | + |
| 148 | +#### Start ClickStack {#start-clickstack} |
| 149 | + |
| 150 | +If you don't already have ClickStack running: |
| 151 | + |
| 152 | +```bash |
| 153 | +docker run -d --name clickstack \ |
| 154 | + -p 8080:8080 -p 4317:4317 -p 4318:4318 \ |
| 155 | + docker.hyperdx.io/hyperdx/hyperdx-all-in-one:latest |
| 156 | +``` |
| 157 | + |
| 158 | +Wait a few moments for ClickStack to fully start up. |
| 159 | + |
| 160 | +#### Import the demo dataset {#import-demo-data} |
| 161 | + |
| 162 | +```bash |
| 163 | +docker exec -i clickstack clickhouse-client --query=" |
| 164 | + INSERT INTO otel.otel_metrics_sum FORMAT JSONEachRow |
| 165 | +" < jvm-metrics.jsonl |
| 166 | +``` |
| 167 | + |
| 168 | +This imports the metrics directly into ClickStack's metrics table. |
| 169 | + |
| 170 | +#### Verify the demo data {#verify-demo-metrics} |
| 171 | + |
| 172 | +Once imported: |
| 173 | + |
| 174 | +1. Open HyperDX at http://localhost:8080 and log in (create an account if needed) |
| 175 | +2. Navigate to the Search view and set source to **Metrics** |
| 176 | +3. Set the time range to **2025-10-20 00:00:00 - 2025-10-21 00:00:00** |
| 177 | +4. Search for `jvm.memory.used` or `jvm.gc.duration` |
| 178 | + |
| 179 | +You should see metrics for the demo service. |
| 180 | + |
| 181 | +:::note[Timezone Display] |
| 182 | +HyperDX displays timestamps in your browser's local timezone. The demo data spans 2025-10-20 00:00:00 - 2025-10-21 00:00:00 UTC (24 hours). |
| 183 | +::: |
| 184 | + |
| 185 | +</VerticalStepper> |
| 186 | + |
| 187 | +## Dashboards and visualization {#dashboards} |
| 188 | + |
| 189 | +To help you monitor JVM applications with ClickStack, we provide a pre-built dashboard with essential visualizations for JVM metrics. |
| 190 | + |
| 191 | +<VerticalStepper headerLevel="h4"> |
| 192 | + |
| 193 | +#### Download the dashboard configuration {#download} |
| 194 | + |
| 195 | +Download the [jvm-metrics-dashboard.json](https://datasets-documentation.s3.eu-west-3.amazonaws.com/clickstack-integrations/jvm-metrics-dashboard.json) file. |
| 196 | + |
| 197 | +#### Import the dashboard {#import-dashboard} |
| 198 | + |
| 199 | +1. Open HyperDX and navigate to Dashboards |
| 200 | +2. Click "Import Dashboard" in the upper right corner |
| 201 | +3. Upload the `jvm-metrics-dashboard.json` file and click finish import |
| 202 | + |
| 203 | +#### View the dashboard {#created-dashboard} |
| 204 | + |
| 205 | +:::note |
| 206 | +For the demo dataset, set the time range to **2025-10-20 00:00:00 - 2025-10-21 00:00:00 (UTC)**. Adjust based on your local timezone. |
| 207 | +::: |
| 208 | + |
| 209 | +The dashboard includes: |
| 210 | +- **Heap Memory Usage**: Visualize heap usage across different memory pools (Eden, Survivor, Old Gen) |
| 211 | +- **Garbage Collection**: Track GC pause duration over time |
| 212 | +- **Thread Count**: Monitor threads by state (runnable, blocked, waiting, timed_waiting) |
| 213 | +- **Non-Heap Memory**: Metaspace usage |
| 214 | +- **CPU Utilization**: JVM CPU usage percentage |
| 215 | +- **Class Loading**: Number of loaded classes over time |
| 216 | + |
| 217 | +</VerticalStepper> |
| 218 | + |
| 219 | +## Troubleshooting {#troubleshooting} |
| 220 | + |
| 221 | +### Agent not starting {#troubleshooting-not-loading} |
| 222 | + |
| 223 | +**Verify the agent JAR exists:** |
| 224 | +```bash |
| 225 | +ls -lh /path/to/opentelemetry-javaagent.jar |
| 226 | +``` |
| 227 | + |
| 228 | +**Check Java version compatibility (requires Java 8+):** |
| 229 | +```bash |
| 230 | +java -version |
| 231 | +``` |
| 232 | + |
| 233 | +**Look for agent startup log message:** |
| 234 | +When your application starts, you should see: |
| 235 | +``` |
| 236 | +[otel.javaagent] OpenTelemetry Javaagent v2.22.0 started |
| 237 | +``` |
| 238 | + |
| 239 | +### No metrics appearing in HyperDX {#no-metrics} |
| 240 | + |
| 241 | +**Verify ClickStack is running and accessible:** |
| 242 | +```bash |
| 243 | +docker ps | grep clickstack |
| 244 | +curl -v http://localhost:4318/v1/metrics |
| 245 | +``` |
| 246 | + |
| 247 | +**Check that metrics exporter is configured:** |
| 248 | +```bash |
| 249 | +# If using environment variables, verify: |
| 250 | +echo $OTEL_METRICS_EXPORTER |
| 251 | +# Should output: otlp |
| 252 | +``` |
| 253 | + |
| 254 | +**Check application logs for OpenTelemetry errors:** |
| 255 | +Look for any error messages related to OpenTelemetry or OTLP export failures in your application logs. |
| 256 | + |
| 257 | +**Verify network connectivity:** |
| 258 | +If ClickStack is on a remote host, ensure port 4318 is accessible from your application server. |
| 259 | + |
| 260 | +### High CPU or memory overhead {#high-overhead} |
| 261 | + |
| 262 | +**Adjust metric export interval (default is 60 seconds):** |
| 263 | +```bash |
| 264 | +-Dotel.metric.export.interval=120000 # Export every 120 seconds instead |
| 265 | +``` |
| 266 | + |
| 267 | +**Verify agent version:** |
| 268 | +Ensure you're using the latest stable agent version (currently 2.22.0), as newer versions often include performance improvements. |
| 269 | + |
| 270 | +## Next steps {#next-steps} |
| 271 | + |
| 272 | +Now that you have JVM metrics flowing into ClickStack, consider: |
| 273 | + |
| 274 | +- **Set up alerts** for critical metrics like high heap usage, frequent GC pauses, or thread exhaustion |
| 275 | +- **Correlate with traces** by enabling trace collection with the same agent to see how JVM performance impacts request latency |
| 276 | +- **Monitor multiple instances** and compare JVM behavior across different services or environments |
| 277 | +- **Create custom dashboards** tailored to your specific application's memory and performance characteristics |
0 commit comments