Есть ли способ разобрать сообщения журнала с помощью config rsyslog и преобразовать их в структурированные сообщения? - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь проанализировать сообщения журнала и преобразовать их в структурированные сообщения с помощью rsyslog.Есть ли способ поддержки такой работы с конфигом rsyslog?Я еще не исследовал возможность написать собственный анализатор или плагин для модификации сообщений.

Я нашел свойства списка шаблонов , которые могут с этим справиться.Есть ли способ сделать следующее?

  1. Сопоставить 2 поля с одним выходным именем.Пример: "__ts": "2018-09-20 10: 18: 56.363" (первые 2 поля в примере ниже).Не использовал бы здесь регулярные выражения, так как я ищу решение, которое не зависит от значения полей.Пример: два поля могут быть двумя строками или некоторыми другими значениями, а не просто датами.
  2. Извлечь то, что осталось в сообщении после извлечения всех известных полей на основе позиции.Пример: "msg": "Отмена регистрации приложения nameOfAnApiHere с someOtherName со статусом DOWN".
  3. Есть ли способ использовать локальные переменные для хранения значений полей из msg и использования переменных в шаблонах?

Пример Сообщение в журнале:

2018-09-20 10: 18: 56.363 INFO --- [Thread-68] xyzkey1Value Отмена регистрации имени приложенияOfAnApiHere с someOtherNameсо статусом ВНИЗ

1.Определение шаблона конфигурации rsyslog

template(name="structure-log-format" type="list") {
  constant(value="{")

  # This only extracts the first field with value 2018-09-20.
  # TODO: What is a way to map first 2 fields to map to __ts field? 
  property(outname="__ts" name="msg" field.number="1" field.delimiter="32" format="jsonf") constant(value=", ")

  constant(value="\"event\":[{")
    constant(value="\"payload\":{")
        property(outname="_log_" name="syslogtag" format="jsonf") constant(value=", ")
        property(outname="__loglvl" name="msg" field.number="4" field.delimiter="32" format="jsonf") constant(value=", ")
        property(outname="__thread" name="msg" field.number="7" field.delimiter="32" format="jsonf") constant(value=", ")
        property(outname="__key1" name="msg" field.number="8" field.delimiter="32" format="jsonf") constant(value=", ")
        # The following setting will include full message value starting from "2018-09-20 ... DOWN"
        # TODO: What is a way to only include message starting from "Unregistering ... DOWN"?
        property(name="msg" format="jsonf" droplastlf="on" )
    constant(value="}")
constant(value="}]} \n")

}

2.Ожидаемый результат:

{
   "__ts": "2018-09-20 10:18:56.363",
   "event": [
       {
          "payload": {
             "_log_": "catalina",
             "__loglvl": "INFO",
             "__thread": "Thread-68",
             "__key1": "x.y.z.key1Value",
             "msg": "Unregistering application nameOfAnApiHere with someOtherName with status DOWN"
          }
       }
     ]
}

3.Фактический результат:

{
   "__ts": "2018-09-20",
   "event": [
       {
          "payload": {
             "_log_": "catalina",
             "__loglvl": "INFO",
             "__thread": "Thread-68",
             "__key1": "x.y.z.key1Value",
             "msg": "2018-09-20 10:18:56.363  INFO 2144 --- [Thread-68] x.y.z.key1Value Unregistering application nameOfAnApiHere with someOtherName with status DOWN"
          }
       }
     ]
}

Спасибо.

1 Ответ

0 голосов
/ 04 октября 2018

Вы также можете использовать регулярные выражения для сопоставления частей сообщения.Например, замените свойство outname="__ts" на:

 property(outname="__ts" name="msg" 
  regex.expression="([^ ]+ +[^ ]+)" 
  regex.type="ERE" 
  regex.submatch="1" format="jsonf")

Здесь расширенное регулярное выражение (ERE) ищет не-пробел ([^ ]) одного или нескольких из них (+), а затемпробелом или более, и другим не пробелом.Эти 2 слова перехвачены () как подсправка, и вы выбираете это, считая от 1. Результат должен быть таким, как вы хотите.

Вы также можете использовать регулярное выражение для второго требования, либосчитая "слова" и пробелы снова, или какое-то более точное другое совпадение.Здесь регулярное выражение пропускает 6 слов, помещая счетчик повторений {6} после шаблона слов и пробелов, а затем захватывает остальные (.*).Поскольку существует 2 набора (), то оставшееся до этого совпадение теперь равно 2, а не 1:

 property(name="msg" 
  regex.expression="([^ ]+ +){6}(.*)" 
  regex.type="ERE" 
  regex.submatch="2" format="jsonf" droplastlf="on" )
...