TraceKitTraceKit Docs
Backend SDKs

Java Integration Guide

Add TraceKit to Java applications for distributed tracing and live debugging. Monitor Spring Boot, Micronaut, and Java microservices with production-safe breakpoints.

Learn how to integrate the official TraceKit Java SDK into your applications for distributed tracing, code monitoring, and security scanning.

Let AI set up TraceKit for you -- AI assistants can guide you through the entire setup process. Try AI Setup

Prerequisites

  • Java 8 or higher (Java 11+ recommended)
  • A TraceKit account (create one free)
  • A generated API key from the API Keys page

What Gets Traced Automatically?

With the Java Agent, these operations are traced automatically with ZERO code changes:

ComponentSpan TypeCaptured AttributesAuto-Traced?
HTTP EndpointsSERVERmethod, route, status_code, duration, client_ipYes
JDBC QueriesDBdb.system, db.statement, db.name, durationYes
HTTP Client CallsCLIENTmethod, url, status_code, duration, peer.serviceYes
Spring BootSERVERspring.handler, method, routeYes (auto-config)
Kafka/RabbitMQCustommessaging.system, messaging.destination, messaging.operationYes
Custom Business LogicCustomuser-defined attributesManual

Installation

Add the Spring Boot starter dependency:

<dependency>
    <groupId>dev.tracekit</groupId>
    <artifactId>tracekit-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>

Or with Gradle:

implementation 'dev.tracekit:tracekit-spring-boot-starter:1.3.1'

Vanilla Java

Add the core SDK dependency:

<dependency>
    <groupId>dev.tracekit</groupId>
    <artifactId>tracekit-core</artifactId>
    <version>1.3.1</version>
</dependency>

Or with Gradle:

implementation 'dev.tracekit:tracekit-core:1.3.1'

Basic Setup

Spring Boot Configuration

Configure in application.yml:

tracekit:
  enabled: true
  api-key: ${TRACEKIT_API_KEY}
  service-name: my-service
  environment: production
  endpoint: https://app.tracekit.dev/v1/traces
  enable-code-monitoring: true  # Enables snapshot capture with security scanning

Auto-Configuration! The SDK auto-configures and starts tracing automatically. Spring Boot controllers, database queries, and HTTP clients are traced with zero code changes.

Vanilla Java Initialization

Initialize the SDK programmatically:

import dev.tracekit.TracekitSDK;
import dev.tracekit.TracekitConfig;

public class Application {
    public static void main(String[] args) {
        // Initialize SDK
        TracekitConfig config = TracekitConfig.builder()
            .apiKey(System.getenv("TRACEKIT_API_KEY"))
            .serviceName("my-service")
            .environment("production")
            .endpoint("https://app.tracekit.dev/v1/traces")
            .enableCodeMonitoring(true)
            .build();

        TracekitSDK sdk = TracekitSDK.create(config);

        // Your application code here...

        // Shutdown on application exit
        Runtime.getRuntime().addShutdownHook(new Thread(sdk::shutdown));
    }
}

Verify It Works -- Start your application and make a few requests. Then open the Traces page in your TraceKit dashboard. You should see:

  • SERVER spans for each incoming HTTP request (auto-configured for Spring Boot)
  • DB spans for JDBC database queries
  • CLIENT spans for outgoing HTTP calls

Traces typically appear within 30 seconds. If you don't see them, check the Troubleshooting section.

Framework Integration

The TraceKit SDK automatically instruments popular frameworks with zero code changes.

Spring Boot Example

Your existing Spring Boot controllers are automatically traced:

// Your existing Spring Boot application - NO CHANGES NEEDED!
@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users")
    public List<User> getUsers() {
        // This endpoint is automatically traced!
        return userService.findAll();
    }

    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        // This endpoint is also automatically traced!
        return userService.save(user);
    }
}

// Just add the dependency and configure - everything is traced automatically!

Spring Boot Auto-Configuration API

These classes are automatically registered when you add the Spring Boot starter dependency:

ClassTypeRegistrationDescription
TracekitAutoConfiguration@ConfigurationAuto (spring.factories)Spring Boot auto-configuration class. Automatically creates TracekitSDK bean when tracekit.api-key is set.
TracekitProperties@ConfigurationPropertiesAutoMaps Spring Boot application.properties/yml to TracekitConfig.
TracekitWebMvcConfigurerWebMvcConfigurerAutoRegisters HTTP interceptor for automatic SERVER span creation on all Spring MVC endpoints.

Spring Boot Auto-Configuration Example

Zero-configuration setup with Spring Boot:

