Problema creación de patrón personalizado para fechas en logstash

Buenos días.
Estoy intentando configurar logstash para que obtenga la fecha del campo message de aquellos logs que tengan un formato distinto al de la norma ISO8601 pero no lo consigo.
Un ejemplo de fecha obtenido de un servidor redis es el siguiente:
8934:C 08 Jun 09:56:08.954 * DB saved on disk
y el archivo de configuración de logstash que hice es el siguiente:

input {
   pipeline { address => redis }
}

filter {
   grok {
    match => { "message" => "(?<fecha>%{MONTHNUM} %{MONTH} %{HOUR}:%{MINUTE}:%{SECOND})"}
    tag_on_failure => ["no_date_found"]
    target => "fecha"
   }
   date {
     match => [ "fecha", "dd EEE HH:mm:ss"]
     target => "@timestamp"
     tag_on_failure => ["_dateparsefailure"]
   }

   mutate {
      add_field => { "[custom_index_name]" => "filebeat-logstash-%{[fields][name]}-%{+YYYY.MM.dd}" }
   }
}

output {
  pipeline { send_to => elasticsearch }
}

¿Qué cambios tendría que hacer para que reconociese la fecha desde el campo message y estableciese dicha fecha en el campo @timestamp ?
¡Gracias de antemano!

Hola Miguel,

Creo que tienes un par de temas allí. El principal que no hay año en la fecha. Así que sugiero que lo añadas "fijo", si no se puede obtener de la fuente. En el ejemplo concateno un 2021.

En vez de grok yo usaría dissect, que suele ser más eficiente además.

Y finalmente el formato de la fecha también debería cambiar, tenías EEE en vez de MMM para el mes y faltaba .SSS. Si pueden venir varios formatos, los pueddes añadir al match en la fecha.

Ejemplo de pipeline:

input {
    stdin {
        codec => plain
    }
}

filter {
   dissect {
    mapping => {
      "message" => "%{} %{fecha} %{+fecha} %{+fecha} %{other}"
      }
    tag_on_failure => ["no_date_found"]
   }
   
   mutate {
     replace => { "fecha" => "%{fecha} 2021" }
   }

   date {
     locale => "en"
     match => [ "fecha", "dd MMM HH:mm:ss.SSS YYYY"]
     target => "@timestamp"
     tag_on_failure => ["_dateparsefailure"]
   }
}

output {
    stdout { codec => rubydebug }
}

Este pipeline con 8934:C 08 Jun 09:56:08.954 * DB saved on disk como entrada, devolvería:

{
         "other" => "* DB saved on disk",
    "@timestamp" => 2021-06-08T07:56:08.954Z,
          "host" => "localhost",
         "fecha" => "08 Jun 09:56:08.954 2021",
       "message" => "8934:C 08 Jun 09:56:08.954 * DB saved on disk",
      "@version" => "1"
}

Espero que te sea útil.

Saludos!

Muchas gracias Imma!

1 Like