trace2: make SIDs more unique
[git/git.git] / trace2 / tr2_sid.c
index 984524a..5047095 100644 (file)
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "trace2/tr2_tbuf.h"
 #include "trace2/tr2_sid.h"
 
 #define TR2_ENVVAR_PARENT_SID "GIT_TR2_PARENT_SID"
@@ -6,6 +7,53 @@
 static struct strbuf tr2sid_buf = STRBUF_INIT;
 static int tr2sid_nr_git_parents;
 
+/*
+ * Compute the final component of the SID representing the current process.
+ * This should uniquely identify the process and be a valid filename (to
+ * allow writing trace2 data to per-process files).  It should also be fixed
+ * length for possible use as a database key.
+ *
+ * "<yyyymmdd>T<hhmmss>.<fraction>Z-<host>-<process>"
+ *
+ * where <host> is a 9 character string:
+ *    "H<first_8_chars_of_sha1_of_hostname>"
+ *    "Localhost" when no hostname.
+ *
+ * where <process> is a 9 character string containing the least signifcant
+ * 32 bits in the process-id.
+ *    "P<pid>"
+ * (This is an abribrary choice.  On most systems pid_t is a 32 bit value,
+ * so limit doesn't matter.  On larger systems, a truncated value is fine
+ * for our purposes here.)
+ */
+static void tr2_sid_append_my_sid_component(void)
+{
+       const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA1];
+       struct tr2_tbuf tb_now;
+       git_hash_ctx ctx;
+       pid_t pid = getpid();
+       unsigned char hash[GIT_MAX_RAWSZ + 1];
+       char hex[GIT_MAX_HEXSZ + 1];
+       char hostname[HOST_NAME_MAX + 1];
+
+       tr2_tbuf_utc_datetime(&tb_now);
+       strbuf_addstr(&tr2sid_buf, tb_now.buf);
+
+       strbuf_addch(&tr2sid_buf, '-');
+       if (xgethostname(hostname, sizeof(hostname)))
+               strbuf_add(&tr2sid_buf, "Localhost", 9);
+       else {
+               algo->init_fn(&ctx);
+               algo->update_fn(&ctx, hostname, strlen(hostname));
+               algo->final_fn(hash, &ctx);
+               hash_to_hex_algop_r(hex, hash, algo);
+               strbuf_addch(&tr2sid_buf, 'H');
+               strbuf_add(&tr2sid_buf, hex, 8);
+       }
+
+       strbuf_addf(&tr2sid_buf, "-P%08"PRIx32, (uint32_t)pid);
+}
+
 /*
  * Compute a "unique" session id (SID) for the current process.  This allows
  * all events from this process to have a single label (much like a PID).
@@ -20,7 +68,6 @@ static int tr2sid_nr_git_parents;
  */
 static void tr2_sid_compute(void)
 {
-       uint64_t us_now;
        const char *parent_sid;
 
        if (tr2sid_buf.len)
@@ -38,9 +85,7 @@ static void tr2_sid_compute(void)
                tr2sid_nr_git_parents++;
        }
 
-       us_now = getnanotime() / 1000;
-       strbuf_addf(&tr2sid_buf, "%" PRIuMAX "-%" PRIdMAX, (uintmax_t)us_now,
-                   (intmax_t)getpid());
+       tr2_sid_append_my_sid_component();
 
        setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1);
 }