背景:
目前项目日志使用hsfs收集离线日志,在实时日志查询方面需要录入以方便更好的排查问题和统计情况。
当前项目日志收集方式使用 flume
-> hdfs
实时日志通过flume sink
存储至ElasticSearch
集成过程中遇到日期类型问题
为什么会需要时间类型:在kibana中,如果需要将日志和时间挂钩,例如查询近三天的日志,以及按天分类统计等功能,需要一个索引至少有一个时间类型的字段才能做到,故需要使用日志的生成时间。
- 当索引不存在时,es将会根据客户端的数据进行类型自动推断,例如将date的时间戳推断成long类型。
- kibana对无时区的时间索引会相差8小时。
解决问题:
问题1-时间类型自动推断解决
由于日志索引我们设置的按天创建,所以无法批量生成索引的设置,除非设置定时任务提前生成明天的索引字段设置,but 太麻烦且不易维护,通过查阅ElasticSearch的文档可以使用以下解决方案:
引入index template
方案,在索引未创建客户端调用 **POST **生成数据时,根据预定义的index template去设置索引,参考文档:index-templates
问题2- 时区问题
当收集的日志中不含时区的时间字符串时,es在实际入库中会按照utc时区0进行存储。由于kibana读取浏览器默认的时区时中国区的用户会读取为+08,造成查询数据的时间不一致,那么这个问题有以下几种办法解决:
- 从源头日志上追加时区标记
- 修改kibana时区设置写死为0
- 使用ElasticSearch的Ingest pipelines
最终我这边采用方案为3,通过ingest pipelines,在写入数据的时候设置好时区字段
index template示例:
PUT _index_template/template_logs
{
"index_patterns": ["xxxlogs*"],
"template": {
"settings":{
"default_pipeline":"zone8pipeline"
},
"mappings": {
"properties" : {
"date" : {
"type" : "date",
"format":"yyyy-MM-dd HH:mm:ss"
}
}
}
}
}
Ingest pipelines
PUT _ingest/pipeline/zone8pipeline
{
"description": "set timezone",
"processors": [
{
"date" : {
"field" : "date",
"target_field" : "timestamp",
"formats" : ["yyyy-MM-dd HH:mm:ss.SSS"],
"timezone": "Asia/Shanghai"
}
}
]
}