Logging#
ActivitySim uses the usual Python logging infrastructure, with just a few additional features.
Generally, logging configuration is done via the
dictConfig
interface, with keys and values as documented
here.
This dictionary fed to this configurator is loaded from the logging.yaml
file(s) located in your model’s configuration directory(s) following the
usual pattern for finding and loading config files.
New in version 1.3: ActivitySim no longer permits the use of !!python/object/apply directives inside
yaml input files. These commands imply the capability to allow arbitrary code
execution, and we would like to move away from that.
Instead of allowing arbitrary code to be loaded into and modify the logging configuration, there are just a few particular ActivitySim functions are exposed.
Log file locations#
As noted above, the logging configuration implementation relies heavily on the standard Python logging library, which by default knows nothing about ActivitySim or its typical layout of output files, including placement of logs in a designated output directory. Therefore, if you set the filename of a logging FileHandler to just a string like this:
logfile:
class: logging.FileHandler
filename: just-a-file-name.log
then that file will be created in the Python current working directory (typically
wherever you invoked the script) and not in your designated output directory.
To fix this and write the log into your designated output directory, you can use
get_log_file_path as an intervening key in the configuration between the
filename key and the desired value, like this:
logfile:
class: logging.FileHandler
filename:
get_log_file_path: my-file-name.log
This special formatting will be pre-processed by ActivitySim before configuring the logging, so that the file will be created in your designated output directory. This also works when subprocesses are running, in which case the log file will then be created in (or relative to) the process’ log file directory, not in (or relative to) the main output directory.
Identifying Subprocesses#
You may want to have different settings for subprocess workers and the main ActivitySim process. For example, you may have the main processes log everything it writes to both the console and a log file, while the subprocesses log mostly to files, and only write higher priority messages (warnings and errors) to the console. Any logging configuration can be set to bifurcate like this between the main process and subtasks by setting “is_sub_task” and “is_not_sub_task” keys like this:
handlers:
console:
level:
if_sub_task: WARNING
if_not_sub_task: NOTSET
Logging levels#
Python’s built-in logging module that includes five levels of logging, which are (in order
of increasing severity): DEBUG, INFO, WARNING, ERROR, and CRITICAL. One can set the
minimum level to display messages in both the console window as well as the output logfile
within logging.yaml in the model settings. For example, if the block of code below were
inside the logging.yaml file, than the console window and output activitysim.log file would
print every logging message at the level of INFO and above:
loggers:
activitysim:
level: INFO
handlers: [console, logfile]
propogate: false
However, if a model run were to crash and the user wanted to print all of the DEBUG messages
in order to diagnose what was causing the crash, they would need to change the level within
the logging settings:
loggers:
activitysim:
level: DEBUG
handlers: [console, logfile]
propogate: false
The following guidelines demonstrate how each level is used within ActivitySim:
Debug (Level 10)#
The DEBUG message indicates detailed information that would be of interest to a user while
debugging a model. The information reported at this level can include:
Runtimes of specific steps of model components, such as the time to run each of sampling, logsum computation, and simulation in destination choice
Table attributes at various stages of processing, such as the size or columns
Evaluations of preprocessor or specification expressions
General repetitive messages that can be used to narrow down exactly where an error is occuring
Info (Level 20)#
The INFO message gives reports general information about how the status of the model run,
particularly where in the model flow the system is at. The information reported at this level
can include:
Beginning and ending of a model step
Intermediate stages of a longer step. For example, in trip destination, the trip number and segment will be reported at this level.
Warning (Level 30)#
The WARNING message notifies the user of a potential issue that they should be aware of,
but doesn’t result in the model system failing. The information reported at this level can include:
Future changes to dependencies
ActivitySim needing to force certain travel behavior due to such behavior not working
Error (Level 40)#
The ERROR message gives the user information that is causing an error in a model step. The
information reported at this level can include:
More detailed issues on what could be causing an error message that wouldn’t be shown in the traceback message
Critical (Level 50)#
The CRITICAL message gives the user information that is causing a critical error in a model step.
The information reported at this level can include:
Reporting to the user on the teardown of a subprocess