util/cbfstool/eventlog: Use LocalTime or UTC timestamps

Add a new flag "--utc" to allow the user to choose if
elogtool should print timestamps in Local Time or in UTC.
It is useful for generating automated crash reports
including all system logs when users are located in
various regions (timezones).

Add information about timezone to timestamps printed
on the console.

Signed-off-by: Wojciech Macek <wmacek@google.com>
Change-Id: I30ba0e17c67ab4078e3a7137ece69009a63d68fa
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73201
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jakub Czapiga <jacz@semihalf.com>
This commit is contained in:
Wojciech Macek 2023-02-23 09:33:06 +01:00 committed by Felix Held
parent fd8664e178
commit 9edaccd922
3 changed files with 44 additions and 15 deletions

View File

@ -18,6 +18,10 @@
/* Only refers to the data max size. The "-1" is the checksum byte */
#define ELOG_MAX_EVENT_DATA_SIZE (ELOG_MAX_EVENT_SIZE - sizeof(struct event_header) - 1)
enum elogtool_flag {
ELOGTOOL_FLAG_UTC = (1 << 0),
};
enum elogtool_return {
ELOGTOOL_EXIT_SUCCESS = 0,
ELOGTOOL_EXIT_BAD_ARGS,
@ -28,13 +32,13 @@ enum elogtool_return {
ELOGTOOL_EXIT_NOT_ENOUGH_BUFFER_SPACE,
};
static int cmd_list(const struct buffer *);
static int cmd_clear(const struct buffer *);
static int cmd_add(const struct buffer *);
static int cmd_list(const struct buffer *, enum elogtool_flag);
static int cmd_clear(const struct buffer *, enum elogtool_flag);
static int cmd_add(const struct buffer *, enum elogtool_flag);
static const struct {
const char *name;
int (*func)(const struct buffer *buf);
int (*func)(const struct buffer *buf, enum elogtool_flag flags);
/* Whether it requires to write the buffer back */
bool write_back;
} cmds[] = {
@ -49,6 +53,7 @@ static char *argv0; /* Used as invoked_as */
static struct option long_options[] = {
{"file", required_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{"utc", no_argument, 0, 'U'},
{NULL, 0, 0, 0},
};
@ -66,6 +71,7 @@ static void usage(char *invoked_as)
"-f, --file <filename> File that holds event log partition.\n"
" If empty it will try to read/write from/to\n"
" the " ELOG_RW_REGION_NAME " using flashrom.\n"
"-U, --utc Print timestamps in UTC time zone\n"
"-h, --help Print this help\n",
invoked_as);
}
@ -187,11 +193,15 @@ static int shrink_buffer(const struct buffer *buf, size_t bytes_to_shrink)
return ELOGTOOL_EXIT_SUCCESS;
}
static int cmd_list(const struct buffer *buf)
static int cmd_list(const struct buffer *buf, enum elogtool_flag flags)
{
enum eventlog_timezone tz = EVENTLOG_TIMEZONE_LOCALTIME;
const struct event_header *event;
unsigned int count = 0;
if (flags & ELOGTOOL_FLAG_UTC)
tz = EVENTLOG_TIMEZONE_UTC;
/* Point to the first event */
event = buffer_get(buf) + sizeof(struct elog_header);
@ -203,7 +213,7 @@ static int cmd_list(const struct buffer *buf)
|| event->type == ELOG_TYPE_EOL)
break;
eventlog_print_event(event, count);
eventlog_print_event(event, count, tz);
event = elog_get_next_event(event);
count++;
}
@ -215,7 +225,8 @@ static int cmd_list(const struct buffer *buf)
* Clears the elog events from the given buffer, which is a valid RW_ELOG region.
* A LOG_CLEAR event is appended.
*/
static int cmd_clear(const struct buffer *buf)
static int cmd_clear(const struct buffer *buf,
enum elogtool_flag flags __maybe_unused)
{
uint32_t used_data_size;
struct buffer copy;
@ -318,7 +329,8 @@ static int cmd_add_parse_args(uint8_t *type, uint8_t *data, size_t *data_size)
}
/* Appends an elog entry to EventLog buffer. */
static int cmd_add(const struct buffer *buf)
static int cmd_add(const struct buffer *buf,
enum elogtool_flag flags __maybe_unused)
{
uint8_t data[ELOG_MAX_EVENT_DATA_SIZE];
size_t data_size = 0;
@ -358,6 +370,7 @@ static int cmd_add(const struct buffer *buf)
int main(int argc, char **argv)
{
char *filename = NULL;
enum elogtool_flag flags = 0;
struct buffer buf;
unsigned int i;
int argflag;
@ -370,7 +383,7 @@ int main(int argc, char **argv)
while (1) {
int option_index;
argflag = getopt_long(argc, argv, "hf:", long_options, &option_index);
argflag = getopt_long(argc, argv, "Uhf:", long_options, &option_index);
if (argflag == -1)
break;
@ -388,6 +401,9 @@ int main(int argc, char **argv)
filename = optarg;
break;
case 'U':
flags |= ELOGTOOL_FLAG_UTC;
break;
default:
break;
@ -410,7 +426,7 @@ int main(int argc, char **argv)
/* For commands that parse their own arguments. */
cmd_argv = &argv[optind+1];
argv0 = argv[0];
ret = cmds[i].func(&buf);
ret = cmds[i].func(&buf, flags);
break;
}
}

View File

@ -49,10 +49,12 @@ static void eventlog_printf(const char *format, ...)
*
* Forms the key-value description pair for the event timestamp.
*/
static void eventlog_print_timestamp(const struct event_header *event)
static void eventlog_print_timestamp(const struct event_header *event,
enum eventlog_timezone tz)
{
const char *tm_format = "%y-%m-%d%t%H:%M:%S";
char tm_string[40];
struct tm *tmptr;
struct tm tm;
time_t time;
@ -78,7 +80,11 @@ static void eventlog_print_timestamp(const struct event_header *event)
time = mktime(&tm);
time += tm.tm_gmtoff; /* force adjust for timezone */
strftime(tm_string, sizeof(tm_string), "%Y-%m-%d %H:%M:%S", localtime(&time));
if (tz == EVENTLOG_TIMEZONE_UTC)
tmptr = gmtime(&time);
else
tmptr = localtime(&time);
strftime(tm_string, sizeof(tm_string), "%Y-%m-%d %H:%M:%S%z", tmptr);
eventlog_printf("%s", tm_string);
}
@ -648,13 +654,14 @@ static int eventlog_print_data(const struct event_header *event)
return 0;
}
void eventlog_print_event(const struct event_header *event, int count)
void eventlog_print_event(const struct event_header *event, int count,
enum eventlog_timezone tz)
{
/* Ignore the printf separator at the beginning and end of each line */
eventlog_printf_ignore_separator_once = 1;
eventlog_printf("%d", count);
eventlog_print_timestamp(event);
eventlog_print_timestamp(event, tz);
eventlog_print_type(event);
eventlog_print_data(event);

View File

@ -8,7 +8,13 @@
struct event_header;
struct buffer;
void eventlog_print_event(const struct event_header *event, int count);
enum eventlog_timezone {
EVENTLOG_TIMEZONE_LOCALTIME = 0,
EVENTLOG_TIMEZONE_UTC,
};
void eventlog_print_event(const struct event_header *event, int count,
enum eventlog_timezone tz);
int eventlog_init_event(const struct buffer *buf, uint8_t type,
const void *data, int data_size);