参考python日志模块的使用
参考Python之日志处理(logging模块)
参考python标准日志模块logging及日志系统设计
Python + logging 日志和日志文件(一天一个日志文件)
handlers 可以设置按时间文件超大小自动新增

1 日志相关概念

日志是一种可以追踪某些软件运行时所发生事件的方法。
软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。
一个事件可以用一个可包含可选变量数据的消息来描述。
此外事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)。

(1)日志的作用
通过log的分析,可以方便用户了解系统或软件、应用的运行情况;如果你的应用log足够丰富,也可以分析以往用户的操作行为、类型喜好、地域分布或其他更多信息;如果一个应用的log同时也分了多个级别,那么可以很轻易地分析得到该应用的健康状况,及时发现问题并快速定位、解决问题,补救损失。

(2)日志的等级
在软件开发阶段或部署开发环境时,为了尽可能详细的查看应用程序的运行状态来保证上线后的稳定性,我们可能需要把该应用程序所有的运行日志全部记录下来进行分析,这是非常耗费机器性能的。

当应用程序正式发布或在生产环境部署应用程序时,我们通常只需要记录应用程序的异常信息、错误信息等,这样既可以减小服务器的I/O压力,也可以避免我们在排查故障时被淹没在日志的海洋里。

怎样才能在不改动应用程序代码的情况下实现在不同的环境记录不同详细程度的日志呢?这就是日志等级的作用了,我们通过配置文件指定我们需要的日志等级就可以了。

(3)日志字段信息与日志格式
一条日志信息对应的是一个事件的发生,而一个事件通常需要包括以下几个内容:
事件发生时间;
事件发生位置;
事件的严重程度–日志级别;
事件内容;
上面这些都是一条日志记录中可能包含的字段信息,当然还可以包括一些其他信息,如进程ID、进程名称、线程ID、线程名称等。

日志格式就是用来定义一条日志记录中包含那些字段的,且日志格式通常都是可以自定义的。

(4)常用库
几乎所有开发语言都会内置日志相关功能,或者会有比较优秀的第三方库来提供日志操作功能,比如:log4j。它们功能强大、使用简单。Python自身也提供了一个用于记录日志的标准库模块–logging。

2 logging模块的介绍

logging模块提供了两种记录日志的方式:
第一种方式是使用logging提供的模块级别的函数。
第二种方式是使用logging日志系统的四大组件。
其实logging所提供的模块级别的日志记录函数也是对logging日志系统相关类的封装而已。

2.1 logging模块级别的常用函数

其中logging.basicConfig(**kwargs)函数用于指定“要记录的日志级别”、“日志格式”、“日志输出位置”、“日志文件的打开模式”等信息,其他几个都是用于记录各个级别日志的函数。

logging.debug(msg, *args, **kwargs)  创建一条严重级别为DEBUG的日志记录
logging.info(msg, *args, **kwargs)  创建一条严重级别为INFO的日志记录
logging.warning(msg, *args, **kwargs)   创建一条严重级别为WARNING的日志记录
logging.error(msg, *args, **kwargs) 创建一条严重级别为ERROR的日志记录
logging.critical(msg, *args, **kwargs)  创建一条严重级别为CRITICAL的日志记录
logging.log(level, *args, **kwargs) 创建一条严重级别为level的日志记录
logging.basicConfig(**kwargs)   对root logger进行一次性配置

2.1.1 简单日志输出

import logginglogging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
等价于
logging.log(logging.DEBUG, "This is a debug log.")
logging.log(logging.INFO, "This is a info log.")
logging.log(logging.WARNING, "This is a warning log.")
logging.log(logging.ERROR, "This is a error log.")
logging.log(logging.CRITICAL, "This is a critical log.")
输出
WARNING:root:This is a warning log.
ERROR:root:This is a error log.
CRITICAL:root:This is a critical log.

(1)logging模块提供的日志记录函数所使用的日志器设置的日志级别是WARNING,因此只有WARNING级别的日志记录以及大于它的ERROR和CRITICAL级别的日志记录被输出了,而小于它的DEBUG和INFO级别的日志记录被丢弃了。

(2)输出结果中每行日志记录的各个字段含义分别是:

日志级别:日志器名称:日志内容

之所以会这样输出,是因为logging模块提供的日志记录函数所使用的日志器设置的日志格式默认是BASIC_FORMAT,其值为:

"%(levelname)s:%(name)s:%(message)s"

(3)logging模块提供的日志记录函数所使用的日志器设置的处理器所指定的日志输出位置默认为:sys.stderr,即输出到控制台。

2.1.2 logging.basicConfig()函数

(1)该函数可接收的关键字参数如下

(1)filename
指定日志输出目标文件的文件名,指定该设置项后日志信息就不会被输出到控制台了。(2)filemode
指定日志文件的打开模式,默认为'a'。
需要注意的是,该选项要在filename指定时才有效。(3)format
指定日志格式字符串,即指定日志输出时所包含的字段信息以及它们的顺序。
logging模块定义的格式字段下面会列出。(4)datefmt
指定日期/时间格式。
需要注意的是,该选项要在format中包含时间字段%(asctime)s时才有效。(5)level
指定日志器的日志级别。(6)stream
指定日志输出目标stream,如sys.stdout、sys.stderr以及网络stream。
需要说明的是,stream和filename不能同时提供,否则会引发ValueError异常。(7)style
Python 3.2中新添加的配置项。
指定format格式字符串的风格,可取值为'%'、'{'和'$',默认为'%'。(8)handlers
Python 3.3中新添加的配置项。
该选项如果被指定,它应该是一个创建了多个Handler的可迭代对象,
这些handler将会被添加到root logger。需要说明的是:filename、stream和handlers这三个配置项只能有一个存在,
不能同时出现2个或3个,否则会引发ValueError异常。

(2)logging模块中定义好的可以用于format格式字符串中字段如下

(1)asctime
%(asctime)s
日志事件发生的时间--人类可读时间,如:2003-07-08 16:49:45,896(2)created
%(created)f
日志事件发生的时间--时间戳,就是当时调用time.time()函数返回的值(3)relativeCreated
%(relativeCreated)d
日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)(4)msecs
%(msecs)d
日志事件发生事件的毫秒部分(5)levelname
%(levelname)s
该日志记录的文字形式的日志级别
('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')(6)levelno
%(levelno)s
该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)(7)name            %(name)s        所使用的日志器名称,默认是'root'
(8)message      %(message)s     日志记录的文本内容,通过 msg % args计算得到的
(9)pathname     %(pathname)s    调用日志记录函数的源码文件的全路径
(10)filename    %(filename)s    pathname的文件名部分,包含文件后缀
(11)module      %(module)s      filename的名称部分,不包含后缀
(12)lineno      %(lineno)d      调用日志记录函数的源代码所在的行号
(13)funcName    %(funcName)s    调用日志记录函数的函数名
(14)process     %(process)d     进程ID
(15)processName %(processName)s 进程名称,Python 3.1新增
(16)thread      %(thread)d      线程ID
(17)threadName  %(thread)s      线程名称

2.1.3 配置日志器的日志级别

import logging
logging.basicConfig(level=logging.DEBUG)
logging.log(logging.DEBUG, "This is a debug log.")
logging.log(logging.INFO, "This is a info log.")
logging.log(logging.WARNING, "This is a warning log.")
logging.log(logging.ERROR, "This is a error log.")
logging.log(logging.CRITICAL, "This is a critical log.")
输出
DEBUG:root:This is a debug log.
INFO:root:This is a info log.
WARNING:root:This is a warning log.
ERROR:root:This is a error log.
CRITICAL:root:This is a critical log.

2.1.4 配置日志输出到文件和日志格式

