-
-
Notifications
You must be signed in to change notification settings - Fork 11
Telemetry
CKB integrates with OpenTelemetry to answer the question static analysis can't: "Is this code actually used in production?"
By ingesting runtime metrics, CKB can:
- Detect dead code with high confidence
- Show actual call counts for any symbol
- Enrich impact analysis with observed callers
- Distinguish between "no static references" and "truly unused"
Add to .ckb/config.json:
{
"telemetry": {
"enabled": true,
"serviceMap": {
"my-api-service": "my-repo"
}
}
}Point your collector's exporter at CKB:
# otel-collector-config.yaml
exporters:
otlphttp:
endpoint: "http://localhost:9120/v1/metrics"
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]ckb telemetry statusYou should see:
Telemetry Status
Enabled: true
Last Sync: 2 minutes ago
Coverage:
Symbol: 78% (23,456 of 30,123 symbols have telemetry)
Service: 100% (3 of 3 repos mapped)
Coverage Level: HIGH
CKB requires sufficient telemetry coverage to enable certain features:
| Coverage | Symbol % | What's Available |
|---|---|---|
| High | ≥ 70% | Full dead code detection, high-confidence verdicts |
| Medium | 40-69% | Dead code detection with caveats, observed usage |
| Low | 10-39% | Basic observed usage only |
| Insufficient | < 10% | Telemetry features disabled |
Check your coverage:
ckb telemetry statusWith telemetry enabled, you can find code that's never called in production:
# Find dead code candidates (requires medium+ coverage)
ckb dead-code --min-confidence 0.7
# Scope to a specific module
ckb dead-code --scope internal/legacy
# Include low-confidence results
ckb dead-code --min-confidence 0.5Dead code confidence combines:
- Static analysis — No references found in code
- Telemetry — Zero calls observed over the period
- Match quality — How well telemetry maps to symbols
| Confidence | Meaning |
|---|---|
| 0.9+ | High confidence dead code — safe to remove |
| 0.7-0.9 | Likely dead — verify before removing |
| 0.5-0.7 | Possibly dead — investigate further |
| < 0.5 | Uncertain — may have dynamic callers |
Get observed usage for any symbol:
ckb telemetry usage --symbol "internal/api/handler.go:HandleRequest"Output:
Symbol: HandleRequest
Period: Last 90 days
Observed Usage:
Total Calls: 1,247,832
Daily Average: 13,864
Trend: stable
Match Quality: exact
Last Seen: 2 hours ago
| Quality | Meaning |
|---|---|
| exact | Symbol name matches telemetry span exactly |
| strong | High-confidence fuzzy match |
| weak | Low-confidence match — verify manually |
CKB needs to know which telemetry service corresponds to which repository.
{
"telemetry": {
"serviceMap": {
"api-gateway": "api-repo",
"user-service": "users-repo",
"payment-worker": "payments-repo"
}
}
}- Explicit
serviceMapentry -
ckb_repo_idattribute in telemetry payload - Service name matches repo name exactly
# See which services aren't mapped
ckb telemetry unmapped
# Test if a service name would map
ckb telemetry test-map "my-service-name"When telemetry is enabled, analyzeImpact includes observed callers:
# Via CLI
ckb impact <symbol-id> --include-telemetry
# Via MCP
analyzeImpact({ symbolId: "...", includeTelemetry: true })The response includes:
-
observedCallers— Services that call this symbol at runtime -
blendedConfidence— Combines static + observed confidence -
observedOnly— Callers found only via telemetry (not in code)
This catches cases where static analysis misses dynamic dispatch or reflection.
Full configuration options:
{
"telemetry": {
"enabled": true,
"serviceMap": {
"service-name": "repo-id"
},
"storage": {
"retention_days": 365,
"aggregation_interval": "1h",
"max_symbols_per_service": 100000
},
"privacy": {
"hash_service_names": false,
"redact_symbol_names": false
}
}
}| Setting | Default | Description |
|---|---|---|
enabled |
false | Enable telemetry features |
serviceMap |
{} | Maps service names to repo IDs |
storage.retention_days |
365 | Days to retain telemetry data |
storage.aggregation_interval |
"1h" | How often to aggregate metrics |
privacy.hash_service_names |
false | Hash service names for privacy |
# Check status and coverage
ckb telemetry status
# Get usage for a symbol
ckb telemetry usage --symbol "pkg/handler.go:HandleRequest"
# List unmapped services
ckb telemetry unmapped
# Test service name mapping
ckb telemetry test-map "my-service"
# Find dead code
ckb dead-code [--min-confidence 0.7] [--scope module]| Tool | Purpose |
|---|---|
getTelemetryStatus |
Coverage metrics and sync status |
getObservedUsage |
Runtime usage for a symbol |
findDeadCodeCandidates |
Symbols with zero runtime calls |
Enhanced tools:
-
analyzeImpact— AddincludeTelemetry: truefor observed callers -
getHotspots— IncludesobservedUsagewhen telemetry enabled
# Get status
curl http://localhost:8080/telemetry/status
# Get symbol usage
curl "http://localhost:8080/telemetry/usage/SYMBOL_ID?period=30d"
# Find dead code
curl "http://localhost:8080/telemetry/dead-code?minConfidence=0.7"
# List unmapped services
curl http://localhost:8080/telemetry/unmapped
# OTLP ingest endpoint (for collectors)
POST http://localhost:9120/v1/metricsAdd to .ckb/config.json:
{ "telemetry": { "enabled": true } }Your instrumentation may not cover enough symbols. Check:
- Are all services sending telemetry?
- Is
serviceMapconfigured correctly? - Run
ckb telemetry unmappedto find gaps
Possible causes:
- Symbol isn't called at runtime (it may actually be dead)
- Service mapping is wrong
- Telemetry span names don't match symbol names
Debug with:
ckb telemetry test-map "your-service-name"Reduce retention or aggregation interval:
{
"telemetry": {
"storage": {
"retention_days": 90,
"aggregation_interval": "1d"
}
}
}- Start with explicit serviceMap — Don't rely on auto-detection
- Check coverage before trusting dead-code — Medium+ coverage required
- Use 90-day periods — Catches infrequent code paths (monthly jobs, etc.)
- Verify before deleting — Even high-confidence dead code should be reviewed
- Monitor unmapped services — New services need to be added to serviceMap
- Configuration — Full config reference including telemetry
- MCP-Integration — MCP tool details
- API-Reference — HTTP endpoint details
- Prompt-Cookbook — Example prompts for dead code detection