зеркало из https://github.com/microsoft/git.git
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:
Родитель
98cedd0233
Коммит
3d3adaad91
|
@ -48,6 +48,15 @@ trace2.configParams::
|
|||
May be overridden by the `GIT_TRACE2_CONFIG_PARAMS` environment
|
||||
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::
|
||||
Boolean. When true Git will print error messages when a
|
||||
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"`::
|
||||
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_list_config();
|
||||
trace2_cmd_list_env_vars();
|
||||
trace2_cmd_name("_run_shell_alias_");
|
||||
|
||||
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_list_config();
|
||||
trace2_cmd_list_env_vars();
|
||||
|
||||
*argv = new_argv;
|
||||
*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");
|
||||
trace2_cmd_name(p->cmd);
|
||||
trace2_cmd_list_config();
|
||||
trace2_cmd_list_env_vars();
|
||||
|
||||
validate_cache_entries(the_repository->index);
|
||||
status = p->fn(argc, argv, prefix);
|
||||
|
|
|
@ -111,6 +111,7 @@ int cmd_main(int argc, const char **argv)
|
|||
argc--;
|
||||
trace2_cmd_name(cmds[i].name);
|
||||
trace2_cmd_list_config();
|
||||
trace2_cmd_list_env_vars();
|
||||
return cmds[i].fn(argc, argv);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,6 +199,43 @@ test_expect_success JSON_PP 'event stream, list config' '
|
|||
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_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 &&
|
||||
|
|
9
trace2.c
9
trace2.c
|
@ -121,6 +121,7 @@ static void tr2main_atexit_handler(void)
|
|||
tr2_sid_release();
|
||||
tr2_cmd_name_release();
|
||||
tr2_cfg_free_patterns();
|
||||
tr2_cfg_free_env_vars();
|
||||
tr2_sysenv_release();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
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__)
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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_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
|
||||
* or wildcard patterns into a list of strbufs.
|
||||
|
@ -46,6 +50,45 @@ void tr2_cfg_free_patterns(void)
|
|||
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 {
|
||||
const char *file;
|
||||
int line;
|
||||
|
@ -79,6 +122,21 @@ void tr2_cfg_list_config_fl(const char *file, int line)
|
|||
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,
|
||||
const char *value)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,12 @@
|
|||
*/
|
||||
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
|
||||
* 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_env_vars(void);
|
||||
|
||||
#endif /* TR2_CFG_H */
|
||||
|
|
|
@ -29,6 +29,8 @@ struct tr2_sysenv_entry {
|
|||
static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
|
||||
[TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS",
|
||||
"trace2.configparams" },
|
||||
[TR2_SYSENV_ENV_VARS] = { "GIT_TRACE2_ENV_VARS",
|
||||
"trace2.envvars" },
|
||||
|
||||
[TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG",
|
||||
"trace2.destinationdebug" },
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
enum tr2_sysenv_variable {
|
||||
TR2_SYSENV_CFG_PARAM = 0,
|
||||
TR2_SYSENV_ENV_VARS,
|
||||
|
||||
TR2_SYSENV_DST_DEBUG,
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче