3 #include "run-command.h"
6 #include "trace2/tr2_dst.h"
7 #include "trace2/tr2_sysenv.h"
8 #include "trace2/tr2_tbuf.h"
9 #include "trace2/tr2_tgt.h"
10 #include "trace2/tr2_tls.h"
12 static struct tr2_dst tr2dst_normal
= {
13 .sysenv_var
= TR2_SYSENV_NORMAL
,
17 * Use the TR2_SYSENV_NORMAL_BRIEF setting to omit the "<time> <file>:<line>"
18 * fields from each line written to the builtin normal target.
20 * Unit tests may want to use this to help with testing.
22 static int tr2env_normal_be_brief
;
24 #define TR2FMT_NORMAL_FL_WIDTH (50)
26 static int fn_init(void)
28 int want
= tr2_dst_trace_want(&tr2dst_normal
);
35 brief
= tr2_sysenv_get(TR2_SYSENV_NORMAL_BRIEF
);
36 if (brief
&& *brief
&&
37 ((want_brief
= git_parse_maybe_bool(brief
)) != -1))
38 tr2env_normal_be_brief
= want_brief
;
43 static void fn_term(void)
45 tr2_dst_trace_disable(&tr2dst_normal
);
48 static void normal_fmt_prepare(const char *file
, int line
, struct strbuf
*buf
)
50 strbuf_setlen(buf
, 0);
52 if (!tr2env_normal_be_brief
) {
53 struct tr2_tbuf tb_now
;
55 tr2_tbuf_local_time(&tb_now
);
56 strbuf_addstr(buf
, tb_now
.buf
);
57 strbuf_addch(buf
, ' ');
60 strbuf_addf(buf
, "%s:%d ", file
, line
);
61 while (buf
->len
< TR2FMT_NORMAL_FL_WIDTH
)
62 strbuf_addch(buf
, ' ');
66 static void normal_io_write_fl(const char *file
, int line
,
67 const struct strbuf
*buf_payload
)
69 struct strbuf buf_line
= STRBUF_INIT
;
71 normal_fmt_prepare(file
, line
, &buf_line
);
72 strbuf_addbuf(&buf_line
, buf_payload
);
73 tr2_dst_write_line(&tr2dst_normal
, &buf_line
);
74 strbuf_release(&buf_line
);
77 static void fn_version_fl(const char *file
, int line
)
79 struct strbuf buf_payload
= STRBUF_INIT
;
81 strbuf_addf(&buf_payload
, "version %s", git_version_string
);
82 normal_io_write_fl(file
, line
, &buf_payload
);
83 strbuf_release(&buf_payload
);
86 static void fn_start_fl(const char *file
, int line
,
87 uint64_t us_elapsed_absolute
, const char **argv
)
89 struct strbuf buf_payload
= STRBUF_INIT
;
91 strbuf_addstr(&buf_payload
, "start ");
92 sq_append_quote_argv_pretty(&buf_payload
, argv
);
93 normal_io_write_fl(file
, line
, &buf_payload
);
94 strbuf_release(&buf_payload
);
97 static void fn_exit_fl(const char *file
, int line
, uint64_t us_elapsed_absolute
,
100 struct strbuf buf_payload
= STRBUF_INIT
;
101 double elapsed
= (double)us_elapsed_absolute
/ 1000000.0;
103 strbuf_addf(&buf_payload
, "exit elapsed:%.6f code:%d", elapsed
, code
);
104 normal_io_write_fl(file
, line
, &buf_payload
);
105 strbuf_release(&buf_payload
);
108 static void fn_signal(uint64_t us_elapsed_absolute
, int signo
)
110 struct strbuf buf_payload
= STRBUF_INIT
;
111 double elapsed
= (double)us_elapsed_absolute
/ 1000000.0;
113 strbuf_addf(&buf_payload
, "signal elapsed:%.6f code:%d", elapsed
,
115 normal_io_write_fl(__FILE__
, __LINE__
, &buf_payload
);
116 strbuf_release(&buf_payload
);
119 static void fn_atexit(uint64_t us_elapsed_absolute
, int code
)
121 struct strbuf buf_payload
= STRBUF_INIT
;
122 double elapsed
= (double)us_elapsed_absolute
/ 1000000.0;
124 strbuf_addf(&buf_payload
, "atexit elapsed:%.6f code:%d", elapsed
, code
);
125 normal_io_write_fl(__FILE__
, __LINE__
, &buf_payload
);
126 strbuf_release(&buf_payload
);
129 static void maybe_append_string_va(struct strbuf
*buf
, const char *fmt
,
135 va_copy(copy_ap
, ap
);
136 strbuf_vaddf(buf
, fmt
, copy_ap
);
142 static void fn_error_va_fl(const char *file
, int line
, const char *fmt
,
145 struct strbuf buf_payload
= STRBUF_INIT
;
147 strbuf_addstr(&buf_payload
, "error");
149 strbuf_addch(&buf_payload
, ' ');
150 maybe_append_string_va(&buf_payload
, fmt
, ap
);
152 normal_io_write_fl(file
, line
, &buf_payload
);
153 strbuf_release(&buf_payload
);
156 static void fn_command_path_fl(const char *file
, int line
, const char *pathname
)
158 struct strbuf buf_payload
= STRBUF_INIT
;
160 strbuf_addf(&buf_payload
, "cmd_path %s", pathname
);
161 normal_io_write_fl(file
, line
, &buf_payload
);
162 strbuf_release(&buf_payload
);
165 static void fn_command_ancestry_fl(const char *file
, int line
, const char **parent_names
)
167 const char *parent_name
= NULL
;
168 struct strbuf buf_payload
= STRBUF_INIT
;
170 /* cmd_ancestry parent <- grandparent <- great-grandparent */
171 strbuf_addstr(&buf_payload
, "cmd_ancestry ");
172 while ((parent_name
= *parent_names
++)) {
173 strbuf_addstr(&buf_payload
, parent_name
);
174 /* if we'll write another one after this, add a delimiter */
175 if (parent_names
&& *parent_names
)
176 strbuf_addstr(&buf_payload
, " <- ");
179 normal_io_write_fl(file
, line
, &buf_payload
);
180 strbuf_release(&buf_payload
);
183 static void fn_command_name_fl(const char *file
, int line
, const char *name
,
184 const char *hierarchy
)
186 struct strbuf buf_payload
= STRBUF_INIT
;
188 strbuf_addf(&buf_payload
, "cmd_name %s", name
);
189 if (hierarchy
&& *hierarchy
)
190 strbuf_addf(&buf_payload
, " (%s)", hierarchy
);
191 normal_io_write_fl(file
, line
, &buf_payload
);
192 strbuf_release(&buf_payload
);
195 static void fn_command_mode_fl(const char *file
, int line
, const char *mode
)
197 struct strbuf buf_payload
= STRBUF_INIT
;
199 strbuf_addf(&buf_payload
, "cmd_mode %s", mode
);
200 normal_io_write_fl(file
, line
, &buf_payload
);
201 strbuf_release(&buf_payload
);
204 static void fn_alias_fl(const char *file
, int line
, const char *alias
,
207 struct strbuf buf_payload
= STRBUF_INIT
;
209 strbuf_addf(&buf_payload
, "alias %s -> ", alias
);
210 sq_append_quote_argv_pretty(&buf_payload
, argv
);
211 normal_io_write_fl(file
, line
, &buf_payload
);
212 strbuf_release(&buf_payload
);
215 static void fn_child_start_fl(const char *file
, int line
,
216 uint64_t us_elapsed_absolute
,
217 const struct child_process
*cmd
)
219 struct strbuf buf_payload
= STRBUF_INIT
;
221 strbuf_addf(&buf_payload
, "child_start[%d]", cmd
->trace2_child_id
);
224 strbuf_addstr(&buf_payload
, " cd ");
225 sq_quote_buf_pretty(&buf_payload
, cmd
->dir
);
226 strbuf_addstr(&buf_payload
, ";");
230 * TODO if (cmd->env) { Consider dumping changes to environment. }
231 * See trace_add_env() in run-command.c as used by original trace.c
234 strbuf_addch(&buf_payload
, ' ');
236 strbuf_addstr(&buf_payload
, "git ");
237 sq_append_quote_argv_pretty(&buf_payload
, cmd
->args
.v
);
239 normal_io_write_fl(file
, line
, &buf_payload
);
240 strbuf_release(&buf_payload
);
243 static void fn_child_exit_fl(const char *file
, int line
,
244 uint64_t us_elapsed_absolute
, int cid
, int pid
,
245 int code
, uint64_t us_elapsed_child
)
247 struct strbuf buf_payload
= STRBUF_INIT
;
248 double elapsed
= (double)us_elapsed_child
/ 1000000.0;
250 strbuf_addf(&buf_payload
, "child_exit[%d] pid:%d code:%d elapsed:%.6f",
251 cid
, pid
, code
, elapsed
);
252 normal_io_write_fl(file
, line
, &buf_payload
);
253 strbuf_release(&buf_payload
);
256 static void fn_child_ready_fl(const char *file
, int line
,
257 uint64_t us_elapsed_absolute
, int cid
, int pid
,
258 const char *ready
, uint64_t us_elapsed_child
)
260 struct strbuf buf_payload
= STRBUF_INIT
;
261 double elapsed
= (double)us_elapsed_child
/ 1000000.0;
263 strbuf_addf(&buf_payload
, "child_ready[%d] pid:%d ready:%s elapsed:%.6f",
264 cid
, pid
, ready
, elapsed
);
265 normal_io_write_fl(file
, line
, &buf_payload
);
266 strbuf_release(&buf_payload
);
269 static void fn_exec_fl(const char *file
, int line
, uint64_t us_elapsed_absolute
,
270 int exec_id
, const char *exe
, const char **argv
)
272 struct strbuf buf_payload
= STRBUF_INIT
;
274 strbuf_addf(&buf_payload
, "exec[%d] ", exec_id
);
276 strbuf_addstr(&buf_payload
, exe
);
277 strbuf_addch(&buf_payload
, ' ');
279 sq_append_quote_argv_pretty(&buf_payload
, argv
);
280 normal_io_write_fl(file
, line
, &buf_payload
);
281 strbuf_release(&buf_payload
);
284 static void fn_exec_result_fl(const char *file
, int line
,
285 uint64_t us_elapsed_absolute
, int exec_id
,
288 struct strbuf buf_payload
= STRBUF_INIT
;
290 strbuf_addf(&buf_payload
, "exec_result[%d] code:%d", exec_id
, code
);
292 strbuf_addf(&buf_payload
, " err:%s", strerror(code
));
293 normal_io_write_fl(file
, line
, &buf_payload
);
294 strbuf_release(&buf_payload
);
297 static void fn_param_fl(const char *file
, int line
, const char *param
,
300 struct strbuf buf_payload
= STRBUF_INIT
;
301 enum config_scope scope
= current_config_scope();
302 const char *scope_name
= config_scope_name(scope
);
304 strbuf_addf(&buf_payload
, "def_param scope:%s %s=%s", scope_name
, param
,
306 normal_io_write_fl(file
, line
, &buf_payload
);
307 strbuf_release(&buf_payload
);
310 static void fn_repo_fl(const char *file
, int line
,
311 const struct repository
*repo
)
313 struct strbuf buf_payload
= STRBUF_INIT
;
315 strbuf_addstr(&buf_payload
, "worktree ");
316 sq_quote_buf_pretty(&buf_payload
, repo
->worktree
);
317 normal_io_write_fl(file
, line
, &buf_payload
);
318 strbuf_release(&buf_payload
);
321 static void fn_printf_va_fl(const char *file
, int line
,
322 uint64_t us_elapsed_absolute
, const char *fmt
,
325 struct strbuf buf_payload
= STRBUF_INIT
;
327 maybe_append_string_va(&buf_payload
, fmt
, ap
);
328 normal_io_write_fl(file
, line
, &buf_payload
);
329 strbuf_release(&buf_payload
);
332 struct tr2_tgt tr2_tgt_normal
= {
333 .pdst
= &tr2dst_normal
,
338 .pfn_version_fl
= fn_version_fl
,
339 .pfn_start_fl
= fn_start_fl
,
340 .pfn_exit_fl
= fn_exit_fl
,
341 .pfn_signal
= fn_signal
,
342 .pfn_atexit
= fn_atexit
,
343 .pfn_error_va_fl
= fn_error_va_fl
,
344 .pfn_command_path_fl
= fn_command_path_fl
,
345 .pfn_command_ancestry_fl
= fn_command_ancestry_fl
,
346 .pfn_command_name_fl
= fn_command_name_fl
,
347 .pfn_command_mode_fl
= fn_command_mode_fl
,
348 .pfn_alias_fl
= fn_alias_fl
,
349 .pfn_child_start_fl
= fn_child_start_fl
,
350 .pfn_child_exit_fl
= fn_child_exit_fl
,
351 .pfn_child_ready_fl
= fn_child_ready_fl
,
352 .pfn_thread_start_fl
= NULL
,
353 .pfn_thread_exit_fl
= NULL
,
354 .pfn_exec_fl
= fn_exec_fl
,
355 .pfn_exec_result_fl
= fn_exec_result_fl
,
356 .pfn_param_fl
= fn_param_fl
,
357 .pfn_repo_fl
= fn_repo_fl
,
358 .pfn_region_enter_printf_va_fl
= NULL
,
359 .pfn_region_leave_printf_va_fl
= NULL
,
361 .pfn_data_json_fl
= NULL
,
362 .pfn_printf_va_fl
= fn_printf_va_fl
,