// application.yml -- TracekitAutoConfiguration creates the bean automatically
tracekit:
  api-key: ${TRACEKIT_API_KEY}
  service-name: my-service
  enable-code-monitoring: true

// TracekitWebMvcConfigurer auto-registers the HTTP interceptor
// No @Bean or @Configuration needed -- just add the dependency:
//   implementation 'dev.tracekit:tracekit-spring-boot-starter:1.3.1'

// Your controllers are automatically traced!
@RestController
public class OrderController {
    @GetMapping("/api/orders")
    public List<Order> listOrders() {
        return orderService.findAll(); // Auto-traced!
    }
}

Code Monitoring & Security Scanning

Enable code monitoring to capture snapshots with automatic security scanning. The SDK detects and redacts sensitive information (PII, credentials, API keys) automatically.

// Code monitoring is enabled via configuration
tracekit:
  enable-code-monitoring: true

// Use captureSnapshot() to capture variable state with security scanning
import dev.tracekit.TracekitSDK;

public class OrderService {
    private final TracekitSDK tracekit;

    public void processOrder(Order order) {
        // Capture snapshot with automatic security scanning
        tracekit.captureSnapshot("order_processing",
            Map.of(
                "orderId", order.getId(),
                "customerId", order.getCustomerId(),
                "total", order.getTotal()
            )
        );

        // Process order...
    }
}

Automatic Security Scanning -- Sensitive data is automatically detected and redacted before sending to the backend. This includes email addresses, phone numbers, SSNs, credit cards, API keys, passwords, and private keys.

Code Monitoring API

Internal components used by the SDK for snapshot capture:

SymbolTypeDescription
SnapshotClientClass (Internal)Used internally for breakpoint polling and snapshot transmission. Use captureSnapshot() instead.
CaptureConfigClassConfiguration for snapshot capture including PII scrubbing, custom redaction patterns, and rate limits.
CircuitBreakerConfigClassCircuit breaker thresholds: failure count (default 3), window (default 60s), cooldown (default 5min).
SensitiveDataDetectorClassScans snapshot data for 13 built-in PII patterns and replaces matches with [REDACTED:type] markers.

Security Scanning API

SymbolTypeDescription
enableSecurityScanning(boolean)Builder methodEnable code-level security scanning for hardcoded secrets in snapshot data.
SensitiveDataDetectorClass (Advanced)Scans source code for hardcoded API keys, passwords, and tokens.

End-to-End Workflow

  1. Enable Code Monitoring -- Code monitoring defaults to disabled in Java. Enable via builder API (enableCodeMonitoring(true)) or Spring Boot property (tracekit.enable-code-monitoring: true).

  2. Add Snapshot Capture Points -- Place captureSnapshot() calls at points of interest.

tracekit.captureSnapshot("order-checkout", Map.of(
    "orderId", order.getId(),
    "total", order.getTotal(),
    "items", order.getItems().size(),
    "customer", customer.getEmail()
));
  1. Deploy and Verify Traces -- Deploy via mvn spring-boot:run or as a JAR. Check the Traces dashboard.

  2. Navigate to Code Monitoring -- Go to /snapshots and click the "Browse Code" tab.

  3. Set Breakpoints -- Breakpoints are auto-registered on the first captureSnapshot() call. You can also set them via the UI.

  4. Trigger Snapshot Capture -- Make a request that hits a code path containing captureSnapshot().

  5. View Captured Snapshot -- Inspect variables, stack trace, request context, and security flags at /snapshots.

Important: Spring Boot properties use kebab-case (enable-code-monitoring) while Java code uses camelCase (enableCodeMonitoring). This is standard Spring Boot relaxed binding.

Production Safety

v6.0 adds multiple layers of protection so code monitoring is safe for production workloads:

  • PII Scrubbing -- 13 built-in patterns via SensitiveDataDetector, enabled by default. Matched values are replaced with typed [REDACTED:type] markers before data leaves the process.
  • Crash Isolation -- Every capture entry point is wrapped in catch(Throwable) so a failure in the SDK never propagates to your application code.
  • Circuit Breaker -- After 3 failures within 60 seconds the SDK enters a 5-minute cooldown, then auto-recovers. Uses a synchronized thread-safe implementation.
  • Remote Kill Switch -- Toggle code monitoring on or off from the TraceKit dashboard. The change propagates to all connected SDK instances via SSE (daemon thread) in real time.

Real-Time Updates via SSE -- The Java SDK opens a Server-Sent Events connection using a BufferedReader on a daemon thread. Breakpoint enables/disables, kill-switch toggles, and configuration changes are pushed instantly -- no polling delay.

