|
| 1 | +# 🚀 Quick Start: Using OpenTelemetry Logging in Your CLI |
| 2 | + |
| 3 | +## ⚡ TL;DR - 3 Step Process |
| 4 | + |
| 5 | +1. **Import the logger**: `from codegen.shared.logging.get_logger import get_logger` |
| 6 | +2. **Add `extra={}` to your log calls**: `logger.info("message", extra={"key": "value"})` |
| 7 | +3. **Enable telemetry**: `codegen config telemetry enable` |
| 8 | + |
| 9 | +**That's it!** Your logs automatically go to Grafana Cloud when telemetry is enabled. |
| 10 | + |
| 11 | +## 🎯 Immediate Actions You Can Take |
| 12 | + |
| 13 | +### 1. Quick Enhancement of Existing Commands |
| 14 | + |
| 15 | +Pick **any existing CLI command** and add 2-3 lines: |
| 16 | + |
| 17 | +```python |
| 18 | +# Add this import at the top |
| 19 | +from codegen.shared.logging.get_logger import get_logger |
| 20 | + |
| 21 | +# Add this line after imports |
| 22 | +logger = get_logger(__name__) |
| 23 | + |
| 24 | +# Find any existing console.print() or error handling and add: |
| 25 | +logger.info("Operation completed", extra={ |
| 26 | + "operation": "command_name", |
| 27 | + "org_id": org_id, # if available |
| 28 | + "success": True |
| 29 | +}) |
| 30 | +``` |
| 31 | + |
| 32 | +### 2. Test the Integration Right Now |
| 33 | + |
| 34 | +```bash |
| 35 | +# 1. Enable telemetry |
| 36 | +codegen config telemetry enable |
| 37 | + |
| 38 | +# 2. Run the demo |
| 39 | +python example_enhanced_agent_command.py |
| 40 | + |
| 41 | +# 3. Run any CLI command |
| 42 | +codegen agents # or any other command |
| 43 | + |
| 44 | +# 4. Check status |
| 45 | +codegen config telemetry status |
| 46 | +``` |
| 47 | + |
| 48 | +## 📝 Copy-Paste Patterns |
| 49 | + |
| 50 | +### Pattern 1: Operation Start/End |
| 51 | +```python |
| 52 | +logger = get_logger(__name__) |
| 53 | + |
| 54 | +# At start of function |
| 55 | +logger.info("Operation started", extra={ |
| 56 | + "operation": "command.subcommand", |
| 57 | + "user_input": relevant_input |
| 58 | +}) |
| 59 | + |
| 60 | +# At end of function |
| 61 | +logger.info("Operation completed", extra={ |
| 62 | + "operation": "command.subcommand", |
| 63 | + "success": True |
| 64 | +}) |
| 65 | +``` |
| 66 | + |
| 67 | +### Pattern 2: Error Handling |
| 68 | +```python |
| 69 | +try: |
| 70 | + # your existing code |
| 71 | + pass |
| 72 | +except SomeSpecificError as e: |
| 73 | + logger.error("Specific error occurred", extra={ |
| 74 | + "operation": "command.subcommand", |
| 75 | + "error_type": "specific_error", |
| 76 | + "error_details": str(e) |
| 77 | + }, exc_info=True) |
| 78 | + # your existing error handling |
| 79 | +``` |
| 80 | + |
| 81 | +### Pattern 3: API Calls |
| 82 | +```python |
| 83 | +# Before API call |
| 84 | +logger.info("Making API request", extra={ |
| 85 | + "operation": "api.request", |
| 86 | + "endpoint": "agent/run", |
| 87 | + "org_id": org_id |
| 88 | +}) |
| 89 | + |
| 90 | +# After successful API call |
| 91 | +logger.info("API request successful", extra={ |
| 92 | + "operation": "api.request", |
| 93 | + "endpoint": "agent/run", |
| 94 | + "response_id": response.get("id"), |
| 95 | + "status_code": response.status_code |
| 96 | +}) |
| 97 | +``` |
| 98 | + |
| 99 | +## 🎯 What to Log (Priority Order) |
| 100 | + |
| 101 | +### 🔥 High Priority (Add These First) |
| 102 | +- **Operation start/end**: When commands begin/complete |
| 103 | +- **API calls**: Requests to your backend |
| 104 | +- **Authentication events**: Login/logout/token issues |
| 105 | +- **Errors**: Any exception or failure |
| 106 | +- **User actions**: Commands run, options selected |
| 107 | + |
| 108 | +### ⭐ Medium Priority |
| 109 | +- **Performance**: Duration of operations |
| 110 | +- **State changes**: Status updates, configuration changes |
| 111 | +- **External tools**: Claude CLI detection, git operations |
| 112 | + |
| 113 | +### 💡 Low Priority (Nice to Have) |
| 114 | +- **Debug info**: Internal state, validation steps |
| 115 | +- **User behavior**: Which features are used most |
| 116 | + |
| 117 | +## 🔧 Minimal Changes to Existing Commands |
| 118 | + |
| 119 | +### Example: Enhance agent/main.py |
| 120 | + |
| 121 | +```python |
| 122 | +# Just add these 3 lines to your existing create() function: |
| 123 | + |
| 124 | +from codegen.shared.logging.get_logger import get_logger |
| 125 | +logger = get_logger(__name__) |
| 126 | + |
| 127 | +def create(prompt: str, org_id: int | None = None, ...): |
| 128 | + """Create a new agent run with the given prompt.""" |
| 129 | + |
| 130 | + # ADD: Log start |
| 131 | + logger.info("Agent creation started", extra={ |
| 132 | + "operation": "agent.create", |
| 133 | + "org_id": org_id, |
| 134 | + "prompt_length": len(prompt) |
| 135 | + }) |
| 136 | + |
| 137 | + # Your existing code... |
| 138 | + try: |
| 139 | + response = requests.post(url, headers=headers, json=payload) |
| 140 | + agent_run_data = response.json() |
| 141 | + |
| 142 | + # ADD: Log success |
| 143 | + logger.info("Agent created successfully", extra={ |
| 144 | + "operation": "agent.create", |
| 145 | + "agent_run_id": agent_run_data.get("id"), |
| 146 | + "status": agent_run_data.get("status") |
| 147 | + }) |
| 148 | + |
| 149 | + except requests.RequestException as e: |
| 150 | + # ADD: Log error |
| 151 | + logger.error("Agent creation failed", extra={ |
| 152 | + "operation": "agent.create", |
| 153 | + "error_type": "api_error", |
| 154 | + "error": str(e) |
| 155 | + }) |
| 156 | + # Your existing error handling... |
| 157 | +``` |
| 158 | + |
| 159 | +### Example: Enhance claude/main.py |
| 160 | + |
| 161 | +```python |
| 162 | +# Add to your _run_claude_interactive function: |
| 163 | + |
| 164 | +logger = get_logger(__name__) |
| 165 | + |
| 166 | +def _run_claude_interactive(resolved_org_id: int, no_mcp: bool | None) -> None: |
| 167 | + session_id = generate_session_id() |
| 168 | + |
| 169 | + # ADD: Log session start |
| 170 | + logger.info("Claude session started", extra={ |
| 171 | + "operation": "claude.session_start", |
| 172 | + "session_id": session_id[:8], # Short version for privacy |
| 173 | + "org_id": resolved_org_id |
| 174 | + }) |
| 175 | + |
| 176 | + # Your existing code... |
| 177 | + |
| 178 | + try: |
| 179 | + process = subprocess.Popen([claude_path, "--session-id", session_id]) |
| 180 | + returncode = process.wait() |
| 181 | + |
| 182 | + # ADD: Log session end |
| 183 | + logger.info("Claude session completed", extra={ |
| 184 | + "operation": "claude.session_complete", |
| 185 | + "session_id": session_id[:8], |
| 186 | + "exit_code": returncode, |
| 187 | + "status": "COMPLETE" if returncode == 0 else "ERROR" |
| 188 | + }) |
| 189 | + |
| 190 | + except Exception as e: |
| 191 | + # ADD: Log session error |
| 192 | + logger.error("Claude session failed", extra={ |
| 193 | + "operation": "claude.session_error", |
| 194 | + "session_id": session_id[:8], |
| 195 | + "error": str(e) |
| 196 | + }) |
| 197 | +``` |
| 198 | + |
| 199 | +## 🧪 Verification |
| 200 | + |
| 201 | +After making changes: |
| 202 | + |
| 203 | +1. **Run the command**: Execute your enhanced CLI command |
| 204 | +2. **Check telemetry status**: `codegen config telemetry status` |
| 205 | +3. **Look for logs in Grafana Cloud**: Search for your operation names |
| 206 | +4. **Test with telemetry disabled**: `codegen config telemetry disable` - should still work normally |
| 207 | + |
| 208 | +## 🚀 Progressive Enhancement |
| 209 | + |
| 210 | +**Week 1**: Add basic operation logging to 2-3 commands |
| 211 | +**Week 2**: Add error logging to all commands |
| 212 | +**Week 3**: Add performance metrics and detailed context |
| 213 | +**Week 4**: Create Grafana dashboards using the collected data |
| 214 | + |
| 215 | +## 🎉 Benefits You'll See Immediately |
| 216 | + |
| 217 | +- **Real usage data**: Which commands are used most? |
| 218 | +- **Error tracking**: What breaks and how often? |
| 219 | +- **Performance insights**: Which operations are slow? |
| 220 | +- **User behavior**: How do users actually use your CLI? |
| 221 | +- **Debugging**: Rich context when things go wrong |
| 222 | + |
| 223 | +Start with just **one command** and **one log line** - you'll see the value immediately! 🎯 |
0 commit comments