概述
我们日常应用中都离不开日志。可以说日志是我们在排查问题的一个重要依据。但是日志并不是写了就好了,当你想查看日志的时候,你会发现线上日志堆积的长度已经超越了你一行行浏览的耐性的极限了。于是,很有必要通过一些手段来高效地辅助你来快速的从日志中找到你要找的问题。本文通过一个从项目中衍生出来的例子从查找日志,筛选日志和统计日志3个方面层层递进来简述日志文件查看中一些有用的手段。(注:在Linux环境下)
目录
例子背景:
后台跑一个定时任务,对指定时间段的订单数据表中的每一条记录进行以此任务处理。在日志中输出:
1.订单id
2.订单处理状态
3.日志类别
准备工具:sort, tail, less, uniqu,grep,sed,awk
示例日志:demo.log
0.一些最基础的日志查看命令
最简单的日志查看命令就是浏览日志文件了,一般会从有限浏览文件末尾的
以上命令具体使用详见本机man手册
1.查找关键日志记录 grep
浏览了日志文件后你会发现,日志文件成千上万行,怎么能找到我要找的内容呢。这时候,就可已用grep来进行日志的关键行提取了。
grep 简单使用
规则:grep [选项]...模式 [文件]... (模式是正则表达式)
例子1:
输出:
2011-08-23 19:57:00,610 [] INFO bo.CommodityCerOrderBO - =====>属性订正任务执行开始|每页读取100条数据
2011-08-23 19:57:05,012 [] INFO bo.CommodityCerOrderBO - 当前正在处理页数:1
2011-08-23 19:57:30,688 [] INFO bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:attr_ids不含0跳过
...(略)
例子2:
输出:例子3:
输出:17
例子4:
grep 用法小结(转自网络图片):请点击直接查看大图
详细用法请man之
2.精简日志内容 sed
从n多行的日志文件中提取到一定数量的行后,可能你还会觉得有些功能不够,比如你每行并不需要有哪个类抛出的描述,比如你不需要日志时间,或者要把时间格式换个形式展示等等,这时候你就可以通过sed的替换命令来进行对日志文件提取具体内容了。
如果把grep比作过滤器,那sed就是个修改器了。
sed简单用法:
»'命令'的格式: [地址1[,地址2]][!] 指令 [参数]
» 地址的格式:用行号标识(1 表明匹配第一行),或者用正则表达式匹配('^INFO'表明该地址匹配以INFO打头的行)
» 指令的例子:p打印指令,s替换指令,d删除指令等等(以下表格摘自abs的sed小册子):
操作符 | 名字 | 效果 |
---|---|---|
[地址范围]/p |
打印 | 打印[指定的地址范围] |
[地址范围]/d |
删除 | 删除[指定的地址范围] |
s/pattern1/pattern2/ |
替换 | 将指定行中, 将第一个匹配到的pattern1, 替换为pattern2. |
[地址范围]/s/pattern1/pattern2/ |
替换 | 在地址范围指定的每一行中, 将第一个匹配到的pattern1, 替换为pattern2. |
[地址范围]/y/pattern1/pattern2/ |
transform | 在地址范围指定的每一行中, 将pattern1中的每个匹配到pattern2的字符都使用pattern2的相应字符作替换. (等价于tr命令) |
g |
全局 | 在每个匹配的输入行中, 将每个模式匹配都作相应的操作. (译者注: 不只局限于第一个匹配) |
例1:(摘自abs的sed小册子)
8d |
删除输入的第8行. |
/^$/d |
删除所有空行. |
1,/^$/d |
从输入的开头一直删除到第1个空行(第一个空行也删除掉). |
/Jones/p |
只打印那些包含"Jones"的行(使用-n选项). |
s/Windows/Linux/ |
在每个输入行中, 将第一个出现的"Windows"实例替换为"Linux". |
s/BSOD/stability/g |
在每个输入行中, 将所有"BSOD"都替换为"stability". |
s/ *$// |
删除掉每行结尾的所有空格. |
s/00*/0/g |
将所有连续出现的0都压缩成单个的0. |
/GUI/d |
删除掉所有包含"GUI"的行. |
s/GUI//g |
将所有"GUI"都删除掉, 并保持剩余部分的完整性. |
看完基本用法,让我们结合demo.log来具体应用下:
例2:输出demo.log中的某个日期中的ERROR的行
来具体应用下:
2011-08-23 19:57:30,709 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100104
2011-08-23 19:57:31,721 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100105
2011-08-23 19:57:32,727 [] ERROR bo.CommodityCerOrderBO - order-fix.curr_id:10117,status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100107
例3:提取demo.log中的日期,日志级别,订单id和状态。
输出:
2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳过
sed详细用法可以参考《sed 与 awk》(第二版), 或者man之
或者点击下面这个参考链接http://www.reddragonfly.org/abscn/x17814.html
3.对记录进行排序 sort
经过了日志文件的精炼后,我们可能不想对日志进行时间排序,这时候我们就可以用sort进行排序。
基本使用
sort [options] [file...]
对于demo.log,经过了上面的sed提取后,我希望先用id进行排序,然后再用日志级别倒序进行排序,最后才是日期排序
输出:2011-08-23 19:57:30@10117@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:32@10117@INFO@status:attr_ids成功保存为0|100104|0|100105|100107
2011-08-23 19:57:30@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100104
2011-08-23 19:57:31@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100105
2011-08-23 19:57:32@10117@ERROR@status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100107
2011-08-23 19:57:36@10222@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100104
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100105
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100106
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100107
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:3
2011-08-23 19:57:36@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:46
2011-08-23 19:57:37@10222@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:3
2011-08-23 19:57:32@10226@INFO@status:attr_ids不含0跳过
2011-08-23 19:57:36@10226@INFO@status:attr_ids成功保存为6|100104|0|0|100107|46|100106|100105|3|3
2011-08-23 19:57:32@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100104
2011-08-23 19:57:33@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100107
2011-08-23 19:57:33@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:46
2011-08-23 19:57:34@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100106
2011-08-23 19:57:35@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100105
2011-08-23 19:57:36@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:3
2011-08-23 19:57:36@10226@ERROR@status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:3
详尽手册http://ss64.com/bash/sort.html
4.统计日志相关记录数 awk
现在日志已经比较清晰了,但是如果我想对不同日志进行统计怎么办,比如我要统计所有ERROR的日志记录书,或者要统计每个订单有多少个ERROR?这就需要我们的awk帮忙了。
awk简单使用:
和sed一样,awk也支持2中方式调用,一种是把awk脚本直接在命令行写入,第二种是把awk写在文件中在命令行中调用。
awk处理方式也与sed类似,对文件中的每一个输入行进行处理,每个处理首先判断是否是模式中匹配的行,是的话就具体执行相应的语句。
不同的是,awk侧重与对每一行的列进行处理,并且,awk脚本和c语言类似也拥有变量,条件判断,循环等复杂语句,所以这里只能简单介绍一下基本应用,详细的请查看后面给出的相关链接。而且,awk在处理所有行前和处理完行后各有BEGIN和END语句做预处理和后置处理。
例子1:打印日志中的第2,3列
输出:(对于从sort得出的结果作为输入)例子2. 统计日志中INFO,ERROR出现的总数,以及总记录数
输出:
order total count:22
INFO count:5 ERROR count:17
例子3. 对指定时间范围内的日志进行统计,包括输出INFO,ERROR总数,记录总数,每个订单记录分类统计
下面的例子综合了前面sed和sort
输出:id:10117:
2011-08-23 19:57:32 INFO status:attr_ids成功保存为0|100104|0|100105|100107
2011-08-23 19:57:32 ERROR status:添加属性id,但由于认证分类参数有误默认取匹配属性名称的第一个属性id:100107
id:10226:
2011-08-23 19:57:32 INFO status:attr_ids不含0跳过
2011-08-23 19:57:32 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100104
2011-08-23 19:57:33 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100107
2011-08-23 19:57:33 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:46
2011-08-23 19:57:34 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100106
2011-08-23 19:57:35 ERROR status:添加属性id,但由于没有属性在该分类下默认取匹配属性名称的第一个属性id:100105
#这个例子只是举例说明awk的统计用法,实际运用中可能会统计超时的次数,页面访问次数等。
awk相关资料:
《sed 与 awk》(第二版)
补充:
其他实践时例子:
1. 在本地分支把代码修改从一个分支复制到另一个分支(例子的b1022st.txt是一个记录了文件新增或修改的变化的文件路径名)
通过awk和其system命令结合,这样就把文件从b1022-scm复制到b1022-lpscm下
2.内置函数 http://www.cnblogs.com/chengmo/archive/2010/10/08/1845913.html
3.内建变量 http://www.linuxsong.org/2010/09/awk-built-in-variable/
4.shell变量传递 http://www.51testing.com/?uid-225738-action-viewspace-itemid-246383
5.awk统计某个开始-结束范围内的关键字累加总数:
5.日志规范化
从前面可以看出,日志文件为了要让后续工具能够对里面的内容进行提取和处理,就必须要让日志文件规范的输出。
个人想到有几个点可以规范:
1.记录日志时候可以写入一些特殊的文本语句,一遍与工具的检索和处理。
2.记录日志最好不要用中文,因为在不同语言环境下对日志的处理可能因为编码不同导致没法处理日志。
后面再贴下淘宝中找到的一些打印日志的建议:
6.一些容易遇到的问题
a.处理中文出现乱码
这个主要是因为你的linux locale的配置,与编辑文件的语言环境,还有你登录ssh客户端的编码规则有关,所以最好还是不用中文记录日志。
b.正则表达式不同工具的区别
这个主要是因为不同工具的正则表达式定义的元字符不同,网上有总结的,可点击正则迷雾参考
OO后记:
目前只是简单介绍了grep,sed,sort,awk的几个简单应用,实际上的日志监控回根据不同的情景进行不同的处理。比如需要对调用的耗时进行统计(平均时间或者超时记录),对访问量进行统计,但是基本原理都和本文例子出发点一致。本文一方面是为了记录下学习过程中积累的东西,另一方面为了抛砖引玉引起大家对日志记录的关注。
文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别
文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具
文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量
文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置
文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖
文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...
文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序
文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码
文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型
文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件
文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令
文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线