Elk stack для хранения логов django приложения

Printing Debug Messages to Console

If you are used to using the statement to see what is occurring in a program, you may be used to seeing a program that defines a class and instantiates objects that looks something like this:


pizza.py

The code above has an method to define the and of an object of the class. It then has two methods, one called for making pizzas, and one called for eating pizzas. These two methods take in the parameter of , which is initialized at .

Now let’s run the program:

We’ll receive the following output:

While the statement allows us to see that the code is working, we can use the module to do this instead.

Let’s remove or comment out the statements throughout the code, and add to the top of the file:

pizza.py

The module has a of , which is a level above . Since we’re going to use the module for debugging in this example, we need to modify the configuration so that the level of will return information to the console for us. We can do that by adding the following line below the import statement:

pizza.py

This level of refers to a constant integer value that we reference in the code above to set a threshold. The level of is 10.

Now, we will replace all of the statements with statements instead. Unlike which is a constant, is a method of the module. When working with this method, we can make use of the same string passed to , as shown below.

pizza.py

At this point, when we run the program with the command, we’ll receive this output:

The log messages have the severity level as well as the word embedded in them, which refers to the level of your Python module. The module can be used with a hierarchy of loggers that have different names, so that you can use a different logger for each of your modules.

For example, you can set loggers equal to different loggers that have different names and different output:

Now that we have an understanding of how to use the module to print messages to the console, let’s move on to using the module to print messages out to a file.

Dictionary Schema — Detail

The dictionary passed to dictConfig() must contain the following keys:

version — to be set to an integer value representing the schema version. The only valid value at present is 1, but having this key allows the schema to evolve while still preserving backwards compatibility.

All other keys are optional, but if present they will be interpreted as described below. In all cases below where a ‘configuring dict’ is mentioned, it will be checked for the special '()' key to see if a custom instantiation is required. If so, the mechanism described above is used to instantiate; otherwise, the context is used to determine how to instantiate.

16.6.5. Filter Objects¶

can be used by and for more sophisticated filtering than is provided by levels. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with 〈A.B〉 will allow events logged by loggers 〈A.B〉, 〈A.B.C〉, 〈A.B.C.D〉, 〈A.B.D〉 etc. but not 〈A.BB〉, 〈B.A.B〉 etc. If initialized with the empty string, all events are passed.

class (name=»)

Returns an instance of the class. If name is specified, it names a logger which, together with its children, will have its events allowed through the filter. If name is the empty string, allows every event.

(record)

Is the specified record to be logged? Returns zero for no, nonzero for yes. If deemed appropriate, the record may be modified in-place by this method.

Note that filters attached to handlers are consulted before an event is emitted by the handler, whereas filters attached to loggers are consulted whenever an event is logged (using , , etc.), before sending an event to handlers. This means that events which have been generated by descendant loggers will not be filtered by a logger’s filter setting, unless the filter has also been applied to those descendant loggers.

You don’t actually need to subclass : you can pass any instance which has a method with the same semantics.

버전 3.2에서 변경: You don’t need to create specialized classes, or use other classes with a method: you can use a function (or other callable) as a filter. The filtering logic will check to see if the filter object has a attribute: if it does, it’s assumed to be a and its method is called. Otherwise, it’s assumed to be a callable and called with the record as the single parameter. The returned value should conform to that returned by .

Создаем простой логгер

Создание лога при помощи модуля logging это очень просто. Для начала, будет проще взглянуть на часть кода и объяснить его:

Python

import logging

# add filemode=»w» to overwrite logging.basicConfig(filename=»sample.log», level=logging.INFO)

logging.debug(«This is a debug message») logging.info(«Informational message») logging.error(«An error has happened!»)

1 2 3 4 5 6 7 8

importlogging

  # add filemode=»w» to overwrite

logging.basicConfig(filename=»sample.log»,level=logging.INFO)

logging.debug(«This is a debug message»)

logging.info(«Informational message»)

logging.error(«An error has happened!»)

