本文转自:《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小时的问题了。