日志处理
日志可以使用内置的logging
模块来生成
服务端的日志可以使用内置的sqlite3
模块来持久化。
logging 模块
python
import logging
##级别依次提高
logging.debug("排错信息")
logging.info("正常信息")
logging.warning("警告信息")
logging.error("错误信息")
logging.critical("严重错误信息")
默认情况下 Python 的 logging 模块将日志打印到了标准输出(sys.stdout
)中,
且只显示了大于等于 WARNING 级别的日志
默认的日志格式为 日志级别:Logger名称:用户输出消息
。
它有两种配置方法
- 配置 logging 全局参数
- 显式地创建 logger 实例并配置
也可以同时在两处配置,logger 实例上的配置优先级更高。
配置 logging 全局参数
basicConfig()
函数更改 logging 模块默认行为
- 缺点:低版本 python 里中文会乱码,不能同时控制台打印和写入文件
- 优点:灵活配置日志级别,日志格式,和输出位置
简单的配置:
python
import logging
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s",
datefmt="%a, %d %b %Y %H:%M:%S",
filename="/tmp/test.log",
filemode="w",
)
logging.debug("debug message")
logging.info("info message")
logging.warning("warning message")
logging.error("error message")
logging.critical("critical message")
更多的配置选项
filename
:用指定的文件名创建 FiledHandler,这样日志会被存储在指定的文件中。filemode
:文件打开方式,在指定了 filename 时使用这个参数,默认值为“a”还可指定为“w”。format
:指定 handler 使用的日志显示格式。datefmt
:指定日期时间格式。level
:设置 rootlogger 的日志级别stream
:创建指定的 StreamHandler。默认 sys.stderr 可选 sys.stdout 或者文件句柄
若指定了filename
,则stream
参数会被忽略。
format 参数中可能用到的格式化串
格式化串 | 含义 |
---|---|
%(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 | 用户输出的消息 |
配置 logger 实例参数
logging.getLogger()
实例化一个记录器对象
即使不实例化,也会默认创建root logger
,缺省值读取basicConfig()
的配置
记录器对象可以设置:
logger.setLevel(logging.ERROR)
设置日志级别为 ERRORlogger.addHandler(handler_name)
为 Logger 实例增加一个处理器logger.removeHandler(handler_name)
为 Logger 实例删除一个处理器
创建和添加处理器 Handler
python
import logging
logger = logging.getLogger()
# 用于写入日志文件的handler
fh = logging.FileHandler("test.log", encoding="utf-8")
# 用于输出到控制台的handler
ch = logging.StreamHandler()
# logger对象可以添加多个handler
logger.addHandler(fh)
logger.addHandler(ch)
处理器对象也可以设置:
ch.setLevel(logging.WARN)
# 单对这个流设置日志级别ch.setFormatter(formatter_name)
# 设置一个格式化器 formatterch.addFilter(filter_name)
# 增加一个过滤器,可以增加多个ch.removeFilter(filter_name)
# 删除一个过滤器
创建格式化器:
python
fh = logging.FileHandler("test.log", encoding="utf-8")
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
fh.setFormatter(formatter)
logger.addHandler(fh)
sqlite3 模块
SQLite 是一种文件数据库,它的数据库就是一个文件。Python 内置了 SQLite3。它适合作为保存日志的数据库。谷歌浏览器的 cookie 也使用了它。
基本用法示例
shell
>>> import sqlite3
# 创建连接,如果文件不存在,会自动在当前目录创建:
>>> conn = sqlite3.connect('test.db')
# 创建游标
>>> cursor = conn.cursor()
# 执行SQL语句,创建user表:
>>> cursor.execute(r"""CREATE TABLE "user" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" varchar(20)
);""")
<sqlite3.Cursor object at 0x10f8aa260>
# 继续执行一条SQL语句,插入一条记录:
>>> cursor.execute(r"""INSERT INTO "main"."user"(name) VALUES ('Michael');""")
<sqlite3.Cursor object at 0x10f8aa260>
# 关闭游标
>>> cursor.close()
# 提交事务
>>> conn.commit()
# 关闭连接
>>> conn.close()
游标对象常用属性和方法
cursor.execute()
执行 SQL 语句并返回cursor
对象本身cursor.rowcount
刚刚执行语句影响的行数cursor.fetchone()
弹出刚刚执行查询语句的结果集的第一条,元组cursor.fetchall()
刚刚执行查询语句的全部(剩余)结果集,列表嵌套元组
直接遍历(for in)cursor
对象本身也可以拿到(剩余)结果集
sqlite 方言和一般的 sql 略有区别,比如单引号和双引号的区别,没有实现 truncate 语句等。
基本的 sql 语句和更多的数据库连接模块的用法在之后章节有介绍。