常用模块学习(六)
-
常用模块学习—subprocess模块详解2
-
subprocess.call()方法
#执行命令,返回命令执行状态 , 0 or 非0 >>> retcode = subprocess.call(["ls", "-l"]) #执行命令,如果命令结果为0,就正常返回,否则抛异常 >>> subprocess.check_call(["ls", "-l"]) 0 #接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果 >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') #接收字符串格式命令,并返回结果 >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' #执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res >>> res=subprocess.check_output(['ls','-l']) >>> res b'total 0 drwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM '
[root@wuqianqian-learn ~]# python3 >>> import os >>> os.system('uname -a ') Linux wuqianqian-learn 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:26:13 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux >>> import subprocess >>> subprocess.call(['ls','-lsh']) total 0 >>> subprocess.check_call(['ls','-lsh']) total 0 >>> subprocess.check_call(['ls','-lsh']) total 80K srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> 4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R >>> subprocess.getoutput(['ls','-lsh']) 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R' >>> subprocess.getoutput(['ls /bin/ls']) '/bin/ls' >>> res = subprocess.checkoutput(['ls','-l']) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'subprocess' has no attribute 'checkoutput' >>> res = subprocess.check_output(['ls','-l']) >>> res b'total 4 srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> drwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R ' >>> help(subprocess.check_output) Help on function check_output in module subprocess: check_output(*popenargs, timeout=None, **kwargs) Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null ' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) b'ls: non_existent_file: No such file or directory ' There is an additional optional argument, "input", allowing you to pass a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"], ... input=b"when in the course of fooman events ") b'when in the course of barman events ' If universal_newlines=True is passed, the "input" argument must be a string and the return value will be a string rather than bytes.
-
subprocess.Popen()方法
-
常用参数:
-
-
-
args:shell命令,可以是字符串或者序列类型(如:list,元组)
-
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
-
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
-
shell:同上
-
cwd:用于设置子进程的当前目录
-
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
-
-
下面这2条语句执行会有什么区别?
a=subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE) a=subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE)
区别是Popen会在发起命令后立刻返回,而不等命令执行结果。这样的好处是什么呢?
如果你调用的命令或脚本 需要执行10分钟,你的主程序不需卡在这里等10分钟,可以继续往下走,干别的事情,每过一会,通过一个什么方法来检测一下命令是否执行完成就好了。
Popen调用后会返回一个对象,可以通过这个对象拿到命令执行结果或状态等,该对象有以下方法
poll()Check if child process has terminated. Returns returncode
wait()Wait for child process to terminate. Returns returncode attribute.
terminate()终止所启动的进程Terminate the process with SIGTERMkill()杀死所启动的进程 Kill the process with SIGKILLcommunicate()与启动的进程交互,发送数据到stdin,并从stdout接收输出,然后等待任务结束>>> a = subprocess.Popen('python3 guess_age.py',stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE,shell=True) >>> a.communicate(b'22') (b'your guess:try bigger ', b'')
-
send_signal(signal.xxx)发送系统信号
pid 拿到所启动进程的进程号
[root@wuqianqian-learn ~]# python3 >>> import os >>> os.system('uname -a ') Linux wuqianqian-learn 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:26:13 UTC 2017 x86_64 x86_64 x86_6 >>> import subprocess >>> subprocess.call(['ls','-lsh']) total 0 >>> subprocess.check_call(['ls','-lsh']) total 0 >>> subprocess.check_call(['ls','-lsh']) total 4.0K srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> 4.0K drwx------ 3 root root 4.0K May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R >>> subprocess.getoutput(['ls','-lsh']) 'Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R' >>> subprocess.getoutput(['ls /bin/ls']) '/bin/ls' >>> res = subprocess.checkoutput(['ls','-l']) Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: module 'subprocess' has no attribute 'checkoutput' >>> res = subprocess.check_output(['ls','-l']) >>> res b'total 4 srwxr-xr-x 1 root root 0 May 30 10:25 Aegis-<Guid(5A2C30A2-A87D-490A-9281-6765EDAD7CBA)> drwx------ 3 root root 4096 May 26 11:18 systemd-private-d3b6074cca274d6593128b80ade5cf96-ntpd.service-FZcU6R ' >>> help(subprocess.check_output) Help on function check_output in module subprocess: check_output(*popenargs, timeout=None, **kwargs) Run command with arguments and return its output. If the exit code was non-zero it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute and output in the output attribute. The arguments are the same as for the Popen constructor. Example: >>> check_output(["ls", "-l", "/dev/null"]) b'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null ' The stdout argument is not allowed as it is used internally. To capture standard error in the result, use stderr=STDOUT. >>> check_output(["/bin/sh", "-c", ... "ls -l non_existent_file ; exit 0"], ... stderr=STDOUT) b'ls: non_existent_file: No such file or directory ' There is an additional optional argument, "input", allowing you to pass a string to the subprocess's stdin. If you use this argument you may not also use the Popen constructor's "stdin" argument, as it too will be used internally. Example: >>> check_output(["sed", "-e", "s/foo/bar/"], ... input=b"when in the course of fooman events ") b'when in the course of barman events ' If universal_newlines=True is passed, the "input" argument must be a string and the return value will be a string rather than bytes. >>> >>> a = subprocess.run('sleep 10',shell=True,stdout=subprocess.PIPE) >>> subprocess.Popen() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() missing 1 required positional argument: 'args' >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE) >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE) >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> a.poll() >>> def sayhi(): ... print('run...hahahah') File "<stdin>", line 2 print('run...hahahah') ^ IndentationError: expected an indented block >>> def sayhi(): ... print('run...hahahah') ... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) File "<stdin>", line 3 a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) ^ SyntaxError: invalid syntax >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'sayhi' is not defined >>> def sayhi(): ... print('run...hahahah') ... a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) File "<stdin>", line 3 a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) ^ SyntaxError: invalid syntax >>> import subprocess >>> def sayhi(): ... print('run...hahahah') ... >>> >>> a = subprocess.Popen('sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.stdout <_io.BufferedReader name=3> >>> a.stdout.read() b'run...hahahah ' >>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,cwd="/tmp",stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.stdout.read() b'run...hahahah /tmp ' >>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.stdout.read() b'run...hahahah /root ' >>> a = subprocess.Popen('echo $PWD;sleep 4',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.wait() >>> a = subprocess.Popen('echo $PWD;sleep 10',shell=True,stdout=subprocess.PIPE,preexec_fn=sayhi) >>> a.wait() >>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE) >>> a.pid >>> a.terminate() >>> a.pid >>> a.pid >>> a.pid >>> a.terminate() >>> a = subprocess.Popen('sleep 100',shell=True,stdout=subprocess.PIPE) >>> a.pid >>> a.kill() >>> a.pid >>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE) >>> a = subprocess.Popen('for i in $(seq 1 100);do sleep 1;echo $i >>sleep.log;done',shell=True,stdout=subprocess.PIPE) KeyboardInterrupt >>> a.pid >>> a.kill() KeyboardInterrupt >>> help(os.kill) Help on built-in function kill in module posix: kill(pid, signal, /) Kill a process with a signal.
-
常用模块学习—logging模块基础
很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical()5个级别。
日志级别:
Level |
When it’s used |
|---|---|
DEBUG |
Detailed information, typically of interest only when diagnosing problems. (详细信息,通常只有在诊断问题时才会感兴趣。) |
INFO |
Confirmation that things are working as expected. (确认一切都按预期工作。) |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. (这表明发生了一些意想不到的事情,或者预示着在不久的将来会出现一些问题(例如,“磁盘空间低”)。该软件仍按预期运行。) |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. (由于一个更严重的问题,该软件无法执行某些功能。) |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. (一个严重的错误,表明程序本身可能无法继续运行。) |
#最简单的用法: import logging logging.warning("user [alex] attempted wrong password more than 3 times") logging.critical("server is down")

