All of lore.kernel.org
 help / color / mirror / Atom feed
From: git@jeffhostetler.com
To: git@vger.kernel.org
Cc: gitster@pobox.com, peff@peff.net,
	Jeff Hostetler <jeffhost@microsoft.com>
Subject: [PATCH v1 16/25] structured-logging: add aux-data facility
Date: Fri, 13 Jul 2018 16:56:12 +0000	[thread overview]
Message-ID: <20180713165621.52017-17-git@jeffhostetler.com> (raw)
In-Reply-To: <20180713165621.52017-1-git@jeffhostetler.com>

From: Jeff Hostetler <jeffhost@microsoft.com>

Add facility to add extra data to the structured logging data allowing
arbitrary key/value pair data to be added to the "cmd_exit" event.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
---
 Documentation/config.txt |   6 +++
 structured-logging.c     | 116 +++++++++++++++++++++++++++++++++++++++++++++++
 structured-logging.h     |  21 +++++++++
 3 files changed, 143 insertions(+)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 7817966..ca78d4c 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -3195,6 +3195,12 @@ slog.timers::
 	enabled.  Defaults to off.  Data for enabled timers is added to
 	the `cmd_exit` event.
 
+slog.aux::
+	(EXPERIMENTAL) May be set to a boolean value or a list of
+	comma separated tokens.  Controls which categories of SLOG
+	"aux" data are enabled.  Defaults to off.  "Aux" data is added
+	to the `cmd_exit` event.
+
 splitIndex.maxPercentChange::
 	When the split index feature is used, this specifies the
 	percent of entries the split index can contain compared to the
diff --git a/structured-logging.c b/structured-logging.c
index 215138c..584f70a 100644
--- a/structured-logging.c
+++ b/structured-logging.c
@@ -35,6 +35,19 @@ static struct timer_data_array my__timers;
 static void format_timers(struct json_writer *jw);
 static void free_timers(void);
 
+struct aux_data {
+	char *category;
+	struct json_writer jw;
+};
+
+struct aux_data_array {
+	struct aux_data **array;
+	size_t nr, alloc;
+};
+
+static struct aux_data_array my__aux_data;
+static void format_and_free_aux_data(struct json_writer *jw);
+
 static uint64_t my__start_time;
 static uint64_t my__exit_time;
 static int my__is_config_loaded;
@@ -62,6 +75,7 @@ struct category_filter
 
 static struct category_filter my__detail_categories;
 static struct category_filter my__timer_categories;
+static struct category_filter my__aux_categories;
 
 static void set_want_categories(struct category_filter *cf, const char *value)
 {
@@ -255,6 +269,12 @@ static void emit_exit_event(void)
 			format_timers(&jw);
 			jw_end(&jw);
 		}
+
+		if (my__aux_data.nr) {
+			jw_object_inline_begin_object(&jw, "aux");
+			format_and_free_aux_data(&jw);
+			jw_end(&jw);
+		}
 	}
 	jw_end(&jw);
 
@@ -327,6 +347,12 @@ static int cfg_timers(const char *key, const char *value)
 	return 0;
 }
 
+static int cfg_aux(const char *key, const char *value)
+{
+	set_want_categories(&my__aux_categories, value);
+	return 0;
+}
+
 int slog_default_config(const char *key, const char *value)
 {
 	const char *sub;
@@ -349,6 +375,8 @@ int slog_default_config(const char *key, const char *value)
 			return cfg_detail(key, value);
 		if (!strcmp(sub, "timers"))
 			return cfg_timers(key, value);
+		if (!strcmp(sub, "aux"))
+			return cfg_aux(key, value);
 	}
 
 	return 0;
@@ -699,4 +727,92 @@ static void free_timers(void)
 	my__timers.alloc = 0;
 }
 
