Python日志系统logging使用介绍

2023-05-16

日志记录对于软件开发调试和运行都非常重要。Python标准库提供了一个日志记录系统,可以很方便的在python项目中添加日志记录。本文将详细介绍如何使用python的 logging 模块来记录日志。

目录

  • 基础使用
    • 日志级别
    • 基本配置
    • 保存日志到文件
    • 格式化输出
    • 捕获异常信息
  • 自定义logger
    • 日志模块四大组件
    • 处理器
    • 格式器
    • 过滤器
    • 示例
  • 其他配置方法
    • fileConfig()方法
    • dictConfig()方法
      • 1. yaml配置文件
      • 2. json配置文件

基础使用

日志级别

主要包括了5种日志级别,代表5种严重级别(严重程度由低到高):

  • DEBUG:提供详细的详细
  • INFO:程序运行的关键步骤信息
  • WARNING:警告信息
  • ERROR:程序错误,某个功能无法执行
  • CRITICAL:严重错误,可能整个程序无法执行

Logger提供了一个默认的记录器,称为root Logger。

import logging

logging.debug('Debug 级别日志信息')
logging.info('Info 级别日志信息')
logging.warning('Warning 级别日志信息')
logging.error('Error 级别日志信息')
logging.critical('Critical 级别日志信息')

输出:

WARNING:root:Warning 级别日志信息
ERROR:root:Error 级别日志信息
CRITICAL:root:Critical 级别日志信息

默认打印WARNING及更高严重级别的日志。

基本配置

可以使用basicConfig(**kwargs)方法对日志系统进行配置。常用参数如下:

  • level: 指定严重级别。
  • filename: 指定文件。
  • filemode: 如果指定了filename,则以该模式打开文件。默认是a,表示追加。
    • a:追加
    • w:覆盖
  • format:日志信息的格式。默认levelname, name和message属性,用冒号分隔。

注意:basicConfig函数只能被调用一次。

level参数可以设置要记录的日志消息的严重级别:

import logging

logging.basicConfig(level=logging.DEBUG)

logging.debug('Debug 级别日志信息')
logging.info('Info 级别日志信息')
logging.warning('Warning 级别日志信息')
logging.error('Error 级别日志信息')
logging.critical('Critical 级别日志信息')

输出:

DEBUG:root:Debug 级别日志信息
INFO:root:Info 级别日志信息
WARNING:root:Warning 级别日志信息
ERROR:root:Error 级别日志信息
CRITICAL:root:Critical 级别日志信息

保存日志到文件

import logging

logging.basicConfig(filename='test.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
logging.debug('Debug 级别日志信息')
logging.info('Info 级别日志信息')
logging.warning('Warning 级别日志信息')
logging.error('Error 级别日志信息')
logging.critical('Critical 级别日志信息')

格式化输出

format 参数用于格式化输出设置,除了默认设置levelname, name和message属性:

属性名使用格式描述
asctime%(asctime)s时间,默认格式为 ‘2003-07-08 16:49:45,896’
created%(created)f时间戳
relativeCreated%(relativeCreated)d相对于加载日志模块的时间(以毫秒为单位)。
msecs%(msecs)d日志创建时间的毫秒部分
filename%(filename)s脚本文件名称
funcName%(funcName)s调用日志记录的函数名称
module%(module)s脚本模块名
pathname%(pathname)s脚本文件绝对路径名
name%(name)s记录器名称,默认logger名为root
levelname%(levelname)s文本类型的日志级别 ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
levelno%(levelno)s数字类型的日志级别 (10, 20, 30, 40, 50).
lineno%(lineno)d日志调用的代码所在行号
message%(message)s日志信息
process%(process)d进程ID
processName%(processName)s进程名称
thread%(thread)d线程ID
threadName%(threadName)s线程名

其中 asctime 时间格式可以使用 datefmt 属性更改,语法格式与python datetime模块的格式化函数相同,例如:

import logging

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(message)s', datefmt='%Y%m%d-%H:%M:%S')

logging.debug('Debug 级别日志信息')
logging.info('Info 级别日志信息')
logging.warning('Warning 级别日志信息')
logging.error('Error 级别日志信息')
logging.critical('Critical 级别日志信息')

输出:

20230228-22:13:05 - Debug 级别日志信息
20230228-22:13:05 - Info 级别日志信息
20230228-22:13:05 - Warning 级别日志信息
20230228-22:13:05 - Error 级别日志信息
20230228-22:13:05 - Critical 级别日志信息

除了以上属性外,还支持自定义属性,使用 extra 参数传递:

import logging

FORMAT = '%(asctime)s - %(clientip)s - %(message)s'
logging.basicConfig(format=FORMAT)
clientip = '192.168.0.1'
d = {'clientip':clientip}

logging.info('Info 级别日志信息')
logging.warning('Warning 级别日志信息', extra=d)

输出:

2023-03-04 11:21:23,459 - 192.168.0.1 - Warning 级别日志信息

捕获异常信息

设置 exc_info 参数为 True 可以输出信息报错信息:

import logging

try:
  res = 1 / 0
except Exception as e:
  logging.error(e, exc_info=True)

输出:

ERROR:root:division by zero
Traceback (most recent call last):
  File "d:\logging\log_demo3.py", line 4, in <module>
    res = 1 / 0
ZeroDivisionError: division by zero

也可以使用 logging.exception() 方法,效果一样:

logging.exception(e)

另外,stack_info 参数设置为 True 是可以打印堆栈信息。

自定义logger

可以通过创建logger类的对象来定义自己的记录器。

日志模块四大组件

日志模块最常用的类:

  • Logger:公开了一个接口,代码通过使用该接口记录日志消息。
  • Handler:处理器,将logger创建的日志发送到目的地(控制台或文件)。常用的处理程序包括:
    • FileHandler:用于将日志消息发送到文件
    • StreamHandler:用于向输出流(如stdout)发送日志消息
    • SyslogHandler:用于向syslog守护进程发送日志消息
    • HTTPHandler:用于使用HTTP协议发送日志消息
  • Filter:过滤器,提供一种机制来确定记录哪些日志。
  • Formatter:格式器,决定日志消息的输出格式。

Logger类是入口,使用模块级别函数 logging.getLogger(name) 实例化,最终由Handler来对日志进行处理,Handler会调用Filter和Formatter来对日志进行过滤和格式化。

import logging

logger = logging.getLogger('mylogger')

logger.debug('Debug 级别日志信息')
logger.info('Info 级别日志信息')
logger.warning('Warning 级别日志信息')
logger.error('Error 级别日志信息')
logger.critical('Critical 级别日志信息')

自定义logger不能使用 basicConfig() 来配置,需要使用 处理器(Handler)和 格式器(Formatter)来配置。

处理器

可以使用处理器(Handler)来配置自定义logger将日志保存到文件、输出到控制台、通过HTTP发送或者通过邮件发送。

处理器也可以设置日志严重级别,为文件处理器(FileHandler)和控制台处理器(StreamHandler)设置不同的日志级别。

# 创建处理器 handlers
console_handler = logging.StreamHandler() # 输出到控制台
file_handler    = logging.FileHandler(logname) # 输出到文件
console_handler.setLevel(logging.WARNING)
file_handler.setLevel(logging.ERROR)

格式器

格式器(Formatter)用来配置格式化输出。

# 创建格式器
console_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s', '%Y%m%d-%H:%M:%S')
file_format    = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', '%Y%m%d-%H:%M:%S')

过滤器

过滤器(Filter)可实现日志过滤操作,

import logging
import sys
import os

class failureFilter(logging.Filter):
    def filter(self, record):
        if 'Failure' in record.msg:
            return True
        return False

logger = logging.getLogger(__name__)  
console_handler = logging.StreamHandler(stream=sys.stdout) # 输出到控制台
# 添加filter
loggingFiletr = failureFilter()
console_handler.addFilter(loggingFiletr)

logger.addHandler(console_handler)
logger.info('Info 级别日志信息')
logger.error('Failure')

示例

自定义logger示例脚本:

import logging
import sys
import os

class failureFilter(logging.Filter):
    def filter(self, record):
        if 'Failure' in record.msg:
            return True
        return False

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

abspath = os.path.dirname(os.path.abspath(__file__)) # 脚本绝对路径
logname = os.path.join(abspath, 'file.log')

# 创建处理器 handlers
console_handler = logging.StreamHandler(stream=sys.stdout) # 输出到控制台
file_handler    = logging.FileHandler(logname) # 输出到文件
console_handler.setLevel(logging.WARNING)
file_handler.setLevel(logging.ERROR)

# 添加filter
loggingFiletr = failureFilter()
console_handler.addFilter(loggingFiletr)
file_handler.addFilter(loggingFiletr)

# 创建格式器
console_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s', '%Y%m%d-%H:%M:%S')
file_format    = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s', '%Y%m%d-%H:%M:%S')

# 将格式器添加到处理器中
console_handler.setFormatter(console_format)
file_handler.setFormatter(file_format)

# 将处理器添加到logger
logger.addHandler(console_handler)
logger.addHandler(file_handler)

logger.info('Info 级别日志信息')
logger.error('Failure')

其他配置方法

除了前面介绍的 basicConfig() 方法、logger、handler和formatter来配置日志记录器外,还可以使用 fileConfig()dictConfig() 方法来加载配置文件或字典实现日志记录器的配置。

fileConfig()方法

配置文件(可使用configparser类读取)格式如下,此配置文件配置了控制台和文件输出两种方式:

[loggers]
keys=root,mylogger

[handlers]
keys=consoleHandler,fileHandler

[formatters]
keys=sampleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_mylogger]
level=DEBUG
handlers=consoleHandler,fileHandler
qualname=mylogger
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=sampleFormatter
args=(sys.stdout,)

