简体   繁体   English

使用elasticsearch-py记录

[英]Logging using elasticsearch-py

I would like to log my python script that uses elasticsearch-py . 我想记录使用elasticsearch-py python脚本。 In particular, I want to have three logs: 特别是,我想要三个日志:

  1. General log: log INFO and above both to the stdout and to a file. 常规日志:将 INFO日志记录到stdout和文件中。
  2. ES log: only ES related messages only to a file. ES日志:仅ES与文件相关的消息。
  3. ES tracing log : Extended ES logging (curl queries and their output for instance) only to a file. ES跟踪日志 :扩展ES日志记录(例如,卷曲查询及其输出)仅限于文件。

Here is what I have so far: 这是我到目前为止:

import logging
import logging.handlers

es_logger = logging.getLogger('elasticsearch')
es_logger.setLevel(logging.INFO)
es_logger_handler=logging.handlers.RotatingFileHandler('top-camps-base.log',
                                                          maxBytes=0.5*10**9,
                                                          backupCount=3)
es_logger.addHandler(es_logger_handler)

es_tracer = logging.getLogger('elasticsearch.trace')
es_tracer.setLevel(logging.DEBUG)
es_tracer_handler=logging.handlers.RotatingFileHandler('top-camps-full.log',
                                                       maxBytes=0.5*10**9,
                                                       backupCount=3)
es_tracer.addHandler(es_tracer_handler)

logger = logging.getLogger('mainLog')
logger.setLevel(logging.DEBUG)
# create file handler
fileHandler = logging.handlers.RotatingFileHandler('top-camps.log',
                                                   maxBytes=10**6,
                                                   backupCount=3)
fileHandler.setLevel(logging.INFO)
# create console handler
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(consoleHandler)
logger.addHandler(fileHandler)

My problem is that INFO messages of es_logger are displayed also on the terminal. 我的问题是es_logger INFO消息也显示在终端上。 As a matter of fact the log messages are saved to the right files! 事实上,日志消息被保存到正确的文件中!

If I remover the part related to logger , then the ES logging works fine, ie only saved to the corresponding files. 如果我卸下与logger相关的部分,那么ES记录工作正常,即只保存到相应的文件。 But then I don't have the other part.... What is it that I'm doing wrong with the last part of the settings? 但后来我没有其他部分......我在设置的最后一部分做错了什么?


Edit 编辑

Possible hint: In the sources of elasticsearch-py there's a logger named logger . 可能的提示:在elasticsearch-py的源代码中,有一个名为logger的记录logger Could it be that it conflicts with mine? 它可能与我的冲突吗? I tried to change the name of logger to main_logger in the lines above but it didn't help. 我试图在上面的行main_logger logger的名称更改为main_logger ,但它没有帮助。

Possible hint 2: If I replace logger = logging.getLogger('mainLog') with logger = logging.getLogger() , then the format of the output to the console of es_logger changes and becomes identical to the one defined in the snippet. 可能暗示2:如果我更换logger = logging.getLogger('mainLog')logger = logging.getLogger()则输出到控制台的格式es_logger改变和变成等于在所述摘录中定义的一个。

I think you are being hit by the somewhat confusing logger hierarchy propagation. 我认为你被有点令人困惑的记录器层次结构传播所打击。 Everything that is logged in "elasticsearch.trace" that passes the loglevel of that logger, will propagate first to the "elasticsearch" logger and then to the root ("") logger. 传递给记录器的loglevel的“elasticsearch.trace”中记录的所有内容将首先传播到“elasticsearch”记录器,然后传播到root(“”)记录器。 Note that once the message passes the loglevel of the "elasticsearch.trace" logger, the loglevels of the parents ("elasticsearch" and root) are not checked, but all messages will be sent to the handlers. 请注意,一旦消息通过“elasticsearch.trace”记录器的日志级别,就不会检查父级(“elasticsearch”和root)的日志级别,但会将所有消息发送给处理程序。 (The handlers themselves have log levels that do apply.) (处理程序本身具有适用的日志级别。)

Consider the following example that illustrates the issue, and a possible solution: 请考虑以下示例来说明问题,以及可能的解决方案:

import logging

# The following line will basicConfig() the root handler
logging.info('DUMMY - NOT SEEN')
ll = logging.getLogger('foo')
ll.setLevel('DEBUG')
ll.addHandler(logging.StreamHandler())
ll.debug('msg1')
ll.propagate = False
ll.debug('msg2')

Output: 输出:

msg1
DEBUG:foo:msg1
msg2

You see that "msg1" is logged both by the "foo" logger, and its parent, the root logger (as "DEBUG:foo:msg1"). 您会看到“msg1”由“foo”记录器及其父记录器(根记录器)记录(如“DEBUG:foo:msg1”)。 Then, when propagation is turned off ll.propagate = False before "msg2", the root logger no longer logs it. 然后,当在“msg2”之前关闭传播ll.propagate = False ,根记录器不再记录它。 Now, if you were to comment out the first line ( logging.info("DUMMY...") , then the behavior would change so that the root logger line would not be shown. This is because the logging module top level functions info() , debug() etc. configure the root logger with a handler when no handler has yet been defined. That is also why you see different behavior in your example when you modify the root handler by doing logger = logging.getLogger() . 现在,如果您要注释掉第一行( logging.info("DUMMY...") ,那么行为将会改变,以便不显示根记录器行。这是因为logging模块顶层功能info()debug()等在没有定义处理程序的情况下使用处理程序配置根记录器。这也是在你通过执行logger = logging.getLogger()修改根处理程序时在示例中看到不同行为的原因。

I can't see in your code that you would be doing anything to the root logger, but as you see, a stray logging.info() or the like in your code or library code would cause a handler to be added. 我无法在您的代码中看到您将对根记录器执行任何操作,但正如您所看到的,代码或库代码中的logging.info()等将导致添加处理程序。

So, to answer your question, I would set logger.propagate = False to the loggers where it makes sense for you and where you want propagation, check that the log level of the handlers themselves are as you want them. 因此,为了回答您的问题,我会将logger.propagate = False设置为对您有意义的记录器以及您希望传播的位置,检查处理程序本身的日志级别是否符合您的要求。

Here is an attempt: 这是一个尝试:

es_logger = logging.getLogger('elasticsearch')
es_logger.propagate = False
es_logger.setLevel(logging.INFO)
es_logger_handler=logging.handlers.RotatingFileHandler('top-camps-base.log',
                                                      maxBytes=0.5*10**9,
                                                      backupCount=3)
es_logger.addHandler(es_logger_handler)

es_tracer = logging.getLogger('elasticsearch.trace')
es_tracer.propagate = False
es_tracer.setLevel(logging.DEBUG)
es_tracer_handler=logging.handlers.RotatingFileHandler('top-camps-full.log',
                                                   maxBytes=0.5*10**9,
                                                   backupCount=3)
es_tracer.addHandler(es_tracer_handler)

logger = logging.getLogger('mainLog')
logger.propagate = False
logger.setLevel(logging.DEBUG)
# create file handler
fileHandler = logging.handlers.RotatingFileHandler('top-camps.log',
                                               maxBytes=10**6,
                                               backupCount=3)
fileHandler.setLevel(logging.INFO)
# create console handler
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.INFO)
# create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
consoleHandler.setFormatter(formatter)
fileHandler.setFormatter(formatter)
# add the handlers to logger
logger.addHandler(consoleHandler)
logger.addHandler(fileHandler)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM