mirror of
https://github.com/AuxXxilium/eudev.git
synced 2024-12-19 21:16:37 +07:00
systemctl: show timestamps for state changes
This commit is contained in:
parent
f1e36d677a
commit
584be568b9
@ -1489,6 +1489,11 @@ typedef struct UnitStatusInfo {
|
||||
const char *path;
|
||||
const char *default_control_group;
|
||||
|
||||
usec_t inactive_exit_timestamp;
|
||||
usec_t active_enter_timestamp;
|
||||
usec_t active_exit_timestamp;
|
||||
usec_t inactive_enter_timestamp;
|
||||
|
||||
bool need_daemon_reload;
|
||||
|
||||
/* Service */
|
||||
@ -1523,6 +1528,9 @@ typedef struct UnitStatusInfo {
|
||||
static void print_status_info(UnitStatusInfo *i) {
|
||||
ExecStatusInfo *p;
|
||||
const char *on, *off, *ss;
|
||||
usec_t timestamp;
|
||||
char since1[FORMAT_TIMESTAMP_PRETTY_MAX], *s1;
|
||||
char since2[FORMAT_TIMESTAMP_MAX], *s2;
|
||||
|
||||
assert(i);
|
||||
|
||||
@ -1559,17 +1567,34 @@ static void print_status_info(UnitStatusInfo *i) {
|
||||
on = off = "";
|
||||
|
||||
if (ss)
|
||||
printf("\t Active: %s%s (%s)%s\n",
|
||||
printf("\t Active: %s%s (%s)%s",
|
||||
on,
|
||||
strna(i->active_state),
|
||||
ss,
|
||||
off);
|
||||
else
|
||||
printf("\t Active: %s%s%s\n",
|
||||
printf("\t Active: %s%s%s",
|
||||
on,
|
||||
strna(i->active_state),
|
||||
off);
|
||||
|
||||
timestamp = (streq_ptr(i->active_state, "active") ||
|
||||
streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
|
||||
(streq_ptr(i->active_state, "inactive") ||
|
||||
streq_ptr(i->active_state, "maintenance")) ? i->inactive_enter_timestamp :
|
||||
streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
|
||||
i->active_exit_timestamp;
|
||||
|
||||
s1 = format_timestamp_pretty(since1, sizeof(since1), timestamp);
|
||||
s2 = format_timestamp(since2, sizeof(since2), timestamp);
|
||||
|
||||
if (s1)
|
||||
printf(" since [%s; %s]\n", s2, s1);
|
||||
else if (s2)
|
||||
printf(" since [%s]\n", s2);
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
if (i->sysfs_path)
|
||||
printf("\t Device: %s\n", i->sysfs_path);
|
||||
else if (i->where)
|
||||
@ -1782,6 +1807,14 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn
|
||||
i->start_timestamp = (usec_t) u;
|
||||
else if (streq(name, "ExecMainExitTimestamp"))
|
||||
i->exit_timestamp = (usec_t) u;
|
||||
else if (streq(name, "ActiveEnterTimestamp"))
|
||||
i->active_enter_timestamp = (usec_t) u;
|
||||
else if (streq(name, "InactiveEnterTimestamp"))
|
||||
i->inactive_enter_timestamp = (usec_t) u;
|
||||
else if (streq(name, "InactiveExitTimestamp"))
|
||||
i->inactive_exit_timestamp = (usec_t) u;
|
||||
else if (streq(name, "ActiveExitTimestamp"))
|
||||
i->active_exit_timestamp = (usec_t) u;
|
||||
|
||||
break;
|
||||
}
|
||||
|
57
src/util.c
57
src/util.c
@ -1659,6 +1659,63 @@ char *format_timestamp(char *buf, size_t l, usec_t t) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
|
||||
usec_t n, d;
|
||||
|
||||
n = now(CLOCK_REALTIME);
|
||||
|
||||
if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
|
||||
return NULL;
|
||||
|
||||
d = n - t;
|
||||
|
||||
if (d >= USEC_PER_YEAR)
|
||||
snprintf(buf, l, "%llu years and %llu months ago",
|
||||
(unsigned long long) (d / USEC_PER_YEAR),
|
||||
(unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
|
||||
else if (d >= USEC_PER_MONTH)
|
||||
snprintf(buf, l, "%llu months and %llu days ago",
|
||||
(unsigned long long) (d / USEC_PER_MONTH),
|
||||
(unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
|
||||
else if (d >= USEC_PER_WEEK)
|
||||
snprintf(buf, l, "%llu weeks and %llu days ago",
|
||||
(unsigned long long) (d / USEC_PER_WEEK),
|
||||
(unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
|
||||
else if (d >= 2*USEC_PER_DAY)
|
||||
snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
|
||||
else if (d >= 25*USEC_PER_HOUR)
|
||||
snprintf(buf, l, "1 day and %lluh ago",
|
||||
(unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
|
||||
else if (d >= 6*USEC_PER_HOUR)
|
||||
snprintf(buf, l, "%lluh ago",
|
||||
(unsigned long long) (d / USEC_PER_HOUR));
|
||||
else if (d >= USEC_PER_HOUR)
|
||||
snprintf(buf, l, "%lluh %llumin ago",
|
||||
(unsigned long long) (d / USEC_PER_HOUR),
|
||||
(unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
|
||||
else if (d >= 5*USEC_PER_MINUTE)
|
||||
snprintf(buf, l, "%llumin ago",
|
||||
(unsigned long long) (d / USEC_PER_MINUTE));
|
||||
else if (d >= USEC_PER_MINUTE)
|
||||
snprintf(buf, l, "%llumin %llus ago",
|
||||
(unsigned long long) (d / USEC_PER_MINUTE),
|
||||
(unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
|
||||
else if (d >= USEC_PER_SEC)
|
||||
snprintf(buf, l, "%llus ago",
|
||||
(unsigned long long) (d / USEC_PER_SEC));
|
||||
else if (d >= USEC_PER_MSEC)
|
||||
snprintf(buf, l, "%llums ago",
|
||||
(unsigned long long) (d / USEC_PER_MSEC));
|
||||
else if (d > 0)
|
||||
snprintf(buf, l, "%lluus ago",
|
||||
(unsigned long long) d);
|
||||
else
|
||||
snprintf(buf, l, "now");
|
||||
|
||||
buf[l-1] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *format_timespan(char *buf, size_t l, usec_t t) {
|
||||
static const struct {
|
||||
const char *suffix;
|
||||
|
@ -52,12 +52,15 @@ typedef struct dual_timestamp {
|
||||
#define USEC_PER_HOUR (60ULL*USEC_PER_MINUTE)
|
||||
#define USEC_PER_DAY (24ULL*USEC_PER_HOUR)
|
||||
#define USEC_PER_WEEK (7ULL*USEC_PER_DAY)
|
||||
#define USEC_PER_MONTH (2629800ULL*USEC_PER_SEC)
|
||||
#define USEC_PER_YEAR (31557600ULL*USEC_PER_SEC)
|
||||
|
||||
/* What is interpreted as whitespace? */
|
||||
#define WHITESPACE " \t\n\r"
|
||||
#define NEWLINE "\n\r"
|
||||
|
||||
#define FORMAT_TIMESTAMP_MAX 64
|
||||
#define FORMAT_TIMESTAMP_PRETTY_MAX 256
|
||||
#define FORMAT_TIMESPAN_MAX 64
|
||||
|
||||
#define ANSI_HIGHLIGHT_ON "\x1B[1;31m"
|
||||
@ -248,6 +251,7 @@ bool ignore_file(const char *filename);
|
||||
bool chars_intersect(const char *a, const char *b);
|
||||
|
||||
char *format_timestamp(char *buf, size_t l, usec_t t);
|
||||
char *format_timestamp_pretty(char *buf, size_t l, usec_t t);
|
||||
char *format_timespan(char *buf, size_t l, usec_t t);
|
||||
|
||||
int make_stdio(int fd);
|
||||
|
Loading…
Reference in New Issue
Block a user