Как и ожидалось, чтобы получит доступ к модулю logging, для начала нужно импортировать модуль. Простейший способ создания лога – это использовать функцию basicConfig модуля logging и передать ей несколько ключевых аргументов. Функция принимает следующее: filename, filemode, format, datefmt, level и stream. В нашем примере, мы передадим её названию файла и уровню логирования, что мы и настроим в INFO.

Существует пять уровней логирования (в порядке возрастания): DEBUG, INFO, WARNING, ERROR и CRITICAL. По умолчанию, если вы запустите этот код несколько раз, он добавится в лог, если он существует. Если вы хотите, чтобы ваш логгер перезаписывал лог, передайте его filemode=”w”, как было указано в комментарии к коду. Говоря о запуске кода, вы должны получить следующий результат, после запуска:

Python

INFO:root:Informational message ERROR:root:An error has happened!

1 2

INFOrootInformational message

ERRORrootAn error has happened!

Обратите внимание на то, что сообщение о дебаггинге находится не на выходе. Это связанно с тем, что мы установили уровень в INFO, так что наш логгер будет записывать только сообщения INFO, WARNING, ERROR или CRITICAL

Часть root означает, что данное сообщение пришло либо от корневого логгера, либо от основного. Мы взглянем на то, как это можно изменить, что бы следующая часть была более понятной. Если вы не используете basicConfig, тогда модуль протоколирования выведет на консоль / stdout. Модуль logging также может учитывать некоторые исключения в файле, или там, где вы указали. Взглянем на пример:

Python

import logging

logging.basicConfig(filename=»sample.log», level=logging.INFO) log = logging.getLogger(«ex»)

try: raise RuntimeError except RuntimeError: log.exception(«Error!»)

1 2 3 4 5 6 7 8 9

importlogging

logging.basicConfig(filename=»sample.log»,level=logging.INFO)

log=logging.getLogger(«ex»)

try

raiseRuntimeError

exceptRuntimeError

log.exception(«Error!»)

Давайте немного притормозим. Здесь мы использовали метод getLogger модуля logging, чтобы вернуть объект логгера под названием ex. Это удобно, если у вас есть несколько логгеров в одном приложении, так как это позволяет вам узнать, какие сообщения приходят с каждого логгера. Этот пример провоцирует возникновение ошибки RuntimeError, затем это регистрируется в файле, что может быть очень удобно при лечении багов.

16.6.7. LogRecord 属性¶

LogRecord 具有许多属性,它们大多数来自于传递给构造器的形参。 (请注意 LogRecord 构造器形参与 LogRecord 属性的名称并不总是完全彼此对应的。) 这些属性可被用于将来自记录的数据合并到格式字符串中。 下面的表格(按字母顺序)列出了属性名称、它们的含义以及相应的 %-style 格式字符串内占位符。

如果是使用 {}-格式化 (),你可以将 用作格式字符串内的占位符。 如果是使用 $-格式化 (),则会使用 的形式。 当然在这两种情况下,都应当将 替换为你想要使用的实际属性名称。

在 {}-格式化的情况下,你可以在属性名称之后放置指定的格式化旗标,并用冒号来分隔两者。 例如,占位符 会将毫秒值 格式化为 。 请参看 文档了解你所能使用的选项的完整细节。

属性名称

格式

描述

args

不需要格式化。

合并到 以产生 的包含参数的元组,或是其中的值将被用于合并的字典(当只有一个参数且其类型为字典时)。

asctime

表示 何时被创建的供人查看时间值。 默认形式为 ‘2003-07-08 16:49:45,896’ (逗号之后的数字为时间的毫秒部分)。

created

被创建的时间(即 的返回值)。

exc_info

不需要格式化。

异常元组 (例如 ) 或者如未发生异常则为 。

filename

的文件名部分。

funcName

函数名包括调用日志记录.

levelname

消息文本记录级别 (, , , , ).

levelno

消息数字记录级别 (, , , , ).

lineno

发出日志记录调用所在的源行号(如果可用)。

message

记入日志的消息,即 的结果。 这是在发起调用 时设置的。

module 模块

模块 ( 的名称部分)。

msecs

被创建的时间的毫秒部分。

msg

不需要格式化。


在原始日志记录调用中传入的格式字符串。 与 合并以产生 ,或是一个任意对象 (参见 )。

