From: Stephan Bosch Date: Tue, 8 Oct 2019 18:15:31 +0000 (+0200) Subject: stats: event-exporter-fmt-json - Use the new lib-json X-Git-Tag: 2.4.0~2361 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b84fe1b58b352a360be2c003c57ee30b3d5eb3cb;p=thirdparty%2Fdovecot%2Fcore.git stats: event-exporter-fmt-json - Use the new lib-json --- diff --git a/src/stats/Makefile.am b/src/stats/Makefile.am index f538cb9a6a..a6b0da3483 100644 --- a/src/stats/Makefile.am +++ b/src/stats/Makefile.am @@ -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 \ diff --git a/src/stats/event-exporter-fmt-json.c b/src/stats/event-exporter-fmt-json.c index b93a900e8f..fda3f6bd18 100644 --- a/src/stats/event-exporter-fmt-json.c +++ b/src/stats/event-exporter-fmt-json.c @@ -1,174 +1,170 @@ /* 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); }