Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:设置日志记录,允许多行字符串:logging.info(';foo\nbar';)_Python_Logging - Fatal编程技术网

Python:设置日志记录,允许多行字符串:logging.info(';foo\nbar';)

Python:设置日志记录,允许多行字符串:logging.info(';foo\nbar';),python,logging,Python,Logging,到目前为止,我对文件进行了简单的日志记录,如果我记录了一个多行字符串,那么结果如下所示: 发射日志: logging.info('foo\nbar') 日志文件: 2018-03-05 10:51:53 root.main +16: INFO [28302] foo 酒吧 到目前为止,所有不包含“INFO”或“DEBUG”的行都会报告给操作员 这意味着将报告行条。这是假阳性 环境:Linux 如何在Python中设置日志记录,以将INFOfoo\nbar保存在一个字符串中,并忽略整

到目前为止,我对文件进行了简单的日志记录,如果我记录了一个多行字符串,那么结果如下所示:

发射日志:

logging.info('foo\nbar') 
日志文件:

2018-03-05 10:51:53 root.main +16: INFO     [28302] foo
酒吧

到目前为止,所有不包含“INFO”或“DEBUG”的行都会报告给操作员

这意味着将报告行
。这是假阳性

环境:Linux

如何在Python中设置日志记录,以将INFO
foo\nbar
保存在一个字符串中,并忽略整个字符串,因为它只是“INFO”


注意:是的,您可以在解释器中过滤日志记录。不幸的是,这不是问题所在。这个问题是不同的。首先进行日志记录。然后对日志进行解析

下面是一个脚本来复制它:

import sys
import logging


def set_up_logging(level=logging.INFO):
    root_logger = logging.getLogger()
    root_logger.setLevel(level)
    handler = logging.StreamHandler(sys.stdout)
    handler.setFormatter(
        logging.Formatter('%(asctime)s %(name)s: %(levelname)-8s [%(process)d] %(message)s', '%Y-%m-%d %H:%M:%S'))
    root_logger.addHandler(handler)


def main():
    set_up_logging()
    logging.info('foo\nbar')


if __name__ == '__main__':
    main()
在再次思考之后,我认为真正的问题是:哪种日志格式是可行的?只需删除跨越多行的消息中的换行符,某些输出就很难被人眼读取。另一方面,logging.info()和日志文件中的一行之间的当前1:1关系很容易读取。。。我不确定您是否可以使用:

logging.basicConfig(level=your_level)
如果您的_级别是以下级别之一:

  'debug': logging.DEBUG,
  'info': logging.INFO,
  'warning': logging.WARNING,
  'error': logging.ERROR,
  'critical': logging.CRITICAL
在您的情况下,您可以使用警告忽略信息

import logging
logging.basicConfig(filename='example.log',level=logging.WARNING)

logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')

Output:
WARNING:root:And this, too
您可以尝试在登录为之前禁用信息

import logging
logging.basicConfig(filename='example.log')

logging.debug('This message should go to the log file')
logging.disable(logging.INFO)
logging.info('So should this')
logging.disable(logging.NOTSET)
logging.warning('And this, too')
Output:
WARNING:root:And this, too


我通常有一个自定义日志记录的类,但您可以通过自定义
日志记录来实现所需的功能。格式化程序

import logging

class NewLineFormatter(logging.Formatter):

    def __init__(self, fmt, datefmt=None):
        """
        Init given the log line format and date format
        """
        logging.Formatter.__init__(self, fmt, datefmt)


    def format(self, record):
        """
        Override format function
        """
        msg = logging.Formatter.format(self, record)

        if record.message != "":
            parts = msg.split(record.message)
            msg = msg.replace('\n', '\n' + parts[0])

        return msg
上面的
format()
函数拆分行并复制每行中的时间戳/日志前导(在每行
\n
之后)

现在需要将格式化程序连接到根记录器。如果您构建了自己的日志设置/结构,则可以将其附加到任何
处理程序

# Basic config as usual
logging.basicConfig(level=logging.DEBUG)

# Some globals/consts
DATEFORMAT = '%d-%m-%Y %H:%M:%S'
LOGFORMAT = '%(asctime)s %(process)s %(levelname)-8s %(filename)15s-%(lineno)-4s: %(message)s'

# Create a new formatter
formatter = NewLineFormatter(LOGFORMAT, datefmt=DATEFORMAT)

# Attach the formatter on the root logger
lg = logging.getLogger()

# This is a bit of a hack... might be a better way to do this
lg.handlers[0].setFormatter(formatter)


# test root logger
lg.debug("Hello\nWorld")

# test module logger + JSON
lg = logging.getLogger("mylogger")
lg.debug('{\n    "a": "Hello",\n    "b": "World2"\n}')
以上内容为您提供了:

05-03-2018 08:37:34 13065 DEBUG     test_logger.py-47  : Hello
05-03-2018 08:37:34 13065 DEBUG     test_logger.py-47  : World
05-03-2018 08:37:34 13065 DEBUG     test_logger.py-51  : {
05-03-2018 08:37:34 13065 DEBUG     test_logger.py-51  :     "a": "Hello",
05-03-2018 08:37:34 13065 DEBUG     test_logger.py-51  :     "b": "World2"
05-03-2018 08:37:34 13065 DEBUG     test_logger.py-51  : }

请注意,我正在访问根记录器的
.handlers[0]
,这有点像黑客,但我找不到解决此问题的方法。。。另外,请注意格式化的JSON打印:)

我认为保持这种1:1的关系,在日志文件中为每个
logging.info()
调用指定一行,非常有利于保持日志文件的简单性和可解析性。因此,如果您确实需要记录换行符,那么我只需记录字符串表示,例如:

logging.info(repr('foo\nbar'))
产出:

2018-03-05 11:34:54 root: INFO     [32418] 'foo\nbar'
2018-03-05 15:39:44 root: INFO     [4196] foo
2018-03-05 15:39:44 root: INFO     [4196] bar
一个简单的替代方法是分别记录每个部分:

log_string = 'foo\nbar'
for item in log_string.split('\n'):
    logging.info(item)
产出:

2018-03-05 11:34:54 root: INFO     [32418] 'foo\nbar'
2018-03-05 15:39:44 root: INFO     [4196] foo
2018-03-05 15:39:44 root: INFO     [4196] bar

是的,您可以在解释器中过滤日志记录。不幸的是,这不是问题所在。这个问题是不同的。首先进行日志记录。然后对日志进行分析。@guettli我已编辑了我的答案,以便您可以在生成日志之前禁用信息。我希望信息包含在日志文件中。这个问题是关于日志文件的解析/读取/分析。我希望通过配置可以解决这个问题。但似乎你需要做编程。。。。当然,你的答案比没有答案要好得多:-)我明白了。。。上述代码/解决方案来自3年前!所以在这个时候,
日志记录
可能引入了一种更好的方法。然而,当时我找不到任何东西。使用第三方及其处理器堆栈将更容易。您能显示您的日志设置行吗?像
logging.basicConfig(..
)一样,还可以显示不同日志记录级别下的期望输出是什么?@Chris_Rands我添加了一个脚本来复制它。您的问题是“期望输出是什么?”非常好。我没有任何线索。到目前为止,我们解析日志文件并假设每一行都是一个日志条目。我猜当前的模式不再可行。最简单、理智、最具python风格的解决方案是什么?我在想(对我来说很少见:)-你用什么来解析日志?增强这一部分可能更容易、更一致,特别是如果您不想修改python源代码的话。例如,在下面的“我的解决方案”中,您可能会收到2个或多个警报,其中没有一个包含完整消息!(取决于解析器的工作方式)。不过,这需要一个单独的问题……您可以使用
logging.info(json.dumps(message))
返回包含转义换行符的字符串。或者,您可以创建一个自定义的
格式化程序
类来自动执行此操作。我不确定。我从1996年开始使用Linux,非常喜欢简单的基于ascii的解决方案。但也许是时候换个位置了?这种1:1的关系自古以来就存在。可以用什么来代替它?如果你只删除换行符,事情可能变得不可读。