【Python】#规范# 关于日志的那点事

==== 前言 == 自勉 =========

20160526 今天开了一个科室会议,感觉事情有点杂。。。期待数据库的迁移任务

当你可以给别人讲东西的时候,才是你真正学会的时候。

======================

import logging

======================

**** 小浪浪:之前的日志部分 ****

前一阵子,帮公司用一个PyQt写一个GUI,刚开始的时候,感觉内容很简单,所以关于编程规范方面的事情,就没太注意。写的很随意,想print就print。没有规范化的日志输出等格式。后来公司除了一个脚本规范文档,发觉让在脚本书写时,写日志。。。。

格式为[yyyy-mm-dd hh:mi:ss][WARNING] message

当时并不知道有logging这个模块,于是自己写这个模块。我觉得最重要的部分就是这个时间戳,所以当时的代码对于时间戳的处理如下:

 1 import time
 2
 3 def log_write(level, message):
 4     now_timestamp = time.strftime("%Y%m%d_%H%M%S",time.localtime())
 5     # 将当前时间格式化转换成想要的结构
 6
 7     result_line = "[%s][%s] %s" % (now_timestamp, level, message)
 8
 9     return result_line
10  

虽然这么写了,也可以表达了日志的内容,但是如果需要将日志写入到文件中时,就会很麻烦。每次要open、close文件。

所以之前非常不喜欢写日志,想着等程序调整好再追加日志。但真实情况时,如果调整成功时,便不会再去添加日志,反正自己写的代码,哪里有问题一看就知道了。

非常坏的习惯!!!! 于是再次认真学习Python,蜕变成大浪浪。

**************************

----- 大浪浪:专业的日志 ---------

突然听别人介绍到一个logging模块,当看到它的使用时,震惊了~原来可以这么简单!

所以根据自己的python代码情况,做了一个关于【日志】的规范,要求自己以后再书写时,按照以下内容书写

-- 该规范要求logging既可以写入文档,又可以展示在屏幕。

#/usr/env/bin python
#-*- coding=utf-8 -*-

import logging

# 关于日志的书写只要有四个步骤:
# (1)Loggers: 创建
# (2)Handlers:把日志传送给合适的目标
# (3)Filters: 过滤出想要的内容
# (4)Formatters: 格式化

# 日志等级(从小到大):
# debug()-->info()-->warning()-->error()-->critical()

# Step 1: Loggers, 并设置全局level
logger = logging.getLogger(‘logging_blog‘)
logger.setLevel(logging.DEBUG)

# Step 2: Handler
# print to screen
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# write to file
fh = logging.FileHandler(‘log_file.log‘)
fh.setLevel(logging.WARNING)

# Step 3: Formatter
my_formatter = logging.Formatter(‘[%(asctime)s][%(name)s][%(levelname)s]%(message)s‘)
ch.setFormatter(my_formatter)
fh.setFormatter(my_formatter)

logger.addHandler(ch)
logger.addHandler(fh)

# 开始使用:不同等级会写入到屏幕和文件中
logger.debug(‘This is a debug log.‘)
logger.info(‘This is a info log.‘)
logger.warning(‘This is a warning log.‘)
logger.error(‘This is a error log.‘)
logger.critical(‘This is a critial log.‘)

执行后屏幕的输出为:

[2016-05-26 21:49:50,825][logging_blog][DEBUG]This is a debug log.
[2016-05-26 21:49:50,851][logging_blog][INFO]This is a info log.
[2016-05-26 21:49:50,855][logging_blog][WARNING]This is a warning log.
[2016-05-26 21:49:50,858][logging_blog][ERROR]This is a error log.
[2016-05-26 21:49:50,865][logging_blog][CRITICAL]This is a critial log.

执行后文件的输出为:

[2016-05-26 21:49:50,855][logging_blog][WARNING]This is a warning log.
[2016-05-26 21:49:50,858][logging_blog][ERROR]This is a error log.
[2016-05-26 21:49:50,865][logging_blog][CRITICAL]This is a critial log.

