提问人:Camões 提问时间:10/20/2023 最后编辑:Ken WhiteCamões 更新时间:10/25/2023 访问量:66
解析带有转义字符的 key=values 字符串
Parse string of key=values with escaped characters
问:
Loki 以键值格式输出以下日志,其结构如下:key1=value1 key2=value2
level=info ts=2023-10-20T14:30:48.716410806Z caller=metrics.go:159 component=frontend org_id=fake traceID=58290ebda8d79180 latency=fast query=\"sum by (level) (count_over_time({k8s_namespace=\\\"ingress-nginx\\\"} |= ``[1s]))\" query_hash=110010092 query_type=metric range_type=range length=15m0.001s start_delta=15m0.833402507s end_delta=832.40267ms step=1s duration=61.999532ms status=200 limit=1000 returned_lines=0 throughput=4.2MB total_bytes=260kB total_bytes_structured_metadata=0B lines_per_second=4209 total_lines=261 post_filter_lines=261 total_entries=1 store_chunks_download_time=0s queue_time=819.962996ms splits=2 shards=32 cache_chunk_req=0 cache_chunk_hit=0 cache_chunk_bytes_stored=0 cache_chunk_bytes_fetched=0 cache_chunk_download_time=0s cache_index_req=0 cache_index_hit=0 cache_index_download_time=0s cache_stats_results_req=0 cache_stats_results_hit=0 cache_stats_results_download_time=0s cache_result_req=0 cache_result_hit=0 cache_result_download_time=0s source=logvolhist
在 fluentd 中,我尝试使用带有 as 和 as 的标记制表符分隔值解析器解析此日志,并获得以下结果:delimiter_pattern
/\s+/
label_delimiter
=
{
"level": "info",
"caller": "metrics.go:159",
"component": "frontend",
"org_id": "fake",
"traceID": "58290ebda8d79180",
"latency": "fast",
"query": "\"sum",
"(count_over_time({k8s_namespace": "\\\"ingress-nginx\\\"}",
"|": "",
"query_hash": "110010092",
"query_type": "metric",
"range_type": "range",
...
}
对于键,此解析器只能捕获第一个单词,并使用后面的空格作为另一个键值的分隔符。query
我尝试了不同的正则表达式和两个插件解析器(https://shihadeh.dev/ruby-gems/Key-ValueParser/ 和 https://github.com/fluent-plugins-nursery/fluent-plugin-kv-parser),但到目前为止没有运气。
是获得正确的正则表达式,使用不同的解析器,尝试取消转义字符还是其他问题?
答:
1赞
Camões
10/25/2023
#1
\s(?=\w+=(\\")?.+?(?(1)\1(?=\s)))
从 @CAustin 的评论来看,这个正则表达式的效果比delimiter_pattern
/\s+/
额外
这是针对我关于 Fluentd 和日志解析的具体情况。同时,在更好地分析了 Fluentd 和 Fluent bit 之后,由于解析功能,我可能会改用 Fluent bit。
敬启者 :p
评论
w+)=(?<value>[^“\s]+(?!\S)|\\“(?:[^\\”]|\\{3}“)*\\”)
对你有用吗?如果是,我会写一个答案。请注意,这假设示例中的每个字符都是两个字符的序列,而不是一个转义的双引号。\"
\s(?=\w+=(\\")?.+?(?(1)\1(?=\s)))