-
Notifications
You must be signed in to change notification settings - Fork 72
/
logctl.c
80 lines (68 loc) · 1.68 KB
/
logctl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
* Process an LKRG logger output file. This program currently derives each
* event's ISO timestamp from several recorded relative timestamps.
*
* Written in 2022 by Solar Designer
* Copyright (c) 2022 Binarly
*/
#include <time.h>
#include <stdio.h>
static const char *format_time(char *s, size_t max, unsigned long long t)
{
time_t tu = t / 1000000;
struct tm *tm = gmtime(&tu);
if (strftime(s, max, "%Y-%m-%dT%H:%M:%SZ", tm))
return s;
return "";
}
static int process_log(const char *pathname)
{
int retval = 0;
FILE *f = fopen(pathname, "r");
if (!f) {
perror("fopen");
return 1;
}
char buf[0x2100];
while (fgets(buf, sizeof(buf), f)) {
unsigned long long tr, ts, tsu, seq, teu;
unsigned int sev;
int msgofs = 0;
int n = sscanf(buf, "%llu,%llu,%llu,%u,%llu,%llu,-;%n", &tr, &ts, &tsu, &sev, &seq, &teu, &msgofs);
if (n < 6 || !msgofs) {
if (!(retval & 2)) {
fputs("Warning: Skipping misformatted line(s)\n", stderr);
retval |= 2;
}
continue;
}
const char *msg = buf msgofs;
unsigned long long te = ts;
if (tsu > teu) {
/*
* Infer more accurate event time by subtracting the delay between send uptime
* and event uptime from the send time.
*/
te -= tsu - teu;
} else if (teu - tsu >= 500000 && !(retval & 4)) {
fputs("Warning: Major system uptime clock drift between CPUs\n", stderr);
retval |= 4;
}
char ste[21];
printf("%s %s", format_time(ste, sizeof(ste), te), msg);
}
if (ferror(f)) {
perror("fgets");
retval |= 1;
}
fclose(f);
return retval;
}
int main(int argc, const char * const *argv)
{
if (argc != 2) {
fputs("Usage: lkrg-logctl PATHNAME\n", stderr);
return 1;
}
return process_log(argv[1]);
}