Skip to content

Commit be98d2c

Browse files
docs(logger): add behavioral contracts section and fix color support accuracy (#42058)
1 parent 8b5d68b commit be98d2c

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

pkg/logger/README.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ A simple, debug-style logging framework for Go that follows the pattern matching
1212
- **Pattern matching**: Enable/disable loggers using wildcards and exclusions via the `DEBUG` environment variable
1313
- **Printf interface**: Standard printf-style formatting
1414
- **Time diff display**: Shows time elapsed since last log call (like debug npm package)
15-
- **Automatic color coding**: Each namespace gets a unique color when stderr is a TTY
15+
- **Automatic color coding**: Each namespace gets a unique color, determined by `DEBUG_COLORS` and rendered by lipgloss
1616
- **Zero overhead**: Logger enabled state is computed once at construction time
1717
- **Thread-safe**: Safe for concurrent use
1818

@@ -38,6 +38,17 @@ The `Logger` type provides namespace-based debug logging with pattern matching,
3838
| `NewSlogHandler` | `func(logger *Logger) *SlogHandler` | Creates a `slog.Handler` wrapping the given `Logger` |
3939
| `NewSlogLoggerWithHandler` | `func(logger *Logger) *slog.Logger` | Creates a `slog.Logger` backed by the given `Logger` |
4040

41+
**Behavioral contracts**:
42+
43+
- `New` MUST compute the enabled state exactly once at construction time from the `DEBUG` environment variable (or `ACTIONS_RUNNER_DEBUG=true` as a fallback); subsequent changes to those variables MUST NOT affect already-constructed `Logger` instances.
44+
- `Logger.Printf` and `Logger.Print` MUST be no-ops (return immediately before any string formatting or I/O) when `Enabled()` returns `false`.
45+
- `Logger.Printf` and `Logger.Print` MUST write all output to `os.Stderr` and MUST append a trailing newline to every message.
46+
- `Logger.Printf` and `Logger.Print` MUST include a `+<duration>` suffix showing elapsed time since the previous call on the same instance.
47+
- `Logger.Printf` and `Logger.Print` MUST acquire an internal mutex before updating the `lastLog` timestamp; concurrent callers MUST receive independent, accurate time-diff values without data races.
48+
- `SlogHandler.Enabled` MUST return `false` when the underlying `Logger.Enabled()` is `false`, preventing attribute collection overhead for disabled loggers.
49+
- `SlogHandler.WithAttrs` and `SlogHandler.WithGroup` MUST return the receiver unchanged; attributes and groups are not accumulated across calls.
50+
- Color styling MUST be disabled when `DEBUG_COLORS=0`; when enabled, actual color rendering is delegated to lipgloss which adapts to the output terminal's capabilities.
51+
4152
## Usage Examples
4253

4354
### Basic Usage
@@ -111,11 +122,9 @@ DEBUG=workflow:*,cli:*,-workflow:test
111122

112123
## Color Support
113124

114-
Colors are automatically assigned to each namespace when:
115-
- Stderr is a TTY (terminal)
116-
- `DEBUG_COLORS` is not set to `0`
125+
Color styling is enabled when `DEBUG_COLORS` is not set to `0`. The [lipgloss](https://github.com/charmbracelet/lipgloss) library handles actual color rendering and adapts to the output terminal's capabilities; colors are typically suppressed when piping output to a non-TTY stream.
117126

118-
Each namespace gets a consistent color based on a hash of its name. This makes it easy to visually distinguish between different loggers.
127+
Each namespace gets a consistent color based on a FNV-1a hash of its name. This makes it easy to visually distinguish between different loggers.
119128

120129
### Disabling Colors
121130

0 commit comments

Comments
 (0)