通过关键词采集文章采集api(JAVA通过代码如何使用MDC进行日志打印(output输入插件))

优采云 发布时间: 2021-10-30 18:12

  通过关键词采集文章采集api(JAVA通过代码如何使用MDC进行日志打印(output输入插件))

  我是目录

  审查

  前两篇文章简单介绍了JAVA如何通过代码使用MDC打印日志,查看log4j MDC用户操作日志跟踪配置,以及ELK平台的搭建,查看log4j MDC用户操作日志跟踪配置. 接下来结合实际案例,简单介绍一下logstash采集是如何处理生产服务器的日志的,并统一总结一下,让大家快速、方便、高效的查询日志找到日志。如果是生成服务器,就没有必要盲目的遍历所有生产服务器,只为找出有问题的机器。

  logstash 日志采集

  因为我们打印的日志是多种多样的,为了方便我们通过kibana检索,需要在logstash中配置相应的采集规则。如果你什么都不做,只是简单地采集,一些意想不到的事情可能会出现错误。

  日志采集是按行采集的。当你的日志出现换行时,换行的那一行被认为是单独的一行,所以采集收到的日志可读性很差。如果你使用它,MDC 配置了 log4j 日志格式输出。如果没有规则,一整行将 采集 到消息字段。这时候,你基本上不可能根据某个领域进行快速搜索。

  基于以上可能出现的“错误”,我们需要针对当前项目的日志配置文件制定一套自己的采集规则。

  其实logstash的配置文件很简单,基本就是下面几个套路,日志源从哪里来(输入输入插件),什么样的规则(过滤过滤插件),最后输出日志到哪里(输出输出插件)

  # 输入

input {

...

}

# 过滤器

filter {

...

}

# 输出

output {

...

}

  因为我们这里介绍的是项目日志的采集,所以输入当然是来自file文件,配置如下:

  input {

file {

type => "wechat-log"

path => ["/usr/local/tomcat/logs/wechat/*.log"]

codec => multiline{

pattern => "^\[%{TIMESTAMP_ISO8601}\]"

what => "previous"

negate => true

}

start_position => "beginning"

}

}

  其中path为日志采集所在的地方,从日志文件采集的第一行开始,定义一个类型(通常最后是kibana的索引)。

  编*敏*感*词*插件

  这里的编*敏*感*词*的出现可以解决我们前面提到的日志换行等问题。读入logstash时,通过codec编码将日志解析成对应的格式,从logstash输出时,通过codec解码成对应的格式。当我们的应用打印出有换行符的日志时,比如ERROR日志,通常会有一个错误堆栈信息,并且各种以at开头的行,我们可以通过multiline进行处理,让logstash认为这一行属于内容上一行的。而不是将其视为新行。

  一般我们的tomcat日志都是以time开头的,没有at之类的栈信息的时间,所以我们可以配置正则表达式[^[%{TIMESTAMP_ISO8601}]],只有以time开头的一行才被认为是新的一行。不是时间开始的那个属于前一个[what=>previous]或下一个[what=>next]。在这里,我们的配置属于上一个。

  上面的配置解决了换行问题之后,接下来我们还需要处理日志分字段。

  插件

  在grok中,通过正则表达式提取日志信息。其中,正则表达式分为两种,一种是内置正则表达式,另一种是自定义正则表达式,当内置正则表达式不能满足我们的需求时,就不得不使用自定义正则表达式表达式,但内置的基本满足我们的需求。详情请查看grok介绍

  假设我们的日志配置文件是这样配置的:

  我们设置了商户、openid、queryType、orderId、wechatOrderId、input、source 7个字段。生产服务器打印的日志格式如下:

  [2019-01-27 17:51:22.051] - iPhoneBaoXiu - oisb3smtzToo7jNA4abazKktnECQ - senior - aa4820190127175110 - 4200000283201901277968491434 - 352982093855677 - 1 - INFO com.apple.wechat.service.Worker:401 - 发送模板消息,查询结果为:[email protected]

[2019-01-27 17:51:22.230] - iPhoneBaoXiu - oisb3smtzToo7jNA4abazKktnECQ - senior - aa4820190127175110 - 42000002832019277968491434 - 352982093855677 - 1 - ERROR me.chanjar.weixin.mp.api.impl.WxMpServiceImpl:403 -

[URL]: https://api.weixin.qq.com/cgi-bin/message/template/send

[PARAMS]: {"touser":"olC5FwLnXjtCbQsW76lkevV57nH0","template_id":"Qt1zyzQs4R1uPrJylGQLSUTS6QcG6UyWB2zDzGt7QGY","url":"http://mp.weixin.qq.com/bizmall/mallshelf?id=&t=mall/list&biz=MjM5OTAxMzk4MQ==&shelf_id=7&showwxpaytitle=1#wechat_redirect","data":{"first":{"value":"查询结果","color":"#B452CD"},"keyword1":{"value":"aa4820190127175110","color":"#FF4040"},"keyword2":{"value":"352982093855677","color":"#FF4040"},"keyword3":{"value":"1.00元","color":"#FF4040"},"remark":********************}

[RESPONSE]: {"errcode":40003,"errmsg":"invalid openid hint: [mLJNpa06824120]"}

[2019-01-27 17:51:22.230] - iPhoneBaoXiu - oisb3smtzToo7jNA4abazKktnECQ - senior - aa4820190127175110 - 4200000283201901277968491434 - 352982093855677 - 1 - ERROR com.apple.wechat.service.Worker:405 - 发送模板消息失败,{"errcode":40003,"errmsg":"invalid openid hint: [mLJNpa06824120]"}

[2019-01-27 17:51:22.231] - iPhoneBaoXiu - oisb3smtzToo7jNA4abazKktnECQ - senior - aa4820190127175110 - 4200000283201901277968491434 - 352982093855677 - 1 - INFO com.apple.wechat.service.RefundService:57 - 开始发起退款,退款订单id:2056653,微信订单号:4200000283201901277968491434

[2019-01-27 17:51:22.463] - - - - - - - - INFO com.apple.wechat.service.Worker:94 - 执行任务:QueryTask{msg='C39XQ4NFKPGN', fromUserId='oOEvtjsGdmAKrZx81zsACqBjjdsA', merchant='MLdress', type='senior', authUserId='olC5FwH40UpZakKBZRls_t_HR9Ew', price='1.00', tradeNo='e50b20190127175115', model='', orderId=2056654, needRefund=false, needRedo=false, sendMsg=false, msgType='1', lat='', lon='', token='e50ba187b2f84297b60fc14699748679', wechatOrderNo='4200000269201901277039023012'}

[2019-01-27 17:51:23.327] - iPhoneBaoXiu - oisb3smtzToo7jNA4abazKktnECQ - senior - aa4820190127175110 - 4200000283201901277968491434 - 352982093855677 - 1 - INFO com.apple.wechat.service.RefundService:97 - 退款结果:success, 实付金额:1.00,发起退款金额:1.00

[2019-01-27 17:51:26.876] - - - - - - - - INFO com.apple.wechat.service.Worker:94 - 执行任务:QueryTask{msg='C39T81JEHG01', fromUserId='oOEvtjotDEF8doO3xVxyJ0-dCqFM', merchant='MLdress', type='normal', authUserId='', price='', tradeNo='', model='', orderId=0, needRefund=false, needRedo=false, sendMsg=false, msgType='1', lat='', lon='', token='', wechatOrderNo=''}

[2019-01-27 17:51:28.003] - MLdress - oOEvtjsGdmAKrZx81zsACqBjjdsA - senior - e50b20190127175115 - 4200000269201901277039023012 - C39XQ4NFKPGN - 1 - INFO com.apple.wechat.util.HttpUtils:125 - http execute cost total seconds 5540

  我们可以使用下面的正则表达式对日志进行切割,并将内容分配到对应的字段

  filter {

grok {

match => ["message", "\[%{TIMESTAMP_ISO8601:logdate}\] - (?[\b\w\s]*) - (?[\u4e00-\u9fa5\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - %{WORD:level}\s*%{JAVACLASS:class}:%{NUMBER:lineNumber} - (?[\W\w\S\s]*)"]

}

date {

match => ["logdate", "yyyy-MM-dd HH:mm:ss.SSS"]

target => "@timestamp"

}

}

  (? [\b\w\s]*) 表示利用[]中的正则性把识别结果放到商户领域,其他同理。至于这里怎么写匹配,跟你的日志配置文件和你想要的效果有很大关系,所以只能慢慢调试,直到你写的匹配可以正确剪出你的日志文件。在线测试你的正则表达式是否可以匹配项目输出日志测试工具门户

  完整的配置文件

  input {

file {

type => "wechat-log"

path => ["/usr/local/tomcat/logs/wechat/*.log"]

codec => multiline{

pattern => "^\[%{TIMESTAMP_ISO8601}\]"

what => "previous"

negate => true

}

start_position => "beginning"

}

}

filter {

grok {

match => ["message", "\[%{TIMESTAMP_ISO8601:logdate}\] - (?[\b\w\s]*) - (?[\u4e00-\u9fa5\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - (?[\b\w\s]*) - %{WORD:level}\s*%{JAVACLASS:class}:%{NUMBER:lineNumber} - (?[\W\w\S\s]*)"]

}

date {

match => ["logdate", "yyyy-MM-dd HH:mm:ss.SSS"]

target => "@timestamp"

}

}

output {

elasticsearch {

hosts => "**************:9200"

index => "logstash-%{type}"

template_overwrite => true

}

}

  保存后启动logstash。命令:

  nohup ./bin/logstash agent -f config/log.conf &

  kibana操作首先是创建索引,因为我们的输出配置了logstash-%{type}的索引,所以索引为:logstash-wechat-log。创建索引后,我们可以发现kibana列出了我们之前定义的字段。,如下所示。

  

  接下来,我们可以通过各种条件搜索日志。

  假设我们要搜索商户MLdress,用户输入3565的日志信息,那么我们只需要输入[merchant:MLdress AND input: 3565]就可以搜索到对应的日志,如下图。

  

  总结

  通过在代码中使用MDC进行标准化的日志打印,结合logstash提供的强大的日志采集插件,我们可以将所有服务器的日志统一上报给es,并通过kibana进行自检操作,只有这样,才能大大提高日常开发的效率。除了程序员写代码的能力,另一个加分项必须是快速发现和定位问题的能力。如果没有ELK这样的工具,其实更难快速发现和定位问题。

  所以,你知道,现在使用它。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线