import logging
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(message)s"
logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT)logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")
输出到my.log文件中
2021-08-25 10:32:35,272 - DEBUG - This is a debug log.
2021-08-25 10:32:35,273 - INFO - This is a info log.
2021-08-25 10:32:35,274 - WARNING - This is a warning log.
2021-08-25 10:32:35,274 - ERROR - This is a error log.
2021-08-25 10:32:35,275 - CRITICAL - This is a critical log.

2.1.5 实例应用

import logging
# (1)%(asctime)s日志事件发生的时间--人类可读时间,如:2003-07-08 16:49:45,896
# (2)%(levelname)s该日志记录的文字形式的日志级别('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
# (3)%(filename)s pathname的文件名部分,包含文件后缀
# (4)%(message)s 日志记录的文本内容
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(filename)s - %(message)s"
logging.basicConfig(filename='my.log', level=logging.WARNING, format=LOG_FORMAT)logging.debug("This is a debug log.")
logging.info("This is a info log.")
logging.warning("This is a warning log.")
logging.error("This is a error log.")
logging.critical("This is a critical log.")

2.1.6 多py文件日志输出到同一个文件

Python中,让多个py文件的logging输出到同一个日志log文件中。

对于python子程序文件,完全不需要多余额外设置,只需要:
import logging;然后直接使用logging.info,logging.debug函数。即可实现把日志内容输出去,具体输出的形式,取决于主文件用logging.basicConfig所配置的形式。

输出的位置,即主文件的log文件。

这样,至少可以很好地实现,将多个py文件的logging内容都输出到同一个主文件的log文件中,并且格式都是设置好的,统一的。

一、main.py程序文件

# 配置日志信息
import logging
# (1)%(asctime)s日志事件发生的时间--人类可读时间,如:2003-07-08 16:49:45,896
# (2)%(levelname)s该日志记录的文字形式的日志级别('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
# (3)%(filename)s pathname的文件名部分,包含文件后缀
# (4)%(message)s 日志记录的文本内容
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(filename)s - %(message)s"
logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT)
# logging.debug("This is a debug log.")
# logging.info("This is a info log.")
# logging.warning("This is a warning log.")
# logging.error("This is a error log.")
# logging.critical("This is a critical log.")from aaaa import fun
fun()

二、aaa.py程序文件

import logging
def fun():print("输出到日志文件中")logging.info("This is subprogram results")

三、运行主程序以后,发现my.log文件中记录的日志信息为

2022-01-20 13:43:54,253 - INFO - aaaa.py - This is subprogram results

2.2 logging模块的四大组件

(1)loggers
提供应用程序代码直接使用的接口
(2)handlers
用于将日志记录发送到指定的目的位置
(3)filters
提供更细粒度的日志过滤功能,用于决定哪些日志记录将会被输出
(4)formatters
用于控制日志信息的最终输出格式

logging模块提供的模块级别的那些函数实际上也是通过这几个组件的相关实现类来记录日志的,只是在创建这些类的实例时设置了一些默认值。

2.2.1 示例代码

python的标准库里的日志系统从python2.3开始支持。
引入import logging这个模块即可使用。
如果你想开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件,可以按下面的方式进行使用。

import logging# 创建一个logger
logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test.log')
fh.setLevel(logging.DEBUG)# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)# 给logger添加handler
logger.addHandler(fh)
logger.addHandler(ch)# 记录一条日志
logger.info('foorbar')

2.2.2 按时间滚动新增日志文件

文件名称中不要有空格,否则会出现单引号。

