From 39f3a7117d1e50d4778b0fd630d0e71eb67ed5f8 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sun, 16 Jul 2017 10:51:29 +0200 Subject: [PATCH] pidstat: Add new option to display timestamps in seconds since the Epoch Previously, option -h used to display all activities horizontally on a single line also displayed timestamps in second since the Epoch. Though this was intended to be used by scripts, it was not necessarily a desired feature (see #155). This patch changes option -h so that time format remains unmodified (all activities are displayed on a single line with no average statistics) and adds a new option (-H) that tells pidstat to display time in seconds since the Epoch. This option may be used separately from option -h. Signed-off-by: Sebastien GODARD --- pidstat.c | 49 +++++++++++++++++++++++++++++++++++++------------ pidstat.h | 26 ++++++++++++++------------ 2 files changed, 51 insertions(+), 24 deletions(-) diff --git a/pidstat.c b/pidstat.c index 876635c..c718147 100644 --- a/pidstat.c +++ b/pidstat.c @@ -88,7 +88,7 @@ void usage(char *progname) progname); fprintf(stderr, _("Options are:\n" - "[ -d ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ ] ]\n" + "[ -d ] [ -H ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ ] ]\n" "[ -u ] [ -V ] [ -v ] [ -w ] [ -C ] [ -G ] [ --human ]\n" "[ -p { [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ]\n")); exit(1); @@ -1382,6 +1382,10 @@ void print_line_id(char *timestamp, struct pid_stats *pst) * @prev Index in array where stats used as reference are. * @curr Index in array for current sample statistics. * @dis TRUE if a header line must be printed. + * @prev_string String displayed at the beginning of a header line. This is + * the timestamp of the previous sample. + * @curr_string String displayed at the beginning of current sample stats. + * This is the timestamp of the current sample. * @itv Interval of time in jiffies. * @g_itv Interval of time in jiffies multiplied by the number of * processors. @@ -1392,6 +1396,7 @@ void print_line_id(char *timestamp, struct pid_stats *pst) *************************************************************************** */ int write_pid_task_all_stats(int prev, int curr, int dis, + char *prev_string, char *curr_string, unsigned long long itv, unsigned long long g_itv) { @@ -1401,7 +1406,7 @@ int write_pid_task_all_stats(int prev, int curr, int dis, int again = 0; if (dis) { - PRINT_ID_HDR("# Time", pidflag); + PRINT_ID_HDR(prev_string, pidflag); if (DISPLAY_CPU(actflag)) { printf(" %%usr %%system %%guest %%wait %%CPU CPU"); } @@ -1432,8 +1437,7 @@ int write_pid_task_all_stats(int prev, int curr, int dis, &pstc, &pstp) <= 0) continue; - printf("%11ld", (long) time(NULL)); - __print_line_id(pstc, '0'); + print_line_id(curr_string, pstc); if (DISPLAY_CPU(actflag)) { cprintf_pc(DISPLAY_UNIT(pidflag), 5, 7, 2, @@ -1541,6 +1545,10 @@ int write_pid_task_all_stats(int prev, int curr, int dis, * @prev Index in array where stats used as reference are. * @curr Index in array for current sample statistics. * @dis TRUE if a header line must be printed. + * @prev_string String displayed at the beginning of a header line. This is + * the timestamp of the previous sample. + * @curr_string String displayed at the beginning of current sample stats. + * This is the timestamp of the current sample. * @itv Interval of time in jiffies. * * RETURNS: @@ -1549,6 +1557,7 @@ int write_pid_task_all_stats(int prev, int curr, int dis, *************************************************************************** */ int write_pid_child_all_stats(int prev, int curr, int dis, + char *prev_string, char *curr_string, unsigned long long itv) { struct pid_stats *pstc, *pstp; @@ -1556,7 +1565,7 @@ int write_pid_child_all_stats(int prev, int curr, int dis, int again = 0; if (dis) { - PRINT_ID_HDR("# Time", pidflag); + PRINT_ID_HDR(prev_string, pidflag); if (DISPLAY_CPU(actflag)) printf(" usr-ms system-ms guest-ms"); if (DISPLAY_MEM(actflag)) @@ -1570,8 +1579,7 @@ int write_pid_child_all_stats(int prev, int curr, int dis, &pstc, &pstp) <= 0) continue; - printf("%11ld", (long) time(NULL)); - __print_line_id(pstc, '0'); + print_line_id(curr_string, pstc); if (DISPLAY_CPU(actflag)) { cprintf_f(NO_UNIT, 3, 9, 0, @@ -2308,11 +2316,12 @@ int write_stats_core(int prev, int curr, int dis, int disp_avg, if (DISPLAY_ONELINE(pidflag)) { if (DISPLAY_TASK_STATS(tskflag)) { - again += write_pid_task_all_stats(prev, curr, dis, - itv, g_itv); + again += write_pid_task_all_stats(prev, curr, dis, prev_string, curr_string, + itv, g_itv); } if (DISPLAY_CHILD_STATS(tskflag)) { - again += write_pid_child_all_stats(prev, curr, dis, itv); + again += write_pid_child_all_stats(prev, curr, dis, prev_string, curr_string, + itv); } } else { @@ -2417,7 +2426,14 @@ int write_stats(int curr, int dis) char cur_time[2][TIMESTAMP_LEN]; /* Get previous timestamp */ - if (is_iso_time_fmt()) { + if (DISPLAY_ONELINE(pidflag)) { + strcpy(cur_time[!curr], "# Time "); + } + else if (PRINT_SEC_EPOCH(pidflag)) { + snprintf(cur_time[!curr], TIMESTAMP_LEN, "%-11ld", mktime(&ps_tstamp[!curr])); + cur_time[!curr][TIMESTAMP_LEN - 1] = '\0'; + } + else if (is_iso_time_fmt()) { strftime(cur_time[!curr], sizeof(cur_time[!curr]), "%H:%M:%S", &ps_tstamp[!curr]); } else { @@ -2425,7 +2441,11 @@ int write_stats(int curr, int dis) } /* Get current timestamp */ - if (is_iso_time_fmt()) { + if (PRINT_SEC_EPOCH(pidflag)) { + snprintf(cur_time[curr], TIMESTAMP_LEN, "%-11ld", mktime(&ps_tstamp[curr])); + cur_time[curr][TIMESTAMP_LEN - 1] = '\0'; + } + else if (is_iso_time_fmt()) { strftime(cur_time[curr], sizeof(cur_time[curr]), "%H:%M:%S", &ps_tstamp[curr]); } else { @@ -2713,6 +2733,11 @@ int main(int argc, char **argv) dis_hdr++; break; + case 'H': + /* Display timestamps in sec since the epoch */ + pidflag |= P_D_SEC_EPOCH; + break; + case 'h': /* Display stats on one line */ pidflag |= P_D_ONELINE; diff --git a/pidstat.h b/pidstat.h index cbe3c0a..1ed5a26 100644 --- a/pidstat.h +++ b/pidstat.h @@ -58,18 +58,19 @@ #define DISPLAY_TASK_STATS(m) (((m) & P_TASK) == P_TASK) #define DISPLAY_CHILD_STATS(m) (((m) & P_CHILD) == P_CHILD) -#define P_D_PID 0x001 -#define P_D_ALL_PID 0x002 -#define P_F_IRIX_MODE 0x004 -#define P_F_COMMSTR 0x008 -#define P_D_ACTIVE_PID 0x010 -#define P_D_TID 0x020 -#define P_D_ONELINE 0x040 -#define P_D_CMDLINE 0x080 -#define P_D_USERNAME 0x100 -#define P_F_USERSTR 0x200 -#define P_F_PROCSTR 0x400 -#define P_D_UNIT 0x800 +#define P_D_PID 0x0001 +#define P_D_ALL_PID 0x0002 +#define P_F_IRIX_MODE 0x0004 +#define P_F_COMMSTR 0x0008 +#define P_D_ACTIVE_PID 0x0010 +#define P_D_TID 0x0020 +#define P_D_ONELINE 0x0040 +#define P_D_CMDLINE 0x0080 +#define P_D_USERNAME 0x0100 +#define P_F_USERSTR 0x0200 +#define P_F_PROCSTR 0x0400 +#define P_D_UNIT 0x0800 +#define P_D_SEC_EPOCH 0x1000 #define DISPLAY_PID(m) (((m) & P_D_PID) == P_D_PID) #define DISPLAY_ALL_PID(m) (((m) & P_D_ALL_PID) == P_D_ALL_PID) @@ -83,6 +84,7 @@ #define USER_STRING(m) (((m) & P_F_USERSTR) == P_F_USERSTR) #define PROCESS_STRING(m) (((m) & P_F_PROCSTR) == P_F_PROCSTR) #define DISPLAY_UNIT(m) (((m) & P_D_UNIT) == P_D_UNIT) +#define PRINT_SEC_EPOCH(m) (((m) & P_D_SEC_EPOCH) == P_D_SEC_EPOCH) /* Per-process flags */ #define F_NO_PID_IO 0x01 -- 2.40.0