1 月 042018
 

最近研究elasticsearch,其实是filebeat+logstah+es+kinbana+hdfs集群,发现了很多的坑,譬如时区问题,字段问题,写入hdfs问题,等等。现在做下总结,方便以后查阅:

1,时区问题:

默认解析时间是UTC0,其实用es没啥问题,但是hdfs采集的时候需要争取的时间,所以要对时间进行处理,调换到UTC+8,配置如下(规则一般都是在filter里面添加):

date{
               match=>[“tmstp”, “UNIX_MS”]
               target=>”@timestamp”
}
ruby {  
  code => “event.set(‘timestamp’, event.get(‘@timestamp’).time.localtime + 8*60*60)”  
     }

这样’timestamp’获取的时间就是正确8时区的时间。

如果想把@timestamp 也换掉,就可以替换掉:

ruby {
   code => “event.set(‘@timestamp’,event.get(‘timestamp’))”
}

由于我不希望@timestamp 设置成8时区,但是又想要正确的时间路径,所以自行设置了变量:

date{
                match=>[“tmstp”, “UNIX_MS”]
                target=>”@timestamp”
  }
ruby {  
   code => “event.set(‘timestamp’, event.get(‘@timestamp’).time.localtime + 8*60*60)”  
      }

ruby {
   code => “event.set(‘timestamp1’, event.get(‘@timestamp’))”
}
ruby {
   code => “event.set(‘@timestamp’,event.get(‘timestamp’))”
}

mutate {
          add_field => {
            “datapath”=>”%{+yy-MM}/%{+dd}/%{+HH}”
            “service_type” => “%{service_type1[6]}_access”
          }

       }

ruby {
   code => “event.set(‘@timestamp’, event.get(‘timestamp1’))”
}
mutate {
          remove_field => [“service_type1″,”timestamp1″,”timestamp”]
       }

以上就满足hdfs获取的写入路径是北京时间的格式,@timestamp还是UTC的0时区。

2:json处理

由于我们的日志格式是:

2018-01-04 12:17:59,872 AM GMT+08:00 INFO  – {“p”:”SP”,”ser”:3,”tmstp”:1514996279872,”serip”:”172.23.89.7″,”logtp”:2,”fip”:”/172.23.89.5:58111″}

需要对数据进行处理截取{}作为json格式,前面都需要丢弃。

需要自定义规则,跟之前的nginx日志一样:

[root@emr-worker-1 logstash-6.1.1]# cat vendor/bundle/jruby/2.3.0/gems/logstash-patterns-core-4.1.2/patterns/chat
CHATLOG \{(.*)\}
定义了CHATLOG 格式日志。

grok {
      match => { “message” => “%{CHATLOG:chatlog}” }
  }

这样就对message做了json截取。然后解析下

json {
       source => “chatlog”
   }

这样就变成了纯json格式的日志。

2:写入hdfs的问题

写入经常冲突,后来发现应该每个logstash写入到hdfs最好不是同一个文件,

output {
#     stdout { codec => rubydebug }
if [p] {
     webhdfs {
        host => [“172.23.89.33”]              
        port => 50070                     
        path => “/liaobei/logdata/%{service_type}/%{datapath}/data01-access.log”
        user => “hadoop”                     
        compression => “snappy”
        codec => line {format => “%{chatlog}”} 
      }
     }
}

最好抛出掉json异常(个人觉得这个其实没用)

if  “_jsonparsefailure” in [tags] {
    drop { }
  }

不过后面其实发现是因为我补充的日志,没对service_type做说明,造成service_type没办法获取,才造成的hdfs的写入报错。这点也要注意,因为补充日志的时候,我随便弄个文件,造成了路径获取错误,造成了service_type没办法获取。

mutate {
         add_field=>{“service_type1″=>”%{source}”}
       }

mutate {
          split => [“service_type1” , “/”]
}

mutate {
          add_field => {
            “datapath”=>”%{+yy-MM}/%{+dd}/%{+HH}”
            “service_type” => “%{service_type1[6]}_access”
          }

       }

所以之后的php一直没报错,PHP是因为service_type写死的,所以补充日志也写死了。所以没有报错。只有chat的日志报错。

当然由于后面没有时间验证,就没做重现。大概就是这个问题。

3:kafka和es的坑

kafka主要是 php那边有大的日志写入,会报The request included a message larger than the max message size the server will accept。这个不算坑,只能说我们的日志实在是太大了,不合理。

修改配置

message.max.bytes=10240000
fetch.message.max.bytes=10240000

让kafka接受的消息更大。

 

es的话,是一个index的识别创建有问题。原因还没查明,估计是程序的BUG。我发现es5.5和6.1都有这个报错。

报错如下:

[2018-01-04T14:15:24,625][WARN ][logstash.outputs.elasticsearch] Could not index event to Elasticsearch. {:status=>400, :action=>[“index”, {:_id=>nil, :_index=>”logstash-2018.01.04″, :_type=>”chat_log”, :_routing=>nil}, #<LogStash::Event:0x44960714>], :response=>{“index”=>{“_index”=>”logstash-2018.01.04”, “_type”=>”chat_log”, “_id”=>”AWC_z1Sxlwnz255tEaZZ”, “status”=>400, “error”=>{“type”=>”mapper_parsing_exception”, “reason”=>”failed to parse [verbose]”, “caused_by”=>{“type”=>”illegal_state_exception”, “reason”=>”Can’t get text on a START_OBJECT at 1:174”}}}}}

是说verbose无法json解析(failed to parse [verbose])。但是flume传过来的都是json格式,而且有的更加复杂的json格式都没报错,我当时怀疑是不是verbose字段的问题。所以我更换了名字变成php_verbose。就不再报错。本来怀疑是不是历史创建的索引有问题,但是尝试过删除所有的数据和索引,即使没有verbose的index,也一样报错。我也怀疑版本问题,但是升级logstash 和 es都无法解决问题。目前推测就是  这个字段是系统的字段,有特殊处理。以前遇到过类似情况,譬如@timestamp。后面有空可以查下,目前就是更换字段,就不再报错。

image

if [verbose]  {
     mutate {
         add_field => { “php_verbose”=>”%{verbose}” }
         remove_field => [“verbose”]
            }
}

由于chat日志没有verbose字段,所以在改名之前,还做了字段存在判断。

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理

This website stores cookies on your computer. These cookies are used to provide a more personalized experience and to track your whereabouts around our website in compliance with the European General Data Protection Regulation. If you decide to to opt-out of any future tracking, a cookie will be setup in your browser to remember this choice for one year.

Accept or Deny