573 lines
15 KiB
Markdown
573 lines
15 KiB
Markdown
# Mode 2: Enterprise Setup (Connect to Existing Infrastructure)
|
|
|
|
**Goal:** Configure Claude Code to send telemetry to centralized company infrastructure
|
|
|
|
**When to use:**
|
|
- Company has centralized OTEL Collector endpoint
|
|
- Team rollout scenario
|
|
- Want aggregated team metrics
|
|
- Privacy/compliance requires centralized control
|
|
- No need for local Grafana dashboards
|
|
|
|
**Prerequisites:**
|
|
- OTEL Collector endpoint URL (e.g., `https://otel.company.com:4317`)
|
|
- Authentication credentials (API key or mTLS certificates)
|
|
- Optional: Team/department identifiers
|
|
- Write access to `~/.claude/settings.json`
|
|
|
|
**Estimated Time:** 2-3 minutes
|
|
|
|
---
|
|
|
|
## Phase 0: Gather Requirements
|
|
|
|
### Step 0.1: Collect endpoint information from user
|
|
|
|
Ask the user for the following details:
|
|
|
|
1. **OTEL Collector Endpoint URL**
|
|
- Format: `https://otel.company.com:4317` or `http://otel.company.com:4318`
|
|
- Protocol: gRPC (port 4317) or HTTP (port 4318)
|
|
|
|
2. **Authentication Method**
|
|
- API Key/Bearer Token
|
|
- mTLS certificates
|
|
- Basic Auth
|
|
- No authentication (internal network)
|
|
|
|
3. **Team/Environment Identifiers**
|
|
- Team name (e.g., `team=platform`)
|
|
- Environment (e.g., `environment=production`)
|
|
- Department (e.g., `department=engineering`)
|
|
- Any other custom attributes
|
|
|
|
4. **Optional: Protocol Preferences**
|
|
- Default: gRPC (more efficient)
|
|
- Alternative: HTTP (better firewall compatibility)
|
|
|
|
**Example Questions:**
|
|
|
|
```
|
|
To configure enterprise telemetry, I need a few details:
|
|
|
|
1. **Endpoint:** What is your OTEL Collector endpoint URL?
|
|
(e.g., https://otel.company.com:4317)
|
|
|
|
2. **Protocol:** HTTPS or HTTP? gRPC or HTTP/protobuf?
|
|
|
|
3. **Authentication:** Do you have an API key, certificate, or other credentials?
|
|
|
|
4. **Team identifier:** What team/department should metrics be tagged with?
|
|
(e.g., team=platform, department=engineering)
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 1: Backup Existing Settings
|
|
|
|
### Step 1.1: Backup settings.json
|
|
|
|
**Always backup before modifying!**
|
|
|
|
```bash
|
|
# Check if settings.json exists
|
|
if [ -f ~/.claude/settings.json ]; then
|
|
cp ~/.claude/settings.json ~/.claude/settings.json.backup.$(date +%Y%m%d-%H%M%S)
|
|
echo "✅ Backup created: ~/.claude/settings.json.backup.$(date +%Y%m%d-%H%M%S)"
|
|
else
|
|
echo "⚠️ No existing settings.json found - will create new one"
|
|
fi
|
|
```
|
|
|
|
### Step 1.2: Read existing settings
|
|
|
|
```bash
|
|
# Check current settings
|
|
cat ~/.claude/settings.json
|
|
```
|
|
|
|
**Important:** Preserve all existing settings when adding telemetry configuration!
|
|
|
|
---
|
|
|
|
## Phase 2: Update Claude Code Settings
|
|
|
|
### Step 2.1: Determine configuration based on authentication method
|
|
|
|
**Scenario A: API Key Authentication**
|
|
|
|
```json
|
|
{
|
|
"env": {
|
|
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
|
|
"OTEL_METRICS_EXPORTER": "otlp",
|
|
"OTEL_LOGS_EXPORTER": "otlp",
|
|
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
|
|
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.company.com:4317",
|
|
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer YOUR_API_KEY_HERE",
|
|
"OTEL_METRIC_EXPORT_INTERVAL": "60000",
|
|
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
|
|
"OTEL_LOG_USER_PROMPTS": "1",
|
|
"OTEL_METRICS_INCLUDE_SESSION_ID": "true",
|
|
"OTEL_METRICS_INCLUDE_VERSION": "true",
|
|
"OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "true",
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=production,deployment=enterprise"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Scenario B: mTLS Certificate Authentication**
|
|
|
|
```json
|
|
{
|
|
"env": {
|
|
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
|
|
"OTEL_METRICS_EXPORTER": "otlp",
|
|
"OTEL_LOGS_EXPORTER": "otlp",
|
|
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
|
|
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.company.com:4317",
|
|
"OTEL_EXPORTER_OTLP_CERTIFICATE": "/path/to/client-cert.pem",
|
|
"OTEL_EXPORTER_OTLP_CLIENT_KEY": "/path/to/client-key.pem",
|
|
"OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE": "/path/to/ca-cert.pem",
|
|
"OTEL_METRIC_EXPORT_INTERVAL": "60000",
|
|
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
|
|
"OTEL_LOG_USER_PROMPTS": "1",
|
|
"OTEL_METRICS_INCLUDE_SESSION_ID": "true",
|
|
"OTEL_METRICS_INCLUDE_VERSION": "true",
|
|
"OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "true",
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=production,deployment=enterprise"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Scenario C: HTTP Protocol (Port 4318)**
|
|
|
|
```json
|
|
{
|
|
"env": {
|
|
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
|
|
"OTEL_METRICS_EXPORTER": "otlp",
|
|
"OTEL_LOGS_EXPORTER": "otlp",
|
|
"OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf",
|
|
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.company.com:4318",
|
|
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer YOUR_API_KEY_HERE",
|
|
"OTEL_METRIC_EXPORT_INTERVAL": "60000",
|
|
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
|
|
"OTEL_LOG_USER_PROMPTS": "1",
|
|
"OTEL_METRICS_INCLUDE_SESSION_ID": "true",
|
|
"OTEL_METRICS_INCLUDE_VERSION": "true",
|
|
"OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "true",
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=production,deployment=enterprise"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Scenario D: No Authentication (Internal Network)**
|
|
|
|
```json
|
|
{
|
|
"env": {
|
|
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
|
|
"OTEL_METRICS_EXPORTER": "otlp",
|
|
"OTEL_LOGS_EXPORTER": "otlp",
|
|
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
|
|
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://otel.internal.company.com:4317",
|
|
"OTEL_METRIC_EXPORT_INTERVAL": "60000",
|
|
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
|
|
"OTEL_LOG_USER_PROMPTS": "1",
|
|
"OTEL_METRICS_INCLUDE_SESSION_ID": "true",
|
|
"OTEL_METRICS_INCLUDE_VERSION": "true",
|
|
"OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "true",
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=production,deployment=enterprise"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Step 2.2: Update settings.json
|
|
|
|
**Method 1: Manual Update (Safest)**
|
|
|
|
1. Open `~/.claude/settings.json` in editor
|
|
2. Merge the telemetry configuration into existing `env` object
|
|
3. Preserve all other settings
|
|
4. Save file
|
|
|
|
**Method 2: Programmatic Update (Use with Caution)**
|
|
|
|
```bash
|
|
# Read existing settings
|
|
existing_settings=$(cat ~/.claude/settings.json)
|
|
|
|
# Create merged settings (requires jq)
|
|
cat ~/.claude/settings.json | jq '. + {
|
|
"env": (.env // {} | . + {
|
|
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
|
|
"OTEL_METRICS_EXPORTER": "otlp",
|
|
"OTEL_LOGS_EXPORTER": "otlp",
|
|
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
|
|
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.company.com:4317",
|
|
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer YOUR_API_KEY_HERE",
|
|
"OTEL_METRIC_EXPORT_INTERVAL": "60000",
|
|
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
|
|
"OTEL_LOG_USER_PROMPTS": "1",
|
|
"OTEL_METRICS_INCLUDE_SESSION_ID": "true",
|
|
"OTEL_METRICS_INCLUDE_VERSION": "true",
|
|
"OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "true",
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=production,deployment=enterprise"
|
|
})
|
|
}' > ~/.claude/settings.json.new
|
|
|
|
# Validate JSON
|
|
if jq empty ~/.claude/settings.json.new 2>/dev/null; then
|
|
mv ~/.claude/settings.json.new ~/.claude/settings.json
|
|
echo "✅ Settings updated successfully"
|
|
else
|
|
echo "❌ Invalid JSON - restoring backup"
|
|
rm ~/.claude/settings.json.new
|
|
fi
|
|
```
|
|
|
|
### Step 2.3: Validate configuration
|
|
|
|
```bash
|
|
# Check that settings.json is valid JSON
|
|
jq empty ~/.claude/settings.json
|
|
|
|
# Display telemetry configuration
|
|
jq '.env | with_entries(select(.key | startswith("OTEL_") or . == "CLAUDE_CODE_ENABLE_TELEMETRY"))' ~/.claude/settings.json
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 3: Test Connectivity (Optional)
|
|
|
|
### Step 3.1: Test OTEL endpoint reachability
|
|
|
|
```bash
|
|
# Test gRPC endpoint (port 4317)
|
|
nc -zv otel.company.com 4317
|
|
|
|
# Test HTTP endpoint (port 4318)
|
|
curl -v https://otel.company.com:4318/v1/metrics -d '{}' -H "Content-Type: application/json"
|
|
```
|
|
|
|
### Step 3.2: Validate authentication
|
|
|
|
```bash
|
|
# Test with API key
|
|
curl -v https://otel.company.com:4318/v1/metrics \
|
|
-H "Authorization: Bearer YOUR_API_KEY_HERE" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{}'
|
|
|
|
# Expected: 200 or 401/403 (tells us auth is working)
|
|
# Unexpected: Connection refused, timeout (network issue)
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 4: User Instructions
|
|
|
|
### Step 4.1: Provide restart instructions
|
|
|
|
**Display to user:**
|
|
|
|
```
|
|
✅ Configuration complete!
|
|
|
|
**Important Next Steps:**
|
|
|
|
1. **Restart Claude Code** for telemetry to take effect
|
|
- Telemetry configuration is only loaded at startup
|
|
- Close all Claude Code sessions and restart
|
|
|
|
2. **Verify with your platform team** that they see metrics
|
|
- Metrics should appear within 60 seconds of restart
|
|
- Tagged with: team=platform, environment=production
|
|
- Metric prefix: claude_code_claude_code_*
|
|
|
|
3. **Dashboard access**
|
|
- Contact your platform team for Grafana/dashboard URLs
|
|
- Dashboards should be centrally managed
|
|
|
|
**Troubleshooting:**
|
|
|
|
If metrics don't appear:
|
|
- Check network connectivity to OTEL endpoint
|
|
- Verify authentication credentials are correct
|
|
- Check firewall rules allow outbound connections
|
|
- Review OTEL Collector logs on backend (platform team)
|
|
- Verify OTEL_EXPORTER_OTLP_ENDPOINT is correct
|
|
|
|
**Rollback:**
|
|
|
|
If you need to disable telemetry:
|
|
- Restore backup: cp ~/.claude/settings.json.backup.TIMESTAMP ~/.claude/settings.json
|
|
- Or set: "CLAUDE_CODE_ENABLE_TELEMETRY": "0"
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 5: Create Team Rollout Documentation
|
|
|
|
### Step 5.1: Generate rollout guide for team distribution
|
|
|
|
**Create file: `claude-code-telemetry-setup-guide.md`**
|
|
|
|
```markdown
|
|
# Claude Code Telemetry Setup Guide
|
|
|
|
**For:** [Team Name] Team Members
|
|
**Last Updated:** [Date]
|
|
|
|
## Overview
|
|
|
|
We're collecting Claude Code usage telemetry to:
|
|
- Track API costs and optimize spending
|
|
- Measure productivity metrics (LOC, commits, PRs)
|
|
- Understand token usage patterns
|
|
- Identify high-value use cases
|
|
|
|
**Privacy:** All metrics are aggregated and anonymized at the team level.
|
|
|
|
## Setup Instructions
|
|
|
|
### Step 1: Backup Your Settings
|
|
|
|
```bash
|
|
cp ~/.claude/settings.json ~/.claude/settings.json.backup
|
|
```
|
|
|
|
### Step 2: Update Configuration
|
|
|
|
Add the following to your `~/.claude/settings.json`:
|
|
|
|
```json
|
|
{
|
|
"env": {
|
|
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
|
|
"OTEL_METRICS_EXPORTER": "otlp",
|
|
"OTEL_LOGS_EXPORTER": "otlp",
|
|
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
|
|
"OTEL_EXPORTER_OTLP_ENDPOINT": "https://otel.company.com:4317",
|
|
"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer [PROVIDED_BY_PLATFORM_TEAM]",
|
|
"OTEL_METRIC_EXPORT_INTERVAL": "60000",
|
|
"OTEL_LOGS_EXPORT_INTERVAL": "5000",
|
|
"OTEL_LOG_USER_PROMPTS": "1",
|
|
"OTEL_METRICS_INCLUDE_SESSION_ID": "true",
|
|
"OTEL_METRICS_INCLUDE_VERSION": "true",
|
|
"OTEL_METRICS_INCLUDE_ACCOUNT_UUID": "true",
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=[TEAM_NAME],environment=production"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Important:** Replace `[PROVIDED_BY_PLATFORM_TEAM]` with your API key.
|
|
|
|
### Step 3: Restart Claude Code
|
|
|
|
Close all Claude Code sessions and restart for changes to take effect.
|
|
|
|
### Step 4: Verify Setup
|
|
|
|
After 5 minutes of usage:
|
|
1. Check team dashboard: [DASHBOARD_URL]
|
|
2. Verify your metrics appear in the team aggregation
|
|
3. Contact [TEAM_CONTACT] if you have issues
|
|
|
|
## What's Being Collected?
|
|
|
|
**Metrics:**
|
|
- Session counts and active time
|
|
- Token usage (input, output, cached)
|
|
- API costs by model
|
|
- Lines of code modified
|
|
- Commits and PRs created
|
|
|
|
**Events/Logs:**
|
|
- User prompts (anonymized)
|
|
- Tool executions
|
|
- API requests
|
|
|
|
**NOT Collected:**
|
|
- Source code content
|
|
- File names or paths
|
|
- Personal identifiers (beyond account UUID for deduplication)
|
|
|
|
## Dashboard Access
|
|
|
|
**Team Dashboard:** [URL]
|
|
**Login:** Use your company SSO
|
|
|
|
## Support
|
|
|
|
**Issues?** Contact [TEAM_CONTACT] or #claude-code-telemetry Slack channel
|
|
|
|
**Opt-Out:** Contact [TEAM_CONTACT] if you need to opt out for specific projects
|
|
```
|
|
|
|
---
|
|
|
|
## Phase 6: Success Criteria
|
|
|
|
### Checklist for Mode 2 completion:
|
|
|
|
- ✅ Backed up existing settings.json
|
|
- ✅ Updated settings with correct OTEL endpoint
|
|
- ✅ Added authentication (API key or certificates)
|
|
- ✅ Set team/environment resource attributes
|
|
- ✅ Validated JSON configuration
|
|
- ✅ Tested connectivity (optional)
|
|
- ✅ Provided restart instructions to user
|
|
- ✅ Created team rollout documentation (if applicable)
|
|
|
|
**Expected outcome:**
|
|
- Claude Code sends telemetry to central endpoint within 60 seconds of restart
|
|
- Platform team can see metrics tagged with team identifier
|
|
- User has clear instructions for verification and troubleshooting
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue 1: Connection Refused
|
|
|
|
**Symptoms:** Claude Code can't reach OTEL endpoint
|
|
|
|
**Checks:**
|
|
```bash
|
|
# Test network connectivity
|
|
ping otel.company.com
|
|
|
|
# Test port access
|
|
nc -zv otel.company.com 4317
|
|
|
|
# Check corporate VPN/proxy
|
|
echo $HTTPS_PROXY
|
|
```
|
|
|
|
**Solutions:**
|
|
- Connect to corporate VPN
|
|
- Use HTTP proxy if required: `HTTPS_PROXY=http://proxy.company.com:8080`
|
|
- Try HTTP protocol (port 4318) instead of gRPC
|
|
- Contact network team to allow outbound connections
|
|
|
|
### Issue 2: Authentication Failed
|
|
|
|
**Symptoms:** 401 or 403 errors in logs
|
|
|
|
**Checks:**
|
|
```bash
|
|
# Verify API key format
|
|
jq '.env.OTEL_EXPORTER_OTLP_HEADERS' ~/.claude/settings.json
|
|
|
|
# Test manually
|
|
curl -v https://otel.company.com:4318/v1/metrics \
|
|
-H "Authorization: Bearer YOUR_KEY" \
|
|
-d '{}'
|
|
```
|
|
|
|
**Solutions:**
|
|
- Verify API key is correct and not expired
|
|
- Check header format: `Authorization=Bearer TOKEN` (no quotes, equals sign)
|
|
- Confirm permissions with platform team
|
|
- Try rotating API key
|
|
|
|
### Issue 3: Metrics Not Appearing
|
|
|
|
**Symptoms:** Platform team doesn't see metrics after 5 minutes
|
|
|
|
**Checks:**
|
|
```bash
|
|
# Verify telemetry is enabled
|
|
jq '.env.CLAUDE_CODE_ENABLE_TELEMETRY' ~/.claude/settings.json
|
|
|
|
# Check endpoint configuration
|
|
jq '.env.OTEL_EXPORTER_OTLP_ENDPOINT' ~/.claude/settings.json
|
|
|
|
# Confirm Claude Code was restarted
|
|
ps aux | grep claude
|
|
```
|
|
|
|
**Solutions:**
|
|
- Restart Claude Code (telemetry loads at startup only)
|
|
- Verify endpoint URL has correct protocol and port
|
|
- Check with platform team if OTEL Collector is receiving data
|
|
- Review OTEL Collector logs for errors
|
|
- Verify resource attributes match expected format
|
|
|
|
### Issue 4: Certificate Errors (mTLS)
|
|
|
|
**Symptoms:** SSL/TLS handshake errors
|
|
|
|
**Checks:**
|
|
```bash
|
|
# Verify certificate paths
|
|
ls -la /path/to/client-cert.pem
|
|
ls -la /path/to/client-key.pem
|
|
ls -la /path/to/ca-cert.pem
|
|
|
|
# Check certificate validity
|
|
openssl x509 -in /path/to/client-cert.pem -noout -dates
|
|
```
|
|
|
|
**Solutions:**
|
|
- Ensure certificate files are readable
|
|
- Verify certificates haven't expired
|
|
- Check certificate chain is complete
|
|
- Confirm CA certificate matches server
|
|
- Contact platform team for new certificates if needed
|
|
|
|
---
|
|
|
|
## Enterprise Configuration Examples
|
|
|
|
### Example 1: Multi-Environment Setup
|
|
|
|
**Development:**
|
|
```json
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=development,user=john.doe"
|
|
```
|
|
|
|
**Staging:**
|
|
```json
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=staging,user=john.doe"
|
|
```
|
|
|
|
**Production:**
|
|
```json
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,environment=production,user=john.doe"
|
|
```
|
|
|
|
### Example 2: Department-Level Aggregation
|
|
|
|
```json
|
|
"OTEL_RESOURCE_ATTRIBUTES": "department=engineering,team=platform,squad=backend,environment=production"
|
|
```
|
|
|
|
Enables queries like:
|
|
- Cost by department
|
|
- Usage by team within department
|
|
- Squad-level productivity metrics
|
|
|
|
### Example 3: Project-Based Tagging
|
|
|
|
```json
|
|
"OTEL_RESOURCE_ATTRIBUTES": "team=platform,project=api-v2-migration,environment=production"
|
|
```
|
|
|
|
Track costs and effort for specific initiatives.
|
|
|
|
---
|
|
|
|
## Additional Resources
|
|
|
|
- **OTEL Specification:** https://opentelemetry.io/docs/specs/otel/
|
|
- **Claude Code Metrics Reference:** See `data/metrics-reference.md`
|
|
- **Enterprise Architecture:** See `data/enterprise-architecture.md`
|
|
- **Team Dashboard Queries:** See `data/prometheus-queries.md`
|
|
|
|
---
|
|
|
|
**Mode 2 Complete!** ✅
|