[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=sampleFormatter
args=("config.log", "a")

[formatter_sampleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
qualname=mylogger

使用 fileConfig 方法来加载配置:

import logging
import logging.config
import os

abspath = os.path.dirname(os.path.abspath(__file__)) 
confpath = os.path.join(abspath, 'logging.conf')

if os.path.exists(confpath):
    logging.config.fileConfig(fname=confpath, disable_existing_loggers=False)

# create logger
logger = logging.getLogger("mylogger")

logger.debug('Debug 级别日志信息')
logger.info('Info 级别日志信息')

dictConfig()方法

配置字典可以使用yaml或者json代码来编写。

1. yaml配置文件

创建logging.yaml

version: 1
formatters:
  simple:
    format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
handlers:
  console:
    class: logging.StreamHandler
    level: INFO
    formatter: simple
    stream: ext://sys.stdout
  fileHandler:
    class: logging.FileHandler
    level: DEBUG
    formatter: simple
    filename: yaml.log
    encoding: utf8
loggers:
  mylogger:
    level: DEBUG
    handlers: [console,fileHandler]
    propagate: no
root:
  level: DEBUG
  handlers: [console]

调用示例:

import logging
import logging.config
import os
import yaml

abspath = os.path.dirname(os.path.abspath(__file__))
confpath = os.path.join(abspath, 'logging.yaml')

if os.path.exists(confpath):
    with open(confpath, 'r') as f:
        config = yaml.safe_load(f.read())
    logging.config.dictConfig(config)

logger = logging.getLogger('mylogger')

logger.debug('Debug 级别日志信息')
logger.info('Info 级别日志信息')

2. json配置文件

创建logging.json

{
    "version":1,
    "disable_existing_loggers":false,
    "formatters":{
        "simple":{
            "format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s",
            "datefmt":"%Y-%m-%d %H:%M:%S"
        }
    },
    "handlers":{
        "console":{
            "class":"logging.StreamHandler",
            "level":"DEBUG",
            "formatter":"simple",
            "stream":"ext://sys.stdout"
        },
        "fileHandler":{
            "class":"logging.handlers.RotatingFileHandler",
            "level":"INFO",
            "formatter":"simple",
            "filename":"json.log",
            "maxBytes":10485760,
            "backupCount":10,
            "encoding":"utf8"
        }
    },
    "loggers":{
        "mylogger":{
            "level":"INFO",
            "handlers":["fileHandler"],
            "propagate":"no"
        }
    },
    "root":{
        "level":"INFO",
        "handlers":["console","fileHandler"]
    }
}

调用示例:

import logging
import logging.config
import os
import json

abspath = os.path.dirname(os.path.abspath(__file__)) 
confpath = os.path.join(abspath, 'logging.json')

if os.path.exists(confpath):
    with open(confpath, 'r') as f:
        config = json.load(f)
    logging.config.dictConfig(config)

logger = logging.getLogger("mylogger")

logger.debug('Debug 级别日志信息')
logger.info('Info 级别日志信息')

参考文档:

  1. https://docs.python.org/zh-cn/3.7/library/logging.html
--THE END--

我们的先儒从来就把人类分成君子和小人,前者具有高尚的道德教养,后者则近似于禽兽。这种单纯的思想,固然可以造成许多个人生活中的悲剧,可是也使我们的传统文化增添了永久的光辉。——黄仁宇《万历十五年》

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python日志系统logging使用介绍 的相关文章

  • 在 numpy 数组中查找满足条件的大量连续值

    我在 numpy 数组中加载了一些音频数据 我希望通过查找静音部分 即一段时间内音频幅度低于特定阈值的部分 来对数据进行分段 一个非常简单的方法是这样的 values join 1 if abs x lt SILENCE THRESHOLD
  • 关于使用Python启动SSH隧道的问题

    我在从用 Python 编写的 HTTP RPC 服务器启动 SSH 隧道时遇到了麻烦 基于Python的BaseHTTPServer 有一个用Python编写的简单的HTTP RPC服务器 作为其中一项服务的一部分 我想启动从 RPC 服
  • QSortFilterProxyModel + QAbstractItemModel modelIndex.internalPointer() 导致崩溃

    我在 PyQt 4 8 Python 2 7 中实现了自己的 QAbstractItemModel class FriendListModel QtCore QAbstractItemModel def init self groups c
  • 错误只有 size-1 数组可以转换为 Python 标量

    我有这个代码 for a in data X for i in a if not i isdigit x hash i data X column row x row row 1 row 0 column column 1 desired
  • 如何编写高效的配对算法?

    我需要一种算法的帮助 该算法可以有效地将人们分组 并确保以前的配对不会重复 例如 假设我们有 10 位候选人 candidates 0 1 2 3 4 5 6 7 8 9 并假设我们有一个先前匹配的字典 这样每个键值对即candidate
  • 使用 K 均值聚类 OpenCV 进行交通标志分割

    I used K Means Clustering to perform segmentation on this traffic sign as shown below 这些是我的代码 读取图像并模糊 img cv imread 000
  • 代理阻止网络套接字?如何绕行

    我有一个用 Python 编写的正在运行的 websocket 服务器 来自https github com opiate SimpleWebSocketServer https github com opiate SimpleWebSoc
  • 在 C# 中实例化 python 类

    我已经用 python 编写了一个类 我想通过 IronPython 将其包装到 net 程序集中 并在 C 应用程序中实例化 我已将该类迁移到 IronPython 创建了一个库程序集并引用了它 现在 我如何真正获得该类的实例 该类看起来
  • Python NLP 英式英语与美式英语

    我目前正在用Python 进行NLP 工作 然而 在我的语料库中 既有英式英语也有美式英语 实现 实现 我正在考虑将英式英语转换为美式英语 但是 我没有找到一个好的工具 包来做到这一点 有什么建议么 我也找不到包 但试试这个 请注意 我必须
  • 超时时杀死或终止子进程?

    我想尽可能快地重复执行子进程 然而 有时这个过程会花费太长的时间 所以我想杀死它 我使用 signal signal 如下所示 ppid pipeexe pid signal signal signal SIGALRM stop handl
  • 散景中的时间序列流

    我想在散景中绘制实时时间序列 我只想在每次更新时绘制新的数据点 我怎样才能做到这一点 散景网站上有一个动画情节的示例 但它每次都需要重新绘制整个图片 另外 我正在寻找一个简单的示例 我可以在其中逐点绘制时间序列的实时绘图 散景效果0 11
  • Scrapy - 不会爬行

    我正在尝试运行递归爬行 由于我编写的爬行不能正常工作 因此我从网络上提取了一个示例并进行了尝试 我真的不知道问题出在哪里 但是爬行没有显示任何错误 谁能帮我这个 另外 是否有任何逐步调试工具可以帮助理解蜘蛛的爬行流程 非常感谢任何与此相关的
  • 通过套接字发送字符串(python)

    我有两个脚本 Server py 和 Client py 我心中有两个目标 能够从客户端一次又一次地向服务器发送数据 能够将数据从服务器发送到客户端 这是我的 Server py import socket serversocket soc
  • Pandas - 分割大的Excel文件

    我有一个大约有 500 000 行的 Excel 文件 我想将其拆分为多个 Excel 文件 每个文件有 50 000 行 我想用熊猫来做 这样它会是最快和最简单的 有什么想法如何制作吗 感谢您的帮助 假设您的 Excel 文件只有一个 第
  • 对 pandas 数据框中的每一列应用函数

    我如何以更多的熊猫方式编写以下函数 def calculate df columns mean self df means for column in df columns columns tolist cleaned data self
  • 带有整数的 np.sqrt 和 where 条件返回错误结果

    当我将 numpy sqrt 方法应用于带有 a 的整数数组时 我得到了奇怪的结果where健康 状况 见下文 对于整数 a np array 1 4 9 np sqrt a where a gt 5 Out 3 array 0 0 5 3
  • 升级后 pip 损坏

    我做了 pip install U easyinstall 然后 pip install U pip 来升级我的 pip 但是 当我尝试使用 pip 时 我现在收到此错误 root d8fb98fc3a66 which pip usr lo
  • 在没有numpy的情况下在python中分配变量NaN

    大多数语言都有一个 NaN 常量 您可以使用它为变量分配值 NaN python 可以在不使用 numpy 的情况下做到这一点吗 是的 使用math nan https docs python org 3 library math html
  • 提供节点名或服务名,或未知

    我收到这个 Python 错误 File Library Frameworks Python framework Versions 2 7 lib python2 7 urllib2 py line 1184 in do open rais
  • 将笔记本生成的 HTML 片段转换为 LaTeX 和 PDF

    在我的笔记本里有时会有 from IPython display import display HTML display HTML h3 The s is important h3 question of the day 但当我后来将笔记本

随机推荐

  • 开源代码网站集合

    USB ModeSwitch xff1a http www draisberghof de usb modeswitch LWIP xff1a https savannah nongnu org projects lwip cJSON xf
  • adb.exe无法运行,提示0xc000007b错误

    运行android studio xff0c 提示adb server无法运行 xff0c 在命令行下进入C Users Administrator AppData Local Android Sdk platform tools xff0
  • 【Flutter入门到进阶】Dart进阶篇---进阶用法

    1 Dart对象扩展 1 1 extension 1 1 1 介绍 可以在不更改类或创建子类的情况下 xff0c 向类添加扩展功能的一种方式 灵活使用 extension 对基础类进行扩展 xff0c 对开发效率有显著提升 1 1 2 需求
  • 中国天气网API(最新接口)

    一 产品概述 SmartWeatherAPI 接口 简称 SWA 接口 是中国气象局面向 网络媒体 手机厂商 第三方气象服务机构等用户 xff0c 通过 web 方 式提供数据气象服务的官方载体 二 使用说明 该数据主要包括预警 实况 指数
  • MySQL事务:事务隔离

    对数据进行并发操作时 xff0c 事务可以确保数据的完整性 xff0c 在银行 证券交易等业务场景需要用到它 xff0c 本文将介绍MySQL事务是如何保证数据的一致性的 目录 事务特性事务启动与提交事务回滚 什么是事务隔离事务隔离级别 事
  • MySQL锁:全局锁、表级锁和行锁

    事务的实现离不开MySQL数据库的锁机制 xff0c 设计锁的目的也是为了处理并发访问问题 xff0c 本文简单介绍MySQL 里面的全局锁 表级锁和行锁三类锁 目录 全局锁表级锁表锁1 读锁实例2 写锁实例 元数据锁 行锁行锁简介行锁实例
  • Java环境安装配置步骤介绍

    本文记录Windows环境和Linux环境 centos7 安装Java以及Linux环境升级Java JDK版本的步骤 目录 Windows环境安装Java JDK1 下载安装2 配置环境变量 Linux环境安装Java JDK1 下载安
  • Maven 安装和配置方法详解

    通常一个Java项目会引用大量的 jar 包 xff0c 而jar 包之间可能存在各种依赖关系 xff0c 如果运行Java项目时仅使用classpath 参数来管理jar包会非常不方便 xff0c 此外 xff0c 在项目编译 打包 升级
  • MySQL索引介绍

    索引主要是用来提高数据库的查询效率的 xff0c 它对指定的列或列的集合生成索引 xff0c 然后可以通过索引来检索目标数据 xff0c 就像目录一样 xff0c 缩小了扫描范围 xff0c 大大提高了查询效率 如果不使用索引 xff0c
  • 第二、UIScrollView的使用大全

    UIScrollView 原理详解 ScrollView UIScrollView UIScrollView 为了显示多于一个屏幕的内容或者超过你能放在内存中的内容 Scroll View 为你处理缩小放大手势 xff0c UIScroll
  • 持续集成平台Jenkins:docker镜像升级

    Jenkins 2 357 及 LTS 2 361 1之后的版本要求Java 11 或者 17 xff0c 如果使用的是Java 8 xff0c 要升级最新版本的Jenkins xff0c 就需要升级Java JDK版本 xff0c 本文记
  • 持续集成:通过Jenkins API创建项目和节点

    我在持续集成 xff1a Jenkins API使用方法详细介绍中介绍了jenkins API的使用方法 xff0c 比如使用API读取jenkins项目相关信息 触发构建等操作 xff0c 除此之外 xff0c 还可以直接使用API来创建
  • Android APP稳定性测试工具Fastbot

    我在 自动遍历测试之Monkey工具 和 AppCrawler自动遍历测试 分别介绍了APP稳定性测试工具monkey和AppCrawler xff0c 它们各有优缺点 xff0c 本文介绍另一款也比较好用的稳定性测试工具Fastbot 目
  • 持续集成:使用Jenkins API创建视图

    持续集成 xff1a 通过Jenkins API创建项目和节点介绍了使用jenkins API来创建项目和新建节点 xff0c jenkins API也可以创建视图 xff08 view xff09 目录 1 获取视图配置文件2 创建视图3
  • Fiddler抓取手机APP报文

    Http协议代理工具有很多 xff0c 比如Burp Suite Charles Jmeter Fiddler等 xff0c 它们都可以用来抓取APP报文 xff0c 其中charles和Burp Suite是收费的 xff0c Jmete
  • 使用Jmeter抓取手机APP报文并进行APP接口测试

    Jmeter是一个比较常用的接口测试工具 xff0c 尤其是接口性能测试 当然它也可以用来测试手机APP的HTTP接口 xff0c 我在Fiddler抓取手机APP报文 和 接口测试代理工具charles mock测试 分别介绍了Fiddl
  • 禅道二次开发技巧

    本文记录一些进行禅道二次开发的技巧 目录 代码调试方法1 xff1a error log方法方法2 xff1a file put contents方法方法3 xff1a a var 方法 禅道扩展技巧1 读取当前用户2 读取当前模块方法名3
  • git merge 和 git rebase 的区别

    Git版本控制中 xff0c git rebase 和 git merge 这两个命令都可以用来集成从一个分支和另一个分支的更改 它们是两种不同的合并方法 xff0c 本文将介绍它们的差异 git rebase 和 git merge 主要
  • SVN项目迁移到Git方法

    本文记录如何将SVN项目迁移到Git xff0c 并保留提交日志信息 目录 Git和SVN差异环境准备Git安装 配置 项目迁移1 将源SVN库转换到Git本地仓库2 添加Git远程库地址3 推送代码到Git 常见错误参考文档 Git和SV
  • Python日志系统logging使用介绍

    日志记录对于软件开发调试和运行都非常重要 Python标准库提供了一个日志记录系统 xff0c 可以很方便的在python项目中添加日志记录 本文将详细介绍如何使用python的 logging 模块来记录日志 目录 基础使用日志级别基本配