]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
stats: event-exporter-fmt-json - Use the new lib-json
authorStephan Bosch <stephan.bosch@open-xchange.com>
Tue, 8 Oct 2019 18:15:31 +0000 (20:15 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Sat, 18 Nov 2023 18:58:04 +0000 (18:58 +0000)
src/stats/Makefile.am
src/stats/event-exporter-fmt-json.c

index f538cb9a6a5d498a6852a6f88796bd185cfad244..a6b0da348327a787395e317f0bd6230cfac5f6aa 100644 (file)
@@ -8,6 +8,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-json \
        -I$(top_srcdir)/src/lib-http \
        -I$(top_srcdir)/src/lib-ssl-iostream \
        -I$(top_srcdir)/src/lib-test \
index b93a900e8f98c2fd6b27b857c9d54d498beec5b3..fda3f6bd18277678c0af97f677d489c1275fa09d 100644 (file)
 /* Copyright (c) 2019 Dovecot authors, see the included COPYING file */
 
 #include "lib.h"
+#include "unichar.h"
 #include "ioloop.h"
 #include "array.h"
 #include "lib-event-private.h"
 #include "event-exporter.h"
 #include "str.h"
-#include "json-parser.h"
+#include "json-ostream.h"
 #include "hostpid.h"
 
-static void append_str(string_t *dest, const char *str)
-{
-       str_append_c(dest, '"');
-       json_append_escaped(dest, str);
-       str_append_c(dest, '"');
-}
-
-static void append_str_max_len(string_t *dest, const char *str,
+static void append_str_max_len(struct json_ostream *joutput, const char *str,
                               const struct metric_export_info *info)
 {
-       str_append_c(dest, '"');
-       if (info->exporter->format_max_field_len == 0)
-               json_append_escaped(dest, str);
-       else {
-               size_t len = strlen(str);
-               json_append_escaped_data(dest, (const unsigned char *)str,
-                       I_MIN(len, info->exporter->format_max_field_len));
-               if (len > info->exporter->format_max_field_len)
-                       str_append(dest, "...");
+       if (info->exporter->format_max_field_len == 0) {
+               json_ostream_nwrite_string(joutput, NULL, str);
+               return;
+       }
+
+       size_t len = strlen(str);
+
+       if (len < info->exporter->format_max_field_len) {
+               json_ostream_nwrite_string(joutput, NULL, str);
+               return;
        }
-       str_append_c(dest, '"');
+
+       len = uni_utf8_data_truncate((const unsigned char *)str, len,
+                                    info->exporter->format_max_field_len);
+       json_ostream_nopen_string(joutput, NULL);
+       json_ostream_nwrite_string_data(joutput, NULL, str, len);
+       json_ostream_nwrite_string(joutput, NULL, "...");
+       json_ostream_nclose_string(joutput);
 }
 
 static void
-append_strlist(string_t *dest, const ARRAY_TYPE(const_string) *strlist,
+append_strlist(struct json_ostream *joutput,
+              const ARRAY_TYPE(const_string) *strlist,
               const struct metric_export_info *info)
 {
        const char *value;
-       bool first = TRUE;
-
-       str_append_c(dest, '[');
-       array_foreach_elem(strlist, value) {
-               if (first)
-                       first = FALSE;
-               else
-                       str_append_c(dest, ',');
-               append_str_max_len(dest, value, info);
-       }
-       str_append_c(dest, ']');
+
+       json_ostream_ndescend_array(joutput, NULL);
+       array_foreach_elem(strlist, value)
+               append_str_max_len(joutput, value, info);
+       json_ostream_nascend_array(joutput);
 }
 
-static void append_int(string_t *dest, intmax_t val)
+static void append_int(struct json_ostream *joutput, intmax_t val)
 {
-       str_printfa(dest, "%jd", val);
+       json_ostream_nwrite_number(joutput, NULL, val);
 }
 
-static void append_time(string_t *dest, const struct timeval *time,
-                       enum event_exporter_time_fmt fmt)
+static void
+append_time(struct json_ostream *joutput, const struct timeval *time,
+           enum event_exporter_time_fmt fmt)
 {
+       string_t *time_str = t_str_new(64);
+
        switch (fmt) {
        case EVENT_EXPORTER_TIME_FMT_NATIVE:
                i_panic("JSON does not have a native date/time type");
        case EVENT_EXPORTER_TIME_FMT_UNIX:
-               event_export_helper_fmt_unix_time(dest, time);
+               event_export_helper_fmt_unix_time(time_str, time);
+               json_ostream_nwrite_number_raw(joutput, NULL, str_c(time_str));
                break;
        case EVENT_EXPORTER_TIME_FMT_RFC3339:
-               str_append_c(dest, '"');
-               event_export_helper_fmt_rfc3339_time(dest, time);
-               str_append_c(dest, '"');
+               event_export_helper_fmt_rfc3339_time(time_str, time);
+               json_ostream_nwrite_string_buffer(joutput, NULL, time_str);
                break;
        }
 }
 
-static void append_ip(string_t *dest, const struct ip_addr *ip)
+static void append_ip(struct json_ostream *joutput, const struct ip_addr *ip)
 {
-       str_append_c(dest, '"');
-       str_append(dest, net_ip2addr(ip));
-       str_append_c(dest, '"');
+       json_ostream_nwrite_string(joutput, NULL, net_ip2addr(ip));
 }
 
-static void append_field_value(string_t *dest, const struct event_field *field,
-                              const struct metric_export_info *info)
+static void
+append_field_value(struct json_ostream *joutput,
+                  const struct event_field *field,
+                  const struct metric_export_info *info)
 {
        switch (field->value_type) {
        case EVENT_FIELD_VALUE_TYPE_STR:
-               append_str_max_len(dest, field->value.str, info);
+               append_str_max_len(joutput, field->value.str, info);
                break;
        case EVENT_FIELD_VALUE_TYPE_INTMAX:
-               append_int(dest, field->value.intmax);
+               append_int(joutput, field->value.intmax);
                break;
        case EVENT_FIELD_VALUE_TYPE_TIMEVAL:
-               append_time(dest, &field->value.timeval,
+               append_time(joutput, &field->value.timeval,
                            info->exporter->time_format);
                break;
        case EVENT_FIELD_VALUE_TYPE_IP:
-               append_ip(dest, &field->value.ip);
+               append_ip(joutput, &field->value.ip);
                break;
        case EVENT_FIELD_VALUE_TYPE_STRLIST:
-               append_strlist(dest, &field->value.strlist, info);
+               append_strlist(joutput, &field->value.strlist, info);
                break;
        }
 }
 
-static void json_export_name(string_t *dest, struct event *event,
-                            const struct metric_export_info *info)
+static void
+json_export_name(struct json_ostream *joutput, struct event *event,
+                const struct metric_export_info *info)
 {
        if ((info->include & EVENT_EXPORTER_INCL_NAME) == 0)
                return;
 
-       append_str(dest, "event");
-       str_append_c(dest, ':');
-       append_str(dest, event->sending_name);
-       str_append_c(dest, ',');
+       json_ostream_nwrite_string(joutput, "event", event->sending_name);
 }
 
-static void json_export_hostname(string_t *dest,
-                                const struct metric_export_info *info)
+static void
+json_export_hostname(struct json_ostream *joutput,
+                    const struct metric_export_info *info)
 {
        if ((info->include & EVENT_EXPORTER_INCL_HOSTNAME) == 0)
                return;
 
-       append_str(dest, "hostname");
-       str_append_c(dest, ':');
-       append_str(dest, my_hostname);
-       str_append_c(dest, ',');
+       json_ostream_nwrite_string(joutput, "hostname", my_hostname);
 }
 
-static void json_export_timestamps(string_t *dest, struct event *event,
-                                  const struct metric_export_info *info)
+static void
+json_export_timestamps(struct json_ostream *joutput, struct event *event,
+                      const struct metric_export_info *info)
 {
        if ((info->include & EVENT_EXPORTER_INCL_TIMESTAMPS) == 0)
                return;
 
-       append_str(dest, "start_time");
-       str_append_c(dest, ':');
-       append_time(dest, &event->tv_created, info->exporter->time_format);
-       str_append_c(dest, ',');
+       json_ostream_nwrite_object_member(joutput, "start_time");
+       append_time(joutput, &event->tv_created, info->exporter->time_format);
 
-       append_str(dest, "end_time");
-       str_append_c(dest, ':');
-       append_time(dest, &ioloop_timeval, info->exporter->time_format);
-       str_append_c(dest, ',');
+       json_ostream_nwrite_object_member(joutput, "end_time");
+       append_time(joutput, &ioloop_timeval, info->exporter->time_format);
 }
 
-static void json_export_categories(string_t *dest, struct event *event,
-                                  const struct metric_export_info *info)
+static void
+json_export_categories(struct json_ostream *joutput, struct event *event,
+                      const struct metric_export_info *info)
 {
+       struct event_category_iterator *iter;
+       const struct event_category *cat;
+
        if ((info->include & EVENT_EXPORTER_INCL_CATEGORIES) == 0)
                return;
 
-       append_str(dest, "categories");
-       str_append(dest, ":[");
+       json_ostream_ndescend_array(joutput, "categories");
 
-       event_export_helper_fmt_categories(dest, event, append_str, ",");
+       iter = event_categories_iterate_init(event);
+       while (event_categories_iterate(iter, &cat))
+               json_ostream_nwrite_string(joutput, NULL, cat->name);
+       event_categories_iterate_deinit(&iter);
 
-       str_append(dest, "],");
+       json_ostream_nascend_array(joutput);
 }
 
-static void json_export_fields(string_t *dest, struct event *event,
-                              const struct metric_export_info *info,
-                              const unsigned int fields_count,
-                              const struct metric_field *fields)
+static void
+json_export_fields(struct json_ostream *joutput, struct event *event,
+                  const struct metric_export_info *info,
+                  const unsigned int fields_count,
+                  const struct metric_field *fields)
 {
-       bool appended = FALSE;
-
        if ((info->include & EVENT_EXPORTER_INCL_FIELDS) == 0)
                return;
 
-       append_str(dest, "fields");
-       str_append(dest, ":{");
+       json_ostream_ndescend_object(joutput, "fields");
 
        if (fields_count == 0) {
                /* include all fields */
@@ -180,12 +176,8 @@ static void json_export_fields(string_t *dest, struct event *event,
                for (unsigned int i = 0; i < count; i++) {
                        const struct event_field *field = &fields[i];
 
-                       append_str(dest, field->key);
-                       str_append_c(dest, ':');
-                       append_field_value(dest, field, info);
-                       str_append_c(dest, ',');
-
-                       appended = TRUE;
+                       json_ostream_nwrite_object_member(joutput, field->key);
+                       append_field_value(joutput, field, info);
                }
        } else {
                for (unsigned int i = 0; i < fields_count; i++) {
@@ -196,20 +188,12 @@ static void json_export_fields(string_t *dest, struct event *event,
                        if (field == NULL)
                                continue; /* doesn't exist, skip it */
 
-                       append_str(dest, name);
-                       str_append_c(dest, ':');
-                       append_field_value(dest, field, info);
-                       str_append_c(dest, ',');
-
-                       appended = TRUE;
+                       json_ostream_nwrite_object_member(joutput, name);
+                       append_field_value(joutput, field, info);
                }
        }
 
-       /* remove trailing comma */
-       if (appended)
-               str_truncate(dest, str_len(dest) - 1);
-
-       str_append(dest, "},");
+       json_ostream_nascend_object(joutput);
 }
 
 /*
@@ -238,17 +222,18 @@ void event_export_fmt_json(const struct metric *metric,
                return;
        }
 
-       str_append_c(dest, '{');
+       struct json_ostream *joutput;
 
-       json_export_name(dest, event, info);
-       json_export_hostname(dest, info);
-       json_export_timestamps(dest, event, info);
-       json_export_categories(dest, event, info);
-       json_export_fields(dest, event, info, metric->fields_count,
-                          metric->fields);
+       joutput = json_ostream_create_str(dest, 0);
+       json_ostream_ndescend_object(joutput, NULL);
 
-       /* remove trailing comma */
-       str_truncate(dest, str_len(dest) - 1);
+       json_export_name(joutput, event, info);
+       json_export_hostname(joutput, info);
+       json_export_timestamps(joutput, event, info);
+       json_export_categories(joutput, event, info);
+       json_export_fields(joutput, event, info, metric->fields_count,
+                          metric->fields);
 
-       str_append_c(dest, '}');
+       json_ostream_nascend_object(joutput);
+       json_ostream_nfinish_destroy(&joutput);
 }