flume建立ElasticSearch索引时间的问题

本文转自:《flume建立ElasticSearch索引时间的问题》


本文解决的是Flume导入es中建立的索引时间问题,(index也就是索引在es可以类比为database数据库)


对于@timestamp在es中默认是UTC时区保存,不管flume导入的Date时区是多少,都会强制改为es中默认的时区,所以需要在kibana中设置显示的时区


Reference:http://kibana.logstash.es/content/logstash/plugins/filter/date.html



flume收集到的日志,采用ElasticSearch作为存储,运行一段时间后,发现每天早点八点才会创建索引文件,比北京时间晚了8个小时,导致0点到8点这段时间的数据并没有存储到今天的索引文件中,而是存储在前一天的索引中,当时以为数据丢失了,全文检索后发现数据被存在了前一天的索引文件中。首先确定系统的时间是准备的,基本定位到应该是flume自身创建索引的时候除了问题,查看源代码。

flume创建ElasticSearch索引文件的代码如下

?
1
2
3
4
5
6
7
8
if  (indexRequestBuilderFactory ==  null ) {
       indexRequestBuilder = client
           .prepareIndex(indexNameBuilder.getIndexName(event), indexType)
           .setSource(serializer.getContentBuilder(event).bytes());
else  {
       indexRequestBuilder = indexRequestBuilderFactory.createIndexRequest(
           client, indexNameBuilder.getIndexPrefix(event), indexType, event);
}

下面看indexNameBuilder.getIndexName(event)获取索引

?
1
2
3
4
5
6
7
@Override
   public  String getIndexName(Event event) {
     TimestampedEvent timestampedEvent =  new  TimestampedEvent(event);
     long  timestamp = timestampedEvent.getTimestamp();
     return  new  StringBuilder(indexPrefix).append( '-' )
       .append(fastDateFormat.format(timestamp)).toString();
   }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TimestampedEvent(Event base) {
     setBody(base.getBody());
     Map<String, String> headers = Maps.newHashMap(base.getHeaders());
     String timestampString = headers.get( "timestamp" );
     if  (StringUtils.isBlank(timestampString)) {
       timestampString = headers.get( "@timestamp" );
     }
     if  (StringUtils.isBlank(timestampString)) {
       this .timestamp = DateTimeUtils.currentTimeMillis();
       headers.put( "timestamp" , String.valueOf(timestamp ));
     else  {
       this .timestamp = Long.valueOf(timestampString);
     }
     setHeaders(headers);
   }

TimestampedEvent会先获取事件中的timestamp,如果事件中没有timestamp,就取当前的毫秒时间。

fastDateFormat会格式化timestamp,也就是生成索引后面的日期,如flume-2015-01-01,fastDateFormat默认会采用Etc/UTC时区,也就是会比北京时间晚8小时,北京时间早上8点,获取到的就是0点。

?
1
2
private  FastDateFormat fastDateFormat = FastDateFormat.getInstance( "yyyy-MM-dd" ,
       TimeZone.getTimeZone( "Etc/UTC" ));

另外可以通过配置文件来配置fastDateFormat的时区,我们采用即可

?
1
a1.sinks.k1.timeZone=Asia/Shanghai

使用ElasticSearch sink的时候,要加上上面这句话,这样就可以解决创建索引晚8小时的问题了。


猜你喜欢

转载自blog.csdn.net/yeruby/article/details/50982799