44#include "git-compat-util.h"
55#include "strbuf.h"
66
7+ /**
8+ * The trace API can be used to print debug messages to stderr or a file. Trace
9+ * code is inactive unless explicitly enabled by setting `GIT_TRACE*` environment
10+ * variables.
11+ *
12+ * The trace implementation automatically adds `timestamp file:line ... \n` to
13+ * all trace messages. E.g.:
14+ *
15+ * ------------
16+ * 23:59:59.123456 git.c:312 trace: built-in: git 'foo'
17+ * 00:00:00.000001 builtin/foo.c:99 foo: some message
18+ * ------------
19+ *
20+ * Bugs & Caveats
21+ * --------------
22+ *
23+ * GIT_TRACE_* environment variables can be used to tell Git to show
24+ * trace output to its standard error stream. Git can often spawn a pager
25+ * internally to run its subcommand and send its standard output and
26+ * standard error to it.
27+ *
28+ * Because GIT_TRACE_PERFORMANCE trace is generated only at the very end
29+ * of the program with atexit(), which happens after the pager exits, it
30+ * would not work well if you send its log to the standard error output
31+ * and let Git spawn the pager at the same time.
32+ *
33+ * As a work around, you can for example use '--no-pager', or set
34+ * GIT_TRACE_PERFORMANCE to another file descriptor which is redirected
35+ * to stderr, or set GIT_TRACE_PERFORMANCE to a file specified by its
36+ * absolute path.
37+ *
38+ * For example instead of the following command which by default may not
39+ * print any performance information:
40+ *
41+ * ------------
42+ * GIT_TRACE_PERFORMANCE=2 git log -1
43+ * ------------
44+ *
45+ * you may want to use:
46+ *
47+ * ------------
48+ * GIT_TRACE_PERFORMANCE=2 git --no-pager log -1
49+ * ------------
50+ *
51+ * or:
52+ *
53+ * ------------
54+ * GIT_TRACE_PERFORMANCE=3 3>&2 git log -1
55+ * ------------
56+ *
57+ * or:
58+ *
59+ * ------------
60+ * GIT_TRACE_PERFORMANCE=/path/to/log/file git log -1
61+ * ------------
62+ *
63+ */
64+
65+ /**
66+ * Defines a trace key (or category). The default (for API functions that
67+ * don't take a key) is `GIT_TRACE`.
68+ *
69+ * E.g. to define a trace key controlled by environment variable `GIT_TRACE_FOO`:
70+ *
71+ * ------------
72+ * static struct trace_key trace_foo = TRACE_KEY_INIT(FOO);
73+ *
74+ * static void trace_print_foo(const char *message)
75+ * {
76+ * trace_printf_key(&trace_foo, "%s", message);
77+ * }
78+ * ------------
79+ *
80+ * Note: don't use `const` as the trace implementation stores internal state in
81+ * the `trace_key` structure.
82+ */
783struct trace_key {
884 const char * const key ;
985 int fd ;
@@ -18,31 +94,84 @@ extern struct trace_key trace_perf_key;
1894extern struct trace_key trace_setup_key ;
1995
2096void trace_repo_setup (const char * prefix );
97+
98+ /**
99+ * Checks whether the trace key is enabled. Used to prevent expensive
100+ * string formatting before calling one of the printing APIs.
101+ */
21102int trace_want (struct trace_key * key );
103+
104+ /**
105+ * Disables tracing for the specified key, even if the environment variable
106+ * was set.
107+ */
22108void trace_disable (struct trace_key * key );
109+
110+ /**
111+ * Returns nanoseconds since the epoch (01/01/1970), typically used
112+ * for performance measurements.
113+ * Currently there are high precision timer implementations for Linux (using
114+ * `clock_gettime(CLOCK_MONOTONIC)`) and Windows (`QueryPerformanceCounter`).
115+ * Other platforms use `gettimeofday` as time source.
116+ */
23117uint64_t getnanotime (void );
118+
24119void trace_command_performance (const char * * argv );
25120void trace_verbatim (struct trace_key * key , const void * buf , unsigned len );
26121uint64_t trace_performance_enter (void );
27122
28123#ifndef HAVE_VARIADIC_MACROS
29124
125+ /**
126+ * Prints a formatted message, similar to printf.
127+ */
30128__attribute__((format (printf , 1 , 2 )))
31129void trace_printf (const char * format , ...);
32130
33131__attribute__((format (printf , 2 , 3 )))
34132void trace_printf_key (struct trace_key * key , const char * format , ...);
35133
134+ /**
135+ * Prints a formatted message, followed by a quoted list of arguments.
136+ */
36137__attribute__((format (printf , 2 , 3 )))
37138void trace_argv_printf (const char * * argv , const char * format , ...);
38139
140+ /**
141+ * Prints the strbuf, without additional formatting (i.e. doesn't
142+ * choke on `%` or even `\0`).
143+ */
39144void trace_strbuf (struct trace_key * key , const struct strbuf * data );
40145
41- /* Prints elapsed time (in nanoseconds) if GIT_TRACE_PERFORMANCE is enabled. */
146+ /**
147+ * Prints elapsed time (in nanoseconds) if GIT_TRACE_PERFORMANCE is enabled.
148+ *
149+ * Example:
150+ * ------------
151+ * uint64_t t = 0;
152+ * for (;;) {
153+ * // ignore
154+ * t -= getnanotime();
155+ * // code section to measure
156+ * t += getnanotime();
157+ * // ignore
158+ * }
159+ * trace_performance(t, "frotz");
160+ * ------------
161+ */
42162__attribute__((format (printf , 2 , 3 )))
43163void trace_performance (uint64_t nanos , const char * format , ...);
44164
45- /* Prints elapsed time since 'start' if GIT_TRACE_PERFORMANCE is enabled. */
165+ /**
166+ * Prints elapsed time since 'start' if GIT_TRACE_PERFORMANCE is enabled.
167+ *
168+ * Example:
169+ * ------------
170+ * uint64_t start = getnanotime();
171+ * // code section to measure
172+ * trace_performance_since(start, "foobar");
173+ * ------------
174+ */
46175__attribute__((format (printf , 2 , 3 )))
47176void trace_performance_since (uint64_t start , const char * format , ...);
48177
0 commit comments