You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Treat established keys as compatibility-sensitive — downstream users may build dashboards and alerts on them. Change deliberately.
290
+
291
+
#### Key naming rules
292
+
293
+
-`snake_case`, not dotted; `vcs_` prefix
294
+
- Prefer stable scalars; avoid ad-hoc objects
295
+
- Heavy keys (`vcs_stdout`, `vcs_stderr`) are DEBUG-only; consider companion `vcs_stdout_len` fields or hard truncation (e.g. `stdout[:100]`)
296
+
297
+
#### Lazy formatting
298
+
299
+
`logger.debug("msg %s", val)` not f-strings. Two rationales:
300
+
- Deferred string interpolation: skipped entirely when level is filtered
301
+
- Aggregator message template grouping: `"Running %s"` is one signature grouped ×10,000; f-strings make each line unique
302
+
303
+
When computing `val` itself is expensive, guard with `if logger.isEnabledFor(logging.DEBUG)`.
304
+
305
+
#### stacklevel for wrappers
306
+
307
+
Increment for each wrapper layer so `%(filename)s:%(lineno)d` and OTel `code.filepath` point to the real caller. Verify whenever call depth changes.
308
+
309
+
#### LoggerAdapter for persistent context
310
+
311
+
For objects with stable identity (Repository, Remote, Sync), use `LoggerAdapter` to avoid repeating the same `extra` on every call. Lead with the portable pattern (override `process()` to merge); `merge_extra=True` simplifies this on Python 3.13+.
|`ERROR`| Failures that stop an operation | VCS command failed, invalid URL |
321
+
322
+
Config discovery noise belongs in `DEBUG`; only surprising/user-actionable config issues → `WARNING`.
323
+
324
+
#### Message style
325
+
326
+
- Lowercase, past tense for events: `"repository cloned"`, `"vcs command failed"`
327
+
- No trailing punctuation
328
+
- Keep messages short; put details in `extra`, not the message string
329
+
330
+
#### Exception logging
331
+
332
+
- Use `logger.exception()` only inside `except` blocks when you are **not** re-raising
333
+
- Use `logger.error(..., exc_info=True)` when you need the traceback outside an `except` block
334
+
- Avoid `logger.exception()` followed by `raise` — this duplicates the traceback. Either add context via `extra` that would otherwise be lost, or let the exception propagate
335
+
336
+
#### Testing logs
337
+
338
+
Assert on `caplog.records` attributes, not string matching on `caplog.text`:
0 commit comments