Skip to main content

Logging

The Apify SDK is logging useful information through the logging module from Python's standard library, into the logger with the name apify.

Automatic configuration

When you create an Actor from an Apify-provided template, either in Apify Console or through the Apify CLI, you do not have to configure the logger yourself. The template already contains initialization code for the logger, which sets the logger level to DEBUG and the log formatter to ActorLogFormatter.

Manual configuration

Configuring the log level

In Python's default behavior, if you don't configure the logger otherwise, only logs with level WARNING or higher are printed out to the standard output, without any formatting. To also have logs with DEBUG and INFO level printed out, you need to call the Logger.setLevel() method on the logger, with the desired minimum level as an argument.

Configuring the log formatting

By default, only the log message is printed out to the output, without any formatting. To have a nicer output, with the log level printed in color, the messages nicely aligned, and extra log fields printed out, you can use the ActorLogFormatter class from the apify.log module.

Example log configuration

To configure and test the logger, you can use this snippet:

import logging

from apify import Actor
from apify.log import ActorLogFormatter

handler = logging.StreamHandler()
handler.setFormatter(ActorLogFormatter())

apify_logger = logging.getLogger('apify')
apify_logger.setLevel(logging.DEBUG)
apify_logger.addHandler(handler)

This configuration will cause all levels of messages to be printed to the standard output, with some pretty formatting.

Logger usage

Here you can see how all the log levels would look like.

You can use the extra argument for all log levels, it's not specific to the warning level. When you use Logger.exception(), there is no need to pass the Exception object to the log manually, it will automatiacally infer it from the current execution context and print the exception details.

Actor.log.debug('This is a debug message')
Actor.log.info('This is an info message')
Actor.log.warning('This is a warning message', extra={'reason': 'Bad Actor!'})
Actor.log.error('This is an error message')
try:
raise RuntimeError('Ouch!')
except:
Actor.log.exception('This is an exceptional message')

Result:

DEBUG This is a debug message
INFO This is an info message
WARN This is a warning message ({"reason": "Bad Actor!"})
ERROR This is an error message
ERROR This is an exceptional message
Traceback (most recent call last):
File "main.py", line 6, in <module>
raise RuntimeError('Ouch!')
RuntimeError: Ouch!