+int slog_want_aux(const char *category)
+{
+	return want_category(&my__aux_categories, category);
+}
+
+static struct aux_data *find_aux_data(const char *category)
+{
+	struct aux_data *ad;
+	int k;
+
+	if (!slog_want_aux(category))
+		return NULL;
+
+	for (k = 0; k < my__aux_data.nr; k++) {
+		ad = my__aux_data.array[k];
+		if (!strcmp(category, ad->category))
+			return ad;
+	}
+
+	ad = xcalloc(1, sizeof(struct aux_data));
+	ad->category = xstrdup(category);
+
+	jw_array_begin(&ad->jw, my__is_pretty);
+	/* leave per-category object unterminated for now */
+
+	ALLOC_GROW(my__aux_data.array, my__aux_data.nr + 1, my__aux_data.alloc);
+	my__aux_data.array[my__aux_data.nr++] = ad;
+
+	return ad;
+}
+
+#define add_to_aux(c, k, v, fn)						\
+	do {								\
+		struct aux_data *ad = find_aux_data((c));		\
+		if (ad) {						\
+			jw_array_inline_begin_array(&ad->jw);		\
+			{						\
+				jw_array_string(&ad->jw, (k));		\
+				(fn)(&ad->jw, (v));			\
+			}						\
+			jw_end(&ad->jw);				\
+		}							\
+	} while (0)
+
+void slog_aux_string(const char *category, const char *key, const char *value)
+{
+	add_to_aux(category, key, value, jw_array_string);
+}
+
+void slog_aux_intmax(const char *category, const char *key, intmax_t value)
+{
+	add_to_aux(category, key, value, jw_array_intmax);
+}
+
+void slog_aux_bool(const char *category, const char *key, int value)
+{
+	add_to_aux(category, key, value, jw_array_bool);
+}
+
+void slog_aux_jw(const char *category, const char *key,
+		 const struct json_writer *value)
+{
+	add_to_aux(category, key, value, jw_array_sub_jw);
+}
+
+static void format_and_free_aux_data(struct json_writer *jw)
+{
+	int k;
+
+	for (k = 0; k < my__aux_data.nr; k++) {
+		struct aux_data *ad = my__aux_data.array[k];
+
+		/* terminate per-category form */
+		jw_end(&ad->jw);
+
+		/* insert per-category form into containing "aux" form */
+		jw_object_sub_jw(jw, ad->category, &ad->jw);
+
+		jw_release(&ad->jw);
+		free(ad->category);
+		free(ad);
+	}
+
+	FREE_AND_NULL(my__aux_data.array);
+	my__aux_data.nr = 0;
+	my__aux_data.alloc = 0;
+}
+
 #endif
diff --git a/structured-logging.h b/structured-logging.h
index a29aa6e..2272598 100644
--- a/structured-logging.h
+++ b/structured-logging.h
@@ -25,6 +25,11 @@ typedef int (*slog_fn_main_t)(int, const char **);
 #define slog_emit_detail_event(category, label, data) do { } while (0)
 #define slog_start_timer(category, name) (SLOG_UNDEFINED_TIMER_ID)
 static inline void slog_stop_timer(int tid) { };
+#define slog_want_aux(c) (0)
+#define slog_aux_string(c, k, v) do { } while (0)
+#define slog_aux_intmax(c, k, v) do { } while (0)
+#define slog_aux_bool(c, k, v) do { } while (0)
+#define slog_aux_jw(c, k, v) do { } while (0)
 
 #else
 
@@ -126,5 +131,21 @@ int slog_start_timer(const char *category, const char *name);
  */
 void slog_stop_timer(int tid);
 
+/*
+ * Add arbitrary extra key/value data to the "cmd_exit" event.
+ * These fields will appear under the "aux" object.  This is
+ * intended for "interesting" config values or repo stats, such
+ * as the size of the index.
+ *
+ * These key/value pairs are written as an array-pair rather than
+ * an object/value because the keys may be repeated.
+ */
+int slog_want_aux(const char *category);
+void slog_aux_string(const char *category, const char *key, const char *value);
+void slog_aux_intmax(const char *category, const char *key, intmax_t value);
+void slog_aux_bool(const char *category, const char *key, int value);
+void slog_aux_jw(const char *category, const char *key,
+		 const struct json_writer *value);
+
 #endif /* STRUCTURED_LOGGING */
 #endif /* STRUCTURED_LOGGING_H */