名称

用于记录调用的日志记录器名称。

pathname

发出日志记录调用的源文件的完整路径名(如果可用)。

process

进程ID(如果可用)

processName

进程名(如果可用)

relativeCreated

以毫秒数表示的 LogRecord 被创建的时间,即相对于 logging 模块被加载时间的差值。

stack_info

不需要格式化。

当前线程中从堆栈底部起向上直到包括日志记录调用并导致创建此记录的堆栈帧的堆栈帧信息(如果可用)。

thread

线程ID(如果可用)

threadName

线程名(如果可用)

日志级别¶

日志记录级别的数值在下表中给出。如果你想要定义自己的级别,并且需要它们具有相对于预定义级别的特定值,那么这些内容可能是你感兴趣的。如果你定义具有相同数值的级别,它将覆盖预定义的值; 预定义的名称丢失。

级别

数值

50

40

30

20

10

级别也可以与记录器相关联,由开发人员设置或通过加载已保存的日志记录配置。在记录器上调用日志记录方法时,记录器会将其自己的级别与与方法调用关联的级别进行比较。如果记录器的级别高于方法调用的级别,则实际上不会生成任何记录消息。这是控制日志记录输出详细程度的基本机制。

记录消息被编码为 类的实例。当记录器决定实际记录事件时,从记录消息创建 实例。

记录消息通过使用 handlers 进行调度机制,它们是 类的子类的实例。处理程序负责确保记录的消息(以 的形式)最终位于特定位置(或一组位置),这对该消息的目标受众(例如最终用户、 支持服务台员工、系统管理员、开发人员)。传递处理程序用于特定目标的 实例。 每个记录器可以有零个、一个或多个与之关联的处理程序(通过 的 方法)。除了与记录器直接关联的任何处理程序之外,还调用与记录器的 所有祖先相关联的所有处理程序来分派消息(除非记录器的 *propagate 标志设置为false值,这将停止传递到上级处理程序)。

就像记录器一样,处理程序可以具有与它们相关联的级别。处理程序的级别作为过滤器,其方式与记录器级别相同。如果处理程序决定调度一个事件,则使用 方法将消息发送到其目标。大多数用户定义的 子类都需要重载 。

Краткий обзор модуля logging

Модуль logging регистрирует происходящие в программе события, что позволяет увидеть результат любого события.

Очень часто с этой же целью в программах используется оператор print() – это, по сути, базовый способ обнаружения и устранения неполадок. Хотя оператор print() может отслеживать поток выполнения кода и текущее состояние программы, это решение оказывается менее удобным, чем использование модуля logging по нескольким причинам:

  • Сложно отличить вывод для отладки от обычного вывода программы, потому что они не отделяются друг от друга.
  • Используя print() по всему коду программы, вы не можете просто отключить те операторы, которые предназначены для отладки.
  • Завершив отладку программы, удалить операторы print() довольно сложно.
  • Оператор print() не предоставляет логов, в которых можно было бы найти полезные для диагностики данные.

Модуль logging больше подходит для отладки сложных приложений, которые выходят за рамки простых сценариев Python.

В логах регистрируется поведение и ошибки программы, потому они предоставляют более полную картину того, что происходит в процессе разработки приложения.

Why use the logging module?

A developer might argue, why aren’t simple print statements sufficient? The logging module offers multiple benefits, including:

  • Multi-threading support
  • Categorization via different levels of logging
  • Flexibility and configurability
  • Separation of the how from the what

This last point, the actual separation of the what we log from the how we log enables collaboration between different parts of the software. As an example, it allows the developer of a framework or library to add logs and let the sysadmin or person in charge of the runtime configuration decide what should be logged at a later point.

QueueListener¶

버전 3.2에 추가.

모듈에 있는 클래스는 나 모듈에 구현된 것과 같은 큐에서 로깅 메시지를 수신하는 것을 지원합니다. 메시지는 내부 스레드의 큐에서 수신되고 처리를 위해 같은 스레드에서 하나 이상의 처리기로 전달됩니다. 자체는 처리기가 아니지만, 와 함께 사용되기 때문에 여기에 설명되어 있습니다.

클래스와 함께, 를 사용하여 처리기가 로깅을 수행하는 스레드와 다른 스레드에서 작업을 수행하도록 할 수 있습니다. 이는 클라이언트를 처리하는 스레드가 가능한 한 신속하게 응답하고, 느린 작업(가령 를 통해 전자 메일 보내기)은 별도의 스레드에서 수행되어야 하는 웹 응용 프로그램과 다른 서비스 응용 프로그램에서 중요합니다.

class (queue, *handlers, respect_handler_level=False)

클래스의 새 인스턴스를 반환합니다. 인스턴스는 메시지를 보내는 큐와 큐에 있는 항목을 처리할 처리기의 리스트로 초기화됩니다. 큐는 임의의 큐류(queue-like) 객체일 수 있습니다; 메시지를 꺼내는 방법을 알아야 하는 메서드가 있는 그대로 사용합니다. 큐는 작업 추적 API를 갖도록 요구되지 않아서 (가능하면 사용됩니다), queue에 인스턴스를 사용할 수 있습니다.

이 면, 처리기에 메시지를 전달할지를 결정할 때, 처리기의 수준이 존중됩니다 (메시지의 수준과 비교); 그렇지 않으면, 이전 파이썬 버전과 같게 동작합니다 — 항상 각 메시지를 모든 처리기에 전달합니다.

버전 3.5에서 변경: 인자가 추가되었습니다.

(block)

레코드를 큐에서 꺼내 반환합니다. 선택적으로 블록 됩니다.

기본 구현은 을 사용합니다. 시간제한을 사용하거나 사용자 정의 큐 구현을 사용하려면 이 메서드를 재정의할 수 있습니다.

(record)

처리를 위해 레코드를 준비합니다.

이 구현은 단지 전달된 레코드를 반환합니다. 사용자 정의 직렬화를 수행하거나 처리기에 전달하기 전에 레코드를 조작해야 하면, 이 메서드를 재정의할 수 있습니다.

(record)

레코드를 처리합니다.

이것은 단지 모든 처리기로 레코드를 제공합니다. 처리기에 전달되는 실제 객체는 에서 반환된 객체입니다.

()

수신기를 시작합니다.

이것은 처리하기 위해 큐에서 LogRecord를 관찰하는 배경 스레드를 시작합니다.

()

수신기를 정지합니다.

스레드가 종료하도록 요청한 다음, 스레드가 종료할 때까지 대기합니다. 응용 프로그램이 종료되기 전에 이 함수를 호출하지 않으면, 레코드가 큐에 남아있을 수 있고, 이것들은 처리되지 않습니다.

()

수신자에게 종료하도록 알리기 위해 큐에 종료 신호(sentinel)를 씁니다. 이 구현은 를 사용합니다. 시간제한을 사용하거나 사용자 정의 큐 구현을 사용하려면 이 메서드를 재정의할 수 있습니다.

버전 3.3에 추가.

더 보기

모듈

logging 모듈에 관한 API 레퍼런스.

모듈

logging 모듈용 구성 API.

处理器对象¶

Handler 有以下属性和方法。注意不要直接实例化 ;这个类用来派生其他更有用的子类。但是,子类的 方法需要调用 。

class
(level=NOTSET)

初始化 实例时,需要设置它的级别,将过滤列表置为空,并且创建锁(通过 )来序列化对 I/O 的访问。

()

初始化一个线程锁,用来序列化对底层的 I/O 功能的访问,底层的 I/O 功能可能不是线程安全的。

()

使用 获取线程锁。

()

使用 来释放线程锁。

(level)

给处理器设置阈值为 level 。日志级别小于 level 将被忽略。创建处理器时,日志级别被设置为 (所有的消息都会被处理)。

参见 级别列表。

在 3.2 版更改: level 形参现在接受像 ‘INFO’ 这样的字符串形式的级别表达方式,也可以使用像 这样的整数常量。

(fmt)

将此处理器的 设置为 fmt。

(filter)

将指定的过滤器 filter 添加到此处理器。

(filter)

从此处理器中删除指定的过滤器 filter 。

(record)

