#elasticsearch #logstash #grafana #fluentd
#elasticsearch #logstash #графана #fluentd
Вопрос:
Использование Grafana 7.2 и Elasticsearch 7.5.1.
Все запущено и запущено в Openshift. Источник данных Elasticsearch настроен правильно, и создана очень простая панель мониторинга.
Из службы Springboot, также работающей в Openshift, я отправляю журналы в Elasticsearch с помощью Fluentd.
Документы, хранящиеся в Elasticsearch, выглядят следующим образом (взяты из панели результатов Grafana «Журналы»):
Отредактировано: следуя предложению @karan shah, я добавляю исходный журнал, который отправляю в Elastichsearch через Fluentd:
{
"onpay":{
"traceId":"9999",
"inout":"OUT",
"startTime":"2020-10-01T10:13:43.806 0200",
"finishTime":"2020-10-01T10:13:43.827 0200",
"executionTime":21.0,
"entrySize":124.0,
"exitSize":124.0,
"differenceSize":0.0,
"user":"pgallello",
"methodPath":"http://localhost:8083/api/serviceEntryPoint",
"errorMessage":null,
"className":"com.myorganization.mypackage.MyController",
"methodName":"serviceTemplateEntryPoint"
}
}
Это документ Elasticsearch с полем «сообщение», на котором я хочу основать свою панель мониторинга.
Обратите внимание на две вещи на этом этапе:
- Поле отмечено красным: время выполнения.
- Поле _source просто имеет значение [object Object] .
Проблема 1:
Что мне нужно сделать (и я не получаю), так это сложная часть: мне нужно получить гистограмму, показывающую среднее значение значения поля ExecutionTime для каждого интервала.
Следуя официальной документации, в частности этому официальному видео от Grafana, я должен иметь возможность изменить группу по полю на среднее значение и выбрать @value из селектора полей. К сожалению, это значение @value там не отображается (может _source = [object Object]
быть, поле имеет какое-то отношение?)
Проблема 2:
Другое сомнение заключается в том, является ли поле запроса допустимым в этом формате или каков способ доступа к полю ExecutionTime, которое находится внутри поля сообщения внутри документа Elasticsearch. В какой-то иерархии message -> onpay -> executionTime
.
Конфигурационный файл Fluentd:
<source>
@type forward
port 24224
bind "0.0.0.0"
</source>
<filter onpayapp.**>
@type parser
key_name "onpayapp"
reserve_data true
<parse>
@type "json"
</parse>
</filter>
<match onpay.**>
@type copy
<store>
@type "elasticsearch"
host "elasticdb"
port 9200
logstash_format true
logstash_prefix "applogs"
logstash_dateformat "%Y%m%d"
include_tag_key true
type_name "app_log"
tag_key "@log_name"
flush_interval 1s
<parse>
@type json
</parse>
<buffer>
flush_interval 1s
</buffer>
</store>
<store>
@type "stdout"
</store>
</match>
Ответ №1:
В настоящее время у вас есть весь json в виде строки в поле сообщения. Таким образом, Elastic не сможет применить к этому какие-либо математические операции. Что вам нужно сделать, это с помощью fluentd проанализировать строку журнала как json, чтобы в документе Elastic каждое поле (например, logger и level) в этом json было частью документа elastic. Как только у вас есть этот эластичный файл, он в основном автоматически интерпретирует, что время выполнения — это число, и делает его доступным для агрегирования. После этого вы увидите это поле в раскрывающемся списке Grafana.
Здесь вы можете больше узнать о поле _source.
Добавьте также свою исходную строку журнала в вопрос, я думаю, это может помочь понять, что вы хотите использовать, чтобы можно было сделать предложение о возможной конфигурации fluentd.
Обновленный ответ на основе предоставленной дополнительной информации
Для простоты я использовал docker setup для запуска и анализа шаблона журнала, указанного в вопросе.
Конфигурация Fluentd
Я использовал HTTP-ввод, поэтому он позволяет мне выполнять curl, но вы можете переключиться обратно на пересылку. Я удалил фильтр, поскольку предполагаю, что ваш источник уже является JSON, поэтому вам не нужно анализировать его как JSON. Вы можете добавить соответствующий шаблон обратно, если у вас есть несколько типов данных, обрабатываемых через конвейер.
<source>
@type http
port 9880
bind 0.0.0.0
</source>
<match *>
@type copy
<store>
@type "elasticsearch"
host "es01"
port 9200
logstash_format true
logstash_prefix "applogs"
logstash_dateformat "%Y%m%d"
include_tag_key true
type_name "app_log"
tag_key "@log_name"
flush_interval 1s
<parse>
@type json
</parse>
<buffer>
flush_interval 1s
</buffer>
</store>
<store>
@type "stdout"
</store>
</match>
Свободное изображение Docker
# fluentd/Dockerfile
FROM fluent/fluentd:v1.11-debian-1
USER root
RUN touch ~/.gemrc
RUN echo ':ssl_verify_mode: 0' >> ~/.gemrc
RUN buildDeps="sudo make gcc g libc-dev"
amp;amp; apt-get update
amp;amp; apt-get install -y --no-install-recommends $buildDeps
amp;amp; sudo gem install fluent-plugin-elasticsearch
amp;amp; sudo gem sources --clear-all
amp;amp; SUDO_FORCE_REMOVE=yes
apt-get purge -y --auto-remove
-o APT::AutoRemove::RecommendsImportant=false
$buildDeps
amp;amp; rm -rf /var/lib/apt/lists/*
amp;amp; rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem
USER fluent
Docker Compose
Вы можете выбрать запуск только одного узла elasticsearch. У меня уже была запущена эта настройка.
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.8.0
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data01:/usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- elastic
healthcheck:
interval: 20s
retries: 10
test: curl -s http://localhost:9200/_cluster/health | grep -vq '"status":"red"'
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:7.8.0
container_name: es02
environment:
- node.name=es02
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data02:/usr/share/elasticsearch/data
ports:
- 9201:9200
networks:
- elastic
healthcheck:
interval: 20s
retries: 10
test: curl -s http://localhost:9201/_cluster/health | grep -vq '"status":"red"'
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:7.8.0
container_name: es03
environment:
- node.name=es03
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- data03:/usr/share/elasticsearch/data
ports:
- 9202:9200
networks:
- elastic
healthcheck:
interval: 20s
retries: 10
test: curl -s http://localhost:9202/_cluster/health | grep -vq '"status":"red"'
kib01:
image: docker.elastic.co/kibana/kibana:7.8.0
container_name: kib01
ports:
- 5601:5601
environment:
ELASTICSEARCH_URL: http://es01:9200
ELASTICSEARCH_HOSTS: http://es01:9200
networks:
- elastic
healthcheck:
interval: 10s
retries: 20
test: curl --write-out 'HTTP %{http_code}' --fail --silent --output /dev/null http://localhost:5601/api/status
fluentd:
build: ./fluentd
volumes:
- "./fluentd/conf/:/fluentd/etc/:ro"
networks:
- elastic
ports:
- "9880:9880"
volumes:
data01:
driver: local
data02:
driver: local
data03:
driver: local
networks:
elastic:
driver: bridge
Curl для теста
curl -X POST -d 'json={ "onpay": { "traceId": "9999", "inout": "OUT", "startTime": "2020-10-01T10:13:43.806 0200", "finishTime": "2020-10-01T10:13:43.827 0200", "executionTime": 21.0, "entrySize": 124.0, "exitSize": 124.0, "differenceSize": 0.0, "user": "pgallello", "methodPath": "http://localhost:8083/api/serviceEntryPoint", "errorMessage": null, "className": "com.myorganization.mypackage.MyController", "methodName": "serviceTemplateEntryPoint" }}' http://localhost:9880/
Как только вы получите все свои json-ключи, введенные таким образом, Elastic автоматически сопоставит большинство полей и разрешит поиск, агрегирование и т. Д. В зависимости от типа поля. Вы можете изменить тип поля и форматирование в kibana index management, если хотите.
Комментарии:
1. Спасибо за ответ, @karan. Просто отредактировал вопрос с исходной строкой журнала. Просто чтобы убедиться, один вопрос: ваши первые два абзаца отвечают на две разные вещи, верно? Первое указывает на решение, а второе просто отвечает на то, что я говорю о поле _source . Но решение основной истории будет содержаться только в вашем основном объяснении (первый абзац), верно? Теперь выясняю, что настроить во Fluentd, чтобы поля в моем сообщении были среди основных полей документа Elasticsearch
2. Да @EIPiter первый пункт отвечает на ваш главный вопрос, второй — просто с точки зрения понимания. Глядя на ваш исходный журнал, я думаю, что это просто правильное получение вашего приема через fluentd. В зависимости от того, как вы это сделаете, вы либо получите
onpay.executionTime
, либоexecutionTime
в своем эластичном документе, после чего он будет доступен из Grafana.3. Большое спасибо. Поверьте мне, что я читаю много официальной документации о том, что сказать Fluentd, чтобы получить время выполнения в моем эластичном документе. Но все равно не получает его:(. Я буду продолжать пытаться… но если у вас есть подсказка, это было бы очень ценно 🙂
4. Не могли бы вы поделиться своей конфигурацией fluentd, пожалуйста. У меня уже есть настройка эластичности в docker, я разверну контейнер fluentd и посмотрю, смогу ли я помочь вам определить точную конфигурацию.
5. Привет, я немного упростил конфигурационный файл, удалив некоторые поля, которые были не нужны. В любом случае, результат все тот же :(. Есть какие-нибудь подсказки? Спасибо!!