GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing zetcode.com — Python logging - logging in Python with logging module Python logginglast modified January 29, 2024 Python logging tutorial shows how to do logging in Python with the logging module. LoggingLogging is the process of writing information into log files. Log files contain information about various events that happened in operating system, software, or in communication. Purpose of loggingLogging is done for the following purposes:
Logging is not limited to identifying errors in software development. It is also used in detecting security incidents, monitoring policy violations, providing information in case of problems, finding application bottlenecks, or generating usage data. Which events to logEvents that should be logged include input validation failures, authentication and authorization failures, application errors, configuration changes, and application start-ups and shut-downs. Which events not to logEvents that should not be logged include application source code, session identification values, access tokens, sensitive personal data, passwords, database connection strings, encryption keys, bank account and card holder data. Logging best practicesThe following are some best practices for doing logging:
The logging modulePython logging module defines functions and classes which implement a flexible event logging system for applications and libraries. The logging module componentsThe logging module has four main components: loggers, handlers, filters, and formatters. Loggers expose the interface that application code directly uses. Handlers send the log records (created by loggers) to the appropriate destination. Filters provide a finer grained facility for determining which log records to output. Formatters specify the layout of log records in the final output. Python logging hierarchy
Python loggers form a hierarchy. A logger named Child loggers propagate messages up to the handlers associated with their ancestor loggers. Because of this, it is unnecessary to define and configure handlers for all the loggers in the application. It is sufficient to configure handlers for a top-level logger and create child loggers as needed. Python logging levelsLevels are used for identifying the severity of an event. There are six logging levels:
If the logging level is set to Loggers have a concept of effective level. If a level is not explicitly set on a logger, the level of its parent is used instead as its effective level. If the parent has no explicit level set, its parent is examined, and so on - all ancestors are searched until an explicitly set level is found.
When the logger is created with Root logger
All loggers are descendants of the root logger. Each logger passes log messages
on to its parent. New loggers are created with the
The root logger always has an explicit level set, which is The root logger sits at the top of the hierarchy and is always present, even if not configured. In general, the program or library should not log directly against the root logger. Instead a specific logger for the program should be configured. Root logger can be used to easily turn all loggers from all libraries on and off. Python logging simple example
The simple.py
#!/usr/bin/python
import logging
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
The example calls five methods of the $ simple.py WARNING:root:This is a warning message ERROR:root:This is an error message CRITICAL:root:This is a critical message Notice that root logger is used and only three messages were written. This is because by default, only messages with level warning and up are written. Python set logging level
The logging level is set with set_level.py
#!/usr/bin/python
import logging
logger = logging.getLogger('dev')
logger.setLevel(logging.DEBUG)
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')
In the example, we change the logging level to logger = logging.getLogger('dev')
The $ set_level.py This is a warning message This is an error message This is a critical message Now all the messages were written. Python effective logging levelThe effective logging level is the level set explicitly or determined from the logger parents. effective_level.py
#!/usr/bin/python
import logging
main_logger = logging.getLogger('main')
main_logger.setLevel(5)
dev_logger = logging.getLogger('main.dev')
print(main_logger.getEffectiveLevel())
print(dev_logger.getEffectiveLevel())
In the example, we examine the effective logging level of two loggers. dev_logger = logging.getLogger('main.dev')
The level of the $ effective_level.py 5 5 Python logging handlersHandler is an object responsible for dispatching the appropriate log messages (based on the log messages' severity) to the handler's specified destination. Handlers are propagated like levels. If the logger has no handler set, its chain of ancestors is search for a handler. handlers.py
#!/usr/bin/python
import logging
logger = logging.getLogger('dev')
logger.setLevel(logging.INFO)
fileHandler = logging.FileHandler('test.log')
fileHandler.setLevel(logging.INFO)
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)
logger.addHandler(fileHandler)
logger.addHandler(consoleHandler)
logger.info('information message')
The example creates two handlers for a logger: a file handler and a console handler. fileHandler = logging.FileHandler('test.log')
consoleHandler = logging.StreamHandler()
logger.addHandler(fileHandler)
The handler is added to the logger with Python logging formattersFormatter is an object which configures the final order, structure, and contents of the log record. In addition to the message string, log records also include date and time, log names, and log level severity. formatter.py
#!/usr/bin/python
import logging
logger = logging.getLogger('dev')
logger.setLevel(logging.INFO)
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)
logger.addHandler(consoleHandler)
formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s: %(message)s')
consoleHandler.setFormatter(formatter)
logger.info('information message')
The example creates a console logger and adds a formatter to its handler. formatter = logging.Formatter('%(asctime)s %(name)s %(levelname)s: %(message)s')
The formatter is created. It includes the date time, logger name, logging level name, and log message. consoleHandler.setFormatter(formatter)
The formatter is set to the handler with $ formatter.py 2019-03-28 14:53:27,446 dev INFO: information message The message with the defined format is shown in the console. Python logging basicConfig
The basic_config.py
#!/usr/bin/python
import logging
logging.basicConfig(filename='test.log', format='%(filename)s: %(message)s',
level=logging.DEBUG)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
The example configures the root logger with logging.basicConfig(filename='test.log', format='%(filename)s: %(message)s',
level=logging.DEBUG)
With $ basic_config.py $ cat test.log basic_config.py: This is a debug message basic_config.py: This is an info message basic_config.py: This is a warning message basic_config.py: This is an error message basic_config.py: This is a critical message
After running the program, we have five messages written into the
Python logging fileConfig
The log.conf
[loggers] keys=root,dev [handlers] keys=consoleHandler [formatters] keys=extend,simple [logger_root] level=INFO handlers=consoleHandler [logger_dev] level=INFO handlers=consoleHandler qualname=dev propagate=0 [handler_consoleHandler] class=StreamHandler level=INFO formatter=extend args=(sys.stdout,) [formatter_extend] format=%(asctime)s - %(name)s - %(levelname)s - %(message)s [formatter_simple] format=%(asctime)s - %(message)s
The file_config.py
#!/usr/bin/python
import logging
import logging.config
logging.config.fileConfig(fname='log.conf')
logger = logging.getLogger('dev')
logger.info('This is an information message')
The example reads the logging configuration file from
the $ file_config.py 2019-03-28 15:26:31,137 - dev - INFO - This is an information message Python logging variableDynamic data is logged by using string formatting. log_variable.py
#!/usr/bin/python
import logging
root = logging.getLogger()
root.setLevel(logging.INFO)
log_format = '%(asctime)s %(filename)s: %(message)s'
logging.basicConfig(filename="test.log", format=log_format)
# incident happens
error_message = 'authentication failed'
root.error(f'error: {error_message}')
The example writes custom data to the log message. 2019-03-21 14:17:23,196 log_variable.py: error: authentication failed This is the log message. Python logging format datetime
The datetime is included in the log message with the date_time.py
#!/usr/bin/python
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
log_format = '%(asctime)s %(filename)s: %(message)s'
logging.basicConfig(filename="test.log", format=log_format,
datefmt='%Y-%m-%d %H:%M:%S')
logger.info("information message")
The example formats the datetime of the log message. log_format = '%(asctime)s %(filename)s: %(message)s'
We include the datetime string into the log with logging.basicConfig(filename="test.log", format=log_format,
datefmt='%Y-%m-%d %H:%M:%S')
The 2019-03-21 14:17:23,196 log_variable.py: error: authentication failed 2019-03-21 14:23:33 date_time.py: information message Notice the difference in the datetime string format. Python logging stack trace
The stack trace is a call stack of functions that were run
up to the point of a thrown exceptions. The stack trace is
included with the stack_trace.py
#!/usr/bin/python
import logging
log_format = '%(asctime)s %(filename)s: %(message)s'
logging.basicConfig(filename="test.log", format=log_format)
vals = [1, 2]
try:
print(vals[4])
except Exception as e:
logging.error("exception occurred", exc_info=True)
In the example, we log the exception that is thrown when we try to access a non-existing list index. logging.error("exception occurred", exc_info=True)
The stack trace is included in the log by setting the 2019-03-21 14:56:21,313 stack_trace.py: exception occurred
Traceback (most recent call last):
File "C:\Users\Jano\Documents\pyprogs\pylog\stack_trace.py", line 11, in <module>
print(vals[4])
IndexError: list index out of range
The stack trace is included in the log. Python logging getLogger
The All calls to this function with a given name return the same logger instance. This means that logger instances never need to be passed between different parts of an application. get_logger.py
#!/usr/bin/python
import logging
import sys
main = logging.getLogger('main')
main.setLevel(logging.DEBUG)
handler = logging.FileHandler('my.log')
format = logging.Formatter('%(asctime)s %(name)s
%(levelname)s: %(message)s')
handler.setFormatter(format)
main.addHandler(handler)
main.info('info message')
main.critical('critical message')
main.debug('debug message')
main.warning('warning message')
main.error('error message')
The example creates a new logger with main = logging.getLogger('main')
main.setLevel(logging.DEBUG)
A logger named handler = logging.FileHandler('my.log')
A file handler is created. The messages will be written to the
format = logging.Formatter('%(asctime)s %(name)s
%(levelname)s: %(message)s')
handler.setFormatter(format)
A formatter is created. It includes the time, the logger name,
the logging level, and the message in to log. The formatter is
set to the handler with main.addHandler(handler)
The handler is added to the logger with $ cat my.log 2019-03-21 14:15:45,439 main INFO: info message 2019-03-21 14:15:45,439 main CRITICAL: critical message 2019-03-21 14:15:45,439 main DEBUG: debug message 2019-03-21 14:15:45,439 main WARNING: warning message 2019-03-21 14:15:45,439 main ERROR: error message These are the written log messages. Python logging YAML configurationLogging details can be defined in a YAML configuration file. YAML is a human-readable data serialization language. It is commonly used for configuration files. $ pip install pyyaml
We need to install config.yaml
version: 1
formatters:
simple:
format: "%(asctime)s %(name)s: %(message)s"
extended:
format: "%(asctime)s %(name)s %(levelname)s: %(message)s"
handlers:
console:
class: logging.StreamHandler
level: INFO
formatter: simple
file_handler:
class: logging.FileHandler
level: INFO
filename: test.log
formatter: extended
propagate: false
loggers:
dev:
handlers: [console, file_handler]
test:
handlers: [file_handler]
root:
handlers: [file_handler]
In the configuration file, we have defined various formatters, handlers, and
loggers. The log_yaml.py
#!/usr/bin/python
import logging
import logging.config
import yaml
with open('config.yaml', 'r') as f:
log_cfg = yaml.safe_load(f.read())
logging.config.dictConfig(log_cfg)
logger = logging.getLogger('dev')
logger.setLevel(logging.INFO)
logger.info('This is an info message')
logger.error('This is an error message')
In the example, we read the configuration file and use
the $ log_yaml.py 2019-03-28 11:36:54,854 dev: This is an info message 2019-03-28 11:36:54,855 dev: This is an error message When we run the program, there are two messages on the console. The console handlers use the simple formatter with less information. ... 2019-03-28 11:36:54,854 dev INFO: This is an info message 2019-03-28 11:36:54,855 dev ERROR: This is an error message
There are log messages inside the SourceIn this article we have worked with the Python logging library. AuthorMy name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming. List all Python tutorials. |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |