使用Python Log Handler自动上传并解析KV格式的日志

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,恶意文件检测 1000次 1年
对象存储 OSS,内容安全 1000次 1年
简介: Python Logging Handler可以无需写代码自动高效上传日志, 还可以像Splunk一样对KV格式自动解析字段. 本文介绍如何简单配置.

概述

使用Python SDK提供的Log Handler可以实现每一条Python程序的日志在不落盘的情况下自动上传到日志服务上。与写到文件再通过各种方式上传比起来,有如下优势:

  1. 实时性:主动直接发送,不落盘
  2. 吞吐量大,异步发送
  3. 配置简单:无需修改程序,无需知道机器位置,修改程序配置文件即可生效
  4. 智能解析: 自动解析日志中JSON和KV格式信息

本篇主要如何打开自动解析KV格式的功能, 关于如何配置并使用的基本信息, 请参考使用Log Handler自动上传Python日志

解决的问题

在程序中, 有时我们需要将特定数据输出到日志中以便跟踪, 例如:

data = {'name':'xiao ming', 'score': 100.0}

一般情况下, 我们会格式化数据内容, 附加其他信息并输出:

data = {'name':'xiao ming', 'score': 100.0}
logger.error('get some error when parsing data. name="{}" score={}'.format(data['name'], data['score']))

这样会输出的消息为:

get some error when parsing data. name="xiao ming" score=100.0

我们期望在上传到日志服务时可以自动解析出域namescore字段. 使用Python Handler的简单配置即可做到. 如下.

通过Logging的配置文件

参考Logging Handler的详细配置, 将其中参数列表修改为:

args=(os.environ.get('ALIYUN_LOG_SAMPLE_ENDPOINT', ''), os.environ.get('ALIYUN_LOG_SAMPLE_ACCESSID', ''), os.environ.get('ALIYUN_LOG_SAMPLE_ACCESSKEY', ''), os.environ.get('ALIYUN_LOG_SAMPLE_TMP_PROJECT', ''), "logstore", None, None, None, None, None, None, None, None, None, None, None, None, True)

最后一个参数对应了Logging Handler的详细参数extract_kv参数.

注意, 受限于Python Logging的限制, 这里只能用无名参数, 依次传入. 对于不改的参数, 用None占位.

通过代码以JSON形式配置

如果期望更加灵活的配置, 也可以使用代码配置, 如下将参数extract_kv设置为True即可.

#encoding: utf8
import logging, logging.config, os

# 配置
conf = {'version': 1,
        'formatters': {'rawformatter': {'class': 'logging.Formatter',
                                        'format': '%(message)s'}
                       },
        'handlers': {'sls_handler': {'()':
                                     'aliyun.log.QueuedLogHandler',
                                     'level': 'INFO',
                                     'formatter': 'rawformatter',

                                     # custom args:
                                     'end_point': os.environ.get('ALIYUN_LOG_SAMPLE_ENDPOINT', ''),
                                     'access_key_id': os.environ.get('ALIYUN_LOG_SAMPLE_ACCESSID', ''),
                                     'access_key': os.environ.get('ALIYUN_LOG_SAMPLE_ACCESSKEY', ''),
                                     'project': 'project1',
                                     'log_store': "logstore1",
                                     'extract_kv': True
                                     }
                     },
        'loggers': {'sls': {'handlers': ['sls_handler', ],
                                   'level': 'INFO',
                                   'propagate': False}
                    }
        }
logging.config.dictConfig(conf)

# 使用
logger = logging.getLogger('sls')
logger.error("get error, reason=103 return_code=333 agent_type=ios")

支持KV的格式

默认支持key=value的格式, 也就是等号=分隔的值. 其中关键字key的范围是: 中日文, 字母数字, 下划线, 点和横线. 值value在有双引号括起来的情况下是除了双引号的任意字符. 在没有双引号括起来的情况下和关键字是一样的. 如下都是支持的:

c1 = "i=c1, k1=v1,k2=v2 k3=v3"
c2 = 'i=c2, k1=" v 1 ", k2="v 2" k3="~!@#=`;.>"'  # 双引号
c3 = 'i=c3, k1=你好 k2=他们'       # utf8
c4 = u'i=c4, 姓名=小明 年龄=中文 '   # utf8
c5 = u'i=c5, 姓名="小明" 年龄="中文"'# utf8
c6 = u'i=c6, 姓名=中文 年龄=中文'    # unicode
c7 = u'i=c7, 姓名="小明" 年龄=中文 ' # unicode
c8 = """i=c8, k1="hello           # 换行
world" k2="good
morning"
"""

自定义分隔符

默认通过等号=分隔, 也可以通过参数extract_kv_sep修改, 例如冒号:

c9 = 'k1:v1 k2:v2'

有时我们的分隔符是混合的, 有时为=有时为:, 如下:

