博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Python Log Handler自动上传并解析KV格式的日志
阅读量:6572 次
发布时间:2019-06-24

本文共 3692 字,大约阅读时间需要 12 分钟。

概述

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

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

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

解决的问题

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

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的配置文件

参考, 将其中参数列表修改为:

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参数.

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

通过代码以JSON形式配置

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

#encoding: utf8import 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=他们'       # utf8c4 = u'i=c4, 姓名=小明 年龄=中文 '   # utf8c5 = u'i=c5, 姓名="小明" 年龄="中文"'# utf8c6 = u'i=c6, 姓名=中文 年龄=中文'    # unicodec7 = u'i=c7, 姓名="小明" 年龄=中文 ' # unicodec8 = """i=c8, k1="hello           # 换行world" k2="goodmorning""""

自定义分隔符

默认通过等号=分隔, 也可以通过参数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

转载地址:http://sjmjo.baihongyu.com/

你可能感兴趣的文章
通用Web后台魔方NewLife.Cube
查看>>
java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
查看>>
Windows7下安装配置PostgreSQL10
查看>>
HSmartWindowControl 之 显示图像
查看>>
ASP.NET Core 用户注册 - ASP.NET Core 基础教程 - 简单教程,简单编程
查看>>
dom4j解析xml获取所有的子节点并放入map中
查看>>
【spring boot】启动类启动 错误: 找不到或无法加载主类 com.codingapi.tm.TxManagerApplication 的解决方案...
查看>>
WPF 利用键盘钩子来捕获键盘,做一些不为人知的事情...完整实例
查看>>
C# 创建、部署和调用WebService的简单示例
查看>>
因为喜欢“对抗”,这位安全首席架构师一年为网易云节省上千万
查看>>
Dora.Interception,为.NET Core度身打造的AOP框架 [5]:轻松地实现与其他AOP框架的整合...
查看>>
Centos7通过yum安装最新MySQL
查看>>
poi 升级至4.x 的问题总结(POI Excel 单元格内容类型判断并取值)
查看>>
WPF 从文件加载字体
查看>>
Xshell出现要继续使用此程序必须应用到最新的更新或使用新版本
查看>>
JVM常见的七种垃圾收集器的简单比较
查看>>
异步调用webservice
查看>>
(原創) 如何在Ubuntu上啟動ADSL連線? (OS) (Linux) (Ubuntu)
查看>>
Orchard: module开发基础技术知识
查看>>
什么是UPS电源系统
查看>>