Я работаю над приложением Python, в котором хочу отправлять журналы в стек ELK. Однако я изо всех сил пытаюсь добавить настраиваемые поля в записи журнала, чтобы они отображались в Kibana как отдельные поля, а не только внутри поля «сообщение». Я относительно новичок в стеке ELK, поэтому буду признателен за любые рекомендации.
Я пробовал использовать собственные средства форматирования, но все поля по-прежнему оказываются внутри поля «сообщение» в Kibana. Вот мой текущий скрипт Python:
import logging
from logstash_async.formatter import LogstashFormatter
try:
import json
except ImportError:
import simplejson as json
from logstash_async.handler import AsynchronousLogstashHandler
class CustomLogstashFormatter(LogstashFormatter):
def format(self, record):
log_record = {
"timestamp": self._format_timestamp(record.created),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
"filename": record.pathname,
"funcName": record.funcName,
"appName": "MyPythonApp"
}
if record.exc_info:
log_record['exception'] = self._format_exception(record.exc_info)
return json.dumps(log_record)
def activate_logging() -> None:
logstash_handler = AsynchronousLogstashHandler("0.0.0.0", 5000, database_path=None)
logstash_handler.setFormatter(CustomLogstashFormatter())
logging.basicConfig(
level=logging.INFO,
force=True,
handlers=[logstash_handler]
)
Несмотря на эту настройку, все поля журнала отображаются вложенными в поле «сообщение».
Я исследовал и нашел несколько предложений по изменению файла logstash.conf для правильного анализа полей журнала, но в данный момент я не могу изменить конфигурацию Logstash.
Есть ли способ достичь своей цели прямо из приложения?
Любая помощь или руководство будут очень признательны.
Оказалось, что на самом деле единственный способ — обновить файл logstash .conf. Чего я не хотел, так это добавлять фильтры или плагины, но на самом деле это просто проблема того, как я определил входную часть. Моя конфигурация была следующей:
input {
tcp {
port => 5000
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
}
}
Поскольку кодек не был указан, данные обрабатывались как обычный текст. Обновив его до следующего значения, ему удается распаковать «сообщение» по полям.
input {
tcp {
port => 5000
type => syslog
codec => json_lines
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
}
}