analyze: optionally, show more than one elapse time for calendar expressions

This commit is contained in:
Lennart Poettering 2019-02-21 12:07:05 +01:00 committed by Zbigniew Jędrzejewski-Szmek
parent 95a32e9750
commit f2ccf8320a
2 changed files with 56 additions and 14 deletions

View file

@ -251,11 +251,14 @@ NAutoVTs=8
All units files present in the directories containing the command line arguments will
be used in preference to the other paths.</para>
<para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time events, and
will calculate when they will elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting
in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>, following the
syntax described in
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
<para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time
events, and will calculate when they will elapse next. This takes the same input as the
<varname>OnCalendar=</varname> setting in
<citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
following the syntax described in
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. By
default, only the next time the calendar expression will elapse is shown; use
<option>--iterations=</option> to show the specified number of next times the expression elapses.</para>
<para><command>systemd-analyze service-watchdogs</command>
prints the current state of service runtime watchdogs of the <command>systemd</command> daemon.
@ -401,6 +404,13 @@ NAutoVTs=8
the specified root path <replaceable>PATH</replaceable>.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--iterations=<replaceable>NUMBER</replaceable></option></term>
<listitem><para>When used with the <command>calendar</command> command, show the specified number of
iterations the specified calendar expression will elapse next. Defaults to 1.</para></listitem>
</varlistentry>
<xi:include href="user-system-options.xml" xpointer="host" />
<xi:include href="user-system-options.xml" xpointer="machine" />

View file

@ -78,6 +78,7 @@ static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
static bool arg_man = true;
static bool arg_generators = false;
static const char *arg_root = NULL;
static unsigned arg_iterations = 1;
STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep);
@ -1680,7 +1681,7 @@ static int test_calendar(int argc, char *argv[], void *userdata) {
STRV_FOREACH(p, strv_skip(argv, 1)) {
_cleanup_(calendar_spec_freep) CalendarSpec *spec = NULL;
_cleanup_free_ char *t = NULL;
usec_t next;
unsigned i;
r = calendar_spec_from_string(*p, &spec);
if (r < 0) {
@ -1705,21 +1706,42 @@ static int test_calendar(int argc, char *argv[], void *userdata) {
printf("Normalized form: %s\n", t);
r = calendar_spec_next_usec(spec, n, &next);
if (r == -ENOENT)
printf(" Next elapse: never\n");
else if (r < 0) {
ret = log_error_errno(r, "Failed to determine next elapse for '%s': %m", *p);
continue;
} else {
for (i = 0; i < arg_iterations; i++) {
char buffer[CONST_MAX(FORMAT_TIMESTAMP_MAX, FORMAT_TIMESTAMP_RELATIVE_MAX)];
usec_t next;
printf(" Next elapse: %s\n", format_timestamp(buffer, sizeof(buffer), next));
r = calendar_spec_next_usec(spec, n, &next);
if (r == -ENOENT) {
if (i > 0)
break;
printf(" Next elapse: never\n");
return ret;
}
if (r < 0) {
ret = log_error_errno(r, "Failed to determine next elapse for '%s': %m", *p);
break;
}
if (i == 0)
printf(" Next elapse: %s\n", format_timestamp(buffer, sizeof(buffer), next));
else {
int k = DECIMAL_STR_WIDTH(i+1);
if (k < 8)
k = 8 - k;
else
k = 0;
printf("%*sIter. #%u: %s\n", k, "", i+1, format_timestamp(buffer, sizeof(buffer), next));
}
if (!in_utc_timezone())
printf(" (in UTC): %s\n", format_timestamp_utc(buffer, sizeof(buffer), next));
printf(" From now: %s\n", format_timestamp_relative(buffer, sizeof(buffer), next));
n = next;
}
if (*(p+1))
@ -1827,6 +1849,7 @@ static int help(int argc, char *argv[], void *userdata) {
" earlier than the latest in the branch\n"
" --man[=BOOL] Do [not] check for existence of man pages\n"
" --generators[=BOOL] Do [not] run unit generators (requires privileges)\n"
" --iterations=N Show the specified number of iterations\n"
"\nCommands:\n"
" time Print time spent in the kernel\n"
" blame Print list of running units ordered by time to init\n"
@ -1870,6 +1893,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NO_PAGER,
ARG_MAN,
ARG_GENERATORS,
ARG_ITERATIONS,
};
static const struct option options[] = {
@ -1889,6 +1913,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "generators", optional_argument, NULL, ARG_GENERATORS },
{ "host", required_argument, NULL, 'H' },
{ "machine", required_argument, NULL, 'M' },
{ "iterations", required_argument, NULL, ARG_ITERATIONS },
{}
};
@ -1988,6 +2013,13 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_ITERATIONS:
r = safe_atou(optarg, &arg_iterations);
if (r < 0)
return log_error_errno(r, "Failed to parse iterations: %s", optarg);
break;
case '?':
return -EINVAL;