Java

TracesMetricsApp LogsCustom LogsProfiling

This guide walks you through setting up Application Performance Monitoring (APM) on a Java application. These instructions can also be found on the Installation page in your Middleware Account. View example code here.

Prerequisites

1 Java Version

Java version 8 or above. Check your Java version with the following command:

Install

Step 1: Download JAR File

Download the latest Middleware instrumentation JAR file from the Github Release Page.

Step 2: Container Variables

Applications running in a container require an additional environment variable. If your application is not running in a container, move to Step 3.

Docker

Add the following environment variable to your application:

The DOCKER_BRIDGE_GATEWAY_ADDRESS is the IP address of the gateway between the Docker host and bridge network. This is 172.17.0.1 by default. Learn more about Docker bridge networking here

Kubernetes

Run the following command to find the mw-service in Kubernetes:

Add the following environment variable to your application deployment YAML file:

Step 3: Capture Application Data

Traces

Distributed tracing will be automatically enabled upon completing Step 4: Run Application.

Metrics

Metrics collection will be automatically enabled upon completing Step 4: Run Application.

Application & Custom Logs

Application Logs will be automatically enabled upon completing Step 4: Run Application.

To add custom logs, add this dependency in the pom.xml file:

Run the following command to download the above dependencies:

Import the logger package:

Then utilize the following functions based on desired log severity levels.

Profiling

Application Profiling is automatically enabled upon completing Step 4: Run Application.

Stack Traces

Use the Logger.recordError(e) method to record a stack trace when an error occurs. See an example of this method below.

Step 4: Run Application

Run your application with the command given below.

Continuous Profiling

Continuous profiling captures real-time performance insights from your application to enable rapid identification of resource allocation, bottlenecks, and more. Navigate to the Continuous Profiling section to learn more about using Continuous Profiling with the Java APM.

To control continuous profiling, use the MW_APM_COLLECT_PROFILING environment variable:

Enable profiling

Disable profiling

If the variable is not set, continuous profiling is enabled by default.

Head Sampling

Head sampling is a technique that makes sampling decisions at the earliest possible stage. It determines whether to sample or drop a span or trace without inspecting the entire trace.

By default, Java APM samples all the spans and sends them to Middleware backend. If you wish to restrict the amount of spans you send to Middleware, you can introduce a trace sampler and adjust the sampling rate.

Available Samplers

  • always_on: Samples every span, ensuring that 100% of traces are captured. Useful in development environments or when comprehensive trace data is needed.
  • always_off: Does not sample any spans, effectively disabling tracing. Useful in production environments where tracing overhead needs to be minimized.
  • traceidratio: Samples a fixed percentage of traces, determined by the otel.traces.sampler.arg environment variable. For example, setting otel.traces.sampler.arg to 0.1 will sample 10% of traces.
  • parentbased_always_on: If the parent span is sampled, the child span will also be sampled. If there is no parent, the span will be sampled.
  • parentbased_always_off: If the parent span is not sampled, the child span will also not be sampled. If there is no parent, the span will not be sampled.
  • parentbased_traceidratio: Uses the traceidratio sampler for root spans, with the sampling rate set by otel.traces.sampler.arg.

Environment Variables

You can set OTEL_TRACES_SAMPLER environment variable to select the sampler and OTEL_TRACES_SAMPLER_ARG to set the sampling rate.

For example, to configure the SDK to sample parent spans such that only 10% of traces get created:

Java System Properties

You can set otel.traces.sampler Java system property to select the sampler and otel.traces.sampler.arg to set the sampling rate.

Direct Arguments

otel.traces.sampler and ``otel.traces.sampler.argproperties can also be passed directly to thejava` executable as shown below.

This will use parentbased_traceidratio to sample 10% of your root spans.

Properties file

These properties can be set in a Java system properties file and based to the java executable as shown below

You can also set location of the Java system properties file in an environment variable and skip passing it as an argument to the java command.

Replace {PATH-TO-PROPERTY-FILE} above to the location where your Java system properties file is located.

Example Java system properties file should look like below

This sample Java system properties will use parentbased_traceidratio to sample 10% of your root spans.

Logging and debug mode

This document outlines the environment variables and options used to configure debug mode for OpenTelemetry Java Instrumentation.

Environment Variables

Exporter Configuration

OTEL_TRACES_EXPORTER=logging

  • Configures the tracer to log trace data to the console.
  • Useful for viewing trace data directly in your application logs.

OTEL_METRICS_EXPORTER=logging

  • Sets the metrics exporter to log metrics data to the console.
  • Allows for immediate visibility of metrics in your application logs.

OTEL_LOGS_EXPORTER=logging

  • Configures the logs exporter to output log data to the console.
  • Enables viewing of OpenTelemetry log data alongside your application logs.

Logging Configuration

OTEL_EXPORTER_LOGGING_PREFIX="OTEL DEBUG: "

  • Adds a prefix to all OpenTelemetry logged data.
  • Helps distinguish OpenTelemetry logs from other application logs.

Sampling Configuration

OTEL_TRACES_SAMPLER=always_on

  • Ensures that all traces are captured and logged.
  • Useful for debugging but can generate a large volume of data.

Debug mode:

OTEL_JAVAAGENT_DEBUG=true

  • Enables debug logging for the OpenTelemetry Java agent.
  • Provides detailed information about the agent's operations.

Usage

To use these settings, you can set the environment variables before running your Java application with the OpenTelemetry agent. Here's an example command:

Replace path/to/middleware-javaagent-{version}.jar with the actual path to your Middleware Java agent JAR file, and your-application.jar with the path to your application's JAR file.

This table shows the available configuration settings other than the env variables mentioned above.

Environment VariableDefault ValueDescription
MW_PROFILING_SERVER_URLnullURL for the profiling server
MW_PROFILING_ALLOC"512k"Allocation size for profiling
MW_PROFILING_LOCK"10ms"Lock duration for profiling
MW_AGENT_SERVICE"localhost"Agent service address
MW_SERVICE_NAME""Name of the service
MW_AUTH_URL"https://app.middleware.io/api/v1/auth"Authentication URL
MW_APM_COLLECT_PROFILING"true"Enable/disable profiling collection
MW_APM_COLLECT_TRACES"true"Enable/disable trace collection
MW_APM_COLLECT_LOGS"true"Enable/disable log collection
MW_APM_COLLECT_METRICS"true"Enable/disable metric collection
MW_DISABLE_TELEMETRY"true"Enable/disable telemetry
MW_TARGET""Target endpoint for data sending
MW_API_KEYnullAPI key for authentication
MW_PROPAGATORS"b3"Context propagators to use
MW_CUSTOM_RESOURCE_ATTRIBUTEnullCustom resource attributes
MW_LOG_LEVELnullLog level for the application
MW_ENABLE_GZIP"true"Enable/disable GZIP compression
MW_AGENT"true"Enable/disable the agent

Need assistance or want to learn more about Middleware? Contact our support team in Slack.

References