将此处理器的过滤器应用于记录,在要处理记录时返回 。依次查询过滤器,直到其中一个返回假值为止。如果它们都不返回假值,则将发出记录。如果返回一个假值,则处理器将不会发出记录。

()

确保所有日志记录从缓存输出。此版本不执行任何操作,并且应由子类实现。

()

整理处理器使用的所有资源。此版本不输出,但从内部处理器列表中删除处理器,内部处理器在 被调用时关闭 。子类应确保从重写的 方法中调用此方法。

(record)

经已添加到处理器的过滤器过滤后,有条件地发出指定的日志记录。用获取/释放 I/O 线程锁包装记录的实际发出行为。

(record)

调用 期间遇到异常时,应从处理器中调用此方法。如果模块级属性 是 ,则异常将被静默忽略。这是大多数情况下日志系统需要的 —— 大多数用户不会关心日志系统中的错误,他们对应用程序错误更感兴趣。但是,你可以根据需要将其替换为自定义处理器。指定的记录是发生异常时正在处理的记录。( 的默认值是 ,因为这在开发过程中是比较有用的)。

(record)

如果设置了格式器则用其对记录进行格式化。否则,使用模块的默认格式器。

(record)

执行实际记录给定日志记录所需的操作。这个版本应由子类实现,因此这里直接引发 异常。

Using Handlers

Like loggers, you can also set the severity level in handlers. This is useful if you want to set multiple handlers for the same logger but want different severity levels for each of them. For example, you may want logs with level and above to be logged to the console, but everything with level and above should also be saved to a file. Here’s a program that does that:

Here, is creating a that holds all the information of the event and passing it to all the Handlers that it has: and .

is a with level and takes the info from the to generate an output in the format specified and prints it to the console. is a with level , and it ignores this as its level is .

When is called, behaves exactly as before, and gets a at the level of , so it proceeds to generate an output just like , but instead of printing it to console, it writes it to the specified file in this format:

The name of the logger corresponding to the variable is logged as , which is the name Python assigns to the module where execution starts. If this file is imported by some other module, then the variable would correspond to its name logging_example. Here’s how it would look:

BaseRotatingHandler¶

类位于 模块中,它是轮换文件处理程序类 和 的基类。 你不需要实例化此类,但它具有你可能需要重载的属性和方法。

class (filename, mode, encoding=None, delay=False)

类的形参与 的相同。 其属性有:

如果此属性被设为一个可调用对象,则 方法会委托给该可调用对象。 传给该可调用对象的形参与传给 的相同。

注解

namer 函数会在轮换期间被多次调用,因此它应当尽可能的简单快速。 它还应当对给定的输入每次都返回相同的输出,否则轮换行为可能无法按预期工作。

3.3 新版功能.

如果此属性被设为一个可调用对象,则 方法会委托给该可调用对象。 传给该可调用对象的形参与传给 的相同。

3.3 新版功能.

(default_name)

当轮换时修改日志文件的文件名。

提供该属性以便可以提供自定义文件名。

默认实现会调用处理程序的 ‘namer’ 属性,如果它是可调用对象的话,并传给它默认的名称。 如果该属性不是可调用对象 (默认值为 ),则将名称原样返回。

参数

default_name — 日志文件的默认名称。

3.3 新版功能.

(source, dest)

当执行轮换时,轮换当前日志。

默认实现会调用处理程序的 ‘rotator’ 属性,如果它是可调用对象的话,并传给它 source 和 dest 参数。 如果该属性不是可调用对象 (默认值为 ),则将源简单地重命名为目标。

参数
  • source — 源文件名。 这通常为基本文件名,例如 ‘test.log’。

  • dest — 目标文件名。 这通常是源被轮换后的名称,例如 ‘test.log.1’。

3.3 新版功能.

该属性存在的理由是让你不必进行子类化 —— 你可以使用与 和 的实例相同的可调用对象。 如果 namer 或 rotator 可调用对象引发了异常,将会按照与 调用期间的任何其他异常相同的方式来处理,例如通过处理程序的 方法。

如果你需要对轮换进程执行更多的修改,你可以重载这些方法。

유용한 처리기¶

베이스 클래스 외에도 많은 유용한 서브 클래스가 제공됩니다:

  1. 인스턴스는 스트림(파일류 객체)에 메시지를 보냅니다.

  2. 인스턴스는 디스크 파일에 메시지를 보냅니다.

  3. 는 특정 지점에서 로그 파일을 회전시키는 처리기의 베이스 클래스입니다. 직접 인스턴스화하는 것은 아닙니다. 대신 또는 를 사용하십시오.

  4. 인스턴스는 디스크 파일에 메시지를 보내는데, 최대 로그 파일 크기와 로그 파일 회전을 지원합니다.

  5. 인스턴스는 디스크 파일에 메시지를 보내는데, 일정한 시간 간격으로 로그 파일을 회전시킵니다.

  6. 인스턴스는 TCP/IP 소켓에 메시지를 보냅니다. 3.4부터, 유닉스 도메인 소켓도 지원됩니다.

  7. 인스턴스는 UDP 소켓에 메시지를 보냅니다. 3.4부터, 유닉스 도메인 소켓도 지원됩니다.

  8. 인스턴스는 지정된 전자 우편 주소로 메시지를 보냅니다.

  9. 인스턴스는 유닉스 syslog 데몬(원격 기계에 있는 것도 가능합니다)에 메시지를 보냅니다.

  10. 인스턴스는 윈도우 NT/2000/XP 이벤트 로그에 메시지를 보냅니다.

  11. 인스턴스는 메모리에 있는 버퍼에 메시지를 보내는데, 특정 기준이 만족 될 때마다 플러시 됩니다.

  12. 인스턴스는 또는 을 사용해서 HTTP 서버에 메시지를 보냅니다.

  13. 인스턴스는 그들이 로깅하고 있는 파일을 감시합니다. 파일이 변경되면 닫히고 파일 이름을 사용하여 다시 열립니다. 이 처리기는 유닉스 계열 시스템에서만 유용합니다; 윈도우는 사용된 하부 메커니즘을 지원하지 않습니다.

  14. 인스턴스는 또는 모듈에 구현된 것과 같은 큐로 메시지를 보냅니다.

  15. 인스턴스는 에러 메시지로 아무것도 하지 않습니다. 라이브러리 개발자가 로깅을 사용하지만, 라이브러리 사용자가 로깅을 구성하지 않으면 표시될 수 있는 〈No handlers could be found for logger XXX〉 라는 메시지를 피하려고 할 때 사용합니다. 자세한 정보는 를 보십시오.

버전 3.1에 추가: 클래스.

버전 3.2에 추가: 클래스.

, 와 클래스는 코어 logging 패키지에 정의되어 있습니다. 다른 처리기는 하위 모듈인 에 정의되어 있습니다. (구성 기능을 위한, 또 다른 하위 모듈 도 있습니다.)

로그된 메시지는 클래스의 인스턴스를 통해 표시를 위해 포맷됩니다. % 연산자와 딕셔너리와 함께 사용하기에 적합한 포맷 문자열로 초기화됩니다.

일괄 처리로 여러 개의 메시지를 포맷하려면, 의 인스턴스를 사용할 수 있습니다. 포맷 문자열(일괄 처리 때 각 메시지에 적용됩니다)에 더해, 헤더와 트레일러 포맷 문자열에 대한 고려가 있습니다.

로거 수준과 처리기 수준을 기반으로 필터링하는 것만으로는 충분하지 않은 경우, 및 인스턴스에 ( 메서드를 통해) 인스턴스를 추가 할 수 있습니다. 메시지를 더 처리하기로 하기 전에, 로거와 처리기는 모든 필터에 허락을 요청합니다. 한 필터라도 거짓 값을 반환하면 메시지는 더 처리되지 않습니다.

BaseRotatingHandler¶

모듈에 있는 클래스는 회전하는 파일 처리기들(와 )의 베이스 클래스입니다. 이 클래스의 인스턴스를 만들 필요는 없지만, 재정의가 필요할 수 있는 어트리뷰트와 메서드가 있습니다.

class (filename, mode, encoding=None, delay=False)

매개 변수는 와 같습니다. 어트리뷰트는 다음과 같습니다:


이 어트리뷰트가 콜러블로 설정되면, 메서드는 이 콜러블에 위임합니다. 콜러블로 전달되는 매개 변수는 로 전달되는 것입니다.

참고

namer 함수는 롤오버 중에 꽤 자주 호출되므로, 가능한 한 간단하고 빨라야 합니다. 또한, 주어진 입력에 대해 매번 같은 출력을 반환해야 합니다, 그렇지 않으면 롤오버 동작이 예상대로 작동하지 않을 수 있습니다.

버전 3.3에 추가.

이 어트리뷰트가 콜러블로 설정되면, 메서드는 이 콜러블에 위임합니다. 콜러블로 전달되는 매개 변수는 로 전달되는 것입니다.

버전 3.3에 추가.

(default_name)

회전할 때 로그 파일의 파일명을 수정합니다.

사용자 정의 파일명을 제공할 수 있게 하려고 제공됩니다.

기본 구현은 처리기의 〈namer〉 어트리뷰트를(콜러블이라면) 호출하는데, 기본 이름을 전달합니다. 어트리뷰트가 콜러블이 아니면 (기본값은 입니다), 이름은 변경되지 않고 반환됩니다.

매개변수

default_name – 로그 파일의 기본 이름.

버전 3.3에 추가.

(source, dest)

회전할 때, 현재 로그를 회전합니다.

기본 구현은 처리기의 〈rotator〉 어트리뷰트를(콜러블이라면) 호출하는데, source와 dest 인자를 전달합니다. 어트리뷰트가 콜러블이 아니면 (기본값은 입니다), source를 dest 로 단순히 이름을 바꿉니다.

매개변수
  • source – 소스 파일명. 이것은 일반적으로 기본 파일명입니다, 예를 들어 〈test.log〉.

  • dest – 대상 파일명. 이것은 일반적으로 소스가 회전되는 곳입니다, 예를 들어 〈test.log.1〉.

버전 3.3에 추가.

어트리뷰트가 존재하는 이유는 서브 클래싱해야 할 필요를 줄이는 것입니다 — 와 의 인스턴스에 같은 콜러블을 사용할 수 있습니다. namer 나 rotator 콜러블이 예외를 발생시키면, 동안 발생하는 다른 예외와 같은 방식으로 처리됩니다, 즉 처리기의 메서드를 통해.

회전 처리를 더 크게 변경해야 하면, 메서드를 재정의할 수 있습니다.

16.6.7. LogRecord attributes¶

The LogRecord has a number of attributes, most of which are derived from the parameters to the constructor. (Note that the names do not always correspond exactly between the LogRecord constructor parameters and the LogRecord attributes.) These attributes can be used to merge data from the record into the format string. The following table lists (in alphabetical order) the attribute names, their meanings and the corresponding placeholder in a %-style format string.

If you are using {}-formatting (), you can use as the placeholder in the format string. If you are using $-formatting (), use the form . In both cases, of course, replace with the actual attribute name you want to use.

In the case of {}-formatting, you can specify formatting flags by placing them after the attribute name, separated from it with a colon. For example: a placeholder of would format a millisecond value of as . Refer to the documentation for full details on the options available to you.

Attribute name

Format

Description

args

You shouldn’t need to format this yourself.

The tuple of arguments merged into to produce , or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).

asctime

Human-readable time when the was created. By default this is of the form 〈2003-07-08 16:49:45,896〉 (the numbers after the comma are millisecond portion of the time).

created

Time when the was created (as returned by ).

exc_info

You shouldn’t need to format this yourself.

Exception tuple (à la ) or, if no exception has occurred, .

filename

Filename portion of .

funcName

Name of function containing the logging call.

levelname

Text logging level for the message (, , , , ).

levelno

Numeric logging level for the message (, , , , ).

lineno

Source line number where the logging call was issued (if available).

message

The logged message, computed as . This is set when is invoked.

module

Module (name portion of ).

msecs

Millisecond portion of the time when the was created.

msg

You shouldn’t need to format this yourself.

The format string passed in the original logging call. Merged with to produce , or an arbitrary object (see ).

name

Name of the logger used to log the call.

