Перейти к основному содержимому
Версия: 4.6.X

Сбор событий с произвольных HTTP API (http-routes)

Плагин http-routes

HTTP-коллектор поддерживает добавление произвольных API с помощью плагина http-routes. Каждый экземпляр плагина запускает на указанном порту отдельный HTTP-сервер с заданным набором конечных точек (endpoint). Это позволяет, например, имитировать API коллекторов сторонних решений (Splunk HEC, Loki и др.) и принимать события от источников, которые умеют отправлять данные только по определенным протоколам.

Наследование настроек

Кроме порта, все остальные параметры HTTP-сервера (адрес привязки, TLS-сертификаты и т. д.) наследуются от основной конфигурации HTTP-коллектора.


Конфигурация

Корневые параметры плагина:

ПараметрТипОписание
listen-portintПорт, на котором запускается HTTP-сервер
response-headersmapЗаголовки ответа, добавляемые ко всем конечным точкам
response-bodystringШаблон Liquid для тела ответа
response-codeintКод статуса ответа (по умолчанию 200)
include-headersstring[]Заголовки HTTP-запроса, включаемые в генерируемое событие
routesmapСловарь маршрутов API

Маршруты (routes)

Каждый элемент словаря routes описывается объектом со следующими полями:

ПараметрТипОписание
response-headersmapДополнительные заголовки ответа (наследуются вложенными маршрутами)
response-bodystringШаблон тела ответа (переопределяет родительский)
response-codeintКод статуса ответа (переопределяет родительский)
include-headersstring[]Заголовки запроса для включения в событие (дополняют родительский список)
produce-eventboolГенерировать ли событие на основе запроса (по умолчанию true)
routesmapВложенные подмаршруты

Формат ключей маршрутов

Ключ маршрута задается строкой в одном из трех форматов:

ФорматПримерОписание
/путь/itemsЗадает часть URL-пути без метода. Создает недействующий endpoint, используемый для шаблонизации вложенных точек
МЕТОДPOSTСоздает действующий endpoint на полном пути родителя. Полезно, когда одному URL соответствуют разные методы
МЕТОД /путьGET /{id}Создает действующий endpoint, путь формируется как сумма пути родителя и указанного подпути

Пути поддерживают именованные параметры вида {имя} — при обращении к endpoint вместо параметра может быть передана произвольная строка. Значения параметров доступны в шаблоне тела ответа.


Шаблон тела ответа

Поле response-body использует синтаксис шаблонов Liquid. Внутри шаблона доступны следующие переменные:

ПеременнаяОписание
request.raw_bodyНеобработанное тело запроса
request.bodyРазобранное тело запроса (доступно при Content-Type: application/json)
request.headersЗаголовки запроса
request.path_paramsЗначения именованных параметров пути
request.url.paramsQuery-параметры запроса
request.url.rawПолный URL запроса
pathURL-путь конечной точки
response.status_codeКод ответа из конфигурации

Дополнительно доступен фильтр json, который преобразует значение в его JSON-представление.


Примеры

Postman Echo API

Пример реализации классического Echo API, возвращающего клиенту отправленную им информацию:

http-routes:
listen-port: 8080
response-headers:
"Content-Type": application/json
routes:
"GET /get":
response-body: |
{
"args": {{ request.url.params | json }},
"headers": {{ request.headers | json }},
"url": {{ request.url.raw | json }}
}
routes:
"GET /{id}":
response-body: |
{
"args": {{ request.url.params | json }},
"headers": {{ request.headers | json }},
"url": {{ request.url.raw | json }},
"id": {{ request.path_params.id | json }}
}
"POST /post": &body-based-endpoint
response-body: |
{
"args": {{ request.url.params | json }},
"data": {% if request.body %}{{ request.body | json }}{% else %}{{ request.raw_body | json }}{% endif %},
"headers": {{ request.headers | json }},
"json": {% if request.body %}{{ request.body | json }}{% else %}null{% endif %},
"url": {{ request.url.raw | json }}
}
"PUT /put": *body-based-endpoint
"PATCH /patch": *body-based-endpoint
"DELETE /delete": *body-based-endpoint