import logging
import logging.handlers
import re
import os
def setup_log(log_name):# (1)创建logger对象,传入logger名字logger = logging.getLogger(log_name)log_path = os.path.join("./",log_name)# 设置日志记录等级logger.setLevel(logging.INFO)# (2)创建一个handler,用于写入日志文件# interval 滚动周期,# when="MIDNIGHT", interval=1 表示每天0点为更新点,每天生成一个文件# backupCount  表示日志保存个数,会自动滚动更新file_handler = logging.handlers.TimedRotatingFileHandler(filename=log_path, when="S", interval=5, backupCount=5)# filename="mylog" suffix设置,会生成文件名为mylog.2020-02-25.logfile_handler.suffix = "%Y-%m-%d-%H-%M-%S.log"# extMatch是编译好正则表达式,用于匹配日志文件名后缀# 需要注意的是suffix和extMatch一定要匹配的上,如果不匹配,过期日志不会被删除。file_handler.extMatch = re.compile(r"^\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}.log$")# (3)定义日志输出格式file_handler.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] [%(module)s] [%(filename)s:%(lineno)s] %(message)s'))# (4)给logger添加handlerlogger.addHandler(file_handler)return loggerimport time
logger = setup_log("nihao")
while True:logger.debug('This is debug message.')logger.info('This is info message.')logger.warning('This is warning message.')logger.error('This is error message.')logger.critical('This is critical message.')time.sleep(0.5)

2.2.3 按大小滚动新增日志文件

import logging
import logging.handlers
import os
def setup_log(log_name):# (1)创建logger对象,传入logger名字logger = logging.getLogger(log_name)log_path = os.path.join("./",log_name)# 设置日志记录等级logger.setLevel(logging.INFO)# (2)创建一个handler,用于写入日志文件# 当即将超过大小时,文件将被关闭,并且将静默打开一个新文件以进行输出。# backupCount  表示日志保存个数,会自动滚动更新# 每隔500字节保存成一个日志文件file_handler = logging.handlers.RotatingFileHandler(filename=log_path, mode="a", maxBytes=10240, backupCount=5)# (3)定义日志输出格式file_handler.setFormatter(logging.Formatter('[%(asctime)s] [%(levelname)s] [%(module)s] [%(filename)s:%(lineno)s] %(message)s'))# (4)给logger添加handlerlogger.addHandler(file_handler)return loggerimport time
logger = setup_log("nihao.log")
while True:logger.debug('This is debug message.')logger.info('This is info message.')logger.warning('This is warning message.')logger.error('This is error message.')logger.critical('This is critical message.')time.sleep(0.5)

3 常用API

import logging
logger = logging.getLogger([name])
返回一个logger实例,如果没有指定name,返回root logger。
只要name相同,返回的logger实例都是同一个而且只有一个。
即name和logger实例是一一对应的。
这意味着,无需把logger实例在各个模块中传递。只要知道name,就能得到同一个logger实例。

3.1 日志级别

logger.setLevel(logger.DEBUG)
设置logger的level, level有以下几个级别:


级别高低顺序:NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL。
如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出。

logger.debug("foobar")    # 不输出
logger.info("foobar")     # 输出
logger.warning("foobar")  # 输出
logger.error("foobar")    # 输出
logger.critical("foobar") # 输出

3.2 进程结束手动关闭日志

logging的原理机制是在进程全部结束后才会随之结束,那么对于不同文件内容写入不同的log的时候,就会出现前面的log内容越来越多的问题。
官网如下:
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.
通过刷新和关闭所有处理程序,通知日志记录系统执行有序关机。这应该在应用程序退出时调用,并且在调用之后不应该进一步使用日志系统。

for foo in range(0, 10):file_name = "./out/k" + str(foo) + ".log"# 实例化一个logger对象logger = logging.getLogger()  # 设置初始显示级别logger.setLevel(logging.DEBUG)  # 创建一个文件句柄file_handle = logging.FileHandler(file_name, encoding="UTF-8", mode='w')# 创建一个流句柄# stream_handle = logging.StreamHandler()# 创建一个输出格式fmt = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')# 文件句柄设置格式file_handle.setFormatter(fmt) # 流句柄设置格式 # stream_handle.setFormatter(fmt)  # logger对象绑定文件句柄logger.addHandler(file_handle)  # 打印logging.info(" process " + str(foo))logging.shutdown()

通过刷新和关闭所有处理程序来通知日志记录系统执行有序的关闭。这应该在应用程序出口处调用,并且在此调用之后不应进一步使用日志记录系统。

