Python中如何使用Sentry将日志存放到本地?

sentry 是通过 http 传送日志,但是如果网络链接不顺畅,如何将这段时间内产生的日志存放到本地?


Python中如何使用Sentry将日志存放到本地?
7 回复

喜欢折腾就自己架 ELK。


# 安装必要的包
# pip install sentry-sdk

import sentry_sdk
from sentry_sdk.integrations.logging import LoggingIntegration
import logging

# 1. 配置Sentry使用本地文件传输
class FileTransport:
    """自定义传输器将事件写入本地文件"""
    def __init__(self, filepath='sentry_events.log'):
        self.filepath = filepath
    
    def capture_event(self, event):
        """将事件写入文件"""
        import json
        try:
            with open(self.filepath, 'a', encoding='utf-8') as f:
                f.write(json.dumps(event, ensure_ascii=False) + '\n')
            return True
        except Exception as e:
            print(f"写入文件失败: {e}")
            return False
    
    def flush(self, timeout=None, callback=None):
        """实现flush接口"""
        pass
    
    def kill(self):
        """关闭传输器"""
        pass

# 2. 初始化Sentry配置
def init_sentry_local():
    # 创建自定义传输器实例
    transport = FileTransport('logs/sentry_events.json')
    
    # 配置日志集成
    logging_integration = LoggingIntegration(
        level=logging.INFO,        # 捕获INFO及以上级别的日志
        event_level=logging.ERROR  # 发送ERROR及以上级别的事件
    )
    
    # 初始化Sentry SDK
    sentry_sdk.init(
        dsn="",  # 本地模式不需要DSN,但必须提供空字符串
        transport=transport,  # 使用自定义文件传输
        integrations=[logging_integration],
        debug=True,  # 开启调试模式查看详细信息
        # 其他配置
        release="1.0.0",
        environment="local",
        # 关闭默认传输
        default_integrations=False
    )

# 3. 使用示例
def main():
    # 初始化本地Sentry
    init_sentry_local()
    
    # 配置Python标准日志
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)
    
    # 记录不同级别的日志
    logger.info("这是一条普通信息日志")
    logger.warning("这是一条警告日志")
    
    try:
        # 模拟一个错误
        result = 1 / 0
    except Exception as e:
        logger.error(f"发生错误: {e}", exc_info=True)
        # 也可以直接使用Sentry捕获
        sentry_sdk.capture_exception(e)
    
    # 手动捕获消息
    sentry_sdk.capture_message("这是一条手动捕获的消息", level="info")
    
    print("日志已写入 logs/sentry_events.json 文件")

# 4. 文件读取工具函数
def read_sentry_logs(filepath='logs/sentry_events.json'):
    """读取并解析Sentry日志文件"""
    import json
    events = []
    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            for line in f:
                if line.strip():
                    events.append(json.loads(line.strip()))
        return events
    except FileNotFoundError:
        print(f"文件 {filepath} 不存在")
        return []
    except json.JSONDecodeError as e:
        print(f"JSON解析错误: {e}")
        return []

# 5. 运行示例
if __name__ == "__main__":
    # 创建日志目录
    import os
    os.makedirs('logs', exist_ok=True)
    
    main()
    
    # 读取并显示日志
    print("\n--- 读取的日志内容 ---")
    logs = read_sentry_logs()
    for i, log in enumerate(logs, 1):
        print(f"\n事件 {i}:")
        print(f"  级别: {log.get('level', 'N/A')}")
        print(f"  消息: {log.get('message', 'N/A')}")
        print(f"  时间: {log.get('timestamp', 'N/A')}")

核心要点:

  1. 自定义FileTransport:继承并实现capture_event方法,将事件写入本地文件
  2. 初始化配置:设置transport参数为自定义传输器,dsn留空
  3. 日志集成:通过LoggingIntegration将Python标准日志路由到Sentry
  4. 文件格式:使用JSON格式存储,便于后续解析和分析

一句话总结: 实现自定义Transport将事件写入文件,配合空DSN配置即可本地化存储Sentry日志。

谢谢,sentry 下有没有解决方案?

发送端 logger 自己想办法配置,这和 sentry 这个接收端没啥关系

日志是应用侧负责的,Logger 负则日志接收,同时记录到 Sentry 和文件

我用的是 java log4j,是在 log4j 的 properties 里配置吗?

配俩 appender 吧

回到顶部