没有年份的系统日志时间戳?

Syslog timestamp without year?

我正在将我的日志回填到 Elasticsearch 中。因此,为了按时间戳中的日志日期创建索引,我使用 date 过滤器,如下所示:

date {
                "locale" => "en"
                match => ["timestamp", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"]
                target => "@timestamp"
        }

我正在使用来自 syslog 的日志,而 syslog 时间戳格式没有年份:

# Syslog Dates: Month Day HH:MM:SS
SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}

所以使用日期过滤器后,创建的索引就像logstash-2015.12.26 如果我正在阅读 2014 年 12 月 26 日的日志。因此,由于日志中没有时间戳,因此它默认选择当前年份。

知道如何制作正确的索引吗?

Joda Time 解析的字符串中缺少年份,Logstash 当前默认为 Logstash 进程启动的年份。请参阅 github.com/logstash-plugins/logstash-filter-date bug #3. As a temporary workaround, add a temporary filter to append the correct year (2014) to the end of the timestamp field and adjust your date filter 模式以包含 YYYY。

filter {
  mutate {
    replace => ["timestamp", "%{timestamp} 2014"]
  }
  date {
    locale => "en"
    match => ["timestamp",
              "MMM  d HH:mm:ss YYYY",
              "MMM dd HH:mm:ss YYYY",
              "ISO8601"]
  }
}

如果您加载的日志文件的文件名中有年份,您可以使用 grok 过滤器提取它,创建一个新字段,其中包含您从系统日志中提取的日期加上文件名中的年份。

可以在此处找到有关如何从文件名中提取 date/time 的示例:Logstash: How to use date/time in a filename as an imported field

您可以使用日期过滤器将日期字符串转换为日期格式。默认情况下,当您使用日期过滤器时,日志的日期(或日期时间)将覆盖@timestamp。 所以,在你的过滤器中你不需要目标。如果你想将变量字符串转换为日期,你只需使用它。

示例: 匹配 => ["timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss", "ISO8601"]

使用 ruby 函数,我能够将日期动态设置为上一年(如果日志日期大于当前 YYYY)。读取并计算事件日期以查看其是否大于当前系统日期。如果是,减去 365 天,并覆盖时间戳。

ruby {
   code => 'require "date"
   am_date = "%b %d %H:%M:%S"
   parsed=DateTime.strptime(event.get("timestamp"), am_date)
   m_now=DateTime.now

 if parsed>m_now
    parsed=parsed-365
 else
    parsed=parsed
 end

 event.set("timestamp", parsed.to_s) '
}

这将防止对日期进行任何硬编码。