|  | 
|  | 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