Code Monitoring
Debug production code without stopping your application. Set non-breaking breakpoints and capture variable state in real-time.
Production Debugging Without Downtime!
Set breakpoints in production and capture variables, stack traces, and context without redeploying. Built-in PII scrubbing, crash isolation, circuit breakers, and real-time SSE updates. Less than 5ms overhead.
What is Code Monitoring?
Non-Breaking Breakpoints
Create breakpoints that capture data without stopping your application.
Capture Variable State
See all variable values at the exact moment the breakpoint was hit.
Full Stack Traces
Complete call stack showing how code reached that breakpoint.
Request Context
HTTP headers, trace IDs, and more to understand what triggered execution.
How It Works
Automatic Code Discovery
TraceKit automatically indexes your code from traces you're already sending. When traces contain stack traces (from errors or instrumentation), we extract file paths, functions, and line numbers. No extra instrumentation needed!
Send Traces
Your existing traces automatically index code. Stack traces reveal file paths and functions.
Browse & Set Breakpoints
Click "Browse Code" to see discovered files/functions, then click "Set Breakpoint" on any location.
Capture & Debug
When that code runs, we capture variables, stack trace, and context automatically. View snapshots in the UI.
Recommended: Use CheckAndCaptureWithContext() for automatic breakpoint registration. The SDK handles file detection, line tracking, and breakpoint creation for you!
Quick Start
Step 1: Install & Enable Code Monitoring
Choose your language to see install and enable instructions:
Install
go get github.com/Tracekit-Dev/go-sdk/tracekit
Enable Code Monitoring
sdk, _ := tracekit.NewSDK(&tracekit.Config{
APIKey: os.Getenv("TRACEKIT_API_KEY"),
ServiceName: "order-service",
EnableCodeMonitoring: true,
})
defer sdk.Shutdown(context.Background())
Capture Snapshot
sdk.CheckAndCaptureWithContext(ctx, "order-processing", map[string]interface{}{
"orderID": orderID,
"total": total,
"status": "validated",
})
Install
pip install tracekit-apm
Enable Code Monitoring (default: disabled)
import tracekit
client = tracekit.init(
api_key=os.getenv("TRACEKIT_API_KEY"),
service_name="my-flask-app",
enable_code_monitoring=True, # default: False
)
Capture Snapshot
client.capture_snapshot("order-processing", {
"order_id": order["id"],
"total": order["total"],
"user_id": user.id,
})
Install
npm install @tracekit/node-apm
Enable Code Monitoring (default: disabled)
import * as tracekit from '@tracekit/node-apm';
const client = tracekit.init({
apiKey: process.env.TRACEKIT_API_KEY,
serviceName: 'my-app',
enableCodeMonitoring: true,
});
Capture Snapshot (async — use await)
await client.captureSnapshot('checkout-validation', {
userId,
amount,
timestamp: new Date().toISOString(),
});
Install
composer require tracekit/php-apm
Enable Code Monitoring (default: disabled)
$tracekit = new TracekitClient([
'api_key' => getenv('TRACEKIT_API_KEY'),
'service_name' => 'my-php-app',
'endpoint' => 'https://your-app.com/v1/traces',
'code_monitoring_enabled' => true,
]);
Capture Snapshot
$tracekit->captureSnapshot('checkout-validation', [
'user_id' => $userId,
'cart_items' => count($cart['items']),
'total_amount' => $cart['total'],
]);
Install
composer require tracekit/laravel-apm
Enable Code Monitoring (via .env)
TRACEKIT_CODE_MONITORING_ENABLED=true
TRACEKIT_CODE_MONITORING_POLL_INTERVAL=30
Capture Snapshot
tracekit_snapshot('checkout-start', [
'user_id' => $userId,
'cart_total' => $cartTotal,
'items_count' => count($items),
]);
Install
<dependency>
<groupId>dev.tracekit</groupId>
<artifactId>tracekit-core</artifactId>
</dependency>
Enable Code Monitoring (Spring Boot YAML)
tracekit:
enable-code-monitoring: true
Capture Snapshot
tracekit.captureSnapshot("order_processing",
Map.of(
"orderId", order.getId(),
"customerId", order.getCustomerId(),
"total", order.getTotal()
)
);
Install
dotnet add package TraceKit.AspNetCore
Enable Code Monitoring (default: enabled)
var sdk = TracekitSDK.CreateBuilder()
.WithApiKey(Environment.GetEnvironmentVariable("TRACEKIT_API_KEY"))
.WithServiceName("my-dotnet-app")
.WithEnableCodeMonitoring(true) // default: true
.Build();
Capture Snapshot
sdk.CaptureSnapshot("order-checkout", new Dictionary<string, object>
{
{ "orderId", order.Id },
{ "total", order.Total },
{ "userId", user.Id }
});
Install
bundle add tracekit
Enable Code Monitoring (default: enabled)
Tracekit::SDK.configure do |c|
c.api_key = ENV['TRACEKIT_API_KEY']
c.service_name = "my-rails-app"
c.enable_code_monitoring = true # defaults to true
end
Capture Snapshot
Tracekit.capture_snapshot('order-create', {
order_id: order.id,
total: order.total,
user_id: user.id,
items: order.line_items.count
})
Step 3: Add Checkpoints (Automatic)
Recommended: Automatic Breakpoint Registration
Breakpoints are automatically created and updated when you call CheckAndCaptureWithContext. No manual UI setup required!
// Automatic file/line detection + auto-creates breakpoint!
sdk.CheckAndCaptureWithContext(ctx, "payment-processing", map[string]interface{}{
"userID": userID,
"amount": amount,
})
// The SDK will:
// 1. Detect file path and line number automatically
// 2. Auto-create/update the breakpoint in TraceKit
// 3. Capture snapshot when breakpoint is activeStep 4: View & Manage (Optional)
Breakpoints are automatically created and enabled. You can optionally:
- View captured snapshots in the UI at
/snapshots - Adjust conditions or sampling rates
- Browse auto-discovered code
- Disable/enable breakpoints as needed
Advanced: Manual Breakpoint Creation
For advanced users who want full control, you can manually create breakpoints in the UI first:
Go to Code Monitoring and create a breakpoint for payment.go:42
Production Safety
Code monitoring is built for production from day one. Every SDK includes multiple layers of protection to ensure zero impact on your application, even under failure conditions.
PII Scrubbing (Default On)
13 built-in patterns automatically redact sensitive data before it leaves your application. Emails, SSNs, credit cards, API keys, JWTs, and more are replaced with typed markers like [REDACTED:email].
Enabled by default. Add custom patterns or disable per-service.
Crash Isolation
Every SDK entry point is wrapped in language-idiomatic recovery handlers. A bug in TraceKit's snapshot code will never crash your application — the SDK recovers silently and continues.
Go: defer/recover. Node: try/catch. Java: catch(Throwable). And more.
Circuit Breaker
If the TraceKit backend is unreachable, the SDK automatically stops sending snapshots after 3 failures in 60 seconds. It re-enables after a 5-minute cooldown. No manual intervention needed.
Thresholds are configurable per SDK instance.
Remote Kill Switch
Instantly disable all code monitoring for a service from the dashboard. The kill switch propagates to all connected SDKs in real-time via SSE, or within 60 seconds via polling.
One click in the dashboard to stop all captures immediately.
All safety features are enabled by default across all 8 SDKs. No configuration required — just enable code monitoring and you're protected.
Real-Time Updates
Breakpoint changes propagate to your SDKs in under 1 second using Server-Sent Events (SSE). No more waiting for the next 30-second poll cycle.
Auto-Discovery
When your SDK polls for breakpoints, the server returns an sse_endpoint URL. The SDK automatically connects.
Real-Time Streaming
Breakpoint creates, updates, deletes, and kill switch commands stream instantly to connected SDKs. Polling pauses while SSE is active.
Automatic Fallback
If the SSE connection drops, the SDK seamlessly falls back to polling and reconnects SSE on the next successful poll.
Dashboard Live Updates
The Code Monitoring dashboard also uses SSE for live capture counters, breakpoint status changes, and connected SDK count — all without page refresh.
Server-Side Conditions
Breakpoint conditions (e.g., user.id == 42) are evaluated server-side in a sandboxed engine. SDKs send metadata via a check-in endpoint, and the server decides whether to capture.
Available SDKs
Code Monitoring is available in all TraceKit SDKs. Choose your language to get started:
Official SDK for Node.js and TypeScript applications
- Express & Fastify middleware
- Full TypeScript support
- Automatic batching & retry
Official SDK for Python 3.8+ applications
- Flask, Django & FastAPI middleware
- Type hints support
- Context managers for tracing
Official SDK for Go applications
- Goroutine-safe logging
- Automatic batching & retry
- Context support for tracing
Official SDK for PHP 8.1+ applications
- Symfony & PSR-15 middleware
- Strict types & enums
- Auto-shutdown handling
Official SDK for Java & Kotlin applications
- Spring Boot auto-configuration
- Kotlin coroutine support
- Annotation-based tracing
Official SDK for .NET 8+ applications
- ASP.NET Core middleware
- Dependency injection support
- Minimal API integration
First-class Laravel integration package
- Auto-discovery & zero config
- Queue & job tracing
- Blade directive support
Official SDK for Ruby 2.7+ and Rails applications
- Rails Railtie auto-configuration
- Sidekiq & Redis tracing
- Security scanning built-in
Jump to SDK Code Monitoring Sections
Advanced Configuration
All safety features work with zero configuration. For advanced use cases, you can tune capture limits, PII patterns, and circuit breaker thresholds.
sdk, _ := tracekit.NewSDK(&tracekit.Config{
APIKey: os.Getenv("TRACEKIT_API_KEY"),
ServiceName: "order-service",
EnableCodeMonitoring: true,
CaptureConfig: &tracekit.CaptureConfig{
CaptureDepth: 10, // Max nesting depth (0 = unlimited)
MaxPayload: 65536, // Max payload bytes (0 = unlimited)
CaptureTimeout: 5 * time.Second, // Capture timeout (0 = none)
PIIScrubbing: boolPtr(true), // Default: enabled
CircuitBreaker: &tracekit.CircuitBreakerConfig{
MaxFailures: 3, // Failures before tripping (default: 3)
WindowMs: 60000, // Failure window in ms (default: 60s)
CooldownMs: 300000,// Auto-recovery after (default: 5min)
},
},
})
const client = tracekit.init({
apiKey: process.env.TRACEKIT_API_KEY,
serviceName: 'order-service',
enableCodeMonitoring: true,
captureConfig: {
captureDepth: 10, // Max nesting depth (undefined = unlimited)
maxPayload: 65536, // Max payload bytes (undefined = unlimited)
captureTimeout: 5000, // Capture timeout in ms (undefined = none)
piiScrubbing: true, // Default: true
circuitBreaker: {
maxFailures: 3, // Failures before tripping (default: 3)
windowMs: 60000, // Failure window in ms (default: 60s)
cooldownMs: 300000, // Auto-recovery after (default: 5min)
},
},
});
client = tracekit.init(
api_key=os.getenv("TRACEKIT_API_KEY"),
service_name="order-service",
enable_code_monitoring=True,
capture_config={
"capture_depth": 10, # Max nesting depth (None = unlimited)
"max_payload": 65536, # Max payload bytes (None = unlimited)
"capture_timeout": 5.0, # Capture timeout in seconds (None = none)
"pii_scrubbing": True, # Default: True
"circuit_breaker": {
"max_failures": 3, # Failures before tripping (default: 3)
"window_ms": 60000, # Failure window in ms (default: 60s)
"cooldown_ms": 300000, # Auto-recovery after (default: 5min)
},
},
)
TracekitConfig config = TracekitConfig.builder()
.apiKey(System.getenv("TRACEKIT_API_KEY"))
.serviceName("order-service")
.enableCodeMonitoring(true)
.captureDepth(10) // Max nesting depth (0 = unlimited)
.maxPayload(65536) // Max payload bytes (0 = unlimited)
.captureTimeoutMs(5000) // Capture timeout in ms (0 = none)
.piiScrubbing(true) // Default: true
.circuitBreakerMaxFailures(3) // Default: 3
.circuitBreakerWindowMs(60000) // Default: 60s
.circuitBreakerCooldownMs(300000) // Default: 5min
.build();
var sdk = TracekitSDK.CreateBuilder()
.WithApiKey(Environment.GetEnvironmentVariable("TRACEKIT_API_KEY"))
.WithServiceName("order-service")
.WithEnableCodeMonitoring(true)
.WithCaptureDepth(10) // Max nesting depth (0 = unlimited)
.WithMaxPayload(65536) // Max payload bytes (0 = unlimited)
.WithCaptureTimeoutMs(5000) // Capture timeout in ms (0 = none)
.WithPiiScrubbing(true) // Default: true
.WithCircuitBreakerMaxFailures(3) // Default: 3
.WithCircuitBreakerWindowMs(60000) // Default: 60s
.WithCircuitBreakerCooldownMs(300000) // Default: 5min
.Build();
Tracekit::SDK.configure do |c|
c.api_key = ENV['TRACEKIT_API_KEY']
c.service_name = "order-service"
c.enable_code_monitoring = true
c.capture_depth = 10 # Max nesting depth (nil = unlimited)
c.max_payload = 65536 # Max payload bytes (nil = unlimited)
c.capture_timeout = 5.0 # Capture timeout in seconds (nil = none)
c.pii_scrubbing = true # Default: true
c.circuit_breaker_max_failures = 3 # Default: 3
c.circuit_breaker_window_ms = 60000 # Default: 60s
c.circuit_breaker_cooldown_ms = 300000 # Default: 5min
end
Use Cases
Debug Production Issues
Customer reports error? Set breakpoint to see exact state next time it happens.
Performance Investigation
Capture input size and timing to find what causes slowdowns.
Verify Calculations
Track money flows through complex pipelines to ensure correctness.
Troubleshooting
No snapshots captured?
• Check breakpoint is enabled and not expired
• Verify file path and line number match
• Ensure service name matches between SDK and breakpoint
• Check the kill switch is not active for the service
• Verify the circuit breaker hasn't tripped (check SDK logs for "circuit breaker open")
• If using conditions, verify the condition expression is valid
Performance concerns?
• Use max_captures to limit total captures per breakpoint
• Set capture_frequency for sampling
• Set short expiration times on breakpoints
• Use opt-in capture limits (captureDepth, maxPayload, captureTimeout)
• The circuit breaker auto-disables after 3 failures — no manual action needed
Variables showing [REDACTED:type]?
• PII scrubbing is enabled by default and redacts sensitive data before transmission
• 13 built-in patterns detect emails, SSNs, credit cards, API keys, JWTs, and more
• To disable for a specific service, set piiScrubbing: false in your capture config
• Custom patterns can be added via the piiPatterns config option
Circuit breaker tripped?
• The circuit breaker opens after 3 HTTP 5xx/network failures within 60 seconds
• It auto-recovers after 5 minutes — no restart required
• Check your network connectivity and TraceKit server status
• Thresholds can be tuned via circuitBreaker config
SSE not connecting?
• SSE auto-discovers via polling — ensure at least one poll has completed
• SSE only activates when breakpoints exist and kill switch is off
• The SDK falls back to polling if SSE is unavailable
• PHP/Laravel in web request mode use polling only (SSE for CLI/worker processes)