$npx -y skills add decebals/claude-code-java --skill logging-patternsJava logging best practices with SLF4J, structured logging (JSON), and MDC for request tracing. Includes AI-friendly log formats for Claude Code debugging. Use when user asks about logging, debugging application flow, or analyzing logs.
| 1 | # Logging Patterns Skill |
| 2 | |
| 3 | Effective logging for Java applications with focus on structured, AI-parsable formats. |
| 4 | |
| 5 | ## When to Use |
| 6 | - User says "add logging" / "improve logs" / "debug this" |
| 7 | - Analyzing application flow from logs |
| 8 | - Setting up structured logging (JSON) |
| 9 | - Request tracing with correlation IDs |
| 10 | - AI/Claude Code needs to analyze application behavior |
| 11 | |
| 12 | --- |
| 13 | |
| 14 | ## AI-Friendly Logging |
| 15 | |
| 16 | > **Key insight:** JSON logs are better for AI analysis - faster parsing, fewer tokens, direct field access. |
| 17 | |
| 18 | ### Why JSON for AI/Claude Code? |
| 19 | |
| 20 | ``` |
| 21 | # Text format - AI must "interpret" the string |
| 22 | 2026-01-29 10:15:30 INFO OrderService - Order 12345 created for user-789, total: 99.99 |
| 23 | |
| 24 | # JSON format - AI extracts fields directly |
| 25 | {"timestamp":"2026-01-29T10:15:30Z","level":"INFO","orderId":12345,"userId":"user-789","total":99.99} |
| 26 | ``` |
| 27 | |
| 28 | | Aspect | Text | JSON | |
| 29 | |--------|------|------| |
| 30 | | Parsing | Regex/interpretation | Direct field access | |
| 31 | | Token usage | Higher (repeated patterns) | Lower (structured) | |
| 32 | | Error extraction | Parse stack trace text | `exception` field | |
| 33 | | Filtering | grep patterns | `jq` queries | |
| 34 | |
| 35 | ### Recommended Setup for AI-Assisted Development |
| 36 | |
| 37 | ```yaml |
| 38 | # application.yml - JSON by default |
| 39 | logging: |
| 40 | structured: |
| 41 | format: |
| 42 | console: logstash # Spring Boot 3.4+ |
| 43 | |
| 44 | # When YOU need to read logs manually: |
| 45 | # Option 1: Use jq |
| 46 | # tail -f app.log | jq . |
| 47 | |
| 48 | # Option 2: Switch profile temporarily |
| 49 | # java -jar app.jar --spring.profiles.active=human-logs |
| 50 | ``` |
| 51 | |
| 52 | ### Log Format Optimized for AI Analysis |
| 53 | |
| 54 | ```json |
| 55 | { |
| 56 | "timestamp": "2026-01-29T10:15:30.123Z", |
| 57 | "level": "INFO", |
| 58 | "logger": "com.example.OrderService", |
| 59 | "message": "Order created", |
| 60 | "requestId": "req-abc123", |
| 61 | "traceId": "trace-xyz", |
| 62 | "orderId": 12345, |
| 63 | "userId": "user-789", |
| 64 | "duration_ms": 45, |
| 65 | "step": "payment_completed" |
| 66 | } |
| 67 | ``` |
| 68 | |
| 69 | **Key fields for AI debugging:** |
| 70 | - `requestId` - group all logs from same request |
| 71 | - `step` - track progress through flow |
| 72 | - `duration_ms` - identify slow operations |
| 73 | - `level` - quick filter for errors |
| 74 | |
| 75 | ### Reading Logs with AI/Claude Code |
| 76 | |
| 77 | When asking AI to analyze logs: |
| 78 | |
| 79 | ```bash |
| 80 | # Get recent errors |
| 81 | cat app.log | jq 'select(.level == "ERROR")' | tail -20 |
| 82 | |
| 83 | # Follow specific request |
| 84 | cat app.log | jq 'select(.requestId == "req-abc123")' |
| 85 | |
| 86 | # Find slow operations |
| 87 | cat app.log | jq 'select(.duration_ms > 1000)' |
| 88 | ``` |
| 89 | |
| 90 | AI can then: |
| 91 | 1. Parse JSON directly (no guessing) |
| 92 | 2. Follow request flow via requestId |
| 93 | 3. Identify exactly where errors occurred |
| 94 | 4. Measure timing between steps |
| 95 | |
| 96 | --- |
| 97 | |
| 98 | ## Quick Setup (Spring Boot 3.4+) |
| 99 | |
| 100 | ### Native Structured Logging |
| 101 | |
| 102 | Spring Boot 3.4+ has built-in support - no extra dependencies! |
| 103 | |
| 104 | ```yaml |
| 105 | # application.yml |
| 106 | logging: |
| 107 | structured: |
| 108 | format: |
| 109 | console: logstash # or "ecs" for Elastic Common Schema |
| 110 | |
| 111 | # Supported formats: logstash, ecs, gelf |
| 112 | ``` |
| 113 | |
| 114 | ### Profile-Based Switching |
| 115 | |
| 116 | ```yaml |
| 117 | # application.yml (default - JSON for AI/prod) |
| 118 | spring: |
| 119 | profiles: |
| 120 | default: json-logs |
| 121 | |
| 122 | --- |
| 123 | spring: |
| 124 | config: |
| 125 | activate: |
| 126 | on-profile: json-logs |
| 127 | logging: |
| 128 | structured: |
| 129 | format: |
| 130 | console: logstash |
| 131 | |
| 132 | --- |
| 133 | spring: |
| 134 | config: |
| 135 | activate: |
| 136 | on-profile: human-logs |
| 137 | # No structured format = human-readable default |
| 138 | logging: |
| 139 | pattern: |
| 140 | console: "%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n" |
| 141 | ``` |
| 142 | |
| 143 | **Usage:** |
| 144 | ```bash |
| 145 | # Default: JSON (for AI, CI/CD, production) |
| 146 | ./mvnw spring-boot:run |
| 147 | |
| 148 | # Human-readable when needed |
| 149 | ./mvnw spring-boot:run -Dspring.profiles.active=human-logs |
| 150 | ``` |
| 151 | |
| 152 | --- |
| 153 | |
| 154 | ## Setup for Spring Boot < 3.4 |
| 155 | |
| 156 | ### Logstash Logback Encoder |
| 157 | |
| 158 | **pom.xml:** |
| 159 | ```xml |
| 160 | <dependency> |
| 161 | <groupId>net.logstash.logback</groupId> |
| 162 | <artifactId>logstash-logback-encoder</artifactId> |
| 163 | <version>7.4</version> |
| 164 | </dependency> |
| 165 | ``` |
| 166 | |
| 167 | **logback-spring.xml:** |
| 168 | ```xml |
| 169 | <?xml version="1.0" encoding="UTF-8"?> |
| 170 | <configuration> |
| 171 | |
| 172 | <!-- JSON (default) --> |
| 173 | <springProfile name="!human-logs"> |
| 174 | <appender name="JSON" class="ch.qos.logback.core.ConsoleAppender"> |
| 175 | <encoder class="net.logstash.logback.encoder.LogstashEncoder"> |
| 176 | <includeMdcKeyName>requestId</includeMdcKeyName> |
| 177 | <includeMdcKeyName>userId</includeMdcKeyName> |
| 178 | </encoder> |
| 179 | </appender> |
| 180 | <root level="INFO"> |
| 181 | <appender-ref ref="JSON"/> |
| 182 | </root> |
| 183 | </springProfile> |
| 184 | |
| 185 | <!-- Human-readable (optional) --> |
| 186 | <springProfile name="human-logs"> |
| 187 | <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
| 188 | <encoder> |
| 189 | <pattern>%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n</pattern> |
| 190 | </encoder> |
| 191 | </appender> |
| 192 | <root level="INFO"> |
| 193 | <appender-ref ref="CONSOLE"/> |
| 194 | </root> |
| 195 | </springProfile> |
| 196 | |
| 197 | </configuration> |
| 198 | ``` |
| 199 | |
| 200 | ### Adding Custom Fie |