Skip to content

Commit 3d3adaa

Browse files
steadmongitster
authored andcommitted
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 <[email protected]> Acked-by: Jeff Hostetler <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 98cedd0 commit 3d3adaa

File tree

11 files changed

+143
-1
lines changed

11 files changed

+143
-1
lines changed

Documentation/config/trace2.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ trace2.configParams::
4848
May be overridden by the `GIT_TRACE2_CONFIG_PARAMS` environment
4949
variable. Unset by default.
5050

51+
trace2.envVars::
52+
A comma-separated list of "important" environment variables that should
53+
be recorded in the trace2 output. For example,
54+
`GIT_HTTP_USER_AGENT,GIT_CONFIG` would cause the trace2 output to
55+
contain events listing the overrides for HTTP user agent and the
56+
location of the Git configuration file (assuming any are set). May be
57+
overriden by the `GIT_TRACE2_ENV_VARS` environment variable. Unset by
58+
default.
59+
5160
trace2.destinationDebug::
5261
Boolean. When true Git will print error messages when a
5362
trace target destination cannot be opened for writing.

Documentation/technical/api-trace2.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,8 @@ The "exec_id" field is a command-unique id and is only useful if the
656656
------------
657657

658658
`"def_param"`::
659-
This event is generated to log a global parameter.
659+
This event is generated to log a global parameter, such as a config
660+
setting, command-line flag, or environment variable.
660661
+
661662
------------
662663
{

git.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,7 @@ static int handle_alias(int *argcp, const char ***argv)
351351

352352
trace2_cmd_alias(alias_command, child.args.argv);
353353
trace2_cmd_list_config();
354+
trace2_cmd_list_env_vars();
354355
trace2_cmd_name("_run_shell_alias_");
355356

356357
ret = run_command(&child);
@@ -388,6 +389,7 @@ static int handle_alias(int *argcp, const char ***argv)
388389

389390
trace2_cmd_alias(alias_command, new_argv);
390391
trace2_cmd_list_config();
392+
trace2_cmd_list_env_vars();
391393

392394
*argv = new_argv;
393395
*argcp += count - 1;
@@ -439,6 +441,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
439441
trace_argv_printf(argv, "trace: built-in: git");
440442
trace2_cmd_name(p->cmd);
441443
trace2_cmd_list_config();
444+
trace2_cmd_list_env_vars();
442445

443446
validate_cache_entries(the_repository->index);
444447
status = p->fn(argc, argv, prefix);

t/helper/test-tool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int cmd_main(int argc, const char **argv)
111111
argc--;
112112
trace2_cmd_name(cmds[i].name);
113113
trace2_cmd_list_config();
114+
trace2_cmd_list_env_vars();
114115
return cmds[i].fn(argc, argv);
115116
}
116117
}

t/t0212-trace2-event.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,43 @@ test_expect_success JSON_PP 'event stream, list config' '
199199
test_cmp expect actual
200200
'
201201

202+
# Test listing of all "interesting" environment variables.
203+
204+
test_expect_success JSON_PP 'event stream, list env vars' '
205+
test_when_finished "rm trace.event actual expect" &&
206+
GIT_TRACE2_EVENT="$(pwd)/trace.event" \
207+
GIT_TRACE2_ENV_VARS="A_VAR,OTHER_VAR,MISSING" \
208+
A_VAR=1 OTHER_VAR="hello world" test-tool trace2 001return 0 &&
209+
perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual &&
210+
sed -e "s/^|//" >expect <<-EOF &&
211+
|VAR1 = {
212+
| "_SID0_":{
213+
| "argv":[
214+
| "_EXE_",
215+
| "trace2",
216+
| "001return",
217+
| "0"
218+
| ],
219+
| "exit_code":0,
220+
| "hierarchy":"trace2",
221+
| "name":"trace2",
222+
| "params":[
223+
| {
224+
| "param":"A_VAR",
225+
| "value":"1"
226+
| },
227+
| {
228+
| "param":"OTHER_VAR",
229+
| "value":"hello world"
230+
| }
231+
| ],
232+
| "version":"$V"
233+
| }
234+
|};
235+
EOF
236+
test_cmp expect actual
237+
'
238+
202239
test_expect_success JSON_PP 'basic trace2_data' '
203240
test_when_finished "rm trace.event actual expect" &&
204241
GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 &&

trace2.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ static void tr2main_atexit_handler(void)
121121
tr2_sid_release();
122122
tr2_cmd_name_release();
123123
tr2_cfg_free_patterns();
124+
tr2_cfg_free_env_vars();
124125
tr2_sysenv_release();
125126

126127
trace2_enabled = 0;
@@ -311,6 +312,14 @@ void trace2_cmd_list_config_fl(const char *file, int line)
311312
tr2_cfg_list_config_fl(file, line);
312313
}
313314