pathname

Full pathname of the source file where the logging call was issued (if available).

process

Process ID (if available).

processName

Process name (if available).

relativeCreated

Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.

stack_info

You shouldn’t need to format this yourself.

Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record.

thread

Thread ID (if available).

threadName

Thread name (if available).

Формат вывода

Хотя вы можете передавать любую переменную, которая может быть представлена в виде строки из вашей программы в виде сообщения в ваши журналы, есть некоторые базовые элементы, которые уже являются частью LogRecord и могут быть легко добавлены в выходной формат. Если вы хотите записать идентификатор процесса ID вместе с уровнем и сообщением, вы можете сделать что-то вроде этого:

import logging

logging.basicConfig(format='%(process)d-%(levelname)s-%(message)s')
logging.warning('This is a Warning')
18472-WARNING-This is a Warning

format может принимать строку с атрибутами LogRecord в любом порядке. Весь список доступных атрибутов можно найти .

Вот еще один пример, где вы можете добавить информацию о дате и времени:

import logging

logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
logging.info('Admin logged in')
2018-07-11 20:12:06,288 - Admin logged in

%(asctime)s добавляет время создания LogRecord. Формат можно изменить с помощью атрибута datefmt, который использует тот же язык форматирования, что и функции форматирования в модуле datetime, например time.strftime():

import logging

logging.basicConfig(format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S')
logging.warning('Admin logged out')
12-Jul-18 20:53:19 - Admin logged out

Вы можете найти больше информации о формате datetime руководстве.

Логирование переменных

В большинстве случаев вам нужно будет включать динамическую информацию из вашего приложения в журналы. Вы видели, что методы ведения журнала принимают строку в качестве аргумента, и может показаться естественным отформатировать строку с переменными в отдельной строке и передать ее методу log. Но на самом деле это можно сделать напрямую, используя строку формата для сообщения и добавляя переменные в качестве аргументов. Вот пример:

import logging

name = 'John'

logging.error('%s raised an error', name)
ERROR:root:John raised an error

Аргументы, передаваемые методу, будут включены в сообщение в качестве переменных.

Хотя вы можете использовать любой стиль форматирования, f-строки, представленные в Python 3.6, являются лучшим способом форматирования строк, поскольку они могут помочь сделать форматирование коротким и легким для чтения:

import logging

name = 'John'

logging.error(f'{name} raised an error')
ERROR:root:John raised an error

Вывод стека

Модуль регистрации также позволяет вам захватывать стек выполнения в приложении. Информация об исключении может быть получена, если параметр exc_info передан как True, а функции ведения журнала вызываются таким образом:

import logging

a = 5
b = 0

try:
  c = a / b
except Exception as e:
  logging.error("Exception occurred", exc_info=True)
ERROR:root:Exception occurred
Traceback (most recent call last):
  File "exceptions.py", line 6, in <module>
    c = a / b
ZeroDivisionError: division by zero

Если для exc_info не задано значение True, выходные данные вышеприведенной программы не сообщат нам ничего об исключении, которое в реальном сценарии может быть не таким простым, как ZeroDivisionError. Представьте, что вы пытаетесь отладить ошибку в сложной кодовой базе с помощью журнала, который показывает только это:

ERROR:root:Exception occurred

Совет: если вы логируете в обработчике исключений (try..except…), используйте метод logging.exception(), который регистрирует сообщение с уровнем ERROR и добавляет в сообщение информацию об исключении. Проще говоря, вызов logging.exception() похож на вызов logging.error (exc_info = True). Но поскольку этот метод всегда выводит информацию об исключении, его следует вызывать только в обработчике исключений. Взгляните на этот пример:

import logging

a = 5
b = 0
try:
  c = a / b
except Exception as e:
  logging.exception("Exception occurred")
ERROR:root:Exception occurred
Traceback (most recent call last):
  File "exceptions.py", line 6, in <module>
    c = a / b
ZeroDivisionError: division by zero

Использование logging.exception() покажет лог на уровне ERROR. Если вы не хотите этого, вы можете вызвать любой из других методов ведения журнала от debug() до critical() и передать параметр exc_info как True.


С этим читают