-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimestamp_util.cc
133 lines (104 loc) · 4.28 KB
/
timestamp_util.cc
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "bootid-logger/timestamp_util.h"
#include <memory>
#include <string>
#include <base/files/file_enumerator.h>
#include <base/files/file_util.h>
#include "bootid-logger/constants.h"
#include "croslog/log_entry_reader.h"
#include "croslog/log_parser_syslog.h"
// The list is coped from /platform2/init/chromeos-cleanup-logs
// TODO(crbug.com/1168393): share the list with the rotation script.
const char* kLogFiles[] = {"messages",
"secure",
"net.log",
"faillog",
"fwupd.log",
"session_manager",
"atrus.log",
"tlsdate.log",
"authpolicy.log",
"tpm-firmware-updater.log",
"arc.log",
"recover_duts/recover_duts.log",
"hammerd.log",
"upstart.log",
"typecd.log",
"bluetooth.log",
NULL};
base::FilePath kLogDir("/var/log");
base::Time GetFirstTimestamp(const base::FilePath& file) {
croslog::LogEntryReader reader(
file, std::make_unique<croslog::LogParserSyslog>(), false);
croslog::MaybeLogEntry e = reader.GetNextEntry();
if (e.has_value())
return e->time();
return base::Time();
}
base::Time GetOldestTimestampFromLogFiles(const base::FilePath& dir_path,
const std::string& base_log_name) {
base::Time oldest_last_modified;
// Retrieve the path and the last modified date of the latest log file
// (without a suffix).
{
base::FilePath log_file_path = dir_path.Append(base_log_name);
if (base::PathExists(log_file_path))
oldest_last_modified = GetFirstTimestamp(log_file_path);
}
// Pattern to match the older log files with suffix.
std::string pattern = base_log_name + ".*";
// Traverse the older log files.
base::FileEnumerator e(dir_path, false, base::FileEnumerator::FILES, pattern);
for (base::FilePath name = e.Next(); !name.empty(); name = e.Next()) {
base::Time last_modified = GetFirstTimestamp(name);
// If the first timestamp can't be retrieved, Use the timestamp one day
// prior to the last modifiled time of the file (assumeing the file is
// rotated daily).
if (last_modified.is_null())
last_modified = e.GetInfo().GetLastModifiedTime() - base::Days(1);
if (last_modified.is_null())
continue;
if (oldest_last_modified.is_null() || oldest_last_modified > last_modified)
oldest_last_modified = last_modified;
}
return oldest_last_modified;
}
base::Time GetOldestModifiedTime(base::FilePath log_directory,
const char* log_files[]) {
base::Time oldest_last_modified;
for (int i = 0; log_files[i] != NULL; i++) {
base::Time last_modified =
GetOldestTimestampFromLogFiles(log_directory, log_files[i]);
if (last_modified.is_null())
continue;
if (oldest_last_modified.is_null() || oldest_last_modified > last_modified)
oldest_last_modified = last_modified;
}
return oldest_last_modified;
}
base::Time GetOldestModifiedTime() {
return GetOldestModifiedTime(kLogDir, kLogFiles);
}
// Extracts the boot ID from the givin boot ID entry.
base::Time ExtractTimestampString(const std::string& boot_id_entry) {
base::Time time;
if (boot_id_entry[26] == 'Z') {
// Case of UTC time format like "2020-05-25T00:00:00.000000Z".
std::string log_time = boot_id_entry.substr(0, kTimestampLength);
bool result = base::Time::FromString(log_time.c_str(), &time);
if (!result)
return base::Time();
return time;
} else if (boot_id_entry[26] == '+' || boot_id_entry[26] == '-') {
// Case of format with time-zone like "2020-05-25T00:00:00.000000+00:00".
std::string log_time = boot_id_entry.substr(0, kLocalTimeTimestampLength);
bool result = base::Time::FromString(log_time.c_str(), &time);
if (!result)
return base::Time();
return time;
}
// Returning a null time as an error.
return base::Time();
}