-- 
2.9.3


  parent reply	other threads:[~2018-07-13 16:56 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-13 16:55 [PATCH v1 00/25] RFC: structured logging git
2018-07-13 16:55 ` [PATCH v1 01/25] structured-logging: design document git
2018-07-14  8:34   ` Simon Ruderich
2018-08-03 15:26   ` Ben Peart
2018-08-09 14:30     ` Jeff Hostetler
2018-08-21  4:47   ` Jonathan Nieder
2018-07-13 16:55 ` [PATCH v1 02/25] structured-logging: add STRUCTURED_LOGGING=1 to Makefile git
2018-08-21  4:49   ` Jonathan Nieder
2018-07-13 16:55 ` [PATCH v1 03/25] structured-logging: add structured logging framework git
2018-07-26  9:09   ` SZEDER Gábor
2018-07-27 12:45     ` Jeff Hostetler
2018-08-21  5:05   ` Jonathan Nieder
2018-07-13 16:56 ` [PATCH v1 04/25] structured-logging: add session-id to log events git
2018-07-13 16:56 ` [PATCH v1 05/25] structured-logging: set sub_command field for branch command git
2018-07-13 16:56 ` [PATCH v1 06/25] structured-logging: set sub_command field for checkout command git
2018-07-13 16:56 ` [PATCH v1 07/25] structured-logging: t0420 basic tests git
2018-07-13 16:56 ` [PATCH v1 08/25] structured-logging: add detail-event facility git
2018-07-13 16:56 ` [PATCH v1 09/25] structured-logging: add detail-event for lazy_init_name_hash git
2018-07-13 16:56 ` [PATCH v1 10/25] structured-logging: add timer facility git
2018-07-13 16:56 ` [PATCH v1 11/25] structured-logging: add timer around do_read_index git
2018-07-13 16:56 ` [PATCH v1 12/25] structured-logging: add timer around do_write_index git
2018-07-13 16:56 ` [PATCH v1 13/25] structured-logging: add timer around wt-status functions git
2018-07-13 16:56 ` [PATCH v1 14/25] structured-logging: add timer around preload_index git
2018-07-13 16:56 ` [PATCH v1 15/25] structured-logging: t0420 tests for timers git
2018-07-13 16:56 ` git [this message]
2018-07-13 16:56 ` [PATCH v1 17/25] structured-logging: add aux-data for index size git
2018-07-13 16:56 ` [PATCH v1 18/25] structured-logging: add aux-data for size of sparse-checkout file git
2018-07-13 16:56 ` [PATCH v1 19/25] structured-logging: t0420 tests for aux-data git
2018-07-13 16:56 ` [PATCH v1 20/25] structured-logging: add structured logging to remote-curl git
2018-07-13 16:56 ` [PATCH v1 21/25] structured-logging: add detail-events for child processes git
2018-07-13 16:56 ` [PATCH v1 22/25] structured-logging: add child process classification git
2018-07-13 16:56 ` [PATCH v1 23/25] structured-logging: t0420 tests for child process detail events git
2018-07-13 16:56 ` [PATCH v1 24/25] structured-logging: t0420 tests for interacitve child_summary git
2018-07-13 16:56 ` [PATCH v1 25/25] structured-logging: add config data facility git
2018-07-13 18:51 ` [PATCH v1 00/25] RFC: structured logging David Lang
2018-07-16 13:29   ` Jeff Hostetler
2018-08-28 17:38 ` Junio C Hamano
2018-08-28 18:47   ` Jeff Hostetler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180713165621.52017-17-git@jeffhostetler.com \
    --to=git@jeffhostetler.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jeffhost@microsoft.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.