|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +**python-simple-logger** is a Python logging library providing colored console/file logging with duplicate log filtering and sensitive data masking. Built on top of `colorlog`, it extends Python's standard logging with custom log levels (SUCCESS, HASH, STEP) and filters. |
| 8 | + |
| 9 | +## Development Commands |
| 10 | + |
| 11 | +### Testing |
| 12 | + |
| 13 | +```bash |
| 14 | +# Run tests across all Python versions (3.9, 3.10, 3.11, 3.12, 3.13) |
| 15 | +tox |
| 16 | + |
| 17 | +# Run tests for current environment only |
| 18 | +uv run pytest simple_logger/tests |
| 19 | + |
| 20 | +# Run tests with coverage (auto-configured via pytest.ini) |
| 21 | +uv run pytest simple_logger/tests -v |
| 22 | +``` |
| 23 | + |
| 24 | +**Coverage Requirements:** |
| 25 | +- Minimum coverage: 93% (enforced in pyproject.toml) |
| 26 | +- Coverage report: HTML output in `.tests_coverage/` |
| 27 | +- Test files excluded from coverage (see `tool.coverage.run.omit`) |
| 28 | + |
| 29 | +### Code Quality |
| 30 | + |
| 31 | +```bash |
| 32 | +# Format code (ruff auto-fix enabled) |
| 33 | +uv run ruff format . |
| 34 | + |
| 35 | +# Lint code |
| 36 | +uv run ruff check . |
| 37 | + |
| 38 | +# Type checking |
| 39 | +uv run mypy simple_logger/ |
| 40 | +``` |
| 41 | + |
| 42 | +**Quality Standards:** |
| 43 | +- Line length: 120 characters |
| 44 | +- Type hints required (mypy strict mode: disallow_untyped_defs, disallow_incomplete_defs) |
| 45 | +- Ruff preview mode enabled with auto-fix |
| 46 | + |
| 47 | +## Architecture |
| 48 | + |
| 49 | +### Core Components |
| 50 | + |
| 51 | +**`simple_logger/logger.py`** - Single-file library with four main components: |
| 52 | + |
| 53 | +1. **`SimpleLogger`** (lines 60-79) |
| 54 | + - Custom logger class extending Python's `logging.Logger` |
| 55 | + - Adds custom log levels: SUCCESS (32), HASH (33), STEP (34) |
| 56 | + - Provides convenience methods: `.success()`, `.step()`, `.hash()` |
| 57 | + - Set as default logger class via `logging.setLoggerClass(SimpleLogger)` (line 82) |
| 58 | + |
| 59 | +2. **`WrapperLogFormatter`** (lines 55-57) |
| 60 | + - Extends `colorlog.ColoredFormatter` |
| 61 | + - Overrides `formatTime()` to use ISO 8601 timestamps |
| 62 | + - Configured with color mapping for all log levels |
| 63 | + |
| 64 | +3. **Filters** |
| 65 | + - `DuplicateFilter` (lines 18-37): Suppresses repeated logs, appends count summary |
| 66 | + - `RedactingFilter` (lines 40-52): Masks sensitive patterns with regex |
| 67 | + |
| 68 | +4. **`get_logger()`** (lines 85-166) |
| 69 | + - Factory function returning singleton loggers (cached in `LOGGERS` dict) |
| 70 | + - Handles both console and file handlers with rotation |
| 71 | + - Auto-detects `FORCE_COLOR` env var for non-TTY environments (Docker/CI) |
| 72 | + |
| 73 | +### Key Design Patterns |
| 74 | + |
| 75 | +**Singleton Logger Pattern:** |
| 76 | +```python |
| 77 | +if LOGGERS.get(name): |
| 78 | + return LOGGERS[name] # Return cached logger |
| 79 | +``` |
| 80 | +Ensures one logger instance per name. |
| 81 | + |
| 82 | +**Force Color Detection (lines 119-123):** |
| 83 | +```python |
| 84 | +if force_color is None: |
| 85 | + force_color_env = os.environ.get("FORCE_COLOR", "").lower() |
| 86 | + force_color = force_color_env in ("1", "true") |
| 87 | +``` |
| 88 | +Critical for Docker logs - passes `force_color` to ColoredFormatter to enable ANSI codes in non-TTY environments. |
| 89 | + |
| 90 | +## Important Implementation Details |
| 91 | + |
| 92 | +### Adding New Features |
| 93 | + |
| 94 | +When modifying `get_logger()`: |
| 95 | +- Parameters must be added to function signature |
| 96 | +- Update docstring with new parameter |
| 97 | +- Consider singleton behavior - changes affect all future logger creations, not existing ones |
| 98 | +- Update README.md with usage examples |
| 99 | + |
| 100 | +### Color Output |
| 101 | + |
| 102 | +The `force_color` parameter/env var is essential for Docker environments where `sys.stdout.isatty()` returns False. Without it, colorlog disables colors even though Docker can display ANSI codes. |
| 103 | + |
| 104 | +### Testing |
| 105 | + |
| 106 | +Tests use pytest fixtures for logger instances (`basic_logger`, `logger_with_mask`). When adding features: |
| 107 | +- Test both parameter and environment variable paths |
| 108 | +- Use `tmp_log_file` fixture for file output tests |
| 109 | +- Verify both console and file handler behavior |
| 110 | + |
| 111 | +## Release Process |
| 112 | + |
| 113 | +This project uses `release-it` for versioning and releases: |
| 114 | + |
| 115 | +```bash |
| 116 | +# Prerequisites (one-time setup) |
| 117 | +export GITHUB_TOKEN=<token> |
| 118 | +sudo npm install --global release-it |
| 119 | + |
| 120 | +# Create release |
| 121 | +git pull |
| 122 | +release-it # Interactive prompts guide the process |
| 123 | +``` |
| 124 | + |
| 125 | +Version is managed in `pyproject.toml` (currently 2.0.17). |
| 126 | + |
| 127 | +## Build System |
| 128 | + |
| 129 | +- **Package manager:** uv (with lock file) |
| 130 | +- **Build backend:** hatchling |
| 131 | +- **Distribution:** PyPI at `python-simple-logger` |
| 132 | +- **Include:** Only `simple_logger/` directory in builds |
0 commit comments