]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
stats: event export - Add http-post transport support
authorJosef 'Jeff' Sipek <jeff.sipek@open-xchange.com>
Thu, 4 Apr 2019 11:24:50 +0000 (14:24 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Tue, 25 Jun 2019 12:17:39 +0000 (12:17 +0000)
This commit adds support for transport=http-post.

The value of transport_args is used as the HTTP POST URL.

src/stats/Makefile.am
src/stats/event-exporter-transport-http-post.c [new file with mode: 0644]
src/stats/event-exporter.h
src/stats/stats-metrics.c
src/stats/stats-settings.c

index 3be93f38e0646abd40e416754a97cb04e0f5464f..0a5106b1ab88dafc5658fbbb1853495a0966a483 100644 (file)
@@ -6,6 +6,7 @@ AM_CPPFLAGS = \
        -I$(top_srcdir)/src/lib \
        -I$(top_srcdir)/src/lib-settings \
        -I$(top_srcdir)/src/lib-master \
+       -I$(top_srcdir)/src/lib-http \
        $(BINARY_CFLAGS)
 
 stats_LDADD = $(LIBDOVECOT) \
@@ -20,6 +21,7 @@ stats_SOURCES = \
        event-exporter-fmt-json.c \
        event-exporter-fmt-none.c \
        event-exporter-transport-drop.c \
+       event-exporter-transport-http-post.c \
        event-exporter-transport-log.c \
        main.c \
        stats-event-category.c \
diff --git a/src/stats/event-exporter-transport-http-post.c b/src/stats/event-exporter-transport-http-post.c
new file mode 100644 (file)
index 0000000..9ca06e9
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2019 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "str.h"
+#include "event-exporter.h"
+#include "http-client.h"
+
+#define EXPORT_HTTP_TIMEOUT    50 /* msec */
+
+/* the http client used to export all events with exporter=http-post */
+static struct http_client *exporter_http_client;
+
+void event_export_transport_http_post_deinit(void)
+{
+       if (exporter_http_client != NULL)
+               http_client_deinit(&exporter_http_client);
+}
+
+static void response_fxn(const struct http_response *response,
+                        void *context ATTR_UNUSED)
+{
+       static time_t last_log;
+       static unsigned suppressed;
+
+       if (http_response_is_success(response))
+               return;
+
+       if (last_log == ioloop_time) {
+               suppressed++;
+               return; /* don't spam the log */
+       }
+
+       if (suppressed == 0)
+               i_error("Failed to export event via HTTP POST: %d %s",
+                       response->status, response->reason);
+       else
+               i_error("Failed to export event via HTTP POST: %d %s (%u more errors suppressed)",
+                       response->status, response->reason, suppressed);
+
+       last_log = ioloop_time;
+       suppressed = 0;
+}
+
+void event_export_transport_http_post(const struct exporter *exporter,
+                                     const buffer_t *buf)
+{
+       struct http_client_request *req;
+
+       if (exporter_http_client == NULL)
+               exporter_http_client = http_client_init(NULL);
+
+       req = http_client_request_url_str(exporter_http_client, "POST",
+                                         exporter->transport_args,
+                                         response_fxn, NULL);
+       http_client_request_add_header(req, "Content-Type", exporter->format_mime_type);
+       http_client_request_set_payload_data(req, buf->data, buf->used);
+
+       http_client_request_set_timeout_msecs(req, EXPORT_HTTP_TIMEOUT);
+       http_client_request_submit(req);
+}
index a203f45215466a7c48ecf23981175114ea934d8c..c006bbe4105b38e04341aec965d2dec0c5f51462 100644 (file)
@@ -9,6 +9,8 @@ void event_export_fmt_none(const struct metric *metric, struct event *event, buf
 
 /* transport functions */
 void event_export_transport_drop(const struct exporter *exporter, const buffer_t *buf);
+void event_export_transport_http_post(const struct exporter *exporter, const buffer_t *buf);
+void event_export_transport_http_post_deinit(void);
 void event_export_transport_log(const struct exporter *exporter, const buffer_t *buf);
 
 /* append a microsecond resolution RFC3339 UTC timestamp */
index 20763603c4c6f2716a84e149b09afa9017cf8af4..1981375773423db12ad359dfe4b5a6df7f774d38 100644 (file)
@@ -81,6 +81,8 @@ static void stats_exporters_add_set(struct stats_metrics *metrics,
         */
        if (strcmp(set->transport, "drop") == 0) {
                exporter->transport = event_export_transport_drop;
+       } else if (strcmp(set->transport, "http-post") == 0) {
+               exporter->transport = event_export_transport_http_post;
        } else if (strcmp(set->transport, "log") == 0) {
                exporter->transport = event_export_transport_log;
        } else {
@@ -218,6 +220,7 @@ static void stats_metric_free(struct metric *metric)
 static void stats_export_deinit(void)
 {
        /* no need for event_export_transport_drop_deinit() - no-op */
+       event_export_transport_http_post_deinit();
        /* no need for event_export_transport_log_deinit() - no-op */
 }
 
index 2202d24b96b6d78f5eaf9cb85d27667a5234a62d..14059e8b1b4fdee449d881bcc53c35d08e9bf0f3 100644 (file)
@@ -251,6 +251,7 @@ static bool stats_exporter_settings_check(void *_set, pool_t pool ATTR_UNUSED,
                *error_r = "Exporter transport name can't be empty";
                return FALSE;
        } else if (strcmp(set->transport, "drop") == 0 ||
+                  strcmp(set->transport, "http-post") == 0 ||
                   strcmp(set->transport, "log") == 0) {
                /* no-op */
        } else {