Logging#
All messages are emitted by id_translation namespace loggers. The id_translation namespace uses the
logging.WARNING log level (similar to
SQLAlchemy).
To enable logs at the ℹ️ INFO level and below, you must explicitly configure the log level.
Verbose logging#
Set the global ENABLE_VERBOSE_LOGGING flag (or use enable_verbose_debug_messages()) to
enable additional 🪲 DEBUG-level messages. Use the ID_TRANSLATION_VERBOSE variable in containers.
Warning
Verbose logging may emit hundreds of messages for a single translation task!
Note that verbose and 🪲 DEBUG logging are different things; verbose logging may emit hundreds of messages where
regular 🪲 DEBUG might only emit a dozen.
Example#
The ℹ️ INFO-level messages emitted for a single Translator.translate() class.
[id_translation.fetching]: Finished initialization of 'MemoryFetcher' in 205 μs:
MemoryFetcher(sources=['category'], return_all=True)
[id_translation.fetching]: Finished initialization of 'SqlFetcher' in 159 ms:
SqlFetcher('postgresql+pg8000://postgres:***@localhost:5002/sakila',
sources=['address', 'film', 'language', 'customer', 'country', 'staff',
'actor', 'city'])
[id_translation.Translator.map]: Finished mapping of 4/6 names in 'DataFrame' in
4 ms: {'customer_id': 'customer', 'film_id': 'film', 'category_id':
'category', 'staff_id': 'staff', 'rental_date': None, 'return_date': None}.
[id_translation.fetching]: Finished fetching from 1 sources in 2 ms: ['category'
x ('id', 'name') x 16/7 IDs].
[id_translation.fetching]: Finished fetching from 3 sources in 24 ms:
['customer' x ('last_name', 'id', 'name') x 10/10 IDs], ['film' x ('id',
'name') x 10/10 IDs], ['staff' x ('last_name', 'id', 'name') x 2/2 IDs].
[id_translation.Translator]: Finished translation of 'DataFrame' in 31 ms.
Since these are 🔑 key event messages, there are corresponding entry events (the messages
above all all 'exit'-records). The 'enter'-records, however, are only emitted on the 🪲 DEBUG level.
Key Event Records#
Key event messages are emitted at the boundaries of the various stages in the translation process (see the Translation primer and Mapping primer pages). Common fields are listed below.
Field |
Type |
Description |
|---|---|---|
task_id |
|
Unique task identifier, e.g. for a single |
event_key |
|
E.g. MultiFetcher.fetch_all:enter (where |
seconds |
|
Task duration in seconds. Only when |
All key event methods add additional fields that are relevant to the current task and stage. Fields may be added,
removed, or change values depending on the stage of the event.
Event-specific fields#
Let’s take closer look at the final message. The LogRecord contains additional information that isn’t
included in the message itself. The full Translator.translate:exit-record is shown as JSON below.
9726 {
9727 "name": "id_translation.Translator",
9728 "msg": "Finished translation of 'DataFrame' in 31 ms.",
9729 "args": [],
9730 "levelname": "INFO",
9731 "levelno": 20,
9732 "pathname": "<site-packages>/id_translation/_tasks/_translate.py",
9733 "filename": "_translate.py",
9734 "module": "_translate",
9735 "exc_info": null,
9736 "exc_text": null,
9737 "stack_info": null,
9738 "lineno": 174,
9739 "funcName": "log_key_event_exit",
9740 "created": 1557606600.493773,
9741 "msecs": 535.0,
9742 "relativeCreated": 1392.953872680664,
9743 "thread": 137920029544576,
9744 "threadName": "MainThread",
9745 "processName": "MainProcess",
9746 "process": 44038,
9747 "task_id": 20190511,
9748 "event_key": "Translator.translate:exit",
9749 "seconds": 0.031172684000921436,
9750 "duration_ms": {
9751 "map": 3.8,
9752 "extract": 0.1,
9753 "fetch": 25.2,
9754 "verify": 0.4,
9755 "insert": 1.5
9756 },
9757 "online": true,
9758 "translatable_type": "pandas.DataFrame",
9759 "copy": true,
9760 "reverse": false,
9761 "name_to_source": {
9762 "staff_id": "staff",
9763 "customer_id": "customer",
9764 "category_id": "category",
9765 "film_id": "film"
9766 },
9767 "message": "Finished translation of 'DataFrame' in 31 ms.",
9768 "asctime": "2019-05-11T20:30:00"
9769 }
About 350 messages were emitted since ENABLE_VERBOSE_LOGGING=True. If we were using regular 🪲 DEBUG-logging,
about 40 messages would have been emitted instead. The vast majority of the verbose messages relate to mapping and
fetcher initialization.
from logging import basicConfig, DEBUG
from id_translation import Translator
from id_translation.logging import enable_verbose_debug_messages
basicConfig(handlers=[SomeJsonExporter()])
translator = Translator.from_config(main_config, [fetcher_configs..])
with enable_verbose_debug_messages():
translator.translate(df)
The configs that were used are available here.