[RFC PATCH v3 3/3] trace2: write overload message to sentinel files

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add a new "overload" event type for trace2 event destinations. Write
this event into the sentinel file created by the trace2.maxFiles
feature. Bump up the event format version since we've added a new event
type.

Writing this message into the sentinel file is useful for tracking how
often the overload protection feature is triggered in practice.

Signed-off-by: Josh Steadmon <steadmon@xxxxxxxxxx>
---
 Documentation/technical/api-trace2.txt | 17 ++++++++++--
 trace2/tr2_dst.c                       | 38 ++++++++++++++++++++++++--
 trace2/tr2_dst.h                       |  3 ++
 trace2/tr2_tgt_event.c                 | 21 ++++++++++++--
 trace2/tr2_tgt_normal.c                |  2 +-
 trace2/tr2_tgt_perf.c                  |  2 +-
 6 files changed, 74 insertions(+), 9 deletions(-)

diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt
index 80ffceada0..ef26e47805 100644
--- a/Documentation/technical/api-trace2.txt
+++ b/Documentation/technical/api-trace2.txt
@@ -128,7 +128,7 @@ yields
 
 ------------
 $ cat ~/log.event
-{"event":"version","sid":"sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"1","exe":"2.20.1.155.g426c96fcdb"}
+{"event":"version","sid":"sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.620713Z","file":"common-main.c","line":38,"evt":"2","exe":"2.20.1.155.g426c96fcdb"}
 {"event":"start","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621027Z","file":"common-main.c","line":39,"t_abs":0.001173,"argv":["git","version"]}
 {"event":"cmd_name","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621122Z","file":"git.c","line":432,"name":"version","hierarchy":"version"}
 {"event":"exit","sid":"20190408T191610.507018Z-H9b68c35f-P000059a8","thread":"main","time":"2019-01-16T17:28:42.621236Z","file":"git.c","line":662,"t_abs":0.001227,"code":0}
@@ -610,11 +610,24 @@ only present on the "start" and "atexit" events.
 {
 	"event":"version",
 	...
-	"evt":"1",		       # EVENT format version
+	"evt":"2",		       # EVENT format version
 	"exe":"2.20.1.155.g426c96fcdb" # git version
 }
 ------------
 
+`"overload"`::
+	This event is created in a sentinel file if we are overloading a target
+	trace directory (see the trace2.maxFiles config option).
++
+------------
+{
+	"event":"overload",
+	...
+	"dir":"/trace/target/dir/", # The configured trace2 target directory
+	"evt":"2",		    # EVENT format version
+}
+------------
+
 `"start"`::
 	This event contains the complete argv received by main().
 +
diff --git a/trace2/tr2_dst.c b/trace2/tr2_dst.c
index 414053d550..b72be57635 100644
--- a/trace2/tr2_dst.c
+++ b/trace2/tr2_dst.c
@@ -47,6 +47,38 @@ void tr2_dst_trace_disable(struct tr2_dst *dst)
 	dst->need_close = 0;
 }
 
+/*
+ * Create a sentinel file to note that we don't want to create new trace files
+ * in this location. The form of the sentinel file may vary based on the
+ * destination type; the default is to create an empty file, but destination
+ * types can override this by providing an overload_writer function that accepts
+ * the filename, line number, and target path.
+ */
+static void tr2_create_sentinel(struct tr2_dst *dst, const char *dir,
+				const char *sentinel_path)
+{
+	int fd;
+
+	if (dst->overload_writer) {
+		fd = open(sentinel_path, O_WRONLY | O_CREAT | O_EXCL, 0666);
+		if (fd != -1) {
+			dst->fd = fd;
+			/*
+			 * I don't think it's particularly useful to include the
+			 * file and line here, but we expect all trace messages
+			 * (at least for "event" destinations) to include them.
+			 * So I'm adding these for consistency's sake.
+			 */
+			dst->overload_writer(__FILE__, __LINE__, dir);
+			tr2_dst_trace_disable(dst);
+		}
+	} else
+		fd = creat(sentinel_path, 0666);
+
+	if (fd != -1)
+		close(fd);
+}
+
 /*
  * Check to make sure we're not overloading the target directory with too many
  * files. First get the threshold (if present) from the config or envvar. If
@@ -58,7 +90,7 @@ void tr2_dst_trace_disable(struct tr2_dst *dst)
  * from the target directory; after it removes the sentinel file we'll start
  * writing traces again.
  */
-static int tr2_dst_overloaded(const char *tgt_prefix)
+static int tr2_dst_overloaded(struct tr2_dst *dst, const char *tgt_prefix)
 {
 	int file_count = 0, max_files = 0, ret = 0;
 	const char *max_files_var;
@@ -97,7 +129,7 @@ static int tr2_dst_overloaded(const char *tgt_prefix)
 		closedir(dirp);
 
 	if (file_count >= tr2env_max_files) {
-		creat(sentinel_path.buf, 0666);
+		tr2_create_sentinel(dst, path.buf, sentinel_path.buf);
 		ret = 1;
 		goto cleanup;
 	}
@@ -126,7 +158,7 @@ static int tr2_dst_try_auto_path(struct tr2_dst *dst, const char *tgt_prefix)
 	strbuf_addstr(&path, sid);
 	base_path_len = path.len;
 
-	if (tr2_dst_overloaded(tgt_prefix)) {
+	if (tr2_dst_overloaded(dst, tgt_prefix)) {
 		strbuf_release(&path);
 		if (tr2_dst_want_warning())
 			warning("trace2: not opening %s trace file due to too "
diff --git a/trace2/tr2_dst.h b/trace2/tr2_dst.h
index 3adf3bac13..dd09a9541c 100644
--- a/trace2/tr2_dst.h
+++ b/trace2/tr2_dst.h
@@ -4,11 +4,14 @@
 struct strbuf;
 #include "trace2/tr2_sysenv.h"
 
+typedef void(tr2_dst_overload_writer_t)(const char *file, int line, const char *dir);
+
 struct tr2_dst {
 	enum tr2_sysenv_variable sysenv_var;
 	int fd;
 	unsigned int initialized : 1;
 	unsigned int need_close : 1;
+	tr2_dst_overload_writer_t *overload_writer;
 };
 
 /*
diff --git a/trace2/tr2_tgt_event.c b/trace2/tr2_tgt_event.c
index c2852d1bd2..68cb26fc67 100644
--- a/trace2/tr2_tgt_event.c
+++ b/trace2/tr2_tgt_event.c
@@ -10,7 +10,9 @@
 #include "trace2/tr2_tgt.h"
 #include "trace2/tr2_tls.h"
 
-static struct tr2_dst tr2dst_event = { TR2_SYSENV_EVENT, 0, 0, 0 };
+static void fn_overload_fl(const char *file, int line, const char *dir);
+
+static struct tr2_dst tr2dst_event = { TR2_SYSENV_EVENT, 0, 0, 0, fn_overload_fl };
 
 /*
  * The version number of the JSON data generated by the EVENT target
@@ -19,7 +21,7 @@ static struct tr2_dst tr2dst_event = { TR2_SYSENV_EVENT, 0, 0, 0 };
  * to update this if you just add another call to one of the existing
  * TRACE2 API methods.
  */
-#define TR2_EVENT_VERSION "1"
+#define TR2_EVENT_VERSION "2"
 
 /*
  * Region nesting limit for messages written to the event target.
@@ -107,6 +109,21 @@ static void event_fmt_prepare(const char *event_name, const char *file,
 		jw_object_intmax(jw, "repo", repo->trace2_repo_id);
 }
 
+static void fn_overload_fl(const char *file, int line, const char *dir)
+{
+	const char *event_name = "overload";
+	struct json_writer jw = JSON_WRITER_INIT;
+
+	jw_object_begin(&jw, 0);
+	event_fmt_prepare(event_name, file, line, NULL, &jw);
+	jw_object_string(&jw, "dir", dir);
+	jw_object_string(&jw, "evt", TR2_EVENT_VERSION);
+	jw_end(&jw);
+
+	tr2_dst_write_line(&tr2dst_event, &jw.json);
+	jw_release(&jw);
+}
+
 static void fn_version_fl(const char *file, int line)
 {
 	const char *event_name = "version";
diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c
index 00b116d797..ffca0d3811 100644
--- a/trace2/tr2_tgt_normal.c
+++ b/trace2/tr2_tgt_normal.c
@@ -9,7 +9,7 @@
 #include "trace2/tr2_tgt.h"
 #include "trace2/tr2_tls.h"
 
-static struct tr2_dst tr2dst_normal = { TR2_SYSENV_NORMAL, 0, 0, 0 };
+static struct tr2_dst tr2dst_normal = { TR2_SYSENV_NORMAL, 0, 0, 0, NULL };
 
 /*
  * Use the TR2_SYSENV_NORMAL_BRIEF setting to omit the "<time> <file>:<line>"
diff --git a/trace2/tr2_tgt_perf.c b/trace2/tr2_tgt_perf.c
index ea0cbbe13e..0a91e8a1f6 100644
--- a/trace2/tr2_tgt_perf.c
+++ b/trace2/tr2_tgt_perf.c
@@ -11,7 +11,7 @@
 #include "trace2/tr2_tgt.h"
 #include "trace2/tr2_tls.h"
 
-static struct tr2_dst tr2dst_perf = { TR2_SYSENV_PERF, 0, 0, 0 };
+static struct tr2_dst tr2dst_perf = { TR2_SYSENV_PERF, 0, 0, 0, NULL };
 
 /*
  * Use TR2_SYSENV_PERF_BRIEF to omit the "<time> <file>:<line>"
-- 
2.23.0.237.gc6a4ce50a0-goog




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux