git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v1 25/25] structured-logging: add config data facility

From
Ggit@jeffhostetler.com <git@jeffhostetler.com>
Date
Jul 13, 2018, 16:56 UTC
Message-ID
<20180713165621.52017-26-git@jeffhostetler.com>
In-Reply-To
<20180713165621.52017-1-git@jeffhostetler.com>
From: Jeff Hostetler <jeffhost@microsoft.com>

Add "config" section to "cmd_exit" event to record important configuration settings in the log.

Add the value of "slog.detail", "slog.timers", and "slog.aux" config settings to the log. These values control the filtering of the log. Knowing the filter settings can help post-processors reason about the contents of the log.

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
---
 structured-logging.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++
 structured-logging.h |  13 +++++
 2 files changed, 145 insertions(+)
diff --git a/structured-logging.c b/structured-logging.c
index 2571e79..0e3f79e 100644
--- a/structured-logging.c
+++ b/structured-logging.c
@@ -83,6 +83,20 @@ struct child_data_array {
 static struct child_data_array my__child_data;
 static void free_children(void);
 
+struct config_data {
+	char *group;
+	struct json_writer jw;
+};
+
+struct config_data_array {
+	struct config_data **array;
+	size_t nr, alloc;
+};
+
+static struct config_data_array my__config_data;
+static void format_config_data(struct json_writer *jw);
+static void free_config_data(void);
+
 static uint64_t my__start_time;
 static uint64_t my__exit_time;
 static int my__is_config_loaded;
@@ -132,6 +146,15 @@ static int want_category(const struct category_filter *cf, const char *category)
 	return !!strstr(cf->categories, category);
 }
 
+static void set_config_data_from_category(const struct category_filter *cf,
+					  const char *key)
+{
+	if (cf->want == 0 || cf->want == 1)
+		slog_set_config_data_intmax(key, cf->want);
+	else
+		slog_set_config_data_string(key, cf->categories);
+}
+
 /*
  * Compute a new session id for the current process.  Build string
  * with the start time and PID of the current process and append
@@ -249,6 +272,18 @@ static void emit_exit_event(void)
 	struct json_writer jw = JSON_WRITER_INIT;
 	uint64_t atexit_time = getnanotime() / 1000;
 
+	/*
+	 * Copy important (and non-obvious) config settings into the
+	 * "config" section of the "cmd_exit" event.  The values of
+	 * "slog.detail", "slog.timers", and "slog.aux" are used in
+	 * category want filtering, so post-processors should know the
+	 * filter settings so that they can tell if an event is missing
+	 * because of filtering or an error.
+	 */
+	set_config_data_from_category(&my__detail_categories, "slog.detail");
+	set_config_data_from_category(&my__timer_categories, "slog.timers");
+	set_config_data_from_category(&my__aux_categories, "slog.aux");
+
 	/* close unterminated forms */
 	if (my__errors.json.len)
 		jw_end(&my__errors);
@@ -299,6 +334,12 @@ static void emit_exit_event(void)
 		}
 		jw_end(&jw);
 
+		if (my__config_data.nr) {
+			jw_object_inline_begin_object(&jw, "config");
+			format_config_data(&jw);
+			jw_end(&jw);
+		}
+
 		if (my__timers.nr) {
 			jw_object_inline_begin_object(&jw, "timers");
 			format_timers(&jw);
@@ -479,6 +520,7 @@ static void do_final_steps(int in_signal)
 	free_child_summary_data();
 	free_timers();
 	free_children();
+	free_config_data();
 }
 
 static void slog_atexit(void)
@@ -1084,4 +1126,94 @@ static void free_children(void)
 	my__child_data.alloc = 0;
 }
 
+/*
+ * Split <key> into <group>.<sub_key> (for example "slog.path" into "slog" and "path")
+ * Find or insert <group> in config_data_array[].
+ *
+ * Return config_data_arary[<group>].
+ */
+static struct config_data *find_config_data(const char *key, const char **sub_key)
+{
+	struct config_data *cd;
+	char *dot;
+	size_t group_len;
+	int k;
+
+	dot = strchr(key, '.');
+	if (!dot)
+		return NULL;
+
+	*sub_key = dot + 1;
+
+	group_len = dot - key;
+
+	for (k = 0; k < my__config_data.nr; k++) {
+		cd = my__config_data.array[k];
+		if (!strncmp(key, cd->group, group_len))
+			return cd;
+	}
+
+	cd = xcalloc(1, sizeof(struct config_data));
+	cd->group = xstrndup(key, group_len);
+
+	jw_object_begin(&cd->jw, my__is_pretty);
+	/* leave per-group object unterminated for now */
+
+	ALLOC_GROW(my__config_data.array, my__config_data.nr + 1,
+		   my__config_data.alloc);
+	my__config_data.array[my__config_data.nr++] = cd;
+
+	return cd;
+}
+
+void slog_set_config_data_string(const char *key, const char *value)
+{
+	const char *sub_key;
+	struct config_data *cd = find_config_data(key, &sub_key);
+
+	if (cd)
+		jw_object_string(&cd->jw, sub_key, value);
+}
+
+void slog_set_config_data_intmax(const char *key, intmax_t value)
+{
+	const char *sub_key;
+	struct config_data *cd = find_config_data(key, &sub_key);
+
+	if (cd)
+		jw_object_intmax(&cd->jw, sub_key, value);
+}
+
+static void format_config_data(struct json_writer *jw)
+{
+	int k;
+
+	for (k = 0; k < my__config_data.nr; k++) {
+		struct config_data *cd = my__config_data.array[k];
+
+		/* termminate per-group form */
+		jw_end(&cd->jw);
+
+		/* insert per-category form into containing "config" form */
+		jw_object_sub_jw(jw, cd->group, &cd->jw);
+	}
+}
+
+static void free_config_data(void)
+{
+	int k;
+
+	for (k = 0; k < my__config_data.nr; k++) {
+		struct config_data *cd = my__config_data.array[k];
+
+		jw_release(&cd->jw);
+		free(cd->group);
+		free(cd);
+	}
+
+	FREE_AND_NULL(my__config_data.array);
+	my__config_data.nr = 0;
+	my__config_data.alloc = 0;
+}
+
 #endif
