1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// found in the LICENSE file.
4bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/syslog_parser.h"
6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
7bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <string>
8bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include <vector>
9bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
10bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/logging.h"
11bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/memory/linked_ptr.h"
12bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/memory/singleton.h"
13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/strings/string_number_conversions.h"
14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/strings/string_split.h"
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/strings/string_tokenizer.h"
16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "base/time/time.h"
17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/filter_handler.h"
18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/log_parser.h"
19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/browser/extensions/api/log_private/log_private_api.h"
20bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#include "chrome/common/extensions/api/log_private.h"
21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
22bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace extensions {
23bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
24bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace {
25bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst char kProcessInfoDelimiters[] = "[]:";
27bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
28bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace
29bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
30bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochSyslogParser::SyslogParser() {}
31bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
32bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochSyslogParser::~SyslogParser() {}
33bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
34bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochSyslogParser::Error SyslogParser::ParseEntry(
35bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    const std::string& input,
36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    std::vector<linked_ptr<api::log_private::LogEntry> >* output,
37bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    FilterHandler* filter_handler) const {
38bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  linked_ptr<api::log_private::LogEntry> entry(new api::log_private::LogEntry);
39bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
40bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::StringTokenizer tokenizer(input, " ");
41bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!tokenizer.GetNext()) {
42bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    LOG(ERROR)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        << "Error when parsing data. Expect: At least 2 tokens. Actual: 0";
44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return TOKENIZE_ERROR;
45bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
46bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  std::string time = tokenizer.token();
47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (ParseTime(time, &(entry->timestamp)) != SyslogParser::SUCCESS) {
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return SyslogParser::PARSE_ERROR;
49bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!tokenizer.GetNext()) {
51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    LOG(ERROR)
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        << "Error when parsing data. Expect: At least 2 tokens. Actual: 1";
53bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return TOKENIZE_ERROR;
54bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
55bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ParseProcess(tokenizer.token(), entry.get());
56bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ParseLevel(input, entry.get());
57bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  entry->full_entry = input;
58bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
59bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (filter_handler->IsValidLogEntry(*(entry.get()))) {
60bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    output->push_back(entry);
61bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
63bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return SyslogParser::SUCCESS;
64bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
66bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochSyslogParser::Error SyslogParser::ParseTime(const std::string& input,
67bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                            double* output) const {
68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::Time parsed_time;
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (!base::Time::FromString(input.c_str(), &parsed_time)) {
70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    LOG(ERROR) << "Error when parsing time";
71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return SyslogParser::PARSE_ERROR;
72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  *output = parsed_time.ToJsTime();
75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return SyslogParser::SUCCESS;
76bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
77bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochSyslogParser::Error SyslogParser::ParseProcess(
79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    const std::string& input,
80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    api::log_private::LogEntry* entry) const {
81bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  base::StringTokenizer tokenizer(input, kProcessInfoDelimiters);
82bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (!tokenizer.GetNext()) {
83bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    LOG(ERROR)
84bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch        << "Error when parsing data. Expect: At least 1 token. Actual: 0";
85bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    return SyslogParser::PARSE_ERROR;
86bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
87bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  entry->process = tokenizer.token();
88bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  entry->process_id = "unknown";
89bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (tokenizer.GetNext()) {
90bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    std::string token = tokenizer.token();
91bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    int tmp;
92bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    if (base::StringToInt(token, &tmp)) {
93bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      entry->process_id = token;
94bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    }
95bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return SyslogParser::SUCCESS;
97bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
98bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
99bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochvoid SyslogParser::ParseLevel(const std::string& input,
100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                              api::log_private::LogEntry* entry) const {
101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (input.find("ERROR") != std::string::npos) {
102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    entry->level = "error";
103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  } else if (input.find("WARN") != std::string::npos) {
104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    entry->level = "warning";
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  } else if (input.find("INFO") != std::string::npos) {
106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    entry->level = "info";
107bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  } else {
108bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    entry->level = "unknown";
109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  }
110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace extensions
113