git/trace2/tr2_sid.c
SZEDER Gábor e4b75d6a1d trace2: rename environment variables to GIT_TRACE2*
For an environment variable that is supposed to be set by users, the
GIT_TR2* env vars are just too unclear, inconsistent, and ugly.

Most of the established GIT_* environment variables don't use
abbreviations, and in case of the few that do (GIT_DIR,
GIT_COMMON_DIR, GIT_DIFF_OPTS) it's quite obvious what the
abbreviations (DIR and OPTS) stand for.  But what does TR stand for?
Track, traditional, trailer, transaction, transfer, transformation,
transition, translation, transplant, transport, traversal, tree,
trigger, truncate, trust, or ...?!

The trace2 facility, as the '2' suffix in its name suggests, is
supposed to eventually supercede Git's original trace facility.  It's
reasonable to expect that the corresponding environment variables
follow suit, and after the original GIT_TRACE variables they are
called GIT_TRACE2; there is no such thing is 'GIT_TR'.

All trace2-specific config variables are, very sensibly, in the
'trace2' section, not in 'tr2'.

OTOH, we don't gain anything at all by omitting the last three
characters of "trace" from the names of these environment variables.

So let's rename all GIT_TR2* environment variables to GIT_TRACE2*,
before they make their way into a stable release.

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-05-28 10:20:34 -07:00

113 lines
2.9 KiB
C

#include "cache.h"
#include "trace2/tr2_tbuf.h"
#include "trace2/tr2_sid.h"
#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID"
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).
*
* Export this into our environment so that all child processes inherit it.
*
* If we were started by another git instance, use our parent's SID as a
* prefix. (This lets us track parent/child relationships even if there
* is an intermediate shell process.)
*
* Additionally, count the number of nested git processes.
*/
static void tr2_sid_compute(void)
{
const char *parent_sid;
if (tr2sid_buf.len)
return;
parent_sid = getenv(TR2_ENVVAR_PARENT_SID);
if (parent_sid && *parent_sid) {
const char *p;
for (p = parent_sid; *p; p++)
if (*p == '/')
tr2sid_nr_git_parents++;
strbuf_addstr(&tr2sid_buf, parent_sid);
strbuf_addch(&tr2sid_buf, '/');
tr2sid_nr_git_parents++;
}
tr2_sid_append_my_sid_component();
setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1);
}
const char *tr2_sid_get(void)
{
if (!tr2sid_buf.len)
tr2_sid_compute();
return tr2sid_buf.buf;
}
int tr2_sid_depth(void)
{
if (!tr2sid_buf.len)
tr2_sid_compute();
return tr2sid_nr_git_parents;
}
void tr2_sid_release(void)
{
strbuf_release(&tr2sid_buf);
}