diff --git a/structured-logging.h b/structured-logging.h
index 7c98d33..2c90267 100644
--- a/structured-logging.h
+++ b/structured-logging.h
@@ -34,6 +34,8 @@ static inline void slog_stop_timer(int tid) { };
 #define slog_aux_jw(c, k, v) do { } while (0)
 #define slog_child_starting(cmd) (SLOG_UNDEFINED_CHILD_ID)
 #define slog_child_ended(i, p, ec) do { } while (0)
+#define slog_set_config_data_string(k, v) do { } while (0)
+#define slog_set_config_data_intmax(k, v) do { } while (0)
 
 #else
 
@@ -162,5 +164,16 @@ void slog_aux_jw(const char *category, const char *key,
 int slog_child_starting(const struct child_process *cmd);
 void slog_child_ended(int child_id, int child_pid, int child_exit_code);
 
+/*
+ * Add an important config key/value pair to the "cmd_event".  Keys
+ * are assumed to be of the form <group>.<name>, such as "slog.path".
+ * The pair will appear under the "config" object in the resulting JSON
+ * as "config.<group>.<name>:<value>".
+ *
+ * This should only be used for important config settings.
+ */
+void slog_set_config_data_string(const char *key, const char *value);
+void slog_set_config_data_intmax(const char *key, intmax_t value);
+
 #endif /* STRUCTURED_LOGGING */
 #endif /* STRUCTURED_LOGGING_H */
-- 
2.9.3
Previous: git@jeffhostetler.comNext: git@jeffhostetler.com
Message 21 of 38 in “RFC: structured logging”
  1. 00/25 RFC: structured logginggit@jeffhostetler.com, Jul 13, 2018
  2. 01/25 structured-logging: design documentgit@jeffhostetler.com, Jul 13, 2018
  3. Simon RuderichJul 14, 2018
  4. Ben PeartAug 3, 2018
  5. Jeff HostetlerAug 9, 2018
  6. Jonathan NiederAug 21, 2018
  7. 04/25 structured-logging: add session-id to log eventsgit@jeffhostetler.com, Jul 13, 2018
  8. 06/25 structured-logging: set sub_command field for checkout commandgit@jeffhostetler.com, Jul 13, 2018
  9. 08/25 structured-logging: add detail-event facilitygit@jeffhostetler.com, Jul 13, 2018
  10. 07/25 structured-logging: t0420 basic testsgit@jeffhostetler.com, Jul 13, 2018
  11. 10/25 structured-logging: add timer facilitygit@jeffhostetler.com, Jul 13, 2018
  12. 12/25 structured-logging: add timer around do_write_indexgit@jeffhostetler.com, Jul 13, 2018
  13. 14/25 structured-logging: add timer around preload_indexgit@jeffhostetler.com, Jul 13, 2018
  14. 16/25 structured-logging: add aux-data facilitygit@jeffhostetler.com, Jul 13, 2018
  15. 17/25 structured-logging: add aux-data for index sizegit@jeffhostetler.com, Jul 13, 2018
  16. 19/25 structured-logging: t0420 tests for aux-datagit@jeffhostetler.com, Jul 13, 2018
  17. 18/25 structured-logging: add aux-data for size of sparse-checkout filegit@jeffhostetler.com, Jul 13, 2018
  18. 20/25 structured-logging: add structured logging to remote-curlgit@jeffhostetler.com, Jul 13, 2018
  19. 23/25 structured-logging: t0420 tests for child process detail eventsgit@jeffhostetler.com, Jul 13, 2018
  20. 21/25 structured-logging: add detail-events for child processesgit@jeffhostetler.com, Jul 13, 2018
  21. 25/25 structured-logging: add config data facilitygit@jeffhostetler.com, Jul 13, 2018
  22. 22/25 structured-logging: add child process classificationgit@jeffhostetler.com, Jul 13, 2018
  23. 24/25 structured-logging: t0420 tests for interacitve child_summarygit@jeffhostetler.com, Jul 13, 2018
  24. 15/25 structured-logging: t0420 tests for timersgit@jeffhostetler.com, Jul 13, 2018
  25. 13/25 structured-logging: add timer around wt-status functionsgit@jeffhostetler.com, Jul 13, 2018
  26. 11/25 structured-logging: add timer around do_read_indexgit@jeffhostetler.com, Jul 13, 2018
  27. 09/25 structured-logging: add detail-event for lazy_init_name_hashgit@jeffhostetler.com, Jul 13, 2018
  28. 05/25 structured-logging: set sub_command field for branch commandgit@jeffhostetler.com, Jul 13, 2018
  29. 03/25 structured-logging: add structured logging frameworkgit@jeffhostetler.com, Jul 13, 2018
  30. SZEDER GáborJul 26, 2018
  31. Jeff HostetlerJul 27, 2018
  32. Jonathan NiederAug 21, 2018
  33. 02/25 structured-logging: add STRUCTURED_LOGGING=1 to Makefilegit@jeffhostetler.com, Jul 13, 2018
  34. Jonathan NiederAug 21, 2018
  35. David LangJul 13, 2018
  36. Jeff HostetlerJul 16, 2018
  37. Junio C HamanoAug 28, 2018
  38. Jeff HostetlerAug 28, 2018

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.