当前位置: 首页 > 科技观察

别小看Log日志,难倒技术总监

时间:2023-03-14 15:17:24 科技观察

图片来自Pexels因为大家普遍只懂Log4j,其他基本没用过。我们的Leader也说他对ELK这样的大型原木有点生疏,因为好久没用了。所以今天总结一下关于日志的介绍。日志对于程序员来说是必不可少的。在我们的开发过程中,如果写完代码需要调试,那么日志是必不可少的。日志可以帮助我们定位问题,从而更好的帮助我们解决bug。本期小编就给大家详细了解一下我们经常使用的四种日志类型,帮助大家提高开发效率。1.Slf4jSlf4j的全称是SimpleLoggingFacadeForJava。它只是一个为Java程序提供日志输出的统一接口。不是具体的日志实现方案。就像JDBC一样,只是一个规则。所以单靠Slf4j是不行的,必须要搭配其他具体的日志实现方案,比如Apache的org.apache.log4j.Logger。JDK自带的java.util.logging.Logger等语法简单SLF4J不如Log4J常用,因为很多开发者熟悉Log4J却不知道SLF4J,或者不关注SLF4J而坚持Log4J。我们先来看Log4J的例子:Logger.debug("Hello"+name);由于字符串拼接的问题,使用上面的语句会先拼接字符串,然后根据当前级别是否低于Debug来决定是否输出这条日志,即使不是也输出日志,字符串拼接也将执行操作。所以很多公司强制执行如下语句,使得字符串连接只在当前处于Debug级别时执行:if(logger.isDebugEnabled()){LOGGER.debug("Hello"+name);}这避免了字符串连接问题,但有点太麻烦了,不是吗?相对地,SLF4J提供了如下简单的语法:LOGGER.debug("Hello{}",name);它的形式和第一个例子类似,但是没有字符串拼接的问题,也没有第二篇那么繁琐。日志级别LevelSlf4j有四种级别的日志级别可供选择,从上到下,从低到高,优先级高的会被打印出来:Debug:简单来说就是可以输出所有对程序调试有利的信息通过调试。信息:对用户有用的信息。warn:可能导致信息错误。error:顾名思义,发生错误的地方。因为是强制规范,直接使用LoggerFactory创建:importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;publicclassTest{privatestaticfinalLoggerlogger=LoggerFactory.getLogger(Test.class);//...}SpringBoot支持的配置方式Slf4j很好,里面已经集成了Slf4j。一般我们在使用的时候都会配置Slf4j。application.yml文件是唯一需要在SpringBoot中配置的文件。最初创建项目时,它是application.properties文件。个人比较喜欢用yml文件,因为yml文件的层次感特别好,看起来也比较直观。但是yml文件对格式要求比较高。比如英文冒号后面必须有一个空格,否则项目可能无法启动,也不会报错。是用properties还是yml看个人习惯。我们看一下application.yml文件中的日志配置:logging:config:classpath:logback.xmllevel:com.bowen.dao:tracelogging.config用于指定项目启动时读取哪个配置文件,这里指定日志配置文件为classpath:logback.xml文件,日志的相关配置信息放在logback.xml文件中。logging.level用于指定日志在具体mapper中的输出级别。上面的配置表示com.bowen.dao包下所有mapper日志的输出级别都是trace,会打印出操作数据库的sql。开发时设置为trace,方便定位问题。在生产环境中,将此日志级别设置为错误级别。常用的日志级别从高到低依次为:ERROR、WARN、INFO、DEBUG。2.Log4jLog4j是Apache的一个开源项目。通过使用Log4j,我们可以控制日志信息传输到控制台、文件、GUI组件,甚至套接字服务器、NT事件记录器、UNIXSyslog守护进程等的目的地。我们还可以控制每个日志的输出格??式;通过定义每条日志信息的级别,我们可以更详细地控制日志的生成过程。组合架构Log4j由三个重要组件组成:Logger:控制启用或禁用哪些日志语句,并限制日志信息的级别。Appenders:指定日志是打印到控制台还是文件。Layout:控制日志信息的显示格式。Log4j要输出的Log信息定义了5个级别,分别是DEBUG、INFO、WARN、ERROR和FATAL。输出时,只有高于配置中指定级别的信息才能真正输出,因此无需更改代码即可配置在不同情况下输出的内容,非常方便。日志级别LevelLog4j主要有以下几种日志级别:off:关闭日志,级别最高,不能输出任何日志。fatal:灾难性错误,是所有级别中最高的,可以输出日志。error:错误,一般用于异常信息。warn:警告,一般用于非标准引用等信息。信息:一般信息。debug:调试信息,一般用于程序执行。trace:堆栈信息,一般不用。all:开启所有日志,最低级别,所有日志都可以使用。在Logger核心类中,除了off/all之外,每个日志级别对应一组重载方法,用于记录不同级别的日志。当且仅当该方法对应的日志级别大于等于设置的日志级别时,才会记录该日志。使用Log4j只需要导入一个jar包:org.log4jlog4j1.2.9e的配置方法是在Resources的根目录下创建一个log4j.properties配置文件。一定要注意:文件的位置和文件名一定不能错,然后在properties文件中添加配置信息。log4j.rootLogger=调试,conslog4j.appender.cons=org.apache.log4j.ConsoleAppenderlog4j.appender.cons.target=System.outlog4j.appender.cons.layout=org.apache.log4j.PatternLayoutlog4j.appender.cons.layout。ConversionPattern=%m%n属性文件是最常用的配置。在实际开发过程中,基本都是使用properties文件。pripertis配置文件的配置方法为:#配置日志级别,指定有效的Appender名称,AppenderA为定义的Appender名称log4j.rootLogger=loglevel,AppenderA,AppenderB,...#---------------Defineanappender------------------------#Defineanappender,appender名称可以任意,#如果要使用appender生效,必须在rootLogger的上一行加上,后面加上对应的Appender类log4j.appender.appendername=org.apache.log4j.ConsoleAppenderlog4j.appender.appendername.target=System.out#定义Appender的布局log4j.appender.appendername.layout=org.apache.log4j.SimpleLayout3.Logback简单来说,Logback是Java领域的一个日志框架。它被认为是Log4J的继承者。Logback是Log4j的升级,所以Logback自然比Log4j有很多优势。模块组成Logback主要由三个模块组成:logback-corelogback-classiclogback-accesslogback-core是其他模块的基础设施,其他模块都建立在其上。显然,logback-core提供了一些关键的通用机制。logback-classic的地位和作用相当于Log4J,也算是Log4J的改进版,实现了简单的日志门面SLF4J。logback-access主要作为与Servlet容器交互的模块,如Tomcat或Jetty,提供一些HTTP访问相关的功能。三个模块Logback组件Logback的主要组件如下:Logger:日志记录器;将其与应用程序的相应上下文相关联;主要用于存放日志对象;日志类型级别可以自定义。Appender:用于指定日志输出的目的地;目的地可以是控制台、文件、数据库等。Layout:负责将事件转化为字符串;输出格式化日志信息;在logback中,Layout对象被封装在编码器中。Logback优点Logback的主要优点如下:对于相同的代码路径,Logback执行速度更快。更彻底的测试。本机实现了SLF4JAPI(Log4J还需要一个中间转换层)。更丰富的文档。支持XML或Groovy配置。配置文件自动热加载。从IO错误中优雅地恢复。自动删除日志存档。自动将日志压缩成归档文件。支持Prudent模式,让多个JVM进程可以记录同一个日志文件。支持在配置文件中加入条件判断,以适应不同的环境。更强大的过滤器。支持SiftingAppender(可过滤的Appender)。带有包信息的异常堆栈信息。标签属性配置结构Logback的主要标签属性如下:configuration:配置的根节点。scan:为true时,如果配置文件属性发生变化,将扫描并重新加载。默认为真。scanPeriod:监控配置文件是否被修改的时间间隔。如果没有给出时间单位,默认单位为毫秒;默认时间为1分钟;当scan="true"时生效。debug:为true时,会显示logback的内部日志信息,实时查看logback的运行状态;默认值为false。contextName:上下文名称,默认为“default”,使用该标签设置其他名称以区分不同应用的记录;一旦设置,就不能修改。appender:configuration的子节点,负责写日志的组件,有两个必须的属性:name和class。name:加法器的名称。class:appender的全限定名,对应具体的Appender类名,如ConsoleAppender、FileAppender。append:为真时,日志附加到文件末尾。如果是flase,则清除现有文件。默认值是true。配置方式logback框架默认会加载classpath下名为logback-spring或logback的配置文件:[%d{yyyy-MM-dd''HH:mm:ss.sss}][%C][%t][%L][%-5p]%m%nERRORDENYACCEPT[%d{yyyy-MM-dd''HH:mm:ss.sss}][%C][%t][%L][%-5p]%m%n${LOG_INFO_HOME}//%d.log30错误<编码器>[%d{yyyy-MM-dd''HH:mm:ss.sss}][%C][%t][%L][%-5p]%m%n${LOG_ERROR_HOME}//%d.log304.ELKELK是软件集合Elasticsearch、Logstash、Kibana的缩写,由这三个软件及其相关组件组成可以创建一个大型的实时日志处理系统。增加了一个FileBeat,这是一个轻量级的日志收集和处理工具(Agent)。Filebeat占用资源少,适合收集各个服务器上的日志并传输到Logstash,官方也推荐这个工具。架构图Elasticsearch:是一个基于Lucene的分布式存储和索引引擎,支持全文索引。主要负责对日志进行索引存储,方便业务方检索查询。Logstash:是日志收集、过滤、转发的中间件。主要负责统一收集、过滤各个业务线的各种日志,并转发给Elasticsearch做进一步处理。Kibana:是一个可视化工具,主要负责查询Elasticsearch数据,并以可视化的方式呈现给业务方,比如各种饼图、直方图、面积图等。Filebeat:隶属于Beats,是一款轻量级的日志收集和处理工具。Beats目前包括四个工具:Packetbeat(收集网络流量数据)、Topbeat(收集系统、进程和文件系统级别的CPU和内存使用数据)、Filebeat(收集文件数据)、Winlogbeat(收集Windows事件日志数据)。主要特点一个完整的集中式日志系统需要包括以下几个主要特点:收集:可以从多个来源收集日志数据。传输:可以稳定地将日志数据传输到中央系统。存储:日志数据的存储方式。分析:可以支持UI分析。警告:能够提供错误报告、监控机制。ELK提供一整套解决方案,全部为开源软件,可以相互配合使用,完美衔接,高效满足多种场合的应用。目前主流的一个日志系统。应用场景在海量日志系统的运维中,以下几个方面必不可少:分布式日志数据的集中查询和管理。系统监控,包括系统硬件和应用组件的监控。故障排除。安全信息和事件管理。报告功能。ELK运行在分布式系统上。通过采集、过滤、传输、存储,对海量系统和组件日志进行集中管理和准实时搜索分析,并使用简单易用的搜索、监控、事件消息、报表等功能。帮助运维人员实时监控线上业务,及时定位业务异常原因,排查问题,跟踪分析程序开发、业务趋势分析、安全合规审计等过程中的BUG,深度挖掘日志的大数据价值。同时,Elasticsearch提供了多种API(RESTJAVAPYTHON等API)供用户扩展和开发,以满足不同的需求。配置方法filebeat配置,打开filebeat.yml,配置如下:#输入源,可以写多个filebeat.input:-type:logenabled:true#输入源文件地址path:-/data/logs/tomcat/*。log#多行正则匹配,匹配规则示例:2020-09-29,如果不是这样,则与上一条消息合并multiline:pattern:'\s*\['negate:truematch:after#Createanametags:["tomcat"]#Outputtarget,可以将logstash改为esoutput.logstash:hosts:[172.29.12.35:5044]logstash配置,新建一个.conf为后缀的文件,或者打开.conf下的文件config文件夹,这里的配置文件可以同时启动多个,还有一个强大的过滤功能,可以过滤原始数据,如下:#Inputsource(required)input{#Consoletypestdin{}#Filereadfile{#类似给定名称类型=>"info"#文件路径,可以用*表示所有路径=>['/usr/local/logstash-7.9.1/config/data-my.log']#第一次从t开始阅读从头开始,下次从上一个位置继续读取start_position=>"beginning"}file{type=>"error"path=>['/usr/local/logstash-7.9.1/config/data-my2.log']start_position=>"beginning"codec=>multiline{pattern=>"\s*\["negate=>truewhat=>"previous"}}#Usewithfilebatesbeats{port=>5044}}#OutputTarget(required)output{#判断类型是否相同if[type]=="error"{#如果是,则写入这个eselasticsearch{hosts=>"172.29.12.35:9200"#kibana根据索引名称查询,其中YYYY为动态获取的日期index=>"log-error-%{+YYYY.MM.dd}"}}if[type]=="info"{elasticsearch{hosts=>"172.29.12.35:9200"#kibana通过索引index的名字查询=>"log-info-%{+YYYY.MM.dd}"}}#judged这里filebates给出的tag是否是tomcatif"tomcat"in[tags]{elasticsearch{hosts=>"172.29.12.35:9200"#kibana通过索引index=>"tomcat"}}的名称查询#控制台会还打印信息stdout{codec=>rubydebug{}}}作者:浅木Eric编辑:陶家龙来源:转载自公众号浅叶的IT之家(ID:QY18804079159)