程序员的工作离不开日志。
日志就像一个笔记本,可以记录程序运行时的一些信息。
日志文件
通过日志,我们可以做很多事情。
日志的作用
1.记录系统和接口的使用情况,比如请求日志
2.记录和分析用户的行为,比如网站访问日志
3.调试程序,和控制台的作用类似,但是控制台中的内容并不会保存到文件中,而日志可以长期保存。
4.帮助我们排查和定位错误。比如在系统抛出异常时,将异常信息记录到日志,可以事后复盘。
5.通过分析日志还能够优化代码逻辑、提升系统性能、稳定性等。
日志虽然有那么多的作用,但如果数量过多,也会让开发人员感到头疼。对于大型的系统,程序员们经常要看几千、几万行日志,常常看日志看到头晕眼花。
但是,其实处理日志是有很多技巧的,下面鱼皮分享自己和日志的故事。
故事分为7个阶段,
从看日志看到怀疑人生,再到玩弄千万日志于股掌
,鱼皮都做了哪些事情?
鱼皮和日志的爱恨情仇
第一阶段无日志
刚开始搭建新的系统时,为了图个方便,鱼皮没有给系统接入任何的日志框架,也没有记录任何日志,整个项目非常的干净丝滑。需要调试时就直接用输出函数将信息打印在控制台,出了异常就直接打印堆栈。
真是无事一身轻,爽的不得了!
可惜,好景不长。在项目上线之后,突然有一天,系统出问题了,数据查不出来了,同事找上门来了。
鱼皮笑着说:“问题不大!”
然后登录服务器,进入项目目录,瞬间傻眼。
项目目录依旧干净丝滑,原来我特么根本没记日志啊!
这下好了,什么问题都查不出来。乖乖地去给项目加上日志功能吧。
第二阶段引入日志类库
Java语言有很多优秀的日志类库,比如Logback、Log4j2等,提供了很多记录和打印日志的方法,非常方便。可以直接使用其中一个类库,而无需自己实现。此处因为鱼皮的项目使用SpringBoot框架进行开发,直接使用其默认日志库Logback即可。
使用方式很简单,先添加logback.xml配置文件,主要配置了日志文件的存储路径和格式。Logback框架还会自动将日志按天进行压缩,并且在一定天数后进行删除,以节约磁盘空间。最大存储天数也可以在配置文件中指定。
配置文件大概长这样:
在要打印日志的类上创建一个日志对象:
Loggerlogger=LoggerFactory.getLogger(MyApp.class);
然后就可以使用该对象去记录日志啦:
catch(Exceptione){logger.error("apperror",e);}
加上配置文件后,启动项目,就可以看见生成的日志文件了。欧耶,下次系统再出问题,就不怕缺乏信息来排错啦!
系统运行了一个小时之后,同事又找上门来了,这次鱼皮很有底气,笑着说:“问题不大!”
然后打开日志文件一看,傻眼了,有几千行日志,我怎么知道哪行日志是报错信息呢?
就这你能秒了我?直接用Linux命令过滤出带“ERROR”字段的日志行就行了~
catapplication.log|grep
'ERROR'
虽然解决了问题,但是后面每次报错,都要输一遍这个筛选命令,而且随着文件越来越大,命令执行的速度越来越慢了。
能不能
把所有错误日志和正常日志区分开
,放在不同的文件中呢?
第三阶段日志分级
幸运的是,一般的日志框架都提供了日志分级存储功能,可以通过修改配置文件来实现。
修改logback.xml配置文件,将ERROR(错误)级别的日志单独输出到error.log文件中,实现日志分级:
启动项目,日志按预期分级写到了application.log和error.log两个文件。系统再出现异常时,鱼皮只需打开error.log文件,错误信息一览无遗!
系统运行一段时间后,鱼皮上线了一个很重要的服务,记录了相当多的业务日志。虽然目前错误日志可以单独查看,但是
核心服务的日志和其他服务的正常日志都堆积在application.log中
,想要仅查看核心服务的日志依旧要采用命令过滤的方式,比较麻烦。
有没有什么办法,把核心业务的日志单独记录到一个文件中呢?
第四阶段按类隔离
幸运的是,Logback日志框架支持将不同的类产生的日志记录到不同的文件中,修改配置文件即可。比如将所有RequestAOP类产生的请求日志记录到request.log中:
启动项目,自动生成了request.log文件,打开这个文件,就可以查看所有的请求日志,可以用于流控分析等等,真爽死了!
后来,随着系统的访问量越来越大,单台服务器已经不能满足对并发的需求,因此鱼皮又加了三台机器,共同提供服务。
有一天,系统又出问题了,同事找上门来,鱼皮心想:信不信分分钟给你解决bug!
一顿操作猛如虎,登录一台服务器查看日志,结果错误日志
空空如也
,比鱼皮的兜儿都干净。
奇怪了,怎么找不到错误信息?
对啊,现在有四台机器,请求可能落在了其他机器上,因此错误日志也可能在别的机器上!
哎,没办法,一台一台登录服务器去找错误信息吧。
其实四台机器还能忍,但是后来随着并发量的增大,鱼皮负责的系统已经有十台机器了,每次查看日志要依次登录十台机器去找!而且单个日志数据的量已经达到几十万行,无论怎么切分看起来都太累了。
哦,乔治,这太难受了!有没有什么办法,能让我在一个地方
集中看日志
啊!
要不直接把日志记录到数据库中?
不行不行,日志数据量太大了,数据库肯定存不下。而且写入数据库的速度受到网络传输等限制,比较缓慢。
怎么办啊?算了,先睡一觉。
第五阶段日志上报与集中式管理
“嘿,少年,你想要力量么?”
“废话,谁不想要!”
“听说过ELK么?他会指引你前进的方向。”
鱼皮从梦中惊醒,对啊,可以用ELK搭建一个分布式日志收集系统啊!
ELK是Elasticsearch、Logstash和Kibana的简称,
不是单独的一个软件,而是一整套问题的解决方案
Elasticsearch(简称ES)是
全文搜索引擎
,能够对海量数据进行存储和高效的搜索。
Logstash是一个
数据管道
,能够从各种数据源(比如MySQL数据库)收集数据,将数据从一处传输到另一处,并加以解析和转换。
Kibana是
数据可视化平台
,可以将Elasticsearch中存储的数据进行展示。在Kibana上,我们不仅可以看到所有原始的日志信息,还能够自定义各种精美直观的可视化图表。
通常使用Logstash统一收集各个机器上的数据,并传输至Elasticsearch进行存储,最后通过Kibana进行数据展示,之后就可以利用Kibana轻松地查看和分析所有的数据了。
既然可以解决问题,那就接入ELK吧~
但是使用ELK相当于为系统引入了三个新组件,考虑到系统使用的组件越多,复杂度越高,就越难维护;而且Logstash比较重,对CPU和内存的占用较高。因此,鱼皮灵机一动,干脆舍弃掉Logstash,直接将Elasticsearch当成数据库来使用。
先在SpringBoot中整合Elasticsearch,然后将日志数据通过依赖包提供的API接口存储到Elasticsearch,最后接入Kibana进行展示。
Maven引入依赖:
访问ES的接口:
@RepositorypublicinterfaceUserRepositoryext
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.