这样就解决了log无法关闭不停续写的问题。

4 应用实例

4.1 log_helper.py

# -- coding: utf-8 --
import logging
import os.path
import time# 初始化全局的日志输出格式
LOG_FORMAT = '%(asctime)s - %(levelname)s--->: %(message)s'
logging.basicConfig(format=LOG_FORMAT,level=logging.DEBUG,filemode='a')def createLogFile(name, level):''':param name: 日志名,附加到日志文件名称里:param level: 日志等级'''# 一、创建一个loggerlogger = logging.getLogger()  # 无参调用,返回root loggerlogger.setLevel(logging.INFO)  # Log等级总开关# 二、创建一个handler,用于写入日志文件cur_time = time.strftime('%Y-%m-%d', time.localtime(time.time()))log_path = os.getcwd() + '/Logs/'  # 日志文件目录is_exists = os.path.exists(log_path)# 判断目录是否存在,否即创建if not is_exists:os.makedirs(log_path)# 创建日志文件名log_name = log_path + '{}-'.format(cur_time) + name + '.log'fh = logging.FileHandler(log_name, mode='a')fh.setLevel(level)  # 输出到file的log等级的开关# 三、定义handler的输出格式formatter = logging.Formatter("%(asctime)s - %(levelname)s--->: %(message)s")fh.setFormatter(formatter)# 四、给logger添加handlerlogger.addHandler(fh)def print_info(info, *args):# 确保每天生成新的文件名称createLogFile("info", logging.INFO)if len(args) > 0:log = ""for arg in args:log += "{}"logging.info((info + log).format(*args))else:logging.info(info)def print_error(error, *args):# 确保每天生成新的文件名称createLogFile("error",logging.ERROR)if len(args) > 0:log = ""for arg in args:log += "{}"logging.error((error + log).format(*args))else:logging.error(error)def deleteBigFile(path):for file in os.listdir(path):fsize = os.path.getsize(f'{path}{file}')if (fsize > 1 * 1024 * 1024 * 1024):os.remove(f'{path}{file}')if __name__ == '__main__':print_info("正常",2,4,7)print_error("错误",5,8,9)

4.2 app.py

import time
import log_helperfrom flask import Flaskapp = Flask(__name__)# 定义一个装饰器
def access_log(fn):def wrapper():t_begin = time.time()res = fn()t_end = time.time()print("调试输出查看响应时间",t_begin,t_end)return resreturn wrapper@app.route('/')
@access_log
def hello_world():# 记录日志信息log_helper.print_error("有访客进入错误")return 'Welcome to use me!'if __name__ == '__main__':app.run(host='127.0.0.1', port=9000, threaded=True)

5 Python中获取异常(Exception)信息

异常信息的获取对于程序的调试非常重要,可以有助于快速定位有错误程序语句的位置。
采用traceback模块

需要导入traceback模块,此时获取的信息最全,与python命令行运行程序出现错误信息一致。使用traceback.print_exc()打印异常信息到标准错误,就像没有获取一样,或者使用traceback.format_exc()将同样的输出获取为字符串。你可以向这些函数传递各种各样的参数来限制输出,或者重新打印到像文件类型的对象。

try:pass
except Exception as err:# 只提取指定部分message = "".join(traceback.format_exception_only(err.__class__, err))#或者,提取全部信息message =  "".join(traceback.format_exc())logger.error("计算出错{}".format(message))

python-27-日志模块logging的应用相关推荐

  1. Python的日志模块logging的使用

    Python的日志模块logging的使用 1 logging模块介绍 2 logging 简单示例 3 logging.basicConfig() 4 logging组件 4.1 Logger类 4 ...

  2. 【Python】—日志模块logging使用详解1

    文章目录 1.日志级别 2.logging流程 3.几个重要的类 3.1 Logger类 1) 最常用的配置方法 2) 创建`Logger`对象`logging.getLogger([name])` ...

  3. Python之配置日志模块logging

    一.定义日志打印方式 如果我们运行自己的程序,有时候需要记录程序运行过程中出现的问题或者信息.可以运用日志模块logging来记录,该模块日志格式可以根据用户需求来自己定义. 常见打印日志信息形式如下 ...

  4. python logging模块的作用_Python 日志模块logging分析及使用-2

    本文作为Python日志模块的补充,主要介绍日志回滚RotatingFileHandler和TimedRotatingFileHandler的使用,以及其所带来的问题.Logger对象的日志等级是如何 ...

  5. Python日志模块logging高级用法

    推荐图书: <Python程序设计(第3版)>,(ISBN:978-7-302-55083-9),董付国,清华大学出版社,2020年6月第1次印刷,2021年12月第11次印刷,山东省一流 ...

  6. 日志模块-logging模块

    日志模块 -logging(非常重要) 记录用户行为 程序运行过程 程序错误记录 logging.debug()通常调试时用到的日志信息 logging.info() #证明事情按照预期的那样工作 l ...

  7. python logging模块默认日志级别_Python 日志模块logging

    logging模块: logging是一个日志记录模块,可以记录我们日常的操作. logging日志文件写入默认是gbk编码格式的,所以在查看时需要使用gbk的解码方式打开. logging日志等级: ...

  8. python 日志模块 logging

    如何使用python自带的 logging 模块实现日志功能 1.初始化一个logger对象 1)引入模块 import os import logging import sys 2)初始化变量,声明 ...

  9. python configuration_Python(2.7.6) 标准日志模块 - Logging Configuration

    除了使用 logging 模块中的 basicConfig 方法配置日志, Python 的 logging.config 模块中, dictConfig 和 fileConfig 方法分别支持通过字 ...

  10. python logging模块的作用_【python】【logging】python日志模块logging常用功能

    logging模块:应用程序的灵活事件日志系统,可以打印并自定义日志内容 logging.getLogger 创建一个log对象 >>> log1=logging.getLogger ...

最新文章

  1. javax.servlet.ServletException: Servlet[springmvc]的Servlet.init()引发异常
  2. 當前主流防拷光碟的備份
  3. 如何让你投出的简历得到回应
  4. Java 8 - Stream流骚操作解读
  5. SQL Compare
  6. python 运行日志logging代替方案
  7. 在线斯诺克html5,用HTML 5打造斯诺克桌球俱乐部
  8. 多媒体视频知识入门贴zt(一)
  9. MinGW 64的安装 - 官网sourceforge安装失败非翻墙解决办法
  10. 蒲公英自动更新版本管理以及更新后展示引导图
  11. 关于kinect的一些想法
  12. 你不知道的那些console
  13. matlab 怎么使用function,Matlab怎么调用函数 自定义函数使用方法
  14. 一键环境安装包无法修改网站目录提示.user.ini权限问题解决方法
  15. SpringBoot+thymeleaf 发送邮件
  16. 什么是黑帽seo?黑帽seo技术盘点。
  17. 泰格如何修改服务器地址,泰格X7盘点机使用说明
  18. 淘宝用户api 如何获得App Key和API Secret
  19. ”故乡飘已远,往意浩无边“
  20. 用Photoshop制作电子签

热门文章

  1. Spark与Hadoop相比的优缺点
  2. 在MTK平台配置一个支持smartPA的audio驱动
  3. Java版工程项目管理系统平台+java版企业工程系统源码+助力工程企业实现数字化管理
  4. 第3章第15节:如何利用Smart Art快速生成漂亮的组织结构图 [PowerPoint精美幻灯片实战教程]
  5. WOW魔兽世界账号安全完全攻略(转)
  6. 致广大用户关于 iPhone 电池及性能的说明
  7. java解压.rar、.zip和.7z格式压缩包
  8. 2022新版神算网PHP八字算命风水测字占卜起名星座解梦周易程序源码搭建指南
  9. 仿猎豹垃圾清理 实现原理+源码
  10. 华为资深工程师为你深入讲解 Kubernetes及云原生应用