summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/api/log_private/syslog_parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/extensions/api/log_private/syslog_parser.cc')
-rw-r--r--chrome/browser/extensions/api/log_private/syslog_parser.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/chrome/browser/extensions/api/log_private/syslog_parser.cc b/chrome/browser/extensions/api/log_private/syslog_parser.cc
new file mode 100644
index 0000000..5479886
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/syslog_parser.cc
@@ -0,0 +1,144 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/api/log_private/syslog_parser.h"
+
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/singleton.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_tokenizer.h"
+#include "base/time/time.h"
+#include "chrome/browser/extensions/api/log_private/filter_handler.h"
+#include "chrome/browser/extensions/api/log_private/log_parser.h"
+#include "chrome/browser/extensions/api/log_private/log_private_api.h"
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+
+namespace {
+
+const int kExpectedTimeTokenNum = 7;
+const char kLogEntryDelimiters[] = "-:T";
+const char kProcessInfoDelimiters[] = "[]";
+
+} // namespace
+
+SyslogParser::SyslogParser() {}
+
+SyslogParser::~SyslogParser() {}
+
+SyslogParser::Error SyslogParser::ParseEntry(
+ const std::string& input,
+ std::vector<linked_ptr<api::log_private::LogEntry> >* output,
+ FilterHandler* filter_handler) const {
+ linked_ptr<api::log_private::LogEntry> entry(new api::log_private::LogEntry);
+
+ base::StringTokenizer tokenizer(input, " ");
+ if (!tokenizer.GetNext()) {
+ LOG(ERROR)
+ << "Error when parsing data. Expect: At least 3 tokens. Actual: 0";
+ return TOKENIZE_ERROR;
+ }
+ std::string time = tokenizer.token();
+ if (ParseTime(time, &(entry->timestamp)) != SyslogParser::SUCCESS) {
+ return SyslogParser::PARSE_ERROR;
+ }
+ // Skips "localhost" field.
+ if (!tokenizer.GetNext()) {
+ LOG(ERROR)
+ << "Error when parsing data. Expect: At least 3 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;
+ }
+ ParseProcess(tokenizer.token(), entry.get());
+ ParseLevel(input, entry.get());
+ entry->full_entry = input;
+
+ if (filter_handler->IsValidLogEntry(*(entry.get()))) {
+ output->push_back(entry);
+ }
+
+ return SyslogParser::SUCCESS;
+}
+
+SyslogParser::Error ParseTimeHelper(base::StringTokenizer* tokenizer,
+ std::string* output) {
+ if (!tokenizer->GetNext()) {
+ LOG(ERROR) << "Error when parsing time";
+ return SyslogParser::PARSE_ERROR;
+ }
+ *output = tokenizer->token();
+ return SyslogParser::SUCCESS;
+}
+
+SyslogParser::Error SyslogParser::ParseTime(const std::string& input,
+ double* output) const {
+ base::StringTokenizer tokenizer(input, kLogEntryDelimiters);
+ std::string tokens[kExpectedTimeTokenNum];
+ for (int i = 0; i < kExpectedTimeTokenNum; i++) {
+ if (ParseTimeHelper(&tokenizer, &(tokens[i])) != SyslogParser::SUCCESS)
+ return SyslogParser::PARSE_ERROR;
+ }
+
+ std::string buffer = tokens[1] + '-' + tokens[2] + '-' + tokens[0] + ' ' +
+ tokens[3] + ':' + tokens[4] + ":00";
+
+ base::Time parsed_time;
+ if (!base::Time::FromString(buffer.c_str(), &parsed_time)) {
+ LOG(ERROR) << "Error when parsing time";
+ return SyslogParser::PARSE_ERROR;
+ }
+
+ double seconds;
+ base::StringToDouble(tokens[5], &seconds);
+ *output = parsed_time.ToJsTime() +
+ (seconds * base::Time::kMillisecondsPerSecond);
+
+ return SyslogParser::SUCCESS;
+}
+
+SyslogParser::Error SyslogParser::ParseProcess(
+ const std::string& input,
+ api::log_private::LogEntry* entry) const {
+ base::StringTokenizer tokenizer(input, kProcessInfoDelimiters);
+ if (!tokenizer.GetNext()) {
+ LOG(ERROR)
+ << "Error when parsing data. Expect: At least 1 token. Actual: 0";
+ return SyslogParser::PARSE_ERROR;
+ }
+ entry->process = tokenizer.token();
+ entry->process_id = "unknown";
+ if (tokenizer.GetNext()) {
+ std::string token = tokenizer.token();
+ int tmp;
+ if (base::StringToInt(token, &tmp)) {
+ entry->process_id = token;
+ }
+ }
+ return SyslogParser::SUCCESS;
+}
+
+void SyslogParser::ParseLevel(const std::string& input,
+ api::log_private::LogEntry* entry) const {
+ if (input.find("ERROR") != std::string::npos) {
+ entry->level = "error";
+ } else if (input.find("WARN") != std::string::npos) {
+ entry->level = "warning";
+ } else if (input.find("INFO") != std::string::npos) {
+ entry->level = "info";
+ } else {
+ entry->level = "unknown";
+ }
+}
+
+} // namespace extensions