在Logstash中转换时间戳时区以获取输出索引名称

时间:2015-03-27 13:58:41

标签: ruby indexing elasticsearch timezone logstash

在我的场景中,Logstash接收的syslog行的“timestamp”是UTC格式,我们在Elasticsearch输出中使用事件“timestamp”:

output {
    elasticsearch {
        embedded => false
        host => localhost
        port => 9200
        protocol => http
        cluster => 'elasticsearch'
        index => "syslog-%{+YYYY.MM.dd}"
    }
}

我的问题是,在UTC午夜,Logstash在时区结束之前将日志发送到不同的索引(GMT-4 => America / Montreal),并且索引在20h(晚上8点)之后没有日志,因为“时间戳”是UTC。

我们已经完成了转换时区的工作,但我们遇到了显着的性能下降:

filter {
    mutate {
        add_field => {
            # Create a new field with string value of the UTC event date
            "timestamp_zoned" => "%{@timestamp}"
        }
    }

    date {
        # Parse UTC string value and convert it to my timezone into a new field
        match => [ "timestamp_zoned", "yyyy-MM-dd HH:mm:ss Z" ]
        timezone => "America/Montreal"
        locale => "en"
        remove_field => [ "timestamp_zoned" ]
        target => "timestamp_zoned_obj"
    }

    ruby {
        # Output the zoned date to a new field
        code => "event['index_day'] = event['timestamp_zoned_obj'].strftime('%Y.%m.%d')"
        remove_field => [ "timestamp_zoned_obj" ]
    }
}

output {
    elasticsearch {
        embedded => false
        host => localhost
        port => 9200
        protocol => http
        cluster => 'elasticsearch'
        # Use of the string value
        index => "syslog-%{index_day}"
    }
}

有没有办法优化此配置?

5 个答案:

答案 0 :(得分:10)

这是优化配置,请试试并测试性能。

您无需使用mutatedate插件。直接使用ruby插件。

input {
    stdin {
    }
}

filter {
    ruby {
            code => "
                    event['index_day'] = event['@timestamp'].localtime.strftime('%Y.%m.%d')
            "
    }
}

output {
    stdout { codec => rubydebug }
}

示例输出:

{
       "message" => "test",
      "@version" => "1",
    "@timestamp" => "2015-03-30T05:27:06.310Z",
          "host" => "BEN_LIM",
     "index_day" => "2015.03.29"
}

答案 1 :(得分:1)

在1.5.0版本中,我们可以按索引名称的本地时区转换时间戳。这是我的配置:

filter {
    ruby {
        code => "event['index_day'] = event.timestamp.time.localtime.strftime('%Y.%m.%d')"
    }
}
output {
    elasticsearch {
        host => localhost
        index => "thrall-%{index_day}"
    }
}

答案 2 :(得分:0)

在Logstash V5.0.2中,API已被修改。我们可以通过本地时区为时间戳转换索引名称。这是我的配置:

filter { 
   ruby { 
       code => "event['index_day'] = event.timestamp.time.localtime.strftime('%Y.%m.%d')" 
   } 
} 

答案 3 :(得分:0)

logstash version 5.0 and later中,您可以使用此功能:

filter{
ruby {
        code => "event.set('index_day', event.get('[@timestamp]').time.localtime.strftime('%Y%m%d'))"
    }
}

答案 4 :(得分:0)

类似的用例 - 但使用 logstash file output plugin 并写入以事件到达的当地时间为日期的文件。 已于 logstash version 7.12 验证。

改编自 discuss.elastic.co,主要是零填充偏移时间。注意!如果您的偏移量有半小时,则需要相应调整。

filter {
    ruby {
        code => "
        require 'tzinfo'
        tz = 'Europe/Oslo'
        offset = TZInfo::Timezone.get(tz).current_period.utc_total_offset / (60*60)
        event.set('[@metadata][local_date]',
                  event.get('@timestamp').time.localtime(
                      sprintf('+%02i:00', offset.to_s)
                  ).strftime('%Y%m%d'))
        "
    }   
    if ([agent][type] == "filebeat") {
        mutate {
            add_field => ["file_path", "%{[host][name]}_%{[log][file][path]}.%{[@metadata][local_date]}"]
        }  
    } else {   
        mutate {
            add_field => ["file_path", "%{[agent][hostname]}_%{[agent][type]}.%{[@metadata][local_date]}"]
        }
    }
}