Skip to content

Instrument a Java container for Datadog

This guide shows you how to instrument Java applications running in Amazon ECS containers. OpenTelemetry Collector will be configured to collect the resulting logs, metrics, and traces.

Things to consider

Recommended practice

Enable auto-instrumentation to automatically capture useful telemetry from HTTP requests, database queries, external service calls, and application logs. You don't need to change any code in your app.

Before you begin

Make sure you have:

Step 1: Enable telemetry collection and auto-instrumentation

Auto-instrumentation automatically captures logs, metrics, and traces from your Java app. You don't need to change any code in your app.

  1. Update to the newest version of the app template for the application you want to instrument.

  2. Edit your package-config.yml file to enable telemetry collection:

    TelemetryCollection:
      Enable: true
      AutoInstrumentation:
        Enable: true # Disable this if you're already bundling the Java Agent with your application
        Runtime: java # This is the only supported runtime for auto-instrumentation
    
  3. Apply the configuration:

    ok pkg install
    
  4. Apply the Terraform configuration:

    terraform plan
    terraform apply
    

Step 2: Customize OpenTelemetry configuration (optional)

You can customize the OpenTelemetry collector configuration by overriding otel_* variables in config_override.tf. For example, you can add custom processors to your OTel pipelines to filter and transform data, modify trace sampling, and more.

Example: Filter out specific metrics

stacks/dev/app-example/config_override.tf
locals {
  # Add a custom processor to drop specific metrics
  otel_additional_processors = {
    "filter/drop_metrics" = {
      metrics = {
        exclude = {
          match_type = "strict"
          metric_names = [
            "http.client.request.body.size"
          ]
        }
      }
    }
  }

  # Use the custom processor in a specific OTel pipeline
  otel_pipeline_processors = {
    "metrics" = {
      processors = ["filter/drop_metrics"]
    }
  }
}

Example: Only keep traces from a specific endpoint

stacks/dev/app-example/config_override.tf
locals {
  # Configure tail sampling to only keep traces from a specific endpoint
  otel_tail_sampling_config = {
    additional_policies = [
      {
        name = "drop-everything-but-one-route"
        type = "drop"
        drop = {
          drop_sub_policy = [
            {
              name = "inverted-match"
              type = "string_attribute"
              string_attribute = {
                key                    = "http.route"
                values                 = ["^/my-route$"]
                enabled_regex_matching = true
                invert_match           = true
              }
            }
          ]
        }
      }
    ]
  }
}

Example: Bring your own OTel Collector configuration

Warning

When you bring your own OTel configuration, you'll lose useful behavior and telemetry tags that the Golden Path provides out-of-the-box. Consider using the otel-config-generator to extend the default configuration rather than replacing it completely, or ask Kjøremiljø to support your use case.

stacks/dev/app-example/config_override.tf
locals {
  otel_config = yamlencode(file("my-config.yml"))
}

For advanced configuration examples, check out the otel-config-generator examples.

Step 3: Add manual instrumentation (optional)

Auto-instrumentation provides basic telemetry, but custom business metrics need manual instrumentation with the OpenTelemetry SDK. Add the API dependency and use @WithSpan annotations or the API directly.

For detailed instructions on manual instrumentation, see the OpenTelemetry Java documentation.

Step 4: Verify instrumentation

Check Datadog for incoming traces, metrics, and logs. Use the env and service tags to filter the results. For example:

env:pirates-dev service:too-tikki`.