Full Code Monitoring Documentation

Manual Instrumentation (Optional)

For custom business logic not automatically traced, you can manually create spans using the OpenTelemetry API:

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;

public class OrderService {
    private static final Tracer tracer =
        GlobalOpenTelemetry.getTracer("order-service");

    public void processOrder(String orderId) {
        // Start a parent span
        Span span = tracer.spanBuilder("process_order")
            .setAttribute("order.id", orderId)
            .startSpan();

        try (Scope scope = span.makeCurrent()) {
            // Child spans automatically link to parent
            validateOrder(orderId);
            chargePayment(orderId);

            span.setAttribute("order.status", "completed");
        } finally {
            span.end();
        }
    }

    private void validateOrder(String orderId) {
        Span span = tracer.spanBuilder("validate_order")
            .setAttribute("order.id", orderId)
            .startSpan();
        try (Scope scope = span.makeCurrent()) {
            // Validation logic here
        } finally {
            span.end();
        }
    }
}

Core Tracing API

MethodParametersReturnsDescription
getOpenTelemetry()noneOpenTelemetryReturns the underlying OpenTelemetry instance for advanced usage.
getServiceName()noneStringReturns the configured service name.

LLM Instrumentation

TraceKit can instrument OpenAI and Anthropic API calls made via OkHttp. LLM calls appear as spans with OTel GenAI semantic convention attributes.

Manual setup required -- Add the TraceKit LLM interceptor to your OkHttp client to instrument OpenAI and Anthropic API calls. The interceptor captures model, tokens, cost, and latency automatically.

Setup

import dev.tracekit.llm.TracekitLlmInterceptor;
import okhttp3.OkHttpClient;

// Create an OkHttpClient with TraceKit LLM interceptor
OkHttpClient llmClient = new OkHttpClient.Builder()
    .addInterceptor(new TracekitLlmInterceptor())
    .build();

// Use this client with your OpenAI/Anthropic SDK
// OpenAI example:
OpenAIClient openai = OpenAIClient.builder()
    .httpClient(llmClient)
    .apiKey(System.getenv("OPENAI_API_KEY"))
    .build();

Configuration

TracekitLlmInterceptor interceptor = new TracekitLlmInterceptor(LlmConfig.builder()
    .captureContent(false)  // Capture prompts/completions (off by default)
    .openai(true)           // OpenAI instrumentation
    .anthropic(true)        // Anthropic instrumentation
    .build());

Captured Attributes

AttributeDescription
gen_ai.systemProvider name (openai, anthropic)
gen_ai.request.modelModel name (gpt-4o, claude-sonnet-4-20250514, etc.)
gen_ai.usage.input_tokensPrompt token count
gen_ai.usage.output_tokensCompletion token count
gen_ai.response.finish_reasonsFinish reason (stop, end_turn, tool_calls)

Environment Variable Override

Use TRACEKIT_LLM_CAPTURE_CONTENT=true to enable prompt/completion capture without code changes. Useful for enabling in staging but not production.

Streaming Support

Streaming responses produce a single span that covers the entire stream. Token counts are accumulated from the final chunk. No special configuration needed.

LLM Dashboard

View LLM cost, token usage, and latency metrics on the dedicated LLM Observability dashboard at /ai/llm in your TraceKit instance.

Environment Variables

Best practice: Store sensitive configuration in environment variables:

# .env or environment variables
TRACEKIT_API_KEY=ctxio_your_generated_api_key_here
OTEL_SERVICE_NAME=my-java-app
OTEL_EXPORTER_OTLP_ENDPOINT=https://app.tracekit.dev/v1/traces

Core Configuration (TracekitConfig)

OptionTypeDefaultEnv VariableDescription
apiKeyStringrequiredTRACEKIT_API_KEYYour TraceKit API key for authentication
serviceNameStringrequiredTRACEKIT_SERVICE_NAMEName of your service in the trace dashboard
endpointString"https://app.tracekit.dev/v1/traces"TRACEKIT_ENDPOINTTraceKit collector endpoint URL
environmentString"production"TRACEKIT_ENVIRONMENTDeployment environment (e.g. production, staging)
enableCodeMonitoringbooleanfalseTRACEKIT_CODE_MONITORING_ENABLEDEnable live code debugging / snapshot capture
enableSecurityScanningbooleanfalseTRACEKIT_SECURITY_SCANNING_ENABLEDEnable security scanning for code analysis
localUIPortint9999TRACEKIT_LOCAL_UI_PORTPort for the local development UI

Spring Boot Properties

PropertyTypeDefaultDescription
tracekit.enabledbooleantrueEnable or disable TraceKit auto-configuration
tracekit.api-keyStringrequiredYour TraceKit API key
tracekit.service-nameStringrequiredName of your service
tracekit.endpointString"https://app.tracekit.dev/v1/traces"TraceKit collector endpoint URL
tracekit.environmentString"production"Deployment environment
tracekit.enable-code-monitoringbooleanfalseEnable live code debugging
tracekit.enable-security-scanningbooleanfalseEnable security scanning
tracekit.local-ui-portint9999Port for local development UI

Spring Boot auto-reads properties from application.properties or application.yml. For standalone Java, use environment variables with manual loading.

Production Configuration

Production Checklist:

  • Use HTTPS/TLS for the OTLP endpoint
  • Store API keys in a secrets manager (AWS Secrets Manager, HashiCorp Vault)
  • Set appropriate service names and versions
  • Configure resource attributes (deployment.environment, host.name, etc.)
  • Adjust sampling rates if needed for high-traffic services
  • Monitor Java Agent overhead (typically less than 5%)

Custom Metrics

Track custom metrics like request counts, queue sizes, and response times using the TraceKit metrics API.

Counter

Track monotonically increasing values (requests, events):

import dev.tracekit.TracekitSDK;
import dev.tracekit.metrics.Counter;
import java.util.Map;

// Get the SDK (injected in Spring Boot or created manually)
TracekitSDK sdk = ...;

// Create a counter with optional tags
Counter counter = sdk.counter("http.requests.total",
    Map.of("service", "api"));

// Increment by 1
counter.inc();

// Add a specific value
counter.add(5.0);

Gauge

Track values that can go up or down (queue size, connections):

import dev.tracekit.metrics.Gauge;

// Create a gauge
Gauge gauge = sdk.gauge("http.connections.active", Map.of());

// Set to specific value
gauge.set(42.0);

// Increment/decrement
gauge.inc();
gauge.dec();

Histogram

Track value distributions (latencies, sizes):

import dev.tracekit.metrics.Histogram;

// Create a histogram with tags
Histogram histogram = sdk.histogram("http.request.duration",
    Map.of("unit", "ms"));

// Record values
histogram.record(45.2);
histogram.record(123.5);

View Custom Metrics Guide

Troubleshooting

Traces not appearing?

Cause: The SDK is not initialized or the endpoint URL is incorrect.

Fix:

  • Verify TracekitConfig is created with correct apiKey and endpoint
  • For Spring Boot, check application.properties has tracekit.api-key (kebab-case, NOT tracekit.apiKey)
  • Look for OpenTelemetry errors in application logs

-javaagent not working?

Cause: JVM argument ordering matters -- the agent must be loaded before the application.

Fix:

  • Place -javaagent:/path/to/opentelemetry-javaagent.jar BEFORE -jar myapp.jar in your command
  • Verify with java -javaagent:otel.jar -jar myapp.jar (not java -jar myapp.jar -javaagent:otel.jar)

Code monitoring not working?

Cause: Code monitoring defaults to disabled in the Java SDK.

Fix:

  • Set enableCodeMonitoring(true) in TracekitConfig builder
  • For Spring Boot: tracekit.enable-code-monitoring=true in application.properties
  • Add TracekitSDK.captureSnapshot("label") calls in target code
  • Verify permissions in dashboard

Spring Boot property names not recognized?

Cause: Spring Boot uses kebab-case for properties, not camelCase.

Fix:

  • Use tracekit.api-key not tracekit.apiKey
  • Use tracekit.service-name not tracekit.serviceName
  • Use tracekit.enable-code-monitoring not tracekit.enableCodeMonitoring
  • Spring Boot's relaxed binding handles some variations but kebab-case is the canonical form

Authentication errors (401/403)?

Cause: API key is wrong or has extra characters.

Fix:

  • For Spring Boot, verify in application.properties (no quotes needed around values)
  • For standalone Java, trim whitespace from env var
  • Regenerate key in dashboard if expired
  • Check that the full endpoint URL includes the path: https://app.tracekit.dev/v1/traces

Complete Example

Here's a complete working Spring Boot example:

// Complete Spring Boot example with TraceKit SDK

// pom.xml
<dependency>
    <groupId>dev.tracekit</groupId>
    <artifactId>tracekit-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</dependency>

// application.yml
tracekit:
  enabled: true
  api-key: ${TRACEKIT_API_KEY}
  service-name: spring-api
  environment: production
  enable-code-monitoring: true

// Application.java
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// UserController.java - automatically traced!
@RestController
@RequestMapping("/api")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @GetMapping("/users")
    public List<User> getUsers() {
        // Automatically traced - no code changes needed!
        return userRepository.findAll();
    }

    @PostMapping("/users")
    public User createUser(@RequestBody User user) {
        // Automatically traced - no code changes needed!
        return userRepository.save(user);
    }
}

// That's it! Run normally: mvn spring-boot:run

You're all set! Your Java application is now sending traces to TraceKit. Visit the Dashboard to see your traces.

Migrating from OpenTelemetry

TraceKit wraps OpenTelemetry internally, so you get the same standards-based trace data with significantly less setup code.

Before vs After

Before: Raw OpenTelemetry (~40 lines):

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.ResourceAttributes;

OtlpGrpcSpanExporter exporter = OtlpGrpcSpanExporter.builder()
    .setEndpoint("https://api.tracekit.io")
    .build();
SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
    .addSpanProcessor(BatchSpanProcessor.builder(exporter).build())
    .setResource(Resource.getDefault().toBuilder()
        .put(ResourceAttributes.SERVICE_NAME, "my-service")
        .build())
    .build();
OpenTelemetrySdk.builder()
    .setTracerProvider(tracerProvider)
    .buildAndRegisterGlobal();

After: TraceKit SDK (6 lines):

# application.yml (Spring Boot)
tracekit:
  api-key: ${TRACEKIT_API_KEY}
  service-name: my-service
  enabled: true

Migration Steps

  1. Add dependency: Maven or Gradle: dev.tracekit:tracekit-spring-boot-starter
  2. For Spring Boot: Add YAML config. For programmatic: replace OTel init with TracekitSDK.create()
  3. Remove agent flags: If using the OTel Java agent, remove -javaagent JVM flags
  4. Remove OTel dependencies: Remove opentelemetry-api, opentelemetry-sdk, and opentelemetry-exporter-otlp
  5. Verify: Start your app and check the Traces page for incoming data

Key Migration Benefits:

  • 40 lines to 6 lines -- Spring Boot auto-configuration replaces manual SDK setup
  • No OTel dependency management -- TraceKit handles version pinning internally
  • Built-in code monitoring -- not available with raw OpenTelemetry
  • Built-in security scanning -- automatic variable redaction on snapshots
  • Spring Boot starter -- auto-configuration with YAML properties

Performance Overhead

TraceKit is built on OpenTelemetry's efficient batch processing pipeline. The SDK adds minimal overhead to your Java application.

MetricImpactDetails
Request Tracing< 1ms per requestSpans are batched and exported asynchronously
Code Monitoring (Idle)Zero overheadNo performance impact when no active breakpoints
Code Monitoring (Capture)< 5ms per snapshotIncludes variable serialization and security scanning
Memory Footprint~20-40 MBSDK runtime and span buffer
SDK Initialization< 1s one-timeIncludes OpenTelemetry provider setup and Spring Boot auto-configuration

Java Agent: Monitor Java Agent overhead is typically less than 5% CPU. The agent uses bytecode instrumentation to minimize runtime impact.

Performance characteristics are typical for production workloads and may vary with application complexity, request volume, and number of instrumented libraries. Use sampling configuration to reduce overhead in high-traffic services.

Best Practices

DO:

  • Use Spring Boot auto-configuration when possible -- just add the dependency and configure via application.yml
  • Use application.yml / application.properties for config in Spring Boot apps
  • Use environment variables for API keys -- store in TRACEKIT_API_KEY rather than hardcoding
  • Call shutdown/flush on application exit -- Spring Boot handles this via @PreDestroy
  • Enable code monitoring in staging first before production
  • Use sampling in high-traffic services -- set TRACEKIT_SAMPLING_RATE below 1.0
  • Set meaningful service names for easy identification in the trace viewer

DON'T:

  • Mix Java agent and SDK initialization -- use one approach, not both
  • Use TracekitSDK.create() manually in Spring Boot apps -- auto-configuration handles it
  • Create spans for every function -- trace boundaries like HTTP handlers, DB calls, and external services
  • Add high-cardinality attributes -- avoid user IDs, request IDs, or session tokens as span attributes
  • Disable TLS in production -- the TRACEKIT_INSECURE flag is for local development only

Next Steps

  • Explore your traces on the Traces page to identify performance bottlenecks
  • Optionally add custom spans for specific business logic you want to measure
  • Configure sampling for high-traffic services to reduce overhead
  • Set up alert rules to get notified when issues occur

On this page