В этом примере используются YAML-якоря (&якорь) и псевдонимы (*якорь) для повторного использования одинаковой конфигурации конечных точек.

Endpoint GET /{id} вложен в GET /get, поэтому его итоговый путь — GET /get/{id}.

Проверка с помощью curl:

curl -X POST -d 'data' 'http://localhost:8080/post?arg=1&arg2=2&arg3=4'

Ответ сервера:

{
"args": {"arg":"1","arg2":"2","arg3":"4"},
"data": "data",
"headers": {"Accept":"*/*","Content-Length":"4","Content-Type":"application/x-www-form-urlencoded","Host":"localhost:8080","User-Agent":"curl/7.81.0"},
"json": null,
"url": "http://localhost:8080/post?arg=1&arg2=2&arg3=4"
}

При отправке JSON-данных шаблон автоматически заполняет поле json:

curl -X POST -H 'Content-Type: application/json' -d '["value1", "value2"]' \
'http://localhost:8080/post?arg=1&arg2=2&arg3=4'
{
"args": {"arg":"1","arg2":"2","arg3":"4"},
"data": ["value1","value2"],
"headers": {"Accept":"*/*","Content-Length":"20","Content-Type":"application/json","Host":"localhost:8080","User-Agent":"curl/7.81.0"},
"json": ["value1","value2"],
"url": "http://localhost:8080/post?arg=1&arg2=2&arg3=4"
}

Splunk HTTP Event Collector

Плагин http-routes позволяет имитировать API существующих коллекторов событий. Пример ниже воспроизводит Splunk HTTP Event Collector, что дает возможность принимать события от систем, настроенных на отправку данных в Splunk.

Конфигурация плагина:

http-routes:
listen-port: 8088
routes:
"POST /services/collector":
response-body: '{"text":"Success","code":0}'
routes:
"POST /event": {}
"POST /event/1.0": {}
"POST /raw": {}
"POST /raw/1.0": {}
"GET /health":
produce-event: false
"GET /health/1.0":
produce-event: false

Предоставляемые конечные точки:

Метод и путьОписание
POST /services/collectorОтправка события без указания типа
POST /services/collector/eventОтправка события с временной отметкой
POST /services/collector/event/1.0То же (версионированный путь)
POST /services/collector/rawОтправка события в сыром виде
POST /services/collector/raw/1.0То же (версионированный путь)
GET /services/collector/healthПроверка работоспособности (событие не создается)
GET /services/collector/health/1.0То же (версионированный путь)

Для проверки можно использовать Vector с целью назначения типа splunk_hec_logs:

vector.yaml
sources:
generator:
type: demo_logs
format: json

sinks:
splunkhec:
type: splunk_hec_logs
inputs: [generator]
endpoint: http://localhost:8088
endpoint_target: event
default_token: token
encoding:
codec: json

Loki

Пример имитации API приема событий системы агрегации логов Loki:

http-routes:
listen-port: 3100
routes:
"POST /loki/api/v1/push":
response-code: 204
"POST /otlp/v1/logs":
response-code: 204

Loki при приеме событий не возвращает тела ответа, поэтому используется код 204 (No Content).

Конфигурация Vector для отправки событий:

vector.yaml
sources:
generator:
type: demo_logs
format: json

sinks:
loki:
type: loki
inputs: [generator]
endpoint: http://localhost:3100
compression: none
labels:
source: vector
encoding:
codec: json

Для извлечения полей из событий Loki, поступающих на /loki/api/v1/push, можно использовать следующий конвейер processors:

processors:
- module: split
type: json_array
path: streams
- module: json
patterns:
- expr: stream.source
to: ECS.Event.Module
- module: split
type: json_array
path: values
- module: json
patterns:
- expr: 1
to: ECS.Event.Original