前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python日志和配置库

Python日志和配置库

作者头像
雪飞鸿
发布2023-07-09 14:54:19
3440
发布2023-07-09 14:54:19
举报
文章被收录于专栏:me的随笔me的随笔

日志和配置是应用不可缺少的部分,本文用于介绍dynaconf和loguru的简要用法。

dynaconf

dynaconf是一个配置管理包,支持多种配置文件格式,如:toml、yaml、json、ini及环境变量等

代码语言:javascript
复制
pip install dynaconf
​
mkdir config
cd config
dynaconf init -f toml

命令生成的目录结构如下:

代码语言:javascript
复制
config
├── .gitignore
├── .secrets.toml
├── config.py
└── settings.toml

.secrets.toml用于存放敏感信息,默认被添加到.gitignore中,不会提交到代码仓库。

从环境变量读取配置:

代码语言:javascript
复制
# 环境变量前缀在config.py中设置
export PYDEMO_tag=dynaconf
代码语言:javascript
复制
from src.config.config import settings
print(settings.tag) # dynaconf

config.py中可以指定读取的配置文件:

代码语言:javascript
复制
from dynaconf import Dynaconf
​
settings = Dynaconf(
    # 环境变量前缀
    envvar_prefix="PYDEMO",
    # 可以指定多个配置文件,如:settings.dev.toml
    settings_files=['settings.toml', '.secrets.toml'],
)

settinngs.toml中写入配置:

代码语言:javascript
复制
[person]
name = "eason"
age = 30

读取配置数据:

代码语言:javascript
复制
from dataclasses import dataclass
from src.config.config import settings
​
print(settings.person) # 输出:{'name': 'eason', 'age': 30}

绑定配置到类型

也可以定义具体的类型来绑定配置数据,这样在使用时更方便

代码语言:javascript
复制
from dataclasses import dataclass
from src.config.config import settings
​
​
@dataclass
class Person:
    name: str
    age: int
​
​
p = Person(**settings.person)
print(p.name)

多环境配置

单个配置文件

不同环境读取不同的配置:

代码语言:javascript
复制
[production]
person = { name = "prod", age = 100 }
[development]
person = { name = "dev", age = 100 }

config.py中设置environments的值是True

代码语言:javascript
复制
settings = Dynaconf(
    envvar_prefix="PYDEMO",
    settings_files=['settings.toml', '.secrets.toml'],
    environments=True
)

环境变量settings.ENV_FOR_DYNACONF的值默认是development,dynaconf会读取[development]节点下的配置

代码语言:javascript
复制
# 设置环境变量,从production节点下读取配置
export ENV_FOR_DYNACONF=production
# unset ENV_FOR_DYNACONF

或者

代码语言:javascript
复制
import os

os.environ["ENV_FOR_DYNACONF"] = "production"

输出结果

代码语言:javascript
复制
from src.config.config import settings

print(settings.ENV_FOR_DYNACONF)  # 输出production

p = Person(**settings.person)  # 输出prod
print(p.name)
多个配置文件
代码语言:javascript
复制
from dynaconf import Dynaconf

_cfg_files = ['settings.pro.toml', '.secrets.pro.toml']
if __debug__:
    _cfg_files = ['settings.dev.toml', '.secrets.dev.toml']

settings = Dynaconf(
    envvar_prefix="DYNACONF",
    settings_files=_cfg_files
)

这样我们就可以把不同环境下的配置项写入到不同的配置文件中了


loguru

loguru是一个易于配置和使用的Python日志库

安装:

代码语言:javascript
复制
pip install loguru

默认输出日志到控制台:

代码语言:javascript
复制
from loguru import logger

logger.info("一条日志信息")

日志输出结果如下:

代码语言:javascript
复制
2023-06-07 21:06:04.154 | INFO     | __main__:<module>:3 - 一条日志信息

loguru输出的日志带有颜色,不仅美观,还易于阅读,如下图所示

结构化日志

除了简单输出日志外,还可以记录结构化日志,示例如下:

代码语言:javascript
复制
from dataclasses import dataclass

from loguru import logger


@dataclass
class Person:
    name: str
    age: int


person = Person("eason", 30)
logger.info("人员信息:{p}", p=person)

日志输出结果:

代码语言:javascript
复制
2023-06-19 20:48:10.900 | INFO     | __main__:<module>:14 - 人员信息:Person(name='eason', age=30)

对于异常,loguru也可以输出详细的调用堆栈:

代码语言:javascript
复制
from loguru import logger


def throws():
    raise NotImplementedError("未实现的函数")


try:
    throws()
except Exception as err:
    logger.exception("出错了:{err}", err=err)

输出日志:

滚动日志

在生产环境,日志通常会记录到文本中而非仅仅打印到控制台。文本日志要考虑到磁盘占用问题,通常会采用滚动日志,配置如下:

代码语言:javascript
复制
# 禁用控制台日志
logger.remove(0)
logger.add("/Users/Eason/Desktop/pdemo/logs/log.log"
           , encoding="utf-8"
           , level="INFO"        # 输出的最小日志级别
           , rotation="1 MB"     # 每个日志文件的大小,超过该大小则创建新文件
           , retention=10        # 保留的日志文件数量,不超过10个
           , enqueue=True)       # 多进程安全

替换FastAPI中的日志模块

FastAPI是Python中用于开发API的web框架,默认使用内置的logging模块,为了统一使用loguru来记录日志,需要对日志模块进行替换。下面我们结合dynaconf来实现一个自定义的可配置日志,项目目录如下:

代码语言:javascript
复制
.
├── README.md
├── docs
│   └── dev
│       └── local.http
├── mypy.ini
├── requirements.txt
├── ruff.toml
├── src
    ├── config
    │   ├── _config.py
    │   ├── app_options.py
    │   └── settings.yaml
    ├── my_logger.py
    └── main.py

配置如下:

代码语言:javascript
复制
server:
  port: 9001

log:
  level: INFO
  encoding: utf-8
  rotation: 10 MB
  retention: 20
  enqueue: True
  file_path: /Users/Eason/Desktop/pdemo/logs/log.log

app_options.py中定义配置模型:

代码语言:javascript
复制
from __future__ import annotations

from dataclasses import dataclass

from src.config._config import settings


@dataclass
class AppOptions:
    log: LogOptions
    server: ServerOptions

@dataclass
class LogOptions:
    level: str
    file_path: str
    enqueue: bool
    rotation: int | str
    retention: int
    encoding: str


@dataclass
class ServerOptions:
    port: int



options = AppOptions(log=LogOptions(**settings.log), server=ServerOptions(**settings.server))

my_logger.py中添加配置相关代码:

代码语言:javascript
复制
from __future__ import annotations

from dataclasses import dataclass

from src.config._config import settings


@dataclass
class AppOptions:
    log: LogOptions
    server: ServerOptions

@dataclass
class LogOptions:
    level: str
    file_path: str
    enqueue: bool
    rotation: int | str
    retention: int
    encoding: str


@dataclass
class ServerOptions:
    port: int



options = AppOptions(log=LogOptions(**settings.log), server=ServerOptions(**settings.server))

main.py文件中定义API:

代码语言:javascript
复制
import uvicorn
from fastapi import FastAPI, Response, status

import src.my_logger as mylogger
from src.config.app_options import options


app = FastAPI(title="API-Demo", debug=__debug__)


@app.get("/healthcheck")
@app.head("/healthcheck")
def health_check():
    return "healthcheck"



if __name__ == "__main__":
    mylogger.init_log()
    log_config = mylogger.replace_uvicorn_log(uvicorn.config.LOGGING_CONFIG)
    mylogger.logger.info("服务已启动,监听端口:{port}", port=options.server.port)
    uvicorn.run(app, host="0.0.0.0", port=options.server.port, log_config=log_config)

启动API服务,输出如下日志:

可以看到,已经使用loguru成功替换掉了内置的logging模块。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • dynaconf
    • 绑定配置到类型
      • 多环境配置
        • 单个配置文件
        • 多个配置文件
    • loguru
      • 结构化日志
        • 滚动日志
          • 替换FastAPI中的日志模块
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档