mirror of
https://github.com/git/git.git
synced 2024-05-09 00:56:29 +02:00
trace2: teach Git to log environment variables
Via trace2, Git can already log interesting config parameters (see the trace2_cmd_list_config() function). However, this can grant an incomplete picture because many config parameters also allow overrides via environment variables. To allow for more complete logs, we add a new trace2_cmd_list_env_vars() function and supporting implementation, modeled after the pre-existing config param logging implementation. Signed-off-by: Josh Steadmon <steadmon@google.com> Acked-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
98cedd0233
commit
3d3adaad91
|
@ -48,6 +48,15 @@ trace2.configParams::
|
||||||
May be overridden by the `GIT_TRACE2_CONFIG_PARAMS` environment
|
May be overridden by the `GIT_TRACE2_CONFIG_PARAMS` environment
|
||||||
variable. Unset by default.
|
variable. Unset by default.
|
||||||
|
|
||||||
|
trace2.envVars::
|
||||||
|
A comma-separated list of "important" environment variables that should
|
||||||
|
be recorded in the trace2 output. For example,
|
||||||
|
`GIT_HTTP_USER_AGENT,GIT_CONFIG` would cause the trace2 output to
|
||||||
|
contain events listing the overrides for HTTP user agent and the
|
||||||
|
location of the Git configuration file (assuming any are set). May be
|
||||||
|
overriden by the `GIT_TRACE2_ENV_VARS` environment variable. Unset by
|
||||||
|
default.
|
||||||
|
|
||||||
trace2.destinationDebug::
|
trace2.destinationDebug::
|
||||||
Boolean. When true Git will print error messages when a
|
Boolean. When true Git will print error messages when a
|
||||||
trace target destination cannot be opened for writing.
|
trace target destination cannot be opened for writing.
|
||||||
|
|
|
@ -656,7 +656,8 @@ The "exec_id" field is a command-unique id and is only useful if the
|
||||||
------------
|
------------
|
||||||
|
|
||||||
`"def_param"`::
|
`"def_param"`::
|
||||||
This event is generated to log a global parameter.
|
This event is generated to log a global parameter, such as a config
|
||||||
|
setting, command-line flag, or environment variable.
|
||||||
+
|
+
|
||||||
------------
|
------------
|
||||||
{
|
{
|
||||||
|
|
3
git.c
3
git.c
|
@ -351,6 +351,7 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||||
|
|
||||||
trace2_cmd_alias(alias_command, child.args.argv);
|
trace2_cmd_alias(alias_command, child.args.argv);
|
||||||
trace2_cmd_list_config();
|
trace2_cmd_list_config();
|
||||||
|
trace2_cmd_list_env_vars();
|
||||||
trace2_cmd_name("_run_shell_alias_");
|
trace2_cmd_name("_run_shell_alias_");
|
||||||
|
|
||||||
ret = run_command(&child);
|
ret = run_command(&child);
|
||||||
|
@ -388,6 +389,7 @@ static int handle_alias(int *argcp, const char ***argv)
|
||||||
|
|
||||||
trace2_cmd_alias(alias_command, new_argv);
|
trace2_cmd_alias(alias_command, new_argv);
|
||||||
trace2_cmd_list_config();
|
trace2_cmd_list_config();
|
||||||
|
trace2_cmd_list_env_vars();
|
||||||
|
|
||||||
*argv = new_argv;
|
*argv = new_argv;
|
||||||
*argcp += count - 1;
|
*argcp += count - 1;
|
||||||
|
@ -439,6 +441,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
|
||||||
trace_argv_printf(argv, "trace: built-in: git");
|
trace_argv_printf(argv, "trace: built-in: git");
|
||||||
trace2_cmd_name(p->cmd);
|
trace2_cmd_name(p->cmd);
|
||||||
trace2_cmd_list_config();
|
trace2_cmd_list_config();
|
||||||
|
trace2_cmd_list_env_vars();
|
||||||
|
|
||||||
validate_cache_entries(the_repository->index);
|
validate_cache_entries(the_repository->index);
|
||||||
status = p->fn(argc, argv, prefix);
|
status = p->fn(argc, argv, prefix);
|
||||||
|
|
|
@ -111,6 +111,7 @@ int cmd_main(int argc, const char **argv)
|
||||||
argc--;
|
argc--;
|
||||||
trace2_cmd_name(cmds[i].name);
|
trace2_cmd_name(cmds[i].name);
|
||||||
trace2_cmd_list_config();
|
trace2_cmd_list_config();
|
||||||
|
trace2_cmd_list_env_vars();
|
||||||
return cmds[i].fn(argc, argv);
|
return cmds[i].fn(argc, argv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -199,6 +199,43 @@ test_expect_success JSON_PP 'event stream, list config' '
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# Test listing of all "interesting" environment variables.
|
||||||
|
|
||||||
|
test_expect_success JSON_PP 'event stream, list env vars' '
|
||||||
|
test_when_finished "rm trace.event actual expect" &&
|
||||||
|
GIT_TRACE2_EVENT="$(pwd)/trace.event" \
|
||||||
|
GIT_TRACE2_ENV_VARS="A_VAR,OTHER_VAR,MISSING" \
|
||||||
|
A_VAR=1 OTHER_VAR="hello world" test-tool trace2 001return 0 &&
|
||||||
|
perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual &&
|
||||||
|
sed -e "s/^|//" >expect <<-EOF &&
|
||||||
|
|VAR1 = {
|
||||||
|
| "_SID0_":{
|
||||||
|
| "argv":[
|
||||||
|
| "_EXE_",
|
||||||
|
| "trace2",
|
||||||
|
| "001return",
|
||||||
|
| "0"
|
||||||
|
| ],
|
||||||
|
| "exit_code":0,
|
||||||
|
| "hierarchy":"trace2",
|
||||||
|
| "name":"trace2",
|
||||||
|
| "params":[
|
||||||
|
| {
|
||||||
|
| "param":"A_VAR",
|
||||||
|
| "value":"1"
|
||||||
|
| },
|
||||||
|
| {
|
||||||
|
| "param":"OTHER_VAR",
|
||||||
|
| "value":"hello world"
|
||||||
|
| }
|
||||||
|
| ],
|
||||||
|
| "version":"$V"
|
||||||
|
| }
|
||||||
|
|};
|
||||||
|
EOF
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success JSON_PP 'basic trace2_data' '
|
test_expect_success JSON_PP 'basic trace2_data' '
|
||||||
test_when_finished "rm trace.event actual expect" &&
|
test_when_finished "rm trace.event actual expect" &&
|
||||||
GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 &&
|
GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 &&
|
||||||
|
|
9
trace2.c
9
trace2.c
|
@ -121,6 +121,7 @@ static void tr2main_atexit_handler(void)
|
||||||
tr2_sid_release();
|
tr2_sid_release();
|
||||||
tr2_cmd_name_release();
|
tr2_cmd_name_release();
|
||||||
tr2_cfg_free_patterns();
|
tr2_cfg_free_patterns();
|
||||||
|
tr2_cfg_free_env_vars();
|
||||||
tr2_sysenv_release();
|
tr2_sysenv_release();
|
||||||
|
|
||||||
trace2_enabled = 0;
|
trace2_enabled = 0;
|
||||||
|
@ -311,6 +312,14 @@ void trace2_cmd_list_config_fl(const char *file, int line)
|
||||||
tr2_cfg_list_config_fl(file, line);
|
tr2_cfg_list_config_fl(file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void trace2_cmd_list_env_vars_fl(const char *file, int line)
|
||||||
|
{
|
||||||
|
if (!trace2_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tr2_list_env_vars_fl(file, line);
|
||||||
|
}
|
||||||
|
|
||||||
void trace2_cmd_set_config_fl(const char *file, int line, const char *key,
|
void trace2_cmd_set_config_fl(const char *file, int line, const char *key,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
|
|
13
trace2.h
13
trace2.h
|
@ -182,6 +182,19 @@ void trace2_cmd_list_config_fl(const char *file, int line);
|
||||||
|
|
||||||
#define trace2_cmd_list_config() trace2_cmd_list_config_fl(__FILE__, __LINE__)
|
#define trace2_cmd_list_config() trace2_cmd_list_config_fl(__FILE__, __LINE__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Emit one or more 'def_param' events for "important" environment variables.
|
||||||
|
*
|
||||||
|
* Use the TR2_SYSENV_ENV_VARS setting to register a comma-separated list of
|
||||||
|
* environment variables considered important. For example:
|
||||||
|
* git config --system trace2.envVars 'GIT_HTTP_USER_AGENT,GIT_CONFIG'
|
||||||
|
* or:
|
||||||
|
* GIT_TRACE2_ENV_VARS="GIT_HTTP_USER_AGENT,GIT_CONFIG"
|
||||||
|
*/
|
||||||
|
void trace2_cmd_list_env_vars_fl(const char *file, int line);
|
||||||
|
|
||||||
|
#define trace2_cmd_list_env_vars() trace2_cmd_list_env_vars_fl(__FILE__, __LINE__)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emit a "def_param" event for the given config key/value pair IF
|
* Emit a "def_param" event for the given config key/value pair IF
|
||||||
* we consider the key to be "important".
|
* we consider the key to be "important".
|
||||||
|
|
|
@ -7,6 +7,10 @@ static struct strbuf **tr2_cfg_patterns;
|
||||||
static int tr2_cfg_count_patterns;
|
static int tr2_cfg_count_patterns;
|
||||||
static int tr2_cfg_loaded;
|
static int tr2_cfg_loaded;
|
||||||
|
|
||||||
|
static struct strbuf **tr2_cfg_env_vars;
|
||||||
|
static int tr2_cfg_env_vars_count;
|
||||||
|
static int tr2_cfg_env_vars_loaded;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a string containing a comma-delimited list of config keys
|
* Parse a string containing a comma-delimited list of config keys
|
||||||
* or wildcard patterns into a list of strbufs.
|
* or wildcard patterns into a list of strbufs.
|
||||||
|
@ -46,6 +50,45 @@ void tr2_cfg_free_patterns(void)
|
||||||
tr2_cfg_loaded = 0;
|
tr2_cfg_loaded = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse a string containing a comma-delimited list of environment variable
|
||||||
|
* names into a list of strbufs.
|
||||||
|
*/
|
||||||
|
static int tr2_load_env_vars(void)
|
||||||
|
{
|
||||||
|
struct strbuf **s;
|
||||||
|
const char *varlist;
|
||||||
|
|
||||||
|
if (tr2_cfg_env_vars_loaded)
|
||||||
|
return tr2_cfg_env_vars_count;
|
||||||
|
tr2_cfg_env_vars_loaded = 1;
|
||||||
|
|
||||||
|
varlist = tr2_sysenv_get(TR2_SYSENV_ENV_VARS);
|
||||||
|
if (!varlist || !*varlist)
|
||||||
|
return tr2_cfg_env_vars_count;
|
||||||
|
|
||||||
|
tr2_cfg_env_vars = strbuf_split_buf(varlist, strlen(varlist), ',', -1);
|
||||||
|
for (s = tr2_cfg_env_vars; *s; s++) {
|
||||||
|
struct strbuf *buf = *s;
|
||||||
|
|
||||||
|
if (buf->len && buf->buf[buf->len - 1] == ',')
|
||||||
|
strbuf_setlen(buf, buf->len - 1);
|
||||||
|
strbuf_trim_trailing_newline(*s);
|
||||||
|
strbuf_trim(*s);
|
||||||
|
}
|
||||||
|
|
||||||
|
tr2_cfg_env_vars_count = s - tr2_cfg_env_vars;
|
||||||
|
return tr2_cfg_env_vars_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tr2_cfg_free_env_vars(void)
|
||||||
|
{
|
||||||
|
if (tr2_cfg_env_vars)
|
||||||
|
strbuf_list_free(tr2_cfg_env_vars);
|
||||||
|
tr2_cfg_env_vars_count = 0;
|
||||||
|
tr2_cfg_env_vars_loaded = 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct tr2_cfg_data {
|
struct tr2_cfg_data {
|
||||||
const char *file;
|
const char *file;
|
||||||
int line;
|
int line;
|
||||||
|
@ -79,6 +122,21 @@ void tr2_cfg_list_config_fl(const char *file, int line)
|
||||||
read_early_config(tr2_cfg_cb, &data);
|
read_early_config(tr2_cfg_cb, &data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tr2_list_env_vars_fl(const char *file, int line)
|
||||||
|
{
|
||||||
|
struct strbuf **s;
|
||||||
|
|
||||||
|
if (tr2_load_env_vars() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (s = tr2_cfg_env_vars; *s; s++) {
|
||||||
|
struct strbuf *buf = *s;
|
||||||
|
const char *val = getenv(buf->buf);
|
||||||
|
if (val && *val)
|
||||||
|
trace2_def_param_fl(file, line, buf->buf, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tr2_cfg_set_fl(const char *file, int line, const char *key,
|
void tr2_cfg_set_fl(const char *file, int line, const char *key,
|
||||||
const char *value)
|
const char *value)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
*/
|
*/
|
||||||
void tr2_cfg_list_config_fl(const char *file, int line);
|
void tr2_cfg_list_config_fl(const char *file, int line);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Iterate over all "interesting" environment variables and emit 'def_param'
|
||||||
|
* events for them to TRACE2.
|
||||||
|
*/
|
||||||
|
void tr2_list_env_vars_fl(const char *file, int line);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Emit a "def_param" event for the given key/value pair IF we consider
|
* Emit a "def_param" event for the given key/value pair IF we consider
|
||||||
* the key to be "interesting".
|
* the key to be "interesting".
|
||||||
|
@ -16,4 +22,6 @@ void tr2_cfg_set_fl(const char *file, int line, const char *key,
|
||||||
|
|
||||||
void tr2_cfg_free_patterns(void);
|
void tr2_cfg_free_patterns(void);
|
||||||
|
|
||||||
|
void tr2_cfg_free_env_vars(void);
|
||||||
|
|
||||||
#endif /* TR2_CFG_H */
|
#endif /* TR2_CFG_H */
|
||||||
|
|
|
@ -29,6 +29,8 @@ struct tr2_sysenv_entry {
|
||||||
static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
|
static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
|
||||||
[TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS",
|
[TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS",
|
||||||
"trace2.configparams" },
|
"trace2.configparams" },
|
||||||
|
[TR2_SYSENV_ENV_VARS] = { "GIT_TRACE2_ENV_VARS",
|
||||||
|
"trace2.envvars" },
|
||||||
|
|
||||||
[TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG",
|
[TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG",
|
||||||
"trace2.destinationdebug" },
|
"trace2.destinationdebug" },
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
*/
|
*/
|
||||||
enum tr2_sysenv_variable {
|
enum tr2_sysenv_variable {
|
||||||
TR2_SYSENV_CFG_PARAM = 0,
|
TR2_SYSENV_CFG_PARAM = 0,
|
||||||
|
TR2_SYSENV_ENV_VARS,
|
||||||
|
|
||||||
TR2_SYSENV_DST_DEBUG,
|
TR2_SYSENV_DST_DEBUG,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue