Commit 1a2f0e08 authored by quiche's avatar quiche Committed by Commit bot

Update syslog parser for new ChromeOS log format

In R39, ChromeOS rsyslogd no longer includes the hostname
field. Update SyslogParser accordingly.

While there:
- Update example shill log message to include process ID.
  (ChromeOS syslog recently started recording process IDs
  whenever possible.)
- Add a test log message from the kernel. This message does
  not include a process ID.
- Fix parsing of messages that do not have a process ID.
  Previously, for such messages, the process name would include
  a trailing ':'. With this change, they no longer do. (The
  process name will now be 'kernel', instead of 'kernel:'.)
- Simplify string EXPECTations. (No need for cstr() and STREQ.)

BUG=403558
TEST=unit test (ExtensionSyslogParserTest.ParseLog)

Review URL: https://codereview.chromium.org/486873005

Cr-Commit-Position: refs/heads/master@{#292058}
parent 3b70ef14
...@@ -23,7 +23,7 @@ namespace extensions { ...@@ -23,7 +23,7 @@ namespace extensions {
namespace { namespace {
const char kProcessInfoDelimiters[] = "[]"; const char kProcessInfoDelimiters[] = "[]:";
} // namespace } // namespace
...@@ -40,22 +40,16 @@ SyslogParser::Error SyslogParser::ParseEntry( ...@@ -40,22 +40,16 @@ SyslogParser::Error SyslogParser::ParseEntry(
base::StringTokenizer tokenizer(input, " "); base::StringTokenizer tokenizer(input, " ");
if (!tokenizer.GetNext()) { if (!tokenizer.GetNext()) {
LOG(ERROR) LOG(ERROR)
<< "Error when parsing data. Expect: At least 3 tokens. Actual: 0"; << "Error when parsing data. Expect: At least 2 tokens. Actual: 0";
return TOKENIZE_ERROR; return TOKENIZE_ERROR;
} }
std::string time = tokenizer.token(); std::string time = tokenizer.token();
if (ParseTime(time, &(entry->timestamp)) != SyslogParser::SUCCESS) { if (ParseTime(time, &(entry->timestamp)) != SyslogParser::SUCCESS) {
return SyslogParser::PARSE_ERROR; return SyslogParser::PARSE_ERROR;
} }
// Skips "localhost" field.
if (!tokenizer.GetNext()) { if (!tokenizer.GetNext()) {
LOG(ERROR) LOG(ERROR)
<< "Error when parsing data. Expect: At least 3 tokens. Actual: 1"; << "Error when parsing data. Expect: At least 2 tokens. Actual: 1";
return TOKENIZE_ERROR;
}
if (!tokenizer.GetNext()) {
LOG(ERROR)
<< "Error when parsing data. Expect: At least 3 tokens. Actual: 2";
return TOKENIZE_ERROR; return TOKENIZE_ERROR;
} }
ParseProcess(tokenizer.token(), entry.get()); ParseProcess(tokenizer.token(), entry.get());
......
...@@ -14,13 +14,17 @@ ...@@ -14,13 +14,17 @@
namespace extensions { namespace extensions {
namespace { namespace {
const char kKernelLogEntry[] =
"2014-08-18T14:04:58.606132-07:00 kernel: [269374.012690] "
"cfg80211: World regulatory domain updated:";
const char kShillLogEntry[] = const char kShillLogEntry[] =
"2013-07-08T11:28:12.440308+02:00 localhost shill:" "2014-08-15T11:20:24.575058-07:00 shill[1018]: "
"[0708/112812:ERROR:manager.cc(480)] Skipping unload of service"; "[INFO:service.cc(290)] Disconnecting from service 32: Unload";
const char kWpaSupplicantLogEntry[] = const char kWpaSupplicantLogEntry[] =
"2013-07-18T12:39:07.443100-07:00 localhost wpa_supplicant[894]:" "2014-08-15T12:36:06.137021-07:00 wpa_supplicant[818]: "
"dbus: Failed to construct signal"; "nl80211: Received scan results (0 BSSes)";
} // namespace } // namespace
...@@ -32,23 +36,33 @@ TEST_F(ExtensionSyslogParserTest, ParseLog) { ...@@ -32,23 +36,33 @@ TEST_F(ExtensionSyslogParserTest, ParseLog) {
api::log_private::Filter filter; api::log_private::Filter filter;
FilterHandler filter_handler(filter); FilterHandler filter_handler(filter);
SyslogParser p; SyslogParser p;
// Test kernel log
p.Parse(kKernelLogEntry, &output, &filter_handler);
ASSERT_EQ(1u, output.size());
EXPECT_EQ("unknown", output[0]->level);
EXPECT_EQ("kernel", output[0]->process);
EXPECT_EQ("unknown", output[0]->process_id);
EXPECT_EQ(kKernelLogEntry, output[0]->full_entry);
EXPECT_DOUBLE_EQ(1408395898606.132, output[0]->timestamp);
// Test shill log // Test shill log
p.Parse(kShillLogEntry, &output, &filter_handler); p.Parse(kShillLogEntry, &output, &filter_handler);
ASSERT_EQ(1u, output.size()); ASSERT_EQ(2u, output.size());
EXPECT_STREQ("error", output[0]->level.c_str()); EXPECT_EQ("info", output[1]->level);
EXPECT_STREQ("shill:", output[0]->process.c_str()); EXPECT_EQ("shill", output[1]->process);
EXPECT_STREQ("unknown", output[0]->process_id.c_str()); EXPECT_EQ("1018", output[1]->process_id);
EXPECT_STREQ(kShillLogEntry, output[0]->full_entry.c_str()); EXPECT_EQ(kShillLogEntry, output[1]->full_entry);
EXPECT_DOUBLE_EQ(1373275692440.308, output[0]->timestamp); EXPECT_DOUBLE_EQ(1408126824575.058, output[1]->timestamp);
// Test WpaSupplicant log // Test WpaSupplicant log
p.Parse(kWpaSupplicantLogEntry, &output, &filter_handler); p.Parse(kWpaSupplicantLogEntry, &output, &filter_handler);
ASSERT_EQ(2u, output.size()); ASSERT_EQ(3u, output.size());
EXPECT_STREQ("unknown", output[1]->level.c_str()); EXPECT_EQ("unknown", output[2]->level);
EXPECT_STREQ("wpa_supplicant", output[1]->process.c_str()); EXPECT_EQ("wpa_supplicant", output[2]->process);
EXPECT_STREQ("894", output[1]->process_id.c_str()); EXPECT_EQ("818", output[2]->process_id);
EXPECT_STREQ(kWpaSupplicantLogEntry, output[1]->full_entry.c_str()); EXPECT_EQ(kWpaSupplicantLogEntry, output[2]->full_entry);
EXPECT_DOUBLE_EQ(1374176347443.1, output[1]->timestamp); EXPECT_DOUBLE_EQ(1408131366137.021, output[2]->timestamp);
} }
} // namespace extensions } // namespace extensions
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment