本文共 3692 字,大约阅读时间需要 12 分钟。
使用Python SDK提供的Log Handler可以实现每一条Python程序的日志在不落盘的情况下自动上传到日志服务上。与写到文件再通过各种方式上传比起来,有如下优势:
本篇主要如何打开自动解析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
我们期望在上传到日志服务时可以自动解析出域name
和score
字段. 使用Python 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
参数.
注意, 受限于的限制, 这里只能用无名参数, 依次传入. 对于不改的参数, 用None
占位.
如果期望更加灵活的配置, 也可以使用代码配置, 如下将参数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")
默认支持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_prefix
和extract_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 | 给系统域添加后缀 | 空串 |
转载地址:http://sjmjo.baihongyu.com/