#把日志写到文件里 import logging logging.basicConfig(filename='log_test.log',level=logging.INFO) #输入三条错误 logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this,too')

其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。
logging.basicConfig(filename='log_test.log',level=logging.DEBUG)

自定义日志格式
import logging logging.basicConfig(filename='log_test.log', level=logging.DEBUG, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this,too')

支持的格式:
%(name)s |
Logger的名字 |
|---|---|
| %(levelno)s | 数字形式的日志级别 |
| %(levelname)s | 文本形式的日志级别 |
| %(pathname)s | 调用日志输出函数的模块的完整路径名,可能没有 |
| %(filename)s | 调用日志输出函数的模块的文件名 |
| %(module)s | 调用日志输出函数的模块名 |
| %(funcName)s | 调用日志输出函数的函数名 |
| %(lineno)d | 调用日志输出函数的语句所在的代码行 |
| %(created)f | 当前时间,用UNIX标准的表示时间的浮 点数表示 |
| %(relativeCreated)d | 输出日志信息时的,自Logger创建以 来的毫秒数 |
| %(asctime)s | 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
| %(thread)d | 线程ID。可能没有 |
| %(threadName)s | 线程名。可能没有 |
| %(process)d | 进程ID。可能没有 |
| %(message)s | 用户输出的消息 |
import logging logging.basicConfig(filename='log_test.log', level=logging.DEBUG, #format='%(asctime)s %(message)s', #format='%(asctime)s-%(levelno)s- %(message)s', #format='%(asctime)s-%(levelname)s- %(message)s', #format='%(asctime)s-%(levelname)s-%(pathname)s-%(message)s', #format='%(asctime)s-%(levelname)s-%(filename)s-%(message)s', #format='%(asctime)s-%(levelname)s-%(funcName)s-%(message)s', format='%(asctime)s-%(levelname)s-%(funcName)s-%(lineno)s-%(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') def sayhi(): logging.error('from sayhi...') sayhi() logging.debug('This message should go to the log file') logging.info('So should this') logging.warning('And this,too')
#log_test.log 09/29/2018 10:07:06 AM from sayhi... 09/29/2018 10:07:06 AM This message should go to the log file 09/29/2018 10:07:06 AM So should this 09/29/2018 10:07:06 AM And this,too 09/29/2018 10:07:24 AM-40- from sayhi... 09/29/2018 10:07:24 AM-10- This message should go to the log file 09/29/2018 10:07:24 AM-20- So should this 09/29/2018 10:07:24 AM-30- And this,too 09/29/2018 10:07:40 AM-ERROR- from sayhi... 09/29/2018 10:07:40 AM-DEBUG- This message should go to the log file 09/29/2018 10:07:40 AM-INFO- So should this 09/29/2018 10:07:40 AM-WARNING- And this,too 09/29/2018 10:07:49 AM-ERROR-E:/Python/work/myFirstPro/第4章/21—logging模块基础.py-from sayhi... 09/29/2018 10:07:49 AM-DEBUG-E:/Python/work/myFirstPro/第4章/21—logging模块基础.py-This message should go to the log file 09/29/2018 10:07:49 AM-INFO-E:/Python/work/myFirstPro/第4章/21—logging模块基础.py-So should this 09/29/2018 10:07:49 AM-WARNING-E:/Python/work/myFirstPro/第4章/21—logging模块基础.py-And this,too 09/29/2018 10:08:04 AM-ERROR-21—logging模块基础.py-from sayhi... 09/29/2018 10:08:04 AM-DEBUG-21—logging模块基础.py-This message should go to the log file 09/29/2018 10:08:04 AM-INFO-21—logging模块基础.py-So should this 09/29/2018 10:08:04 AM-WARNING-21—logging模块基础.py-And this,too 09/29/2018 10:08:16 AM-ERROR-sayhi-from sayhi... 09/29/2018 10:08:16 AM-DEBUG-<module>-This message should go to the log file 09/29/2018 10:08:16 AM-INFO-<module>-So should this 09/29/2018 10:08:16 AM-WARNING-<module>-And this,too 09/29/2018 10:08:26 AM-ERROR-sayhi-15-from sayhi... 09/29/2018 10:08:26 AM-DEBUG-<module>-18-This message should go to the log file 09/29/2018 10:08:26 AM-INFO-<module>-19-So should this 09/29/2018 10:08:26 AM-WARNING-<module>-20-And this,too
-
常用模块学习—logging模块进阶
-
日志同时输出到屏幕和文件。
-
Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适:
-
-
- logger 提供了应用程序可以直接使用的接口;
- handler 将(logger创建的)日志记录发送到合适的目的输出;
- filter 提供了细度设备来决定输出哪条日志记录;
- formatter 决定日志记录的最终输出格式;
-
他们之间的关系是这样的:
-

-
-
每个组件的主要功能:
-
-
-
-
logger
-
-
每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
LOG=logging.getLogger(”chat.gui”)
而核心模块可以这样:
LOG=logging.getLogger(”chat.kernel”)
还可以绑定handler和filters
Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别
-
-
-
handler
-
-
handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Handler可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
Handler.setFormatter():给这个handler选择一个格式
Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象
每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
1、logging.StreamHandler 使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。
2、logging.FileHandler 和StreamHandler 类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。
3、logging.handlers.RotatingFileHandler 这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的函数是: RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
其中 filename 和 mode 两个参数和 FileHandler 一样。 1、maxBytes 用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。 2、backupCount 用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。
4、logging.handlers.TimedRotatingFileHandler 这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的函数是: TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]]) 其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。 interval是时间间隔。 when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值: S 秒 M 分 H 小时 D 天 W 每星期(interval==0时代表星期一) midnight 每天凌晨
-
-
-
formatter 组件
-
-
日志的formatter是个独立的组件,可以跟handler组合。
fh = logging.FileHandler("access.log") formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) #把formmater绑定到fh上
''' logger 提供了应用程序可以直接使用的接口; handler 将(logger创建的)日志记录发送到合适的目的输出; filter 提供了细度设备来决定输出哪条日志记录; formatter 决定日志记录的最终输出格式; ''' #同时输出到屏幕、文件、不带filter: import logging #1、生成 logger 对象 logger = logging.getLogger('web') #logger.setLevel(logging.INFO) #全局变量 #2、生成 handler 对象 ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) #屏幕 fh = logging.FileHandler('web.log') fh.setLevel(logging.WARNING) #设置日志级别 #2.1、把 handler 对象 绑定到 logger logger.addHandler(ch) logger.addHandler(fh) #3、生成 formatter 对象 #3.1、把 formatter 对象 绑定到 handler file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(lineno)d - %(message)s') ch.setFormatter(console_formatter) fh.setFormatter(file_formatter) #进行打印日志 logger.debug('test_log') #logger.error('test_log 2') #logger.warning('test_log 2') logger.info('test_log 2') #全局console DEBUG #屏幕globale INFO 默认级别是warning #文件file Warning #全局设置为DEBUG后,console handler 设置为INFO,如果输出的日志级别是debug,那就不会在屏幕上打印输出
-
常用模块学习—logging 日志过滤和日志文件自动截取
-
-
filter 组件
如果你想对日志内容进行过滤,就可自定义一个filterclass IgnoreBackupLogFilter(logging.Filter): """忽略带db backup 的日志""" def filter(self, record): #固定写法 return "db backup" not in record.getMessage() 注意:filter函数会返加True or False,logger根据此值决定是否输出此日志
然后把这个filter添加到logger中
logger.addFilter(IgnoreBackupLogFilter())
下面的日志就会把符合filter条件的过滤掉
logger.debug("test ....") logger.info("test info ....") logger.warning("start to run db backup job ....") logger.error("test error ....")
#一个同时输出到屏幕、文件、带filter的完成例子:
import logging class IgnoreBackupLogFilter(logging.Filter): """忽略带db backup 的日志""" def filter(self, record): #固定写法 return "db backup" not in record.getMessage() #console handler ch = logging.StreamHandler() ch.setLevel(logging.INFO) #file handler fh = logging.FileHandler('mysql.log') #fh.setLevel(logging.WARNING) #formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') #bind formatter to ch ch.setFormatter(formatter) fh.setFormatter(formatter) logger = logging.getLogger("Mysql") logger.setLevel(logging.DEBUG) #logger 优先级高于其它输出途径的 #add handler to logger instance logger.addHandler(ch) logger.addHandler(fh) #add filter logger.addFilter(IgnoreBackupLogFilter()) logger.debug("test ....") logger.info("test info ....") logger.warning("start to run db backup job ....") logger.error("test error ....")文件自动截断例子 import logging from logging import handlers logger = logging.getLogger(__name__) log_file = "timelog.log" #fh = handlers.RotatingFileHandler(filename=log_file,maxBytes=10,backupCount=3) fh = handlers.TimedRotatingFileHandler(filename=log_file,when="S",interval=5,backupCount=3) formatter = logging.Formatter('%(asctime)s %(module)s:%(lineno)d %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) logger.warning("test1") logger.warning("test12") logger.warning("test13") logger.warning("test14")
-