gouge.parseable¶
Machine-readable log formatters.
CSVLogwrites one CSV row per record.XMLLogwrites one<record>element per record.JSONLogwrites one JSON object per line (JSON Lines), including the extra attributes of the record. This is the format to use for log aggregation.
-
class gouge.parseable.CSVLog(fmt=
None, datefmt=None, style='%', validate=True, *, defaults=None)¶ Bases:
FormatterCSV formatter: one row per record.
The columns correspond to the following fields:
created
filename
funcName
levelname
levelno
lineno
module
msecs
name
pathname
process
processName
relativeCreated
thread
threadName
message
exc_text
- Parameters:¶
- fmt=
None¶ Passed on to
logging.Formatter.- datefmt=
None¶ Passed on to
logging.Formatter.- style=
'%'¶ Passed on to
logging.Formatter.- validate=
True¶ Passed on to
logging.Formatter.- defaults=
None¶ Passed on to
logging.Formatter.
- fmt=
With
logging.config.dictConfig(), use either{"()": "gouge.parseable.CSVLog"}or{"class": "gouge.parseable.CSVLog"}as the formatter.- static basicConfig(**kwargs)¶
Call
logging.basicConfig()with kwargs, then set aCSVLogformatter on every handler of the root logger.- Parameters:¶
- **kwargs¶
Passed on to
logging.basicConfig().
- Return type:¶
-
class gouge.parseable.XMLLog(fmt=
None, datefmt=None, style='%', validate=True, *, defaults=None)¶ Bases:
FormatterXML formatter: one
<record>element per record.The records have the following schema:
<record> <created /> <filename /> <funcName /> <levelname /> <levelno /> <lineno /> <module /> <msecs /> <name /> <pathname /> <process /> <processName /> <relativeCreated /> <thread /> <threadName /> <message /> <exc_text /> </record>- Parameters:¶
- fmt=
None¶ Passed on to
logging.Formatter.- datefmt=
None¶ Passed on to
logging.Formatter.- style=
'%'¶ Passed on to
logging.Formatter.- validate=
True¶ Passed on to
logging.Formatter.- defaults=
None¶ Passed on to
logging.Formatter.
- fmt=
With
logging.config.dictConfig(), use either{"()": "gouge.parseable.XMLLog"}or{"class": "gouge.parseable.XMLLog"}as the formatter.- static basicConfig(**kwargs)¶
Call
logging.basicConfig()with kwargs, then set aXMLLogformatter on every handler of the root logger.- Parameters:¶
- **kwargs¶
Passed on to
logging.basicConfig().
- Return type:¶
-
class gouge.parseable.JSONLog(fmt=
None, datefmt=None, style='%', validate=True, *, defaults=None)¶ Bases:
FormatterJSON Lines formatter: one JSON object per record.
Each record becomes one compact JSON object on a single line (newlines in values are escaped). Non-ASCII text is written as-is. The keys are, in this order:
timestamp: the creation time of the record in UTC, as ISO 8601 with milliseconds, for example2026-10-27T13:34:48.899+00:00. UTC avoids ambiguous local times around daylight-saving changes.level: the level name, for exampleINFO.logger: the logger name.message: the message with its arguments merged in.every extra attribute of the record, sorted by name. Extra attributes are those passed with
extra={...}to a log call or set by a filter; standardlogging.LogRecordattributes and names starting with_are left out. The OpenTelemetry IDsotelTraceIDandotelSpanIDbecometrace_idandspan_idwhen a span is active.exc_text: the plain traceback, only if the record has exception information. Like the standard formatter, it is cached on the record.stack_info: the stack, only if the record has one.
The keys above always win: an extra attribute with the same name as one of them is written as
extra.<name>instead (and dropped if that name is taken as well).The output is always strict JSON and
format()never raises because of an extra attribute. Values which JSON cannot represent are written as theirstr. This includes non-finite floats (nan,inf), which become"NaN","Infinity"and"-Infinity", also when nested in lists or dictionaries. If a value cannot be serialised at all (a dictionary with keys which are not strings, numbers, booleans orNone, or a circular reference), thestrof the whole value is written instead. Extra attributes whose name is not a string are left out.- Parameters:¶
- fmt=
None¶ Ignored. Accepted so the formatter can be configured like any
logging.Formatter.- datefmt=
None¶ An optional
strftime()format fortimestamp. It is applied to the UTC time, so%zrenders as+0000.- style=
'%'¶ Passed on to
logging.Formatter.- validate=
True¶ Passed on to
logging.Formatter.- defaults=
None¶ Passed on to
logging.Formatter.
- fmt=
Example, with a correlation ID which a filter put on the records:
>>> import logging >>> from gouge.parseable import JSONLog >>> class CorrelationFilter(logging.Filter): ... def filter(self, record): ... record.correlation_id = "4bf92f35" ... return True >>> handler = logging.StreamHandler() >>> handler.addFilter(CorrelationFilter()) >>> handler.setFormatter(JSONLog()) >>> logging.getLogger().addHandler(handler) >>> logging.getLogger("app").warning( ... "Order created", extra={"order.id": 42} ... ) {"timestamp":...,"correlation_id":"4bf92f35","order.id":42}With
logging.config.dictConfig(), use either{"()": "gouge.parseable.JSONLog"}or{"class": "gouge.parseable.JSONLog"}as the formatter.-
CORE_KEYS =
frozenset({'exc_text', 'level', 'logger', 'message', 'stack_info', 'timestamp'})¶ The keys
JSONLogwrites itself.
- static basicConfig(**kwargs)¶
Call
logging.basicConfig()with kwargs, then set aJSONLogformatter on every handler of the root logger.- Parameters:¶
- **kwargs¶
Passed on to
logging.basicConfig().
- Return type:¶