设为首页 收藏本站
查看: 509|回复: 0

[经验分享] Python的标准logging模块(3)

[复制链接]

尚未签到

发表于 2017-4-30 10:54:47 | 显示全部楼层 |阅读模式
Configuring Logging

Programmers can configure logging either by creating loggers, handlers, and formatters explicitly in a main module with the configuration methods listed above (using Python code), or by creating a logging config file. The following code is an example of configuring a very simple logger, a console handler, and a simple formatter in a Python module:

程序员可以显示地通过在主模块里面用上面列出的配置方法创建loggers,handlers和formatters的方式,或者,创建一个logging的配置文件的方式来配置logging.以下是一个非常简单的配置logger的例子,一个python模块里面包含了一个命令行handler和一个简单的formmater:

import logging

 

#create logger

logger = logging.getLogger("simple_example")

logger.setLevel(logging.DEBUG)

#create console handler and set level to debug

ch = logging.StreamHandler()

ch.setLevel(logging.DEBUG)

#create formatter

formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s -

   %(message)s")

#add formatter to ch

ch.setFormatter(formatter)

#add ch to logger

logger.addHandler(ch)

 

#"application" code

logger.debug("debug message")

logger.info("info message")

logger.warn("warn message")

logger.error("error message")

logger.critical("critical message")

Running this module from the command line produces the following output:

在在字符界面下运行上面的命令产生以下输出:

jmjones@bean:~/logging $ python simple_logging_module.py

2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message

2005-03-19 15:10:26,620 - simple_example - INFO - info message

2005-03-19 15:10:26,695 - simple_example - WARNING - warn message

2005-03-19 15:10:26,697 - simple_example - ERROR - error message

2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message

The following Python module creates a logger, handler, and formatter nearly identical to those in the example listed above, with the only difference being the names of the objects:

跟例子差不多,以下的Python模块创建了一个logger,一个handler和一个formatter,这里仅仅换了换名字:

import logging

import logging.config

 

logging.config.fileConfig("logging.conf")

 

#create logger

logger = logging.getLogger("simpleExample")

 

#"application" code

logger.debug("debug message")

logger.info("info message")

logger.warn("warn message")

logger.error("error message")

logger.critical("critical message")

Here is the logging.conf file:

这里是logging.conf文件:

[loggers]

keys=root,simpleExample

 

[handlers]

keys=consoleHandler

 

[formatters]

keys=simpleFormatter

 

[logger_root]

level=DEBUG

handlers=consoleHandler

 

[logger_simpleExample]

level=DEBUG

handlers=consoleHandler

qualname=simpleExample

propagate=0

 

[handler_consoleHandler]

class=StreamHandler

level=DEBUG

formatter=simpleFormatter

args=(sys.stdout,)

 

[formatter_simpleFormatter]

format=%(asctime)s - %(name)s - %(levelname)s - %(message)s

datefmt=

The output is nearly identical to that of the non-config-file-based example:

输出跟没有配置文件的例子完全一样:

jmjones@bean:~/logging $ python simple_logging_config.py

2005-03-19 15:38:55,977 - simpleExample - DEBUG - debug message

2005-03-19 15:38:55,979 - simpleExample - INFO - info message

2005-03-19 15:38:56,054 - simpleExample - WARNING - warn message

2005-03-19 15:38:56,055 - simpleExample - ERROR - error message

2005-03-19 15:38:56,130 - simpleExample - CRITICAL - critical message

The config file approach has a few advantages over the Python code approach. The first is the separation of configuration and code. The second is the ability of noncoders to easily modify the logging properties. The third is the really cool listen() method, which causes the application to listen on a socket for new configurations--and will update configurations at runtime without forcing you to restart the application!

用配置文件的方法比直接在Python代码里面写有几个好处.第一个好处是配置和代码的分离.第二个好处是即使看不懂程序也能方便的更改logging的属性.第三个好处是”最酷的listen()方法”,用这个方法可以让你的应用程序在一个socket上监听新的配置信息 -- 可以直接在运行时改变配置而用不着重启你的应用~!

Here is a slight modification of the previous config file-based script:

这里是一个简单的基于上面配置文件的脚本:

#!/usr/bin/env python

 

import logging

import logging.config

import time

import os

 

#specify logging config file

logging.config.fileConfig("logging.conf")

 

#create and start listener on port 9999

t = logging.config.listen(9999)

t.start()

 

#create logger

logger = logging.getLogger("simpleExample")

 

#watch for existence of file named "f"

#loop through the code while this file exists

while os.path.isfile('f'):

    logger.debug("debug message")

    logger.info("info message")

    logger.warn("warn message")

    logger.error("error message")

    logger.critical("critical message")

    time.sleep(5)

 

#cleanup

logging.config.stopListening()

t.join()

That was simple enough. Unfortunately, figuring out what format the config file needs to be took some investigation. The only useful information that I found in the Python Standard Library Reference documentation was in the logging configuration section under the listen() method:

够简单了吧!不幸地是,理解这个配置文件需要进行些研究.我仅仅在Python的标准库文档logging配置一节里面的listen()方法找到一点有用的信息:

Logging configurations will be sent as a file suitable for processing by fileConfig().

Logging配置会作为一个能被fileConfig()方法处理的文件发送.

Pushing a filename did not work. Pushing the contents of a config file did not work. I had to dig into the source a little. The docstring for the logging socket server's handle() method is:

用文件名不行,用配置文件的内容也不行.我不得不深入一下源码logging socket服务器的handler()方法的docstring是这样写的:

Handle a request.

 

Each request is expected to be a 4-byte length,

followed by the config file. Uses fileConfig() to do the

grunt work.

处理一个请求.

每个请求都应该是4-byte长,后面跟一个配置文件.用fileConfig()方法完成剩下的工作.

This struck me as a bit odd. Does that mean you can send lengths only for config files of up to 9,999 bytes? Converting the length of the config file to a string did not work either. I looked farther down in the source code of the handle() method. Aaahh. It does a struct.unpack(), so the socket expects the first 4 bytes to be packed binary data. I tried it this way and it worked. The following snippet of code sends the contents of the file named on the command line to localhost:9999:

这让我感到有些奇怪.难道说只能发送长度大于9,999bytes的配置文件吗?而且把一个配置文件的内容转化成一个字符串也是不起作用.我又看了一下handler()方法的源码.哈.它其实做了struct.unpack()!,所以socket才要求前面4个bytes打包二进制的数据.我用这种方式重新试了一下,可以了.下面的代码片断把指定的文件内容通过字符界面发送到了localhost:9999端口:

#!/usr/bin/env python

 

import socket

import sys

import struct

 

HOST = 'localhost'

PORT = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

print "connecting..."

s.connect((HOST, PORT))

print "connected..."

data_to_send = open(sys.argv[1], "r").read()

print "sending length..."

s.send(struct.pack(">L", len(data_to_send)))

print "sending data..."

s.send(data_to_send)

print "closing..."

s.close()

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-371128-1-1.html 上篇帖子: 《Python 3面向对象编程》 试读 下篇帖子: 使用Python进行验证码识别
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表