CLTK logging utilities.
Provides a colorized console formatter and a helper to configure a module
logger suitable for libraries and CLI output.
Adds lightweight "structured" fields (doc_id, sentence_idx, model,
glottolog_id, prompt_version) to each log record so they can be grepped or
filtered in the file logs. Use bind_context(...) to attach values for a
code path; otherwise, defaults are injected so formatting never fails.
logger
module-attribute
logger = setup_cltk_logger(level='WARNING')
Bases: Formatter
Console color formatter using Colorama styles.
COLORS = {
DEBUG: CYAN + DIM,
INFO: CYAN,
WARNING: YELLOW,
ERROR: RED,
CRITICAL: RED + BRIGHT + BRIGHT,
}
format(record: LogRecord) -> str
Return a colorized log line for console output.
Source code in cltk/core/cltk_logger.py
| def format(self, record: logging.LogRecord) -> str:
"""Return a colorized log line for console output."""
color = self.COLORS.get(record.levelno, "")
reset = Style.RESET_ALL
# record.msg = f"{color}{record.msg}{reset}"
# return super().format(record)
message = super().format(record)
return f"{color}{message}{reset}"
|
setup_cltk_logger
setup_cltk_logger(
name: str = "CLTK",
log_to_file: bool | None = None,
log_to_console: bool = True,
level: str | None = None,
) -> logging.Logger
Configure and return a library logger.
Parameters:
-
name
(str, default:
'CLTK'
)
–
-
log_to_file
(bool | None, default:
None
)
–
If true, add a file handler writing to cltk.log.
-
log_to_console
(bool, default:
True
)
–
If true, add a colorized console handler.
-
level
(str | None, default:
None
)
–
Optional log level name (e.g., "INFO"). If None, uses
CLTK_LOG_LEVEL environment variable or defaults to INFO.
Returns:
-
Logger
–
A configured logging.Logger instance.
Source code in cltk/core/cltk_logger.py
| def setup_cltk_logger(
name: str = "CLTK",
log_to_file: bool | None = None,
log_to_console: bool = True,
level: str | None = None,
) -> logging.Logger:
"""Configure and return a library logger.
Args:
name: Logger name.
log_to_file: If true, add a file handler writing to ``cltk.log``.
log_to_console: If true, add a colorized console handler.
level: Optional log level name (e.g., ``"INFO"``). If ``None``, uses
``CLTK_LOG_LEVEL`` environment variable or defaults to ``INFO``.
Returns:
A configured ``logging.Logger`` instance.
"""
logger = logging.getLogger(name)
logger.handlers.clear() # Remove any existing handlers
log_level = level or os.getenv("CLTK_LOG_LEVEL", "INFO").upper()
logger.setLevel(getattr(logging, log_level, logging.INFO))
formatter_file = logging.Formatter(
(
"%(asctime)s - %(name)s - %(filename)s:%(lineno)s - %(levelname)s"
" - doc_id=%(doc_id)s sentence_idx=%(sentence_idx)s"
" model=%(model)s glottolog_id=%(glottolog_id)s"
" prompt_version=%(prompt_version)s - %(message)s"
)
)
formatter_console = ColorFormatter("%(levelname)s: %(message)s")
# Determine file logging from explicit arg or env var (default: off)
if log_to_file is None:
env_val = os.getenv("CLTK_LOG_TO_FILE", "").strip().lower()
log_to_file = env_val in {"1", "true", "yes", "on"}
if log_to_file:
file_handler = logging.FileHandler("cltk.log")
file_handler.setFormatter(formatter_file)
file_handler.addFilter(_CLTKContextFilter())
logger.addHandler(file_handler)
if log_to_console:
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter_console)
console_handler.addFilter(_CLTKContextFilter())
logger.addHandler(console_handler)
return logger
|
bind_context
bind_context(
*,
doc_id: Optional[str] = None,
sentence_idx: Optional[int] = None,
model: Optional[str] = None,
glottolog_id: Optional[str] = None,
prompt_version: Optional[str] = None,
base_logger: Optional[Logger] = None
) -> logging.LoggerAdapter
Return a LoggerAdapter that carries structured CLTK context.
Example
log = bind_context(doc_id="abc123", sentence_idx=0, model="gpt-5-mini")
log.info("Generating POS tags")
Parameters:
-
doc_id
(Optional[str], default:
None
)
–
Stable document identifier for correlating events.
-
sentence_idx
(Optional[int], default:
None
)
–
Sentence index within the document (if applicable).
-
model
(Optional[str], default:
None
)
–
Backend model identifier (e.g., LLM model name).
-
glottolog_id
(Optional[str], default:
None
)
–
Language or dialect identifier.
-
prompt_version
(Optional[str], default:
None
)
–
Semantic version of the prompt used for a call.
-
base_logger
(Optional[Logger], default:
None
)
–
Optional base logger to adapt; defaults to module logger.
Source code in cltk/core/cltk_logger.py
| def bind_context(
*,
doc_id: Optional[str] = None,
sentence_idx: Optional[int] = None,
model: Optional[str] = None,
glottolog_id: Optional[str] = None,
prompt_version: Optional[str] = None,
base_logger: Optional[logging.Logger] = None,
) -> logging.LoggerAdapter:
"""Return a LoggerAdapter that carries structured CLTK context.
Example:
```python
log = bind_context(doc_id="abc123", sentence_idx=0, model="gpt-5-mini")
log.info("Generating POS tags")
```
Args:
doc_id: Stable document identifier for correlating events.
sentence_idx: Sentence index within the document (if applicable).
model: Backend model identifier (e.g., LLM model name).
glottolog_id: Language or dialect identifier.
prompt_version: Semantic version of the prompt used for a call.
base_logger: Optional base logger to adapt; defaults to module ``logger``.
"""
base = base_logger or logger
extra: dict[str, Any] = {
"doc_id": doc_id if doc_id is not None else "-",
"sentence_idx": sentence_idx if sentence_idx is not None else "-",
"model": model if model is not None else "-",
"glottolog_id": glottolog_id if glottolog_id is not None else "-",
"prompt_version": prompt_version if prompt_version is not None else "-",
}
return _ContextAdapter(base, extra)
|