315+
void trace2_cmd_list_env_vars_fl(const char *file, int line)
316+
{
317+
if (!trace2_enabled)
318+
return;
319+
320+
tr2_list_env_vars_fl(file, line);
321+
}
322+
314323
void trace2_cmd_set_config_fl(const char *file, int line, const char *key,
315324
const char *value)
316325
{

trace2.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,19 @@ void trace2_cmd_list_config_fl(const char *file, int line);
182182

183183
#define trace2_cmd_list_config() trace2_cmd_list_config_fl(__FILE__, __LINE__)
184184

185+
/*
186+
* Emit one or more 'def_param' events for "important" environment variables.
187+
*
188+
* Use the TR2_SYSENV_ENV_VARS setting to register a comma-separated list of
189+
* environment variables considered important. For example:
190+
* git config --system trace2.envVars 'GIT_HTTP_USER_AGENT,GIT_CONFIG'
191+
* or:
192+
* GIT_TRACE2_ENV_VARS="GIT_HTTP_USER_AGENT,GIT_CONFIG"
193+
*/
194+
void trace2_cmd_list_env_vars_fl(const char *file, int line);
195+
196+
#define trace2_cmd_list_env_vars() trace2_cmd_list_env_vars_fl(__FILE__, __LINE__)
197+
185198
/*
186199
* Emit a "def_param" event for the given config key/value pair IF
187200
* we consider the key to be "important".

trace2/tr2_cfg.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ static struct strbuf **tr2_cfg_patterns;
77
static int tr2_cfg_count_patterns;
88
static int tr2_cfg_loaded;
99

10+
static struct strbuf **tr2_cfg_env_vars;
11+
static int tr2_cfg_env_vars_count;
12+
static int tr2_cfg_env_vars_loaded;
13+
1014
/*
1115
* Parse a string containing a comma-delimited list of config keys
1216
* or wildcard patterns into a list of strbufs.
@@ -46,6 +50,45 @@ void tr2_cfg_free_patterns(void)
4650
tr2_cfg_loaded = 0;
4751
}
4852

53+
/*
54+
* Parse a string containing a comma-delimited list of environment variable
55+
* names into a list of strbufs.
56+
*/
57+
static int tr2_load_env_vars(void)
58+
{
59+
struct strbuf **s;
60+
const char *varlist;
61+
62+
if (tr2_cfg_env_vars_loaded)
63+
return tr2_cfg_env_vars_count;
64+
tr2_cfg_env_vars_loaded = 1;
65+
66+
varlist = tr2_sysenv_get(TR2_SYSENV_ENV_VARS);
67+
if (!varlist || !*varlist)
68+
return tr2_cfg_env_vars_count;
69+
70+
tr2_cfg_env_vars = strbuf_split_buf(varlist, strlen(varlist), ',', -1);
71+
for (s = tr2_cfg_env_vars; *s; s++) {
72+
struct strbuf *buf = *s;
73+
74+
if (buf->len && buf->buf[buf->len - 1] == ',')
75+
strbuf_setlen(buf, buf->len - 1);
76+
strbuf_trim_trailing_newline(*s);
77+
strbuf_trim(*s);
78+
}
79+
80+
tr2_cfg_env_vars_count = s - tr2_cfg_env_vars;
81+
return tr2_cfg_env_vars_count;
82+
}
83+
84+
void tr2_cfg_free_env_vars(void)
85+
{
86+
if (tr2_cfg_env_vars)
87+
strbuf_list_free(tr2_cfg_env_vars);
88+
tr2_cfg_env_vars_count = 0;
89+
tr2_cfg_env_vars_loaded = 0;
90+
}
91+
4992
struct tr2_cfg_data {
5093
const char *file;
5194
int line;
@@ -79,6 +122,21 @@ void tr2_cfg_list_config_fl(const char *file, int line)
79122
read_early_config(tr2_cfg_cb, &data);
80123
}
81124

125+
void tr2_list_env_vars_fl(const char *file, int line)
126+
{
127+
struct strbuf **s;
128+
129+
if (tr2_load_env_vars() <= 0)
130+
return;
131+
132+
for (s = tr2_cfg_env_vars; *s; s++) {
133+
struct strbuf *buf = *s;
134+
const char *val = getenv(buf->buf);
135+
if (val && *val)
136+
trace2_def_param_fl(file, line, buf->buf, val);
137+
}
138+
}
139+
82140
void tr2_cfg_set_fl(const char *file, int line, const char *key,
83141
const char *value)
84142
{

trace2/tr2_cfg.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
*/
88
void tr2_cfg_list_config_fl(const char *file, int line);
99

10+
/*
11+
* Iterate over all "interesting" environment variables and emit 'def_param'
12+
* events for them to TRACE2.
13+
*/
14+
void tr2_list_env_vars_fl(const char *file, int line);
15+
1016
/*
1117
* Emit a "def_param" event for the given key/value pair IF we consider
1218
* the key to be "interesting".
@@ -16,4 +22,6 @@ void tr2_cfg_set_fl(const char *file, int line, const char *key,
1622

1723
void tr2_cfg_free_patterns(void);
1824

25+
void tr2_cfg_free_env_vars(void);
26+
1927
#endif /* TR2_CFG_H */

trace2/tr2_sysenv.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ struct tr2_sysenv_entry {
2929
static struct tr2_sysenv_entry tr2_sysenv_settings[] = {
3030
[TR2_SYSENV_CFG_PARAM] = { "GIT_TRACE2_CONFIG_PARAMS",
3131
"trace2.configparams" },
32+
[TR2_SYSENV_ENV_VARS] = { "GIT_TRACE2_ENV_VARS",
33+
"trace2.envvars" },
3234

3335
[TR2_SYSENV_DST_DEBUG] = { "GIT_TRACE2_DST_DEBUG",
3436
"trace2.destinationdebug" },

0 commit comments

Comments
 (0)