Miller 日志处理实战:用 DKVP 格式对异构日志做临时分析与聚合
CLI数据分析【免费下载链接】millerMiller is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON项目地址https://gitcode.com/gh_mirrors/mi/miller点击查看免费下载本文基于 Miller 官方文档《Log-processing examples》对应仓库文档 docs/src/log-processing-examples.md围绕临时性ad-hoc处理日志文件数据这一场景系统讲解如何利用 Miller 的 DKVP 输入格式、filter/step/sec2gmt/group-like/stats1等动词verb与is_present等 DSL 函数对字段结构不一致的异构日志进行提取、过滤、聚合、时间换算与分组重排。读完本文你将掌握一条完整的程序打日志 → grep 预处理 → Miller 分析流水线并能直接套用到自己的日志分析任务中。DKVP让每条日志行独立自洽的数据格式日志处理是 Miller 的典型使用场景之一而这里的主角是 DKVPKey-Value Pair键值对格式。DKVP 之所以在日志场景中大放异彩官方文档给出的理由非常直白每条记录的行内同时携带字段名和字段值因此每一行都自洽独立可以单独被grep、sed、awk等系统工具处理也可以被 Miller 单独解析因为 schema字段名集合内嵌在数据里不是每一行都必须拥有相同的字段名列表——这正是日志数据的常态不同事件类型携带不同属性。在 Miller 源码中DKVP 读取器位于 pkg/input/record_reader_dkvp_nidx.go它与 NIDX 读取器共用同一套骨架RecordReaderDKVPNIDX唯一差异是行的切分方式DKVP 按keyvalue对切分并解析为MlrmapNIDX 则按位置取序号字段。从源码结构可以推断DKVP 读取器解析一行后直接把keyvalue对还原成记录的字段集合因此字段名天然随行而异。生成与聚合日志输出一个完整的实战流水线官方文档设想了一个非常贴近现实的场景你可以在任何语言的程序里边运行边打印日志行把不同事件的条目混在一起输出。程序跑完后再用 Miller 把混杂的数据分拣出来、过滤、分析、从中学习。假设你的程序打印出了类似 docs/src/log.txt 的内容openter,time1472819681 opcache,typeA9,hit0 opcache,typeA4,hit1 time1472819690,batch_size100,num_filtered237 opcache,typeA1,hit1 opcache,typeA9,hit0 ...注意这里共出现了三类不同形状的记录事件类型携带字段含义openterop,time程序进入记录起始时间戳Unix 秒opcacheop,type,hit缓存访问事件记录缓存类型与是否命中批处理汇总time,batch_size,num_filtered每批数据处理完后的统计信息每条 print 语句只包含局部信息当前时间戳、某个缓存是否命中、本批处理了多少条等等。这正是日志分析的起点——日志行无需统一 schemaMiller 负责在事后把它们整理成可分析的结构。按需挑选记录grep、having-fields 与 is_present 三选一要从混杂的记录中挑出我们关心的部分官方文档给出了三种手段各有适用场景系统grep命令最简单直接适合按文本内容粗筛例如grep opcache log.txtMiller 的having-fields动词按记录的字段名做结构化筛选DSL 的is_present函数在put/filter表达式中判断某字段是否存在。having-fields的实现位于 pkg/transformers/having_fields.go它支持六种判定模式--at-least至少包含这些字段、--which-are字段名恰好是这些、--at-most至多包含这些字段、--all-matching全部字段名匹配正则、--any-matching任一字段名匹配正则、--none-matching没有字段名匹配正则。源码中每种模式对应一个独立的transformHavingFieldsXxx方法例如--any-matching通过遍历记录头指针逐一MatchString判定命中即放行。is_present定义于 pkg/bifs/types.go实现为FromBool(!input1.IsAbsent())——即只要字段值不是缺席absent状态即为真。它与is_null的区别在于is_null在字段缺席、空void、null 三种情况下都返回真而is_present只关心字段是否存在。实战一按缓存类型统计命中率下面的命令先用系统grep筛出所有缓存访问行再用 Miller 以 DKVP 格式读入、按type分组统计hit字段的均值grep opcache log.txt \ | mlr --idkvp --opprint stats1 -a mean -f hit -g type then sort -f type输出type hit_mean A1 0.8571428571428571 A4 0.7142857142857143 A9 0.09090909090909091这条命令把三种能力串成了一条链grep opcache文本级粗筛只保留缓存事件--idkvp告诉 Miller 输入是 DKVP 格式i input--opprint输出采用漂亮的表格pprint格式stats1 -a mean -f hit -g type按type分组对hit计算均值then sort -f typethen是 Miller 的链式动词分隔符这里按type排序输出。注意此处的关键点混入批处理汇总行batch_size等并不影响分析——grep已把它们过滤掉且 DKVP 读取器对每行独立解析字段不同也无妨。实战二用 is_present 过滤 step 计算时间/数量增量官方文档给出的第二组命令是只保留含batch_size字段的记录即批处理汇总行然后计算time与num_filtered相对上一条记录的增量最后把 Unix 时间戳换算成 GMTmlr --from log.txt --opprint \ filter is_present($batch_size) \ then step -a delta -f time,num_filtered \ then sec2gmt time输出time batch_size num_filtered time_delta num_filtered_delta 2016-09-02T12:34:50Z 100 237 0 0 2016-09-02T12:35:05Z 100 348 15 111 2016-09-02T12:35:13Z 100 493 8 145 2016-09-02T12:35:20Z 100 554 7 61 2016-09-02T12:35:36Z 100 612 16 58 2016-09-02T12:35:42Z 100 728 6 116这里出现了三个重要语法与动词逐一拆解--from log.txtMiller 的主标志main flag直接指定输入文件等价于把文件重定向到 stdin。filter is_present($batch_size)filter动词按 DSL 表达式逐记录判定。由于异构日志中大量行没有batch_size字段直接引用$batch_size会得到 absent 值因此必须用is_present先做存在性检查。从 pkg/bifs/types.go 的实现看它返回字段非 absent的布尔值正好充当过滤条件。step -a delta -f time,num_filteredstep动词计算依赖前后记录的值。-a delta表示求相邻记录差值-f time,num_filtered指定参与计算的两个数值字段输出自动追加time_delta、num_filtered_delta后缀列。第一行time_delta0是因为首条记录没有前置记录。step的完整选项可从 pkg/transformers/step.go 的stepOptions看到选项取值说明-acounter,delta,ewma,from-first,ratio,rprod,rsum,shift,shift_lag,shift_lead,slwinstepper 名称可逗号分隔或多个-a-f字段名列表参与计算的数值字段-g字段名列表可选分组字段如按主机名分组求增量-d权重列表EWMA 平滑权重1表示不平滑默认0.5-o后缀列表自定义 EWMA 输出字段后缀须与-d数量一致-F布尔兼容 Miller 5 的 no-op 标志Miller 6 起整数计算自动按浮点处理值得注意的是step的 stepper 名单里有shiftshift_lag的别名、shift_lag、shift_lead、slwin滑动窗口均值等并支持带计数后缀的形式如shift_lag_12回溯 12 条记录、slwin_7_2回溯 7 条、前瞻 2 条。从 pkg/transformers/step.go 的STEPPER_LOOKUP_TABLE可以看到全部内置 stepper 及其语义。sec2gmt time把time字段从 Unix 秒换算为 GMT 时间戳ISO 8601 格式。这本质上是 pkg/transformers/sec2gmt.go 中sec2gmt动词对 DSLsec2gmt函数的按键少字封装——源码注释明确说明mlr sec2gmt time1,time2等价于mlr put $time1 sec2gmt($time1); $time2 sec2gmt($time2)。该动词还支持-1到-9保留 1~9 位小数以及--millis/--micros/--nanos输入为毫秒/微秒/纳秒时间戳等选项。异构数据分组重排group-like 动词前面的例子靠先过滤再分析回避了 schema 不一致问题。但官方文档还展示了一个更偷懒的思路把相似形状的记录聚拢到一起直接观察——这正是group-like动词的用途。mlr --opprint group-like log.txt输出节选op time enter 1472819681 op type hit cache A9 0 cache A4 1 cache A1 1 ... time batch_size num_filtered 1472819690 100 237 1472819705 100 348 ...可以看到group-like把异构记录按字段名集合是否相同分成三批op,time批、op,type,hit批、time,batch_size,num_filtered批批间用空行分隔。从源码 pkg/transformers/group_like.go 看group-like的实现思路是用inrec.GetKeysJoined()把每条记录的字段名拼成分组键存入一个lib.OrderedMap键为字段名串值为记录列表在流结束时EndOfStream按插入顺序把所有分组依次输出。使用有序映射而非普通哈希表保证了输出分组的顺序确定性。group-like动词没有任何选项参数但它同样可以与then链式组合。官方文档紧接着给出了一个组合示例先分组、再顺便把time字段换算成 GMTmlr --opprint group-like then sec2gmt time log.txt输出节选op time enter 2016-09-02T12:34:41Z op type hit cache A9 0 ... time batch_size num_filtered 2016-09-02T12:34:50Z 100 237 2016-09-02T12:35:05Z 100 348 ...注意sec2gmt time作用于三条批openter行的time字段1472819681 → 2016-09-02T12:34:41Z与批处理汇总行的time字段都被正确换算而op,type,hit批没有time字段行原样保留——这再次印证了 Miller 对异构记录各取所需、缺字段不报错的处理哲学。解析日志输出grep/sed 预处理后再交给 Miller生成与聚合一节讨论的是结构化程度较高的keyvalue日志但现实中的日志往往长这样官方文档给出的示例2015-10-08 08:29:09,445 INFO com.company.path.to.ClassName [sometext] various/sorts/of data { punctuation} hits1 status0 time2.378这是一行典型的 Java/Log4j 风格日志时间戳、级别、类名、自由文本和结构化键值对混在一起。Miller 官方文档给出的处理策略是先用grep和/或sed做文本级预处理把结构化部分提取出来再交给 Miller。示例命令grep various sorts *.log \ | sed s/.*} // \ | mlr --fs space --repifs --oxtab stats1 -a min,p10,p50,p90,max -f time -g status这条流水线包含几个值得拆解的要点grep various sorts *.log按关键字粗筛日志文件sed s/.*} //贪婪删除到最后一个}为止的文本只保留后面的hits1 status0 time2.378等键值对--fs space将字段分隔符设为空格此时行内是hits1 status0 time2.378这类空格分隔的键值对--repifs允许重复的字段分隔符——多个连续空格被视为一个分隔符这对日志文本中不规则的空白至关重要--oxtab以 XTAB交叉表格式输出每条记录纵向展开为key: value多行便于阅读stats1 -a min,p10,p50,p90,max -f time -g status按status分组对time字段求最小值、10/50/90 百分位和最大值——典型的延迟分析。文档在此处给出的输出为... output here ...即结果取决于读者日志的实际内容但命令结构本身即是可复用的模板任何一行里既有自由文本又有键值对的日志都可以用这条grep → sed → Miller三段式流水线转成结构化数据做统计。方法论小结异构日志分析的三板斧通读官方文档可以提炼出 Miller 日志分析的三条核心方法论日志行自带 schema天然适合 DKVP写日志时无需约束所有事件使用同一组字段每条日志各说各话事后统一交给 Miller 解析即可。这消除了传统 CSV 日志对字段顺序和表头的强约束。三层筛选手段按需选用文本层用系统grep/sed简单、快、可处理自由文本字段名层用having-fields结构化、支持正则字段值层用filteris_present等 DSL 表达式最灵活可叠加任意逻辑。用 then 链把动词组装成流水线stats1聚合、step增量、sec2gmt时间换算、group-like分组重排都可以用then自由组合输出格式通过--o*系列标志--opprint、--oxtab等切换同一份数据可以看出多种形态。更进一步上述命令均可用 Miller 的回归测试体系复现与验证例如group-like的最小复现命令记录在 test/cases/verb-group-like/0001/cmd内容是mlr group-like test/input/het.dkvp——test/input/het.dkvp正是一个字段形状混杂的 DKVP 样本其预期输出与该动词按相同字段名集合分批输出的语义完全一致。相关动词的更多使用细节可参考仓库文档 docs/src/reference-verbs.md动词总览与 docs/src/reference-dsl-builtin-functions.mdDSL 内建函数含is_present的完整说明。参考本文用到的示例数据与源码位置示例日志数据docs/src/log.txtopenter/opcache/ 批处理汇总三类异构记录官方文档原文docs/src/log-processing-examples.mdDKVP 读取器实现pkg/input/record_reader_dkvp_nidx.gogroup-like动词实现pkg/transformers/group_like.gostep动词实现与 stepper 全表pkg/transformers/step.gosec2gmt动词实现pkg/transformers/sec2gmt.gohaving-fields动词实现pkg/transformers/having_fields.gois_present函数实现pkg/bifs/types.go回归测试样例test/cases/verb-group-like/0001/cmd赞分享CLI数据分析【免费下载链接】millerMiller is like awk, sed, cut, join, and sort for name-indexed data such as CSV, TSV, and tabular JSON项目地址https://gitcode.com/gh_mirrors/mi/miller点击查看免费下载相关推荐SigNoz日志管理日志聚合与实时分析技术SigNoz日志管理日志聚合与实时分析技术 概述现代微服务架构下的日志挑战 在当今的微服务架构中应用通常由数十甚至数百个服务组成每个服务都会产生大量的日可观测性指标监控链路追踪日志分析后端告警Flexile日志分析结构化日志与日志聚合Flexile日志分析结构化日志与日志聚合 引言现代SaaS应用的日志挑战 在复杂的SaaS应用如Flexile中日志管理不再是简单的调试工具而是系统可洛雪音乐音源配置终极指南5分钟搞定全网无损音乐免费听洛雪音乐音源配置终极指南5分钟搞定全网无损音乐免费听 洛雪音乐音源lxmusic 是一个专为洛雪音乐播放器设计的开源音源聚合项目为音乐爱好者提供免费获取音视频上一篇终极C排序算法指南20种排序方法深度对比与实战应用下一篇高级问题解决contribute-to-scroll的复杂集成挑战与方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Zynq UltraScale+ MPSoC多核异构开发:RPU裸机与APU Linux的OpenAMP核间通信实战

Zynq UltraScale+ MPSoC多核异构开发:RPU裸机与APU Linux的OpenAMP核间通信实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/24 14:39:57 阅读更多 →
Stellarium 天空文化深度解析:indian_nakshatras 印度二十七宿(Nakshatras)的史实还原与源码实现

Stellarium 天空文化深度解析:indian_nakshatras 印度二十七宿(Nakshatras)的史实还原与源码实现

桌面应用图形学科研 【免费下载链接】stellarium Stellarium is a free GPL software which renders realistic skies in real time with OpenGL. It is available for Linux/Unix, Windows, macOS and Haiku. With Stellarium, you really see what you can see with your eye…

2026/9/25 16:53:44 阅读更多 →
Quick 测试框架 CocoaPods 安装问题排查:“No such module ‘Quick‘“ 报错的完整解决方案

Quick 测试框架 CocoaPods 安装问题排查:“No such module ‘Quick‘“ 报错的完整解决方案

测试开发工具 【免费下载链接】Quick The Swift (and Objective-C) testing framework. 项目地址: https://gitcode.com/gh_mirrors/qu/Quick 点击查看 免费下载 Quick 是基于行为驱动开发(BDD)风格的 Swift 与 Objective-C 测试框架&#x…

2026/9/24 14:39:57 阅读更多 →

最新新闻

基于SpringBoot的个人健康与运动习惯追踪系统设计与实现

基于SpringBoot的个人健康与运动习惯追踪系统设计与实现

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 1. 项目背景与意义 随着生活节奏的加快和工作压力的增大,久坐、缺乏运动、作息不规律等不良生活习惯日益普遍,亚健康状态成为现代人面临的突出问…

2026/9/25 16:53:19 阅读更多 →
用 Dify 打造数据可视化图表:从数据接入到图表输出的完整配置指南

用 Dify 打造数据可视化图表:从数据接入到图表输出的完整配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 16:53:18 阅读更多 →
为什么 4 卡生成快了近 5 倍?MiniMax-H3-Comfy-NPU 多 NPU 并行 1/2/4 卡配置全解

为什么 4 卡生成快了近 5 倍?MiniMax-H3-Comfy-NPU 多 NPU 并行 1/2/4 卡配置全解

为什么 4 卡生成快了近 5 倍?MiniMax-H3-Comfy-NPU 多 NPU 并行 1/2/4 卡配置全解 【免费下载链接】MiniMax-H3-Comfy-NPU 项目地址: https://ai.gitcode.com/Ascend-SACT/MiniMax-H3-Comfy-NPU MiniMax-H3-Comfy-NPU 是一个让 MiniMax-H3 视频音频联合生成…

