]>
Commit | Line | Data |
---|---|---|
c7d3f8cb KB |
1 | trace API |
2 | ========= | |
3 | ||
4 | The trace API can be used to print debug messages to stderr or a file. Trace | |
5 | code is inactive unless explicitly enabled by setting `GIT_TRACE*` environment | |
6 | variables. | |
7 | ||
8 | The trace implementation automatically adds `timestamp file:line ... \n` to | |
9 | all trace messages. E.g.: | |
10 | ||
11 | ------------ | |
12 | 23:59:59.123456 git.c:312 trace: built-in: git 'foo' | |
13 | 00:00:00.000001 builtin/foo.c:99 foo: some message | |
14 | ------------ | |
15 | ||
16 | Data Structures | |
17 | --------------- | |
18 | ||
19 | `struct trace_key`:: | |
20 | ||
21 | Defines a trace key (or category). The default (for API functions that | |
22 | don't take a key) is `GIT_TRACE`. | |
23 | + | |
24 | E.g. to define a trace key controlled by environment variable `GIT_TRACE_FOO`: | |
25 | + | |
26 | ------------ | |
27 | static struct trace_key trace_foo = TRACE_KEY_INIT(FOO); | |
28 | ||
29 | static void trace_print_foo(const char *message) | |
30 | { | |
4232b21f | 31 | trace_printf_key(&trace_foo, "%s", message); |
c7d3f8cb KB |
32 | } |
33 | ------------ | |
34 | + | |
35 | Note: don't use `const` as the trace implementation stores internal state in | |
36 | the `trace_key` structure. | |
37 | ||
38 | Functions | |
39 | --------- | |
40 | ||
41 | `int trace_want(struct trace_key *key)`:: | |
42 | ||
43 | Checks whether the trace key is enabled. Used to prevent expensive | |
44 | string formatting before calling one of the printing APIs. | |
45 | ||
46 | `void trace_disable(struct trace_key *key)`:: | |
47 | ||
48 | Disables tracing for the specified key, even if the environment | |
49 | variable was set. | |
50 | ||
51 | `void trace_printf(const char *format, ...)`:: | |
52 | `void trace_printf_key(struct trace_key *key, const char *format, ...)`:: | |
53 | ||
54 | Prints a formatted message, similar to printf. | |
55 | ||
56 | `void trace_argv_printf(const char **argv, const char *format, ...)``:: | |
57 | ||
58 | Prints a formatted message, followed by a quoted list of arguments. | |
59 | ||
60 | `void trace_strbuf(struct trace_key *key, const struct strbuf *data)`:: | |
61 | ||
62 | Prints the strbuf, without additional formatting (i.e. doesn't | |
63 | choke on `%` or even `\0`). | |
64 | ||
65 | `uint64_t getnanotime(void)`:: | |
66 | ||
67 | Returns nanoseconds since the epoch (01/01/1970), typically used | |
68 | for performance measurements. | |
69 | + | |
70 | Currently there are high precision timer implementations for Linux (using | |
71 | `clock_gettime(CLOCK_MONOTONIC)`) and Windows (`QueryPerformanceCounter`). | |
72 | Other platforms use `gettimeofday` as time source. | |
73 | ||
74 | `void trace_performance(uint64_t nanos, const char *format, ...)`:: | |
75 | `void trace_performance_since(uint64_t start, const char *format, ...)`:: | |
76 | ||
77 | Prints the elapsed time (in nanoseconds), or elapsed time since | |
78 | `start`, followed by a formatted message. Enabled via environment | |
79 | variable `GIT_TRACE_PERFORMANCE`. Used for manual profiling, e.g.: | |
80 | + | |
81 | ------------ | |
82 | uint64_t start = getnanotime(); | |
83 | /* code section to measure */ | |
84 | trace_performance_since(start, "foobar"); | |
85 | ------------ | |
86 | + | |
87 | ------------ | |
88 | uint64_t t = 0; | |
89 | for (;;) { | |
90 | /* ignore */ | |
91 | t -= getnanotime(); | |
92 | /* code section to measure */ | |
93 | t += getnanotime(); | |
94 | /* ignore */ | |
95 | } | |
96 | trace_performance(t, "frotz"); | |
97 | ------------ | |
3bd1b51d CC |
98 | |
99 | Bugs & Caveats | |
100 | -------------- | |
101 | ||
102 | GIT_TRACE_* environment variables can be used to tell Git to show | |
103 | trace output to its standard error stream. Git can often spawn a pager | |
104 | internally to run its subcommand and send its standard output and | |
105 | standard error to it. | |
106 | ||
107 | Because GIT_TRACE_PERFORMANCE trace is generated only at the very end | |
108 | of the program with atexit(), which happens after the pager exits, it | |
109 | would not work well if you send its log to the standard error output | |
110 | and let Git spawn the pager at the same time. | |
111 | ||
112 | As a work around, you can for example use '--no-pager', or set | |
113 | GIT_TRACE_PERFORMANCE to another file descriptor which is redirected | |
114 | to stderr, or set GIT_TRACE_PERFORMANCE to a file specified by its | |
115 | absolute path. | |
116 | ||
117 | For example instead of the following command which by default may not | |
118 | print any performance information: | |
119 | ||
120 | ------------ | |
121 | GIT_TRACE_PERFORMANCE=2 git log -1 | |
122 | ------------ | |
123 | ||
124 | you may want to use: | |
125 | ||
126 | ------------ | |
127 | GIT_TRACE_PERFORMANCE=2 git --no-pager log -1 | |
128 | ------------ | |
129 | ||
130 | or: | |
131 | ||
132 | ------------ | |
133 | GIT_TRACE_PERFORMANCE=3 3>&2 git log -1 | |
134 | ------------ | |
135 | ||
136 | or: | |
137 | ||
138 | ------------ | |
139 | GIT_TRACE_PERFORMANCE=/path/to/log/file git log -1 | |
140 | ------------ |