c10 = 'k1=v1 k2:v2'
c11 = "k3 = v3"
c12 = "k4 : v4"

可以传入一个正则表达式给参数extract_kv_sep即可, 例如上面的情况可以传入(?:=|:), 这里使用可非捕获分组(?:), 再用|将各种可能的分隔符写入即可.

域名冲突

当关键字和内置日志域冲突时, 需要做一些调整, 例如:

c1 = 'student="xiao ming" level=3'

这里的level和日志域的内建表示日志级别冲突了, 可以通过参数buildin_fields_prefix / buildin_fields_suffix给系统日志域添加前缀后缀;
或者通过参数extract_kv_prefixextract_kv_suffix给抽取的域添加前缀后缀来解决.

其他定制参数

自动抽取KV也支持更多其他相关参数如下:

参数 作用 默认值
extract_kv 是否自动解析KV False
extract_kv_drop_message 匹配KV后是否丢弃掉默认的message域 False
extract_kv_prefix 给解析的域添加前缀 空串
extract_kv_suffix 给解析的域添加后缀 空串
extract_kv_sep 关键字和值的分隔符 =
buildin_fields_prefix 给系统域添加前缀 空串
buildin_fields_suffix 给系统域添加后缀 空串

进一步参考

  • 扫码加入官方钉钉群 (11775223):
    image
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
23天前
|
Java
使用Java代码打印log日志
使用Java代码打印log日志
77 1
|
24天前
|
Linux Shell
Linux手动清理Linux脚本日志定时清理日志和log文件执行表达式
Linux手动清理Linux脚本日志定时清理日志和log文件执行表达式
78 1
|
24天前
|
存储 缓存 算法
Python中collections模块的deque双端队列:深入解析与应用
在Python的`collections`模块中,`deque`(双端队列)是一个线程安全、快速添加和删除元素的双端队列数据类型。它支持从队列的两端添加和弹出元素,提供了比列表更高的效率,特别是在处理大型数据集时。本文将详细解析`deque`的原理、使用方法以及它在各种场景中的应用。
|
2天前
|
Java
log4j异常日志过滤规则配置
log4j异常日志过滤规则配置
11 0
|
5天前
|
数据采集 机器学习/深度学习 数据挖掘
Python数据清洗与预处理面试题解析
【4月更文挑战第17天】本文介绍了Python数据清洗与预处理在面试中的常见问题,包括Pandas基础操作、异常值处理和特征工程。通过示例代码展示了数据读取、筛选、合并、分组统计、离群点检测、缺失值和重复值处理、特征缩放、编码、转换和降维。强调了易错点,如忽视数据质量检查、盲目处理数据、数据隐私保护、过度简化特征关系和忽视模型输入要求。掌握这些技能和策略将有助于在面试中脱颖而出。
23 8
|
7天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
28 0
|
7天前
|
API Python
Python模块化编程:面试题深度解析
【4月更文挑战第14天】了解Python模块化编程对于构建大型项目至关重要,它涉及代码组织、复用和维护。本文深入探讨了模块、包、导入机制、命名空间和作用域等基础概念,并列举了面试中常见的模块导入混乱、不适当星号导入等问题,强调了避免循环依赖、合理使用`__init__.py`以及理解模块作用域的重要性。掌握这些知识将有助于在面试中自信应对模块化编程的相关挑战。
21 0
|
11天前
|
SQL API 数据库
Python中的SQLAlchemy框架:深度解析与实战应用
【4月更文挑战第13天】在Python的众多ORM(对象关系映射)框架中,SQLAlchemy以其功能强大、灵活性和易扩展性脱颖而出,成为许多开发者首选的数据库操作工具。本文将深入探讨SQLAlchemy的核心概念、功能特点以及实战应用,帮助读者更好地理解和使用这一框架。
|
13天前
|
存储 JSON JavaScript
「Python系列」Python JSON数据解析
在Python中解析JSON数据通常使用`json`模块。`json`模块提供了将JSON格式的数据转换为Python对象(如列表、字典等)以及将Python对象转换为JSON格式的数据的方法。
28 0
|
15天前
|
运维 安全 Ubuntu
`/var/log/syslog` 和 `/var/log/messages` 日志详解
`/var/log/syslog` 和 `/var/log/messages` 是Linux系统的日志文件,分别在Debian和Red Hat系发行版中记录系统事件和错误。它们包含时间戳、日志级别、PID及消息内容,由`rsyslog`等守护进程管理。常用命令如`tail`和`grep`用于查看和搜索日志。日志级别从低到高包括`debug`到`emerg`,表示不同严重程度的信息。注意保护日志文件的安全,防止未授权访问,并定期使用`logrotate`进行文件轮转以管理磁盘空间。
19 1

相关产品

  • 日志服务
  • 推荐镜像

    更多