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:
parent
fd8664e178
commit
9edaccd922
|
@ -18,6 +18,10 @@
|
||||||
/* Only refers to the data max size. The "-1" is the checksum byte */
|
/* 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)
|
#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 {
|
enum elogtool_return {
|
||||||
ELOGTOOL_EXIT_SUCCESS = 0,
|
ELOGTOOL_EXIT_SUCCESS = 0,
|
||||||
ELOGTOOL_EXIT_BAD_ARGS,
|
ELOGTOOL_EXIT_BAD_ARGS,
|
||||||
|
@ -28,13 +32,13 @@ enum elogtool_return {
|
||||||
ELOGTOOL_EXIT_NOT_ENOUGH_BUFFER_SPACE,
|
ELOGTOOL_EXIT_NOT_ENOUGH_BUFFER_SPACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cmd_list(const struct buffer *);
|
static int cmd_list(const struct buffer *, enum elogtool_flag);
|
||||||
static int cmd_clear(const struct buffer *);
|
static int cmd_clear(const struct buffer *, enum elogtool_flag);
|
||||||
static int cmd_add(const struct buffer *);
|
static int cmd_add(const struct buffer *, enum elogtool_flag);
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
const char *name;
|
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 */
|
/* Whether it requires to write the buffer back */
|
||||||
bool write_back;
|
bool write_back;
|
||||||
} cmds[] = {
|
} cmds[] = {
|
||||||
|
@ -49,6 +53,7 @@ static char *argv0; /* Used as invoked_as */
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"file", required_argument, 0, 'f'},
|
{"file", required_argument, 0, 'f'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"utc", no_argument, 0, 'U'},
|
||||||
{NULL, 0, 0, 0},
|
{NULL, 0, 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,6 +71,7 @@ static void usage(char *invoked_as)
|
||||||
"-f, --file <filename> File that holds event log partition.\n"
|
"-f, --file <filename> File that holds event log partition.\n"
|
||||||
" If empty it will try to read/write from/to\n"
|
" If empty it will try to read/write from/to\n"
|
||||||
" the " ELOG_RW_REGION_NAME " using flashrom.\n"
|
" the " ELOG_RW_REGION_NAME " using flashrom.\n"
|
||||||
|
"-U, --utc Print timestamps in UTC time zone\n"
|
||||||
"-h, --help Print this help\n",
|
"-h, --help Print this help\n",
|
||||||
invoked_as);
|
invoked_as);
|
||||||
}
|
}
|
||||||
|
@ -187,11 +193,15 @@ static int shrink_buffer(const struct buffer *buf, size_t bytes_to_shrink)
|
||||||
return ELOGTOOL_EXIT_SUCCESS;
|
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;
|
const struct event_header *event;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
|
|
||||||
|
if (flags & ELOGTOOL_FLAG_UTC)
|
||||||
|
tz = EVENTLOG_TIMEZONE_UTC;
|
||||||
|
|
||||||
/* Point to the first event */
|
/* Point to the first event */
|
||||||
event = buffer_get(buf) + sizeof(struct elog_header);
|
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)
|
|| event->type == ELOG_TYPE_EOL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
eventlog_print_event(event, count);
|
eventlog_print_event(event, count, tz);
|
||||||
event = elog_get_next_event(event);
|
event = elog_get_next_event(event);
|
||||||
count++;
|
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.
|
* Clears the elog events from the given buffer, which is a valid RW_ELOG region.
|
||||||
* A LOG_CLEAR event is appended.
|
* 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;
|
uint32_t used_data_size;
|
||||||
struct buffer copy;
|
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. */
|
/* 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];
|
uint8_t data[ELOG_MAX_EVENT_DATA_SIZE];
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
|
@ -358,6 +370,7 @@ static int cmd_add(const struct buffer *buf)
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
|
enum elogtool_flag flags = 0;
|
||||||
struct buffer buf;
|
struct buffer buf;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int argflag;
|
int argflag;
|
||||||
|
@ -370,7 +383,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int option_index;
|
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)
|
if (argflag == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -388,6 +401,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
filename = optarg;
|
filename = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'U':
|
||||||
|
flags |= ELOGTOOL_FLAG_UTC;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -410,7 +426,7 @@ int main(int argc, char **argv)
|
||||||
/* For commands that parse their own arguments. */
|
/* For commands that parse their own arguments. */
|
||||||
cmd_argv = &argv[optind+1];
|
cmd_argv = &argv[optind+1];
|
||||||
argv0 = argv[0];
|
argv0 = argv[0];
|
||||||
ret = cmds[i].func(&buf);
|
ret = cmds[i].func(&buf, flags);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,10 +49,12 @@ static void eventlog_printf(const char *format, ...)
|
||||||
*
|
*
|
||||||
* Forms the key-value description pair for the event timestamp.
|
* 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";
|
const char *tm_format = "%y-%m-%d%t%H:%M:%S";
|
||||||
char tm_string[40];
|
char tm_string[40];
|
||||||
|
struct tm *tmptr;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
time_t time;
|
time_t time;
|
||||||
|
|
||||||
|
@ -78,7 +80,11 @@ static void eventlog_print_timestamp(const struct event_header *event)
|
||||||
time = mktime(&tm);
|
time = mktime(&tm);
|
||||||
time += tm.tm_gmtoff; /* force adjust for timezone */
|
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);
|
eventlog_printf("%s", tm_string);
|
||||||
}
|
}
|
||||||
|
@ -648,13 +654,14 @@ static int eventlog_print_data(const struct event_header *event)
|
||||||
return 0;
|
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 */
|
/* Ignore the printf separator at the beginning and end of each line */
|
||||||
eventlog_printf_ignore_separator_once = 1;
|
eventlog_printf_ignore_separator_once = 1;
|
||||||
|
|
||||||
eventlog_printf("%d", count);
|
eventlog_printf("%d", count);
|
||||||
eventlog_print_timestamp(event);
|
eventlog_print_timestamp(event, tz);
|
||||||
eventlog_print_type(event);
|
eventlog_print_type(event);
|
||||||
eventlog_print_data(event);
|
eventlog_print_data(event);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,13 @@
|
||||||
struct event_header;
|
struct event_header;
|
||||||
struct buffer;
|
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,
|
int eventlog_init_event(const struct buffer *buf, uint8_t type,
|
||||||
const void *data, int data_size);
|
const void *data, int data_size);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue