MINOR: activity/cli: support aggregating task profiling outputs
By default we now dump stats between caller and callee, but by specifying "aggr" on the command line, stats get aggregated by callee again as it used to be before the feature was available. It may sometimes be helpful when comparing total call counts, though that's about all.
This commit is contained in:
parent
64435aaa85
commit
dc89b1806c
@ -2866,7 +2866,7 @@ show pools
|
||||
as the SIGQUIT when running in foreground except that it does not flush
|
||||
the pools.
|
||||
|
||||
show profiling [{all | status | tasks | memory}] [byaddr] [<max_lines>]
|
||||
show profiling [{all | status | tasks | memory}] [byaddr] [aggr] [<max_lines>]
|
||||
Dumps the current profiling settings, one per line, as well as the command
|
||||
needed to change them. When tasks profiling is enabled, some per-function
|
||||
statistics collected by the scheduler will also be emitted, with a summary
|
||||
@ -2878,7 +2878,8 @@ show profiling [{all | status | tasks | memory}] [byaddr] [<max_lines>]
|
||||
information are dumped. It is also possible to limit the number of lines
|
||||
of output of each category by specifying a numeric limit. If is possible to
|
||||
request that the output is sorted by address instead of usage, e.g. to ease
|
||||
comparisons between subsequent calls. Please note that profiling is
|
||||
comparisons between subsequent calls, and to aggregate task activity by
|
||||
called function instead of seeing the details. Please note that profiling is
|
||||
essentially aimed at developers since it gives hints about where CPU cycles
|
||||
or memory are wasted in the code. There is nothing useful to monitor there.
|
||||
|
||||
|
@ -28,6 +28,7 @@ struct show_prof_ctx {
|
||||
int linenum; /* next line to be dumped (starts at 0) */
|
||||
int maxcnt; /* max line count per step (0=not set) */
|
||||
int by_addr; /* 0=sort by usage, 1=sort by address */
|
||||
int aggr; /* 0=dump raw, 1=aggregate on callee */
|
||||
};
|
||||
|
||||
#if defined(DEBUG_MEM_STATS)
|
||||
@ -597,7 +598,7 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
|
||||
const struct ha_caller *caller;
|
||||
const char *str;
|
||||
int max_lines;
|
||||
int i, max;
|
||||
int i, j, max;
|
||||
|
||||
if (unlikely(sc_ic(sc)->flags & (CF_WRITE_ERROR|CF_SHUTW)))
|
||||
return 1;
|
||||
@ -633,9 +634,23 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
|
||||
goto skip_tasks;
|
||||
|
||||
memcpy(tmp_activity, sched_activity, sizeof(tmp_activity));
|
||||
if (ctx->by_addr)
|
||||
qsort(tmp_activity, SCHED_ACT_HASH_BUCKETS, sizeof(tmp_activity[0]), cmp_sched_activity_addr);
|
||||
else
|
||||
/* for addr sort and for callee aggregation we have to first sort by address */
|
||||
if (ctx->aggr || ctx->by_addr)
|
||||
qsort(tmp_activity, SCHED_ACT_HASH_BUCKETS, sizeof(tmp_activity[0]), cmp_sched_activity_addr);
|
||||
|
||||
if (ctx->aggr) {
|
||||
/* merge entries for the same callee and reset their count */
|
||||
for (i = j = 0; i < SCHED_ACT_HASH_BUCKETS; i = j) {
|
||||
for (j = i + 1; j < SCHED_ACT_HASH_BUCKETS && tmp_activity[j].func == tmp_activity[i].func; j++) {
|
||||
tmp_activity[i].calls += tmp_activity[j].calls;
|
||||
tmp_activity[i].cpu_time += tmp_activity[j].cpu_time;
|
||||
tmp_activity[i].lat_time += tmp_activity[j].lat_time;
|
||||
tmp_activity[j].calls = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx->by_addr)
|
||||
qsort(tmp_activity, SCHED_ACT_HASH_BUCKETS, sizeof(tmp_activity[0]), cmp_sched_activity_calls);
|
||||
|
||||
if (!ctx->linenum)
|
||||
@ -646,7 +661,10 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
|
||||
if (!max_lines)
|
||||
max_lines = SCHED_ACT_HASH_BUCKETS;
|
||||
|
||||
for (i = ctx->linenum; i < max_lines && tmp_activity[i].calls; i++) {
|
||||
for (i = ctx->linenum; i < max_lines; i++) {
|
||||
if (!tmp_activity[i].calls)
|
||||
continue; // skip aggregated or empty entries
|
||||
|
||||
ctx->linenum = i;
|
||||
chunk_reset(name_buffer);
|
||||
caller = HA_ATOMIC_LOAD(&tmp_activity[i].caller);
|
||||
@ -669,7 +687,7 @@ static int cli_io_handler_show_profiling(struct appctx *appctx)
|
||||
print_time_short(&trash, " ", tmp_activity[i].lat_time, "");
|
||||
print_time_short(&trash, " ", tmp_activity[i].lat_time / tmp_activity[i].calls, "");
|
||||
|
||||
if (caller && caller->what <= WAKEUP_TYPE_APPCTX_WAKEUP)
|
||||
if (caller && !ctx->aggr && caller->what <= WAKEUP_TYPE_APPCTX_WAKEUP)
|
||||
chunk_appendf(&trash, " <- %s@%s:%d %s",
|
||||
caller->func, caller->file, caller->line,
|
||||
task_wakeup_type_str(caller->what));
|
||||
@ -810,11 +828,14 @@ static int cli_parse_show_profiling(char **args, char *payload, struct appctx *a
|
||||
else if (strcmp(args[arg], "byaddr") == 0) {
|
||||
ctx->by_addr = 1; // sort output by address instead of usage
|
||||
}
|
||||
else if (strcmp(args[arg], "aggr") == 0) {
|
||||
ctx->aggr = 1; // aggregate output by callee
|
||||
}
|
||||
else if (isdigit((unsigned char)*args[arg])) {
|
||||
ctx->maxcnt = atoi(args[arg]); // number of entries to dump
|
||||
}
|
||||
else
|
||||
return cli_err(appctx, "Expects either 'all', 'status', 'tasks', 'memory', 'byaddr' or a max number of output lines.\n");
|
||||
return cli_err(appctx, "Expects either 'all', 'status', 'tasks', 'memory', 'byaddr', 'aggr' or a max number of output lines.\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -977,7 +998,7 @@ INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
|
||||
/* register cli keywords */
|
||||
static struct cli_kw_list cli_kws = {{ },{
|
||||
{ { "set", "profiling", NULL }, "set profiling <what> {auto|on|off} : enable/disable resource profiling (tasks,memory)", cli_parse_set_profiling, NULL },
|
||||
{ { "show", "profiling", NULL }, "show profiling [<what>|<#lines>|byaddr]*: show profiling state (all,status,tasks,memory)", cli_parse_show_profiling, cli_io_handler_show_profiling, NULL },
|
||||
{ { "show", "profiling", NULL }, "show profiling [<what>|<#lines>|<opts>]*: show profiling state (all,status,tasks,memory)", cli_parse_show_profiling, cli_io_handler_show_profiling, NULL },
|
||||
{ { "show", "tasks", NULL }, "show tasks : show running tasks", NULL, cli_io_handler_show_tasks, NULL },
|
||||
{{},}
|
||||
}};
|
||||
|
Loading…
x
Reference in New Issue
Block a user