diff --git a/modules/python-modules/syslogng/modules/webhook/scl/webhook.conf b/modules/python-modules/syslogng/modules/webhook/scl/webhook.conf index d689272ed..a637c129f 100644 --- a/modules/python-modules/syslogng/modules/webhook/scl/webhook.conf +++ b/modules/python-modules/syslogng/modules/webhook/scl/webhook.conf @@ -33,6 +33,7 @@ block source webhook( tls_ca_file("") tls_ca_dir("") proxy_header("") + include_request_headers(no) ... ) { @@ -50,6 +51,7 @@ block source webhook( "tls_ca_file" => "`tls_ca_file`" "tls_ca_dir" => "`tls_ca_dir`" "proxy_header" => "`proxy_header`" + "include_request_headers" => `include_request_headers` ) `__VARARGS__` ); diff --git a/modules/python-modules/syslogng/modules/webhook/source.py b/modules/python-modules/syslogng/modules/webhook/source.py index 2ea28bfd3..e2a7b9fdb 100644 --- a/modules/python-modules/syslogng/modules/webhook/source.py +++ b/modules/python-modules/syslogng/modules/webhook/source.py @@ -21,6 +21,7 @@ ############################################################################# from syslogng import LogSource, LogMessage +from collections import defaultdict import logging import asyncio @@ -28,11 +29,15 @@ import tornado import ssl import signal +import json from typing import Any signal.signal(signal.SIGINT, signal.SIG_IGN) signal.signal(signal.SIGTERM, signal.SIG_IGN) -WEBHOOK_QUERY_NV_PREFIX = "webhook.query." +WEBHOOK_NV_PREFIX = "webhook." +WEBHOOK_QUERY_NV_PREFIX = WEBHOOK_NV_PREFIX + "query." +WEBHOOK_HEADERS_KEY = WEBHOOK_NV_PREFIX + "headers" + class Handler(tornado.web.RequestHandler): @@ -63,6 +68,15 @@ def _set_proxied_ip(self, msg: LogMessage) -> None: msg.set_source_ipaddress(self.request.remote_ip) + def _set_request_headers(self, msg: LogMessage) -> None: + headers = defaultdict(list) + for h in self.request.headers.get_all(): + name = h[0] + if name: + headers[name].append(h[1]) + + msg[WEBHOOK_HEADERS_KEY] = json.dumps(headers) + def _construct_msg(self, request, path_arguments) -> LogMessage: msg = LogMessage(self.request.body) msg.set_recvd_rawmsg_size(len(self.request.body)) @@ -74,6 +88,9 @@ def _construct_msg(self, request, path_arguments) -> LogMessage: for key, value in path_arguments.items(): msg[key] = value + if self.source.include_request_headers: + self._set_request_headers(msg) + if self.source.proxy_header: self._set_proxied_ip(msg) else: @@ -203,6 +220,8 @@ def init_options(self, options: dict[str, Any]) -> bool: if self.proxy_header == "yes": self.proxy_header = "x-forwarded-for" + self.include_request_headers = bool(options.get("include_request_headers", False)) + return True except KeyError as e: self.logger.error(f"Missing option '{e.args[0]}'")