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
= { TR2_SYSENV_NORMAL
, 0, 0, 0, 0 };
15 * Use the TR2_SYSENV_NORMAL_BRIEF setting to omit the "<time> <file>:<line>"
16 * fields from each line written to the builtin normal target.
18 * Unit tests may want to use this to help with testing.
20 static int tr2env_normal_be_brief
;
22 #define TR2FMT_NORMAL_FL_WIDTH (50)
24 static int fn_init(void)
26 int want
= tr2_dst_trace_want(&tr2dst_normal
);
33 brief
= tr2_sysenv_get(TR2_SYSENV_NORMAL_BRIEF
);
34 if (brief
&& *brief
&&
35 ((want_brief
= git_parse_maybe_bool(brief
)) != -1))
36 tr2env_normal_be_brief
= want_brief
;
41 static void fn_term(void)
43 tr2_dst_trace_disable(&tr2dst_normal
);
46 static void normal_fmt_prepare(const char *file
, int line
, struct strbuf
*buf
)
48 strbuf_setlen(buf
, 0);
50 if (!tr2env_normal_be_brief
) {
51 struct tr2_tbuf tb_now
;
53 tr2_tbuf_local_time(&tb_now
);
54 strbuf_addstr(buf
, tb_now
.buf
);
55 strbuf_addch(buf
, ' ');
58 strbuf_addf(buf
, "%s:%d ", file
, line
);
59 while (buf
->len
< TR2FMT_NORMAL_FL_WIDTH
)
60 strbuf_addch(buf
, ' ');
64 static void normal_io_write_fl(const char *file
, int line
,
65 const struct strbuf
*buf_payload
)
67 struct strbuf buf_line
= STRBUF_INIT
;
69 normal_fmt_prepare(file
, line
, &buf_line
);
70 strbuf_addbuf(&buf_line
, buf_payload
);
71 tr2_dst_write_line(&tr2dst_normal
, &buf_line
);
72 strbuf_release(&buf_line
);
75 static void fn_version_fl(const char *file
, int line
)
77 struct strbuf buf_payload
= STRBUF_INIT
;
79 strbuf_addf(&buf_payload
, "version %s", git_version_string
);
80 normal_io_write_fl(file
, line
, &buf_payload
);
81 strbuf_release(&buf_payload
);
84 static void fn_start_fl(const char *file
, int line
,
85 uint64_t us_elapsed_absolute
, const char **argv
)
87 struct strbuf buf_payload
= STRBUF_INIT
;
89 strbuf_addstr(&buf_payload
, "start ");
90 sq_append_quote_argv_pretty(&buf_payload
, argv
);
91 normal_io_write_fl(file
, line
, &buf_payload
);
92 strbuf_release(&buf_payload
);
95 static void fn_exit_fl(const char *file
, int line
, uint64_t us_elapsed_absolute
,
98 struct strbuf buf_payload
= STRBUF_INIT
;
99 double elapsed
= (double)us_elapsed_absolute
/ 1000000.0;
101 strbuf_addf(&buf_payload
, "exit elapsed:%.6f code:%d", elapsed
, code
);
102 normal_io_write_fl(file
, line
, &buf_payload
);
103 strbuf_release(&buf_payload
);
106 static void fn_signal(uint64_t us_elapsed_absolute
, int signo
)
108 struct strbuf buf_payload
= STRBUF_INIT
;
109 double elapsed
= (double)us_elapsed_absolute
/ 1000000.0;
111 strbuf_addf(&buf_payload
, "signal elapsed:%.6f code:%d", elapsed
,
113 normal_io_write_fl(__FILE__
, __LINE__
, &buf_payload
);
114 strbuf_release(&buf_payload
);
117 static void fn_atexit(uint64_t us_elapsed_absolute
, int code
)
119 struct strbuf buf_payload
= STRBUF_INIT
;
120 double elapsed
= (double)us_elapsed_absolute
/ 1000000.0;
122 strbuf_addf(&buf_payload
, "atexit elapsed:%.6f code:%d", elapsed
, code
);
123 normal_io_write_fl(__FILE__
, __LINE__
, &buf_payload
);
124 strbuf_release(&buf_payload
);
127 static void maybe_append_string_va(struct strbuf
*buf
, const char *fmt
,
133 va_copy(copy_ap
, ap
);
134 strbuf_vaddf(buf
, fmt
, copy_ap
);
140 static void fn_error_va_fl(const char *file
, int line
, const char *fmt
,
143 struct strbuf buf_payload
= STRBUF_INIT
;
145 strbuf_addstr(&buf_payload
, "error");
147 strbuf_addch(&buf_payload
, ' ');
148 maybe_append_string_va(&buf_payload
, fmt
, ap
);
150 normal_io_write_fl(file
, line
, &buf_payload
);
151 strbuf_release(&buf_payload
);
154 static void fn_command_path_fl(const char *file
, int line
, const char *pathname
)
156 struct strbuf buf_payload
= STRBUF_INIT
;
158 strbuf_addf(&buf_payload
, "cmd_path %s", pathname
);
159 normal_io_write_fl(file
, line
, &buf_payload
);
160 strbuf_release(&buf_payload
);
163 static void fn_command_ancestry_fl(const char *file
, int line
, const char **parent_names
)
165 const char *parent_name
= NULL
;
166 struct strbuf buf_payload
= STRBUF_INIT
;
168 /* cmd_ancestry parent <- grandparent <- great-grandparent */
169 strbuf_addstr(&buf_payload
, "cmd_ancestry ");
170 while ((parent_name
= *parent_names
++)) {
171 strbuf_addstr(&buf_payload
, parent_name
);
172 /* if we'll write another one after this, add a delimiter */
173 if (parent_names
&& *parent_names
)
174 strbuf_addstr(&buf_payload
, " <- ");
177 normal_io_write_fl(file
, line
, &buf_payload
);
178 strbuf_release(&buf_payload
);
181 static void fn_command_name_fl(const char *file
, int line
, const char *name
,
182 const char *hierarchy
)
184 struct strbuf buf_payload
= STRBUF_INIT
;
186 strbuf_addf(&buf_payload
, "cmd_name %s", name
);
187 if (hierarchy
&& *hierarchy
)
188 strbuf_addf(&buf_payload
, " (%s)", hierarchy
);
189 normal_io_write_fl(file
, line
, &buf_payload
);
190 strbuf_release(&buf_payload
);
193 static void fn_command_mode_fl(const char *file
, int line
, const char *mode
)
195 struct strbuf buf_payload
= STRBUF_INIT
;
197 strbuf_addf(&buf_payload
, "cmd_mode %s", mode
);
198 normal_io_write_fl(file
, line
, &buf_payload
);
199 strbuf_release(&buf_payload
);
202 static void fn_alias_fl(const char *file
, int line
, const char *alias
,
205 struct strbuf buf_payload
= STRBUF_INIT
;
207 strbuf_addf(&buf_payload
, "alias %s -> ", alias
);
208 sq_append_quote_argv_pretty(&buf_payload
, argv
);
209 normal_io_write_fl(file
, line
, &buf_payload
);
210 strbuf_release(&buf_payload
);
213 static void fn_child_start_fl(const char *file
, int line
,
214 uint64_t us_elapsed_absolute
,
215 const struct child_process
*cmd
)
217 struct strbuf buf_payload
= STRBUF_INIT
;
219 strbuf_addf(&buf_payload
, "child_start[%d]", cmd
->trace2_child_id
);
222 strbuf_addstr(&buf_payload
, " cd ");
223 sq_quote_buf_pretty(&buf_payload
, cmd
->dir
);
224 strbuf_addstr(&buf_payload
, ";");
228 * TODO if (cmd->env) { Consider dumping changes to environment. }
229 * See trace_add_env() in run-command.c as used by original trace.c
232 strbuf_addch(&buf_payload
, ' ');
234 strbuf_addstr(&buf_payload
, "git ");
235 sq_append_quote_argv_pretty(&buf_payload
, cmd
->argv
);
237 normal_io_write_fl(file
, line
, &buf_payload
);
238 strbuf_release(&buf_payload
);
241 static void fn_child_exit_fl(const char *file
, int line
,
242 uint64_t us_elapsed_absolute
, int cid
, int pid
,
243 int code
, uint64_t us_elapsed_child
)
245 struct strbuf buf_payload
= STRBUF_INIT
;
246 double elapsed
= (double)us_elapsed_child
/ 1000000.0;
248 strbuf_addf(&buf_payload
, "child_exit[%d] pid:%d code:%d elapsed:%.6f",
249 cid
, pid
, code
, elapsed
);
250 normal_io_write_fl(file
, line
, &buf_payload
);
251 strbuf_release(&buf_payload
);
254 static void fn_child_ready_fl(const char *file
, int line
,
255 uint64_t us_elapsed_absolute
, int cid
, int pid
,
256 const char *ready
, uint64_t us_elapsed_child
)
258 struct strbuf buf_payload
= STRBUF_INIT
;
259 double elapsed
= (double)us_elapsed_child
/ 1000000.0;
261 strbuf_addf(&buf_payload
, "child_ready[%d] pid:%d ready:%s elapsed:%.6f",
262 cid
, pid
, ready
, elapsed
);
263 normal_io_write_fl(file
, line
, &buf_payload
);
264 strbuf_release(&buf_payload
);
267 static void fn_exec_fl(const char *file
, int line
, uint64_t us_elapsed_absolute
,
268 int exec_id
, const char *exe
, const char **argv
)
270 struct strbuf buf_payload
= STRBUF_INIT
;
272 strbuf_addf(&buf_payload
, "exec[%d] ", exec_id
);
274 strbuf_addstr(&buf_payload
, exe
);
275 strbuf_addch(&buf_payload
, ' ');
277 sq_append_quote_argv_pretty(&buf_payload
, argv
);
278 normal_io_write_fl(file
, line
, &buf_payload
);
279 strbuf_release(&buf_payload
);
282 static void fn_exec_result_fl(const char *file
, int line
,
283 uint64_t us_elapsed_absolute
, int exec_id
,
286 struct strbuf buf_payload
= STRBUF_INIT
;
288 strbuf_addf(&buf_payload
, "exec_result[%d] code:%d", exec_id
, code
);
290 strbuf_addf(&buf_payload
, " err:%s", strerror(code
));
291 normal_io_write_fl(file
, line
, &buf_payload
);
292 strbuf_release(&buf_payload
);
295 static void fn_param_fl(const char *file
, int line
, const char *param
,
298 struct strbuf buf_payload
= STRBUF_INIT
;
300 strbuf_addf(&buf_payload
, "def_param %s=%s", param
, value
);
301 normal_io_write_fl(file
, line
, &buf_payload
);
302 strbuf_release(&buf_payload
);
305 static void fn_repo_fl(const char *file
, int line
,
306 const struct repository
*repo
)
308 struct strbuf buf_payload
= STRBUF_INIT
;
310 strbuf_addstr(&buf_payload
, "worktree ");
311 sq_quote_buf_pretty(&buf_payload
, repo
->worktree
);
312 normal_io_write_fl(file
, line
, &buf_payload
);
313 strbuf_release(&buf_payload
);
316 static void fn_printf_va_fl(const char *file
, int line
,
317 uint64_t us_elapsed_absolute
, const char *fmt
,
320 struct strbuf buf_payload
= STRBUF_INIT
;
322 maybe_append_string_va(&buf_payload
, fmt
, ap
);
323 normal_io_write_fl(file
, line
, &buf_payload
);
324 strbuf_release(&buf_payload
);
327 struct tr2_tgt tr2_tgt_normal
= {
340 fn_command_ancestry_fl
,
347 NULL
, /* thread_start */
348 NULL
, /* thread_exit */
353 NULL
, /* region_enter */
354 NULL
, /* region_leave */
356 NULL
, /* data_json */