提交 1b403146 编写于 作者: J Junio C Hamano

Merge branch 'js/trace2-to-directory'

The trace2 tracing facility learned to auto-generate a filename
when told to log to a directory.

* js/trace2-to-directory:
  trace2: write to directory targets
...@@ -109,6 +109,11 @@ values are recognized. ...@@ -109,6 +109,11 @@ values are recognized.
Enables the target, opens and writes to the file in append mode. Enables the target, opens and writes to the file in append mode.
If the target already exists and is a directory, the traces will be
written to files (one per process) underneath the given directory. They
will be named according to the last component of the SID (optionally
followed by a counter to avoid filename collisions).
`af_unix:[<socket_type>:]<absolute-pathname>`:: `af_unix:[<socket_type>:]<absolute-pathname>`::
Enables the target, opens and writes to a Unix Domain Socket Enables the target, opens and writes to a Unix Domain Socket
......
...@@ -80,6 +80,21 @@ test_expect_success 'normal stream, return code 1' ' ...@@ -80,6 +80,21 @@ test_expect_success 'normal stream, return code 1' '
test_cmp expect actual test_cmp expect actual
' '
test_expect_success 'automatic filename' '
test_when_finished "rm -r traces actual expect" &&
mkdir traces &&
GIT_TR2="$(pwd)/traces" test-tool trace2 001return 0 &&
perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <"$(ls traces/*)" >actual &&
cat >expect <<-EOF &&
version $V
start _EXE_ trace2 001return 0
cmd_name trace2 (trace2)
exit elapsed:_TIME_ code:0
atexit elapsed:_TIME_ code:0
EOF
test_cmp expect actual
'
# Verb 002exit # Verb 002exit
# #
# Explicit exit(code) from within cmd_<verb> propagates <code>. # Explicit exit(code) from within cmd_<verb> propagates <code>.
......
#include "cache.h" #include "cache.h"
#include "trace2/tr2_dst.h" #include "trace2/tr2_dst.h"
#include "trace2/tr2_sid.h"
/* /*
* If a Trace2 target cannot be opened for writing, we should issue a * If a Trace2 target cannot be opened for writing, we should issue a
...@@ -12,6 +13,11 @@ ...@@ -12,6 +13,11 @@
*/ */
#define TR2_ENVVAR_DST_DEBUG "GIT_TR2_DST_DEBUG" #define TR2_ENVVAR_DST_DEBUG "GIT_TR2_DST_DEBUG"
/*
* How many attempts we will make at creating an automatically-named trace file.
*/
#define MAX_AUTO_ATTEMPTS 10
static int tr2_dst_want_warning(void) static int tr2_dst_want_warning(void)
{ {
static int tr2env_dst_debug = -1; static int tr2env_dst_debug = -1;
...@@ -36,6 +42,55 @@ void tr2_dst_trace_disable(struct tr2_dst *dst) ...@@ -36,6 +42,55 @@ void tr2_dst_trace_disable(struct tr2_dst *dst)
dst->need_close = 0; dst->need_close = 0;
} }
static int tr2_dst_try_auto_path(struct tr2_dst *dst, const char *tgt_prefix)
{
int fd;
const char *last_slash, *sid = tr2_sid_get();
struct strbuf path = STRBUF_INIT;
size_t base_path_len;
unsigned attempt_count;
last_slash = strrchr(sid, '/');
if (last_slash)
sid = last_slash + 1;
strbuf_addstr(&path, tgt_prefix);
if (!is_dir_sep(path.buf[path.len - 1]))
strbuf_addch(&path, '/');
strbuf_addstr(&path, sid);
base_path_len = path.len;
for (attempt_count = 0; attempt_count < MAX_AUTO_ATTEMPTS; attempt_count++) {
if (attempt_count > 0) {
strbuf_setlen(&path, base_path_len);
strbuf_addf(&path, ".%d", attempt_count);
}
fd = open(path.buf, O_WRONLY | O_CREAT | O_EXCL, 0666);
if (fd != -1)
break;
}
if (fd == -1) {
if (tr2_dst_want_warning())
warning("trace2: could not open '%.*s' for '%s' tracing: %s",
(int) base_path_len, path.buf,
dst->env_var_name, strerror(errno));
tr2_dst_trace_disable(dst);
strbuf_release(&path);
return 0;
}
strbuf_release(&path);
dst->fd = fd;
dst->need_close = 1;
dst->initialized = 1;
return dst->fd;
}
static int tr2_dst_try_path(struct tr2_dst *dst, const char *tgt_value) static int tr2_dst_try_path(struct tr2_dst *dst, const char *tgt_value)
{ {
int fd = open(tgt_value, O_WRONLY | O_APPEND | O_CREAT, 0666); int fd = open(tgt_value, O_WRONLY | O_APPEND | O_CREAT, 0666);
...@@ -202,8 +257,12 @@ int tr2_dst_get_trace_fd(struct tr2_dst *dst) ...@@ -202,8 +257,12 @@ int tr2_dst_get_trace_fd(struct tr2_dst *dst)
return dst->fd; return dst->fd;
} }
if (is_absolute_path(tgt_value)) if (is_absolute_path(tgt_value)) {
if (is_directory(tgt_value))
return tr2_dst_try_auto_path(dst, tgt_value);
else
return tr2_dst_try_path(dst, tgt_value); return tr2_dst_try_path(dst, tgt_value);
}
#ifndef NO_UNIX_SOCKETS #ifndef NO_UNIX_SOCKETS
if (starts_with(tgt_value, PREFIX_AF_UNIX)) if (starts_with(tgt_value, PREFIX_AF_UNIX))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册