----------------- 分割 ------------------------------

既然想这个模块,就要认真的写!!

【官方文档链接】https://docs.python.org/3.4/library/logging.html

1. 设置logging的基本配置:

1 import logging
2
3 logging.basicConfig(level=logging.DEBUG,
4                 format=‘%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s‘,
5                 datefmt=‘%Y%M%D %H:%M:%S‘,
6                 filename=‘my.log‘,
7                 filemode=‘w‘)
8 # 以上logging的设定,是用于对于写入文件的设定。

关于logging.basicConfig的参数:

filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler.
filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to ‘a’).
format Use the specified format string for the handler.
datefmt Use the specified date/time format.
style If format is specified, use this style for the format string. One of ‘%’, ‘{‘ or ‘$’ for %-formatting, str.format() orstring.Template respectively, and defaulting to ‘%’ if not specified.
level Set the root logger level to the specified level.
stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with ‘filename’ - if both are present, a ValueError is raised.
handlers If specified, this should be an iterable of already created handlers to add to the root logger. Any handlers which don’t already have a formatter set will be assigned the default formatter created in this function. Note that this argument is incompatible with ‘filename’ or ‘stream’ - if both are present, a ValueError is raised.

其中stream参数和filename参数不可以一起使用!!

关于format的格式化内容:

Attribute name Format Description
args You shouldn’t need to format this yourself. The tuple of arguments merged into msg to produce message, or a dict whose values are used for the merge (when there is only one argument, and it is a dictionary).
asctime %(asctime)s Human-readable time when the LogRecord 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 %(created)f Time when the LogRecord was created (as returned by time.time()).
exc_info You shouldn’t need to format this yourself. Exception tuple (à la sys.exc_info) or, if no exception has occurred, None.
filename %(filename)s Filename portion of pathname.
funcName %(funcName)s Name of function containing the logging call.
levelname %(levelname)s Text logging level for the message (‘DEBUG‘‘INFO‘‘WARNING‘‘ERROR‘,‘CRITICAL‘).
levelno %(levelno)s Numeric logging level for the message (DEBUGINFOWARNINGERROR,CRITICAL).
lineno %(lineno)d Source line number where the logging call was issued (if available).
module %(module)s Module (name portion of filename).
msecs %(msecs)d Millisecond portion of the time when the LogRecord was created.
message %(message)s The logged message, computed as msg % args. This is set whenFormatter.format() is invoked.
msg You shouldn’t need to format this yourself. The format string passed in the original logging call. Merged with args to produce message, or an arbitrary object (see Using arbitrary objects as messages).
name %(name)s Name of the logger used to log the call.
pathname %(pathname)s Full pathname of the source file where the logging call was issued (if available).
process %(process)d Process ID (if available).
processName %(processName)s Process name (if available).
relativeCreated %(relativeCreated)d 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)d Thread ID (if available).
threadName %(threadName)s Thread name (if available).

也可以如下自定义使用format:但是这里的key必须是跟上面表格中不重复的!!!!

1 FORMAT = ‘%(asctime)-15s %(clientip)s %(user)-8s %(message)s‘
2 logging.basicConfig(format=FORMAT)
3 d = {‘clientip‘: ‘192.168.0.1‘, ‘user‘: ‘fbloggs‘}
4 logger = logging.getLogger(‘tcpserver‘)
5 logger.warning(‘Protocol problem: %s‘, ‘connection reset‘, extra=d)

2. 关于日志是否也存在文件关闭的问题:

(1)Handler

Handler.close()

Tidy up any resources used by the handler. This version does no output but removes the handler from an internal list of handlers which is closed whenshutdown() is called. Subclasses should ensure that this gets called from overridden close() methods.

(2)logging

logging.shutdown()

Informs the logging system to perform an orderly shutdown by flushing and closing all handlers. This should be called at application exit and no further use of the logging system should be made after this call.

---------------------------------