2026/9/25 16:53:18 阅读更多 →
Scoop:Windows软件包管理神器

Scoop:Windows软件包管理神器

文章目录scoopBucketscoop scoop是Windows上的命令行安装器,和Windows自带的Winget相比,Scoop奉行绿色便携的哲学,它下载的大多是压缩包,解压到用户目录(~\scoop\apps)即用。不写注册表,不往系统盘塞垃圾。卸载时直接…

2026/9/25 16:53:18 阅读更多 →
easyocr:基于Pytorch的光学字符识别神器

easyocr:基于Pytorch的光学字符识别神器

文章目录安装并下载模型试用类和方法安装并下载模型 easyocr是基于PyTorch的光学字符识别(Optical Character Recongnition, OCR)工具,开箱即用,支持从自然场景图像到密集文档的文本提取。在确认安装Pytorch之后,用pip安装即可。 pip insta…

2026/9/25 16:53:18 阅读更多 →
MES生产执行系统全流程:工厂车间到底怎么实现数字化管理

MES生产执行系统全流程:工厂车间到底怎么实现数字化管理

1. 为什么工厂车间需要 MES很多工厂已经上了 ERP,计划部门能在系统里排单、算物料、看库存,但计划一旦下达到车间,后面的事情往往就变成“拍脑袋”和“靠人追”。今天生产了多少、哪台设备在停机、这批料是谁领的、质量异常卡在哪个工序&…

2026/9/25 16:52:18 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →