elasticsearch时间字段的处理

本文介绍如何确保Elasticsearch索引映射与Logstash解析的数据字段一致性,包括解决因字段名称不匹配导致的问题,以及配置Logstash从Redis读取JSON数据并将其正确导入ES的具体步骤。

首先,确报创建索引是的mapping字段和json写入的字段名称一致,否则会有意想不到的问题。刚开始,redis里的json字符串字段为regular_detail_hour,但是,我在创建索引时写的为:regular_detail_time。通过logstash写入到ES,并不报错,只是新建了一个叫regular_detail_hour的字段。
通过bean实例化了一个json,然后通过RedisTemplate

 ListOperations<String,String> liststring=redisTemplate.opsForList();
        liststring.rightPush(key,value);
        return(true);

写入到redis数据,list类型。
logstash会通过消息队列类型的操作去读取数据,读完就删。

input {
    redis {
             host => "172.19.112.4"
             data_type => "list"
             key => "di"
             type => "di"
          }
}

filter {
  if [type] == "di" {
    json { source => "message"}
    mutate { remove_field => ["message","tags"] }
    date { match => [ "rept_col_time", "yyyy-MM-dd HH:mm:ss" ]  
           target =>"@timestamp"
           locale => "en"  
           timezone => "+00:00"    
         }  
     }
}

output {
   if [type] == "di"{
    if "_grokparsefailure" not in [tags] and "_groktimeout" not in [tags]{
       elasticsearch {
         hosts => ["10.96.91.208:9200","10.96.91.209:9200","10.96.91.210:9200","10.96.91.211:9200"]
         index => "di"
      }
   }
  }
}

另一边,ElasticSearch,也进行日期类型的处理,必须和json字符串的格式一样,否则出错。

put di
{
   "mappings" : {
        "di" : {
                 "properties" : {
                                  "@timestamp": {"type": "date"},
                                  "@version": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},
                                  "rpt_id" : { "type" : "keyword" },
                                  "iiiii" : { "type" : "keyword" },
                                  "data_type" : { "type" : "keyword" },
                                  "rpt_arrive_time" : { "type" : "date","format": "yyyy-MM-dd HH:mm:ss"},
                                  "filename" : { "type" : "keyword" },
                                  "observe_time" : { "type" : "date","format": "yyyy-MM-dd HH:mm:ss" },
                                  "regular_detail_hour" : { "type" : "date" ,"format": "yyyy-MM-dd HH:mm:ss"},
                                  "bbb" : { "type" : "keyword" },
                                  "rept_validity" : { "type" : "short" },
                                  "rept_status" : { "type" : "short" },
                                  "rept_col_time" : { "type" : "date","format":"yyyy-MM-dd HH:mm:ss"},
                                  "data_source" : { "type" : "keyword" },
                                  "data_source_name" : { "type" : "keyword" },
                                  "part_day" : { "type" : "short" },
                                  "data_type_new":{"type" : "keyword"}
            }
        }
    }
}

至此结束

### 时区转换的基本原理 Elasticsearch 内部存储时间字段(如 `date` 类型字段)时,默认使用 UTC(即 GMT+0)时区。当在 Kibana 或其他前端工具中展示这些时间戳时,如果设置了本地时区(如 `Asia/Shanghai`),Elasticsearch自动将 UTC 时间转换为指定时区的时间进行展示。然而,如果数据源(如 Logstash 或业务系统)在写入时未正确处理时区,可能导致时间显示偏差[^1]。 ### 时间字段的时区配置方法 #### 1. 在索引映射中定义时间字段的格式与时区 Elasticsearch 支持在索引映射中定义字段的日期格式,虽然映射中不能直接指定时区,但可以确保字段被正确解析为 `date` 类型,为后续查询时区转换打下基础。例如: ```json { "mappings": { "properties": { "timestamp": { "type": "date", "format": "yyyy-MM-dd HH:mm:ssZ" } } } } ``` 该配置确保 `timestamp` 字段被解析为日期类型,并支持带时区偏移的格式输入[^3]。 #### 2. 查询时使用 `script` 字段进行时区转换 在查询阶段,可以使用 Painless 脚本语言将 UTC 时间转换为目标时区。例如,将 `timestamp` 字段转换为 `Asia/Shanghai` 时区: ```json { "script_fields": { "localized_time": { "script": { "source": "doc['timestamp'].value.withZoneSameInstant(ZoneId.of('Asia/Shanghai'))" } } } } ``` 此方式在返回结果中生成一个新字段 `localized_time`,其值为本地时区时间。 #### 3. 在 `date_histogram` 聚合中指定时区 当进行时间聚合时,可通过 `time_zone` 参数指定聚合所使用的时区,确保聚合结果基于本地时间进行计算: ```json { "size": 0, "aggs": { "events_over_time": { "date_histogram": { "field": "timestamp", "calendar_interval": "day", "time_zone": "+08:00" } } } } ``` 该配置将按 UTC+8 的时间进行每日聚合。 #### 4. Kibana 中设置默认时区 Kibana 提供了全局时区设置,可以在界面中选择时区,确保时间字段在图表和日志展示中正确反映本地时间。该设置不会影响 Elasticsearch 内部存储时间,仅用于前端展示: - 进入 Kibana → Stack Management → Advanced Settings - 设置 `dateFormat:tz` 为 `Asia/Shanghai` 或其他目标时区 此方式适用于希望统一展示时区而不修改数据源或查询逻辑的场景。 #### 5. 数据写入阶段处理时区 如果数据源(如 Logstash)在写入时间戳时已包含时区信息,则应确保其格式与 Elasticsearch 映射中的 `date` 格式一致。例如,使用 `yyyy-MM-dd HH:mm:ssZ` 可确保时区偏移被正确识别和存储: ```python import time timestamp = 1462451334 time_local = time.localtime(timestamp) dt = time.strftime("%Y-%m-%d %H:%M:%S%z", time_local) print(dt) # 输出格式为 2016-05-05 20:28:54+0800 ``` 此方式确保时间戳在写入时已包含时区信息,便于后续转换[^2]。 ### 综合建议 - **数据写入时**:确保时间字段格式包含时区信息,或使用 UTC 标准时间。 - **索引映射中**:定义 `date` 类型字段并指定支持的日期格式。 - **查询阶段**:根据需求使用 `script` 或 `time_zone` 参数进行本地时区转换。 - **前端展示**:在 Kibana 中设置默认时区,确保统一展示效果。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值