时间: 2024-08-07 19:33:31

【Python】#规范# 关于日志的那点事的相关文章

python高效解析日志入库

python脚本解析日志文件入库一般有三个重要的步骤:读文件.解析文件.入库.在这三个方面下功夫,可确保我们获得最优的性能(这里不讨论并发) 1 读文件:一次读一行,磁盘IO太多,效率低下:一次性读如全部文件内容,可能内存不够.采取一个折中的办法,每次读若干byte(具体大小视实际情况而定). 经过测试,得到结论,在我们写代码的时候应该这样写 f = open(path,'r') for line in f : ............. 这是系统提供的一种读文件的方法,一般比我们自己每次读若干

python基础学习日志day5-各模块文章导航

python基础学习日志day5---模块使用 http://www.cnblogs.com/lixiang1013/p/6832475.html python基础学习日志day5---time和datetime模块 http://www.cnblogs.com/lixiang1013/p/6848245.html python基础学习日志day5---random模块http://www.cnblogs.com/lixiang1013/p/6849162.html python基础学习日志da

python 经典语句日志分析

#!/usr/bin/python import re def buffer_line(): buf = open("/etc/sae/buffer_1").read() if not buf: return 0 else: return int(re.findall("^\d*", buf)[0]) def set_last_pos(pos): open("/etc/sae/buffer_1", "w").write(str

Atitit php java python nodejs错误日志功能的比较

Atitit php  java  python  nodejs错误日志功能的比较 1.1. Php方案 自带 1 1.2. Java解决方案 SLF4J 1 1.3. Python解决方案 自带loggin 2 1.4. Node.js日志解决方案 log4js 2 1.4.1. 玩转Nodejs日志管理log4js - CNode技术社区 2 日志的俩中模式   文件日志与os event 日志.. Os日志的优点是格式整齐.以及有默认os工具gui故居查询等.. 1.1. Php方案 自带

python分析nginx日志的ip,url,status

Python 脚本如下: #!/usr/bin/env python #_*_coding:utf-8 _*_ __author__ = 'lvnian' #!/usr/bin env python # coding: utf-8 import MySQLdb as mysql import sys, os db = mysql.connect(user="root",passwd="[email protected]",db="intest",

python mysql开发日志

开始做python 的数据库访问了,暂时选定了mysql数据库.原本想使用ORM,后来考虑到项目的情况是:表结构不复杂,但是数据库非常大.还是自己来操作sql,不过PYTHON的那些数据库ORM的代码写的还是挺酷的,作为PYTHON和mysql初学者的我来说正好可以学习一下.这里记录下,遇到的所有问题和技术要点 2014-08-14 sql: 查询语句去除重复:使用distinct 关键字 selecti distinct * from table_name python mysql开发日志

python的logging日志模块(一)

最近修改了项目里的logging相关功能,用到了Python标准库里的logging模块,在此做一些记录.主要是从官方文档和stackoverflow上查询到的一些内容. 官方文档 技术博客 基本用法 下面的代码展示了logging最基本的用法. # -*- coding: utf-8 -*- import logging import sys # 获取logger实例,如果参数为空则返回root logger logger = logging.getLogger("AppName")

python添加fluent日志记录-aop

python添加fluent日志,aop实现 1.配置fluent相关信息 fluent_config.ini fluent_config.ini [fluent.aop] #is support fluent log   false #aop total switch fluent.aopStatus=true #project name project.name=py-web-base #fluent join info # not istio fluent.url=192.168.181.

【转】python之配置日志的几种方式

[转]python之配置日志的几种方式 作为开发者,我们可以通过以下3种方式来配置logging: 1)使用Python代码显式的创建loggers, handlers和formatters并分别调用它们的配置函数: 2)创建一个日志配置文件,然后使用fileConfig()函数来读取该文件的内容: 3)创建一个包含配置信息的dict,然后把它传递个dictConfig()函数: 需要说明的是,logging.basicConfig()也属于第一种方式,它只是对loggers, handlers