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:
| Component | Span Type | Captured Attributes | Auto-Traced? |
|---|---|---|---|
| HTTP Endpoints | SERVER | method, route, status_code, duration, client_ip | Yes |
| JDBC Queries | DB | db.system, db.statement, db.name, duration | Yes |
| HTTP Client Calls | CLIENT | method, url, status_code, duration, peer.service | Yes |
| Spring Boot | SERVER | spring.handler, method, route | Yes (auto-config) |
| Kafka/RabbitMQ | Custom | messaging.system, messaging.destination, messaging.operation | Yes |
| Custom Business Logic | Custom | user-defined attributes | Manual |
Installation
Spring Boot (Recommended)
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 scanningAuto-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:
| Class | Type | Registration | Description |
|---|---|---|---|
TracekitAutoConfiguration | @Configuration | Auto (spring.factories) | Spring Boot auto-configuration class. Automatically creates TracekitSDK bean when tracekit.api-key is set. |
TracekitProperties | @ConfigurationProperties | Auto | Maps Spring Boot application.properties/yml to TracekitConfig. |
TracekitWebMvcConfigurer | WebMvcConfigurer | Auto | Registers 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:
| Symbol | Type | Description |
|---|---|---|
SnapshotClient | Class (Internal) | Used internally for breakpoint polling and snapshot transmission. Use captureSnapshot() instead. |
CaptureConfig | Class | Configuration for snapshot capture including PII scrubbing, custom redaction patterns, and rate limits. |
CircuitBreakerConfig | Class | Circuit breaker thresholds: failure count (default 3), window (default 60s), cooldown (default 5min). |
SensitiveDataDetector | Class | Scans snapshot data for 13 built-in PII patterns and replaces matches with [REDACTED:type] markers. |
Security Scanning API
| Symbol | Type | Description |
|---|---|---|
enableSecurityScanning(boolean) | Builder method | Enable code-level security scanning for hardcoded secrets in snapshot data. |
SensitiveDataDetector | Class (Advanced) | Scans source code for hardcoded API keys, passwords, and tokens. |
End-to-End Workflow
-
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). -
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()
));-
Deploy and Verify Traces -- Deploy via
mvn spring-boot:runor as a JAR. Check the Traces dashboard. -
Navigate to Code Monitoring -- Go to /snapshots and click the "Browse Code" tab.
-
Set Breakpoints -- Breakpoints are auto-registered on the first
captureSnapshot()call. You can also set them via the UI. -
Trigger Snapshot Capture -- Make a request that hits a code path containing
captureSnapshot(). -
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
synchronizedthread-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
| Method | Parameters | Returns | Description |
|---|---|---|---|
getOpenTelemetry() | none | OpenTelemetry | Returns the underlying OpenTelemetry instance for advanced usage. |
getServiceName() | none | String | Returns 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
| Attribute | Description |
|---|---|
gen_ai.system | Provider name (openai, anthropic) |
gen_ai.request.model | Model name (gpt-4o, claude-sonnet-4-20250514, etc.) |
gen_ai.usage.input_tokens | Prompt token count |
gen_ai.usage.output_tokens | Completion token count |
gen_ai.response.finish_reasons | Finish 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/tracesCore Configuration (TracekitConfig)
| Option | Type | Default | Env Variable | Description |
|---|---|---|---|---|
apiKey | String | required | TRACEKIT_API_KEY | Your TraceKit API key for authentication |
serviceName | String | required | TRACEKIT_SERVICE_NAME | Name of your service in the trace dashboard |
endpoint | String | "https://app.tracekit.dev/v1/traces" | TRACEKIT_ENDPOINT | TraceKit collector endpoint URL |
environment | String | "production" | TRACEKIT_ENVIRONMENT | Deployment environment (e.g. production, staging) |
enableCodeMonitoring | boolean | false | TRACEKIT_CODE_MONITORING_ENABLED | Enable live code debugging / snapshot capture |
enableSecurityScanning | boolean | false | TRACEKIT_SECURITY_SCANNING_ENABLED | Enable security scanning for code analysis |
localUIPort | int | 9999 | TRACEKIT_LOCAL_UI_PORT | Port for the local development UI |
Spring Boot Properties
| Property | Type | Default | Description |
|---|---|---|---|
tracekit.enabled | boolean | true | Enable or disable TraceKit auto-configuration |
tracekit.api-key | String | required | Your TraceKit API key |
tracekit.service-name | String | required | Name of your service |
tracekit.endpoint | String | "https://app.tracekit.dev/v1/traces" | TraceKit collector endpoint URL |
tracekit.environment | String | "production" | Deployment environment |
tracekit.enable-code-monitoring | boolean | false | Enable live code debugging |
tracekit.enable-security-scanning | boolean | false | Enable security scanning |
tracekit.local-ui-port | int | 9999 | Port 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);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.propertieshastracekit.api-key(kebab-case, NOTtracekit.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.jarBEFORE-jar myapp.jarin your command - Verify with
java -javaagent:otel.jar -jar myapp.jar(notjava -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=truein 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-keynottracekit.apiKey - Use
tracekit.service-namenottracekit.serviceName - Use
tracekit.enable-code-monitoringnottracekit.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:runYou'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: trueMigration Steps
- Add dependency: Maven or Gradle:
dev.tracekit:tracekit-spring-boot-starter - For Spring Boot: Add YAML config. For programmatic: replace OTel init with
TracekitSDK.create() - Remove agent flags: If using the OTel Java agent, remove
-javaagentJVM flags - Remove OTel dependencies: Remove
opentelemetry-api,opentelemetry-sdk, andopentelemetry-exporter-otlp - 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.
| Metric | Impact | Details |
|---|---|---|
| Request Tracing | < 1ms per request | Spans are batched and exported asynchronously |
| Code Monitoring (Idle) | Zero overhead | No performance impact when no active breakpoints |
| Code Monitoring (Capture) | < 5ms per snapshot | Includes variable serialization and security scanning |
| Memory Footprint | ~20-40 MB | SDK runtime and span buffer |
| SDK Initialization | < 1s one-time | Includes 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.propertiesfor config in Spring Boot apps - Use environment variables for API keys -- store in
TRACEKIT_API_KEYrather 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_RATEbelow 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_INSECUREflag 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
PHP Language Integration
Integrate TraceKit with vanilla PHP applications. Automatic distributed tracing with live breakpoints for debugging production PHP code without redeploying.
Ruby Integration Guide
Add TraceKit to your Ruby applications for automatic distributed tracing. Debug production Ruby services with live breakpoints and Rails/Sinatra support.