summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorshinfan@chromium.org <shinfan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-07 22:56:29 +0000
committershinfan@chromium.org <shinfan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-07 22:56:29 +0000
commit2901975cc78133241b9f46a9a758bbf0506d4362 (patch)
tree5fd9152355678c4e518f579233779e737b926eaf
parentf9451a81caf32ebae0c5e13903698b6270ee4b9d (diff)
downloadchromium_src-2901975cc78133241b9f46a9a758bbf0506d4362.zip
chromium_src-2901975cc78133241b9f46a9a758bbf0506d4362.tar.gz
chromium_src-2901975cc78133241b9f46a9a758bbf0506d4362.tar.bz2
Create a private extension API chrome.logPrivate
- This API returns log entries in standard JSON format. - In this CL it only support chrome.logPrivate.getHistorical. - Currently it only supports syslog. (More types of log will be added in future CLs) - This API is implemented based on SystemLogFetcher which retreves log information from debugd - This API is only avaible on Chrome OS - The API design doc: https://docs.google.com/a/google.com/document/d/1yJpromwIx2G-KBhNcKopSAW0S3TF0zdz9gM5w9VVqPI/ BUG= TEST=unittest Review URL: https://chromiumcodereview.appspot.com/18580010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216295 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/extensions/api/log_private/filter_handler.cc58
-rw-r--r--chrome/browser/extensions/api/log_private/filter_handler.h46
-rw-r--r--chrome/browser/extensions/api/log_private/log_parser.cc40
-rw-r--r--chrome/browser/extensions/api/log_private/log_parser.h49
-rw-r--r--chrome/browser/extensions/api/log_private/log_private_api.h38
-rw-r--r--chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc86
-rw-r--r--chrome/browser/extensions/api/log_private/log_private_api_nonchromeos.cc31
-rw-r--r--chrome/browser/extensions/api/log_private/syslog_parser.cc144
-rw-r--r--chrome/browser/extensions/api/log_private/syslog_parser.h46
-rw-r--r--chrome/browser/extensions/api/log_private/syslog_parser_unittest.cc55
-rw-r--r--chrome/browser/extensions/extension_function_histogram_value.h1
-rw-r--r--chrome/chrome_browser_extensions.gypi12
-rw-r--r--chrome/chrome_tests_unit.gypi2
-rw-r--r--chrome/common/extensions/api/_api_features.json5
-rw-r--r--chrome/common/extensions/api/_permission_features.json5
-rw-r--r--chrome/common/extensions/api/api.gyp2
-rw-r--r--chrome/common/extensions/api/log_private.idl52
-rw-r--r--chrome/common/extensions/permissions/api_permission.h3
-rw-r--r--chrome/common/extensions/permissions/chrome_api_permissions.cc1
-rw-r--r--chrome/common/extensions/permissions/permission_set_unittest.cc1
20 files changed, 676 insertions, 1 deletions
diff --git a/chrome/browser/extensions/api/log_private/filter_handler.cc b/chrome/browser/extensions/api/log_private/filter_handler.cc
new file mode 100644
index 0000000..6965932
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/filter_handler.cc
@@ -0,0 +1,58 @@
+// 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/filter_handler.h"
+
+#include <string>
+#include <vector>
+
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+
+namespace {
+
+template <typename T>
+bool IsValidField(const std::vector<T>& filter, const T& field) {
+ return (!filter.size() ||
+ std::find(filter.begin(), filter.end(), field) != filter.end());
+}
+
+} // namespace
+
+FilterHandler::FilterHandler(const api::log_private::Filter& filter) {
+ scoped_ptr<base::DictionaryValue> filter_value = filter.ToValue();
+ api::log_private::Filter::Populate(*filter_value, &filter_);
+}
+
+FilterHandler::~FilterHandler() {}
+
+bool FilterHandler::IsValidLogEntry(
+ const api::log_private::LogEntry& entry) const {
+ return (IsValidProcess(entry.process) && IsValidLevel(entry.level) &&
+ IsValidTime(entry.timestamp));
+}
+
+bool FilterHandler::IsValidTime(double time) const {
+ const double kInvalidTime = 0;
+ if (filter_.start_timestamp != kInvalidTime &&
+ (filter_.start_timestamp > time || filter_.end_timestamp < time)) {
+ return false;
+ }
+ return true;
+}
+
+bool FilterHandler::IsValidSource(const std::string& source) const {
+ return IsValidField(filter_.sources, source);
+}
+
+bool FilterHandler::IsValidLevel(const std::string& level) const {
+ return IsValidField(filter_.level, level);
+}
+
+bool FilterHandler::IsValidProcess(const std::string& process) const {
+ return IsValidField(filter_.process, process);
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/log_private/filter_handler.h b/chrome/browser/extensions/api/log_private/filter_handler.h
new file mode 100644
index 0000000..18e3129
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/filter_handler.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_FILTER_HANDLER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_FILTER_HANDLER_H_
+
+#include <string>
+#include <vector>
+
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+// This class contains multiple filtering methods to filter log entries
+// by multiple fields.
+class FilterHandler {
+ public:
+ explicit FilterHandler(const api::log_private::Filter& filter);
+ ~FilterHandler();
+
+ // This function decides if a log entry should be returned to user.
+ // Returns true if the log entry meets the filtering conditions.
+ bool IsValidLogEntry(const api::log_private::LogEntry& entry) const;
+ // Filters log by timestamp.
+ // Returns true if the timestamp is within the time range of the filter.
+ bool IsValidTime(double time) const;
+ // Filters log by source (syslog, network_event_log, etc).
+ // Returns true if the log is from specified source in the filter.
+ bool IsValidSource(const std::string& source) const;
+ // Filters log by level (DEBUG, ERROR, WARNING).
+ // Returns true if the log level is specified in the filter.
+ bool IsValidLevel(const std::string& level) const;
+ // Filters log by its process name.
+ // Returns true if the process name is specified in the filter.
+ bool IsValidProcess(const std::string& process) const;
+
+ const api::log_private::Filter* GetFilter() const { return &filter_; }
+ private:
+ api::log_private::Filter filter_;
+
+ DISALLOW_COPY_AND_ASSIGN(FilterHandler);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_FILTER_HANDLER_H_
diff --git a/chrome/browser/extensions/api/log_private/log_parser.cc b/chrome/browser/extensions/api/log_private/log_parser.cc
new file mode 100644
index 0000000..d88c73a
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/log_parser.cc
@@ -0,0 +1,40 @@
+// 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/log_parser.h"
+
+#include <string>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
+#include "base/strings/string_split.h"
+#include "chrome/browser/extensions/api/log_private/log_private_api.h"
+#include "chrome/common/extensions/api/log_private.h"
+
+using std::string;
+using std::vector;
+
+namespace extensions {
+
+LogParser::LogParser() {
+}
+
+LogParser::~LogParser() {
+}
+
+void LogParser::Parse(
+ const string& input,
+ std::vector<linked_ptr<api::log_private::LogEntry> >* output,
+ FilterHandler* filter_handler) const {
+ std::vector<string> entries;
+ // Assume there is no newline in the log entry
+ base::SplitString(input, '\n', &entries);
+
+ for (size_t i = 0; i < entries.size(); i++) {
+ ParseEntry(entries[i], output, filter_handler);
+ }
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/log_private/log_parser.h b/chrome/browser/extensions/api/log_private/log_parser.h
new file mode 100644
index 0000000..c73e54f
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/log_parser.h
@@ -0,0 +1,49 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PARSER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PARSER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/linked_ptr.h"
+#include "chrome/browser/extensions/api/log_private/filter_handler.h"
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+
+// This is a abstract class of parsers for different logs.
+// All the specific parsers inherit from this class.
+class LogParser {
+ public:
+ enum Error {
+ SUCCESS = 0,
+ PARSE_ERROR = -1,
+ SERIALIZE_ERROR = -2,
+ TOKENIZE_ERROR = -3
+ };
+
+ virtual ~LogParser();
+ // Parses log text into multiple LogEntry objects.
+ void Parse(
+ const std::string& input,
+ std::vector<linked_ptr<api::log_private::LogEntry> >* output,
+ FilterHandler* filter_handler) const;
+
+ protected:
+ explicit LogParser();
+ // Parses a single line of log text into one LogEntry object.
+ virtual Error ParseEntry(
+ const std::string& input,
+ std::vector<linked_ptr<api::log_private::LogEntry> >* output,
+ FilterHandler* filter_handler) const = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(LogParser);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PARSER_H_
diff --git a/chrome/browser/extensions/api/log_private/log_private_api.h b/chrome/browser/extensions/api/log_private/log_private_api.h
new file mode 100644
index 0000000..f6f8911
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/log_private_api.h
@@ -0,0 +1,38 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PRIVATE_API_H_
+#define CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PRIVATE_API_H_
+
+#include <string>
+
+#include "chrome/browser/chromeos/system_logs/system_logs_fetcher.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/extension_function.h"
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+
+class LogPrivateGetHistoricalFunction : public AsyncExtensionFunction {
+ public:
+ LogPrivateGetHistoricalFunction();
+ DECLARE_EXTENSION_FUNCTION("logPrivate.getHistorical",
+ LOGPRIVATE_GETHISTORICAL);
+
+ protected:
+ virtual ~LogPrivateGetHistoricalFunction();
+ virtual bool RunImpl() OVERRIDE;
+
+ private:
+ void OnSystemLogsLoaded(scoped_ptr<chromeos::SystemLogsResponse> sys_info);
+
+ scoped_ptr<FilterHandler> filter_handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(LogPrivateGetHistoricalFunction);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_LOG_PRIVATE_API_H_
diff --git a/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
new file mode 100644
index 0000000..055c4ac
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/log_private_api_chromeos.cc
@@ -0,0 +1,86 @@
+// 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/log_private_api.h"
+
+#include <string>
+#include <vector>
+
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_ptr.h"
+#include "chrome/browser/chromeos/system_logs/system_logs_fetcher.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/syslog_parser.h"
+#include "chrome/browser/extensions/extension_function.h"
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+namespace {
+
+scoped_ptr<LogParser> CreateLogParser(const std::string& log_type) {
+ if (log_type == "syslog")
+ return scoped_ptr<LogParser>(new SyslogParser());
+ // TODO(shinfan): Add more parser here
+
+ NOTREACHED() << "Invalid log type: " << log_type;
+ return scoped_ptr<LogParser>();
+}
+
+void CollectLogInfo(
+ FilterHandler* filter_handler,
+ chromeos::SystemLogsResponse* logs,
+ std::vector<linked_ptr<api::log_private::LogEntry> >* output) {
+ for (chromeos::SystemLogsResponse::const_iterator request_it = logs->begin();
+ request_it != logs->end();
+ ++request_it) {
+ if (!filter_handler->IsValidSource(request_it->first)) {
+ continue;
+ }
+ scoped_ptr<LogParser> parser(CreateLogParser(request_it->first));
+ if (parser) {
+ parser->Parse(request_it->second, output, filter_handler);
+ }
+ }
+}
+
+} // namespace
+
+LogPrivateGetHistoricalFunction::LogPrivateGetHistoricalFunction() {
+}
+
+LogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() {
+}
+
+bool LogPrivateGetHistoricalFunction::RunImpl() {
+ // Get parameters
+ scoped_ptr<api::log_private::GetHistorical::Params> params(
+ api::log_private::GetHistorical::Params::Create(*args_));
+ EXTENSION_FUNCTION_VALIDATE(params.get());
+ filter_handler_.reset(new FilterHandler(params->filter));
+
+ chromeos::SystemLogsFetcher* fetcher = new chromeos::SystemLogsFetcher();
+ fetcher->Fetch(
+ base::Bind(&LogPrivateGetHistoricalFunction::OnSystemLogsLoaded, this));
+ return true;
+}
+
+void LogPrivateGetHistoricalFunction::OnSystemLogsLoaded(
+ scoped_ptr<chromeos::SystemLogsResponse> sys_info) {
+ std::vector<linked_ptr<api::log_private::LogEntry> > data;
+
+ CollectLogInfo(filter_handler_.get(), sys_info.get(), &data);
+
+ // Prepare result
+ api::log_private::Result result;
+ result.data = data;
+ api::log_private::Filter::Populate(
+ *((filter_handler_->GetFilter())->ToValue()), &result.filter);
+ SetResult(result.ToValue().release());
+ SendResponse(true);
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/log_private/log_private_api_nonchromeos.cc b/chrome/browser/extensions/api/log_private/log_private_api_nonchromeos.cc
new file mode 100644
index 0000000..c2ae4ad
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/log_private_api_nonchromeos.cc
@@ -0,0 +1,31 @@
+// 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/log_private_api.h"
+
+namespace extensions {
+
+namespace {
+
+const char kErrorNotImplemented[] = "Not implemented";
+
+} // namespace
+
+LogPrivateGetHistoricalFunction::LogPrivateGetHistoricalFunction() {
+}
+
+LogPrivateGetHistoricalFunction::~LogPrivateGetHistoricalFunction() {
+}
+
+bool LogPrivateGetHistoricalFunction::RunImpl() {
+ SetError(kErrorNotImplemented);
+ SendResponse(error_.empty());
+ return false;
+}
+
+void LogPrivateGetHistoricalFunction::OnSystemLogsLoaded(
+ scoped_ptr<chromeos::SystemLogsResponse> sys_info) {
+}
+
+} // namespace extensions
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
diff --git a/chrome/browser/extensions/api/log_private/syslog_parser.h b/chrome/browser/extensions/api/log_private/syslog_parser.h
new file mode 100644
index 0000000..b746334
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/syslog_parser.h
@@ -0,0 +1,46 @@
+// 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.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_SYSLOG_PARSER_H_
+#define CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_SYSLOG_PARSER_H_
+
+#include <string>
+#include <vector>
+
+#include "base/memory/linked_ptr.h"
+#include "chrome/browser/extensions/api/log_private/log_parser.h"
+#include "chrome/common/extensions/api/log_private.h"
+
+namespace extensions {
+
+// A parser that parses syslog into LogEntry objects.
+class SyslogParser : public LogParser {
+ public:
+ SyslogParser();
+ virtual ~SyslogParser();
+
+ protected:
+ // Parses one line log text into a LogEntry object.
+ virtual Error ParseEntry(
+ const std::string& input,
+ std::vector<linked_ptr<api::log_private::LogEntry> >* output,
+ FilterHandler* filter_handler) const
+ OVERRIDE;
+
+ private:
+ // Parses time token and get time in milliseconds.
+ Error ParseTime(const std::string& input, double* output) const;
+ // Parses process token and get process name and ID.
+ Error ParseProcess(const std::string& input,
+ api::log_private::LogEntry* entry) const;
+ // Parses level token and get log level.
+ void ParseLevel(const std::string& input,
+ api::log_private::LogEntry* entry) const;
+
+ DISALLOW_COPY_AND_ASSIGN(SyslogParser);
+};
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_LOG_PRIVATE_SYSLOG_PARSER_H_
diff --git a/chrome/browser/extensions/api/log_private/syslog_parser_unittest.cc b/chrome/browser/extensions/api/log_private/syslog_parser_unittest.cc
new file mode 100644
index 0000000..2c0b8f0
--- /dev/null
+++ b/chrome/browser/extensions/api/log_private/syslog_parser_unittest.cc
@@ -0,0 +1,55 @@
+// 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 <stdio.h>
+#include <string>
+#include <vector>
+
+#include "base/json/json_writer.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/browser/extensions/api/log_private/filter_handler.h"
+#include "chrome/browser/extensions/api/log_private/log_private_api.h"
+#include "chrome/browser/extensions/api/log_private/syslog_parser.h"
+#include "chrome/common/extensions/api/log_private.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+namespace {
+
+const char kShillLogEntry[] =
+ "2013-07-08T11:28:12.440308-07:00 localhost shill:"
+ "[0708/112812:ERROR:manager.cc(480)] Skipping unload of service";
+
+const char kWpaSupplicantLogEntry[] =
+ "2013-07-08T12:39:07.443100-07:00 localhost wpa_supplicant[894]:"
+ "dbus: Failed to construct signal";
+
+} // namespace
+
+class ExtensionSyslogParserTest : public testing::Test {
+};
+
+TEST_F(ExtensionSyslogParserTest, ParseLog) {
+ std::vector<linked_ptr<api::log_private::LogEntry> > output;
+ api::log_private::Filter filter;
+ FilterHandler filter_handler(filter);
+ SyslogParser p;
+ // Test shill log
+ p.Parse(kShillLogEntry, &output, &filter_handler);
+ EXPECT_STREQ(output[0]->level.c_str(), "error");
+ EXPECT_STREQ(output[0]->process.c_str(), "shill:");
+ EXPECT_STREQ(output[0]->process_id.c_str(), "unknown");
+ EXPECT_STREQ(output[0]->full_entry.c_str(), kShillLogEntry);
+ EXPECT_EQ(output[0]->timestamp, 1373308092440.308);
+ // Test WpaSupplicant log
+ p.Parse(kWpaSupplicantLogEntry, &output, &filter_handler);
+ EXPECT_STREQ(output[1]->level.c_str(), "unknown");
+ EXPECT_STREQ(output[1]->process.c_str(), "wpa_supplicant");
+ EXPECT_STREQ(output[1]->process_id.c_str(), "894");
+ EXPECT_STREQ(output[1]->full_entry.c_str(), kWpaSupplicantLogEntry);
+ EXPECT_EQ(output[1]->timestamp, 1373312347443.1);
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/extension_function_histogram_value.h b/chrome/browser/extensions/extension_function_histogram_value.h
index ab5ffc5..3408bd6 100644
--- a/chrome/browser/extensions/extension_function_histogram_value.h
+++ b/chrome/browser/extensions/extension_function_histogram_value.h
@@ -587,6 +587,7 @@ enum HistogramValue {
RECOVERYPRIVATE_CANCELWRITE,
RECOVERYPRIVATE_DESTROYPARTITIONS,
FEEDBACKPRIVATE_GETSTRINGS,
+ LOGPRIVATE_GETHISTORICAL,
ENUM_BOUNDARY // Last entry: Add new entries above.
};
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index e6840ca..6f7425d 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -282,6 +282,14 @@
'browser/extensions/api/location/location_api.h',
'browser/extensions/api/location/location_manager.cc',
'browser/extensions/api/location/location_manager.h',
+ 'browser/extensions/api/log_private/filter_handler.cc',
+ 'browser/extensions/api/log_private/filter_handler.h',
+ 'browser/extensions/api/log_private/log_parser.cc',
+ 'browser/extensions/api/log_private/log_parser.h',
+ 'browser/extensions/api/log_private/log_private_api.h',
+ 'browser/extensions/api/log_private/log_private_api_nonchromeos.cc',
+ 'browser/extensions/api/log_private/syslog_parser.cc',
+ 'browser/extensions/api/log_private/syslog_parser.h',
'browser/extensions/api/management/management_api.cc',
'browser/extensions/api/management/management_api.h',
'browser/extensions/api/management/management_api_constants.cc',
@@ -805,8 +813,9 @@
],
'sources!': [
'browser/extensions/api/audio/audio_service.cc',
- 'browser/extensions/api/feedback_private/feedback_service_nonchromeos.cc',
'browser/extensions/api/diagnostics/diagnostics_api_nonchromeos.cc',
+ 'browser/extensions/api/feedback_private/feedback_service_nonchromeos.cc',
+ 'browser/extensions/api/log_private/log_private_api_nonchromeos.cc',
'browser/extensions/api/networking_private/networking_private_api_nonchromeos.cc',
'browser/extensions/default_apps.cc',
'browser/extensions/default_apps.h',
@@ -816,6 +825,7 @@
'browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h',
'browser/extensions/api/input_ime/input_ime_api.cc',
'browser/extensions/api/input_ime/input_ime_api.h',
+ 'browser/extensions/api/log_private/log_private_api_chromeos.cc',
'browser/extensions/api/rtc_private/rtc_private_api.cc',
'browser/extensions/api/rtc_private/rtc_private_api.h',
'browser/extensions/api/terminal/terminal_extension_helper.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 4afe4ad..79f7a73 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -793,6 +793,7 @@
'browser/extensions/api/identity/gaia_web_auth_flow_unittest.cc',
'browser/extensions/api/identity/identity_mint_queue_unittest.cc',
'browser/extensions/api/idle/idle_api_unittest.cc',
+ 'browser/extensions/api/log_private/syslog_parser_unittest.cc',
'browser/extensions/api/messaging/native_message_process_host_unittest.cc',
'browser/extensions/api/messaging/native_messaging_host_manifest_unittest.cc',
'browser/extensions/api/omnibox/omnibox_unittest.cc',
@@ -2211,6 +2212,7 @@
'sources!': [
'browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api_unittest.cc',
'browser/net/gaia/gaia_oauth_fetcher_unittest.cc',
+ 'browser/extensions/api/log_private/syslog_parser_unittest.cc',
],
}],
['use_x11==1', {
diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json
index 2780ca16..d9075d7 100644
--- a/chrome/common/extensions/api/_api_features.json
+++ b/chrome/common/extensions/api/_api_features.json
@@ -308,6 +308,11 @@
"dependencies": ["permission:location"],
"contexts": ["blessed_extension"]
},
+ "logPrivate": {
+ "dependencies": ["permission:logPrivate"],
+ "extension_types": ["extension", "packaged_app"],
+ "contexts": ["blessed_extension"]
+ },
"management": {
"dependencies": ["permission:management"],
"contexts": ["blessed_extension"]
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 464645c..1c761cc 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -334,6 +334,11 @@
"location": "component"
}
],
+ "logPrivate": {
+ "channel": "dev",
+ "extension_types": ["extension", "packaged_app"],
+ "location": "component"
+ },
"management": [
{
"channel": "stable",
diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp
index f079337..465021a 100644
--- a/chrome/common/extensions/api/api.gyp
+++ b/chrome/common/extensions/api/api.gyp
@@ -66,6 +66,7 @@
'idle.json',
'infobars.json',
'input_ime.json',
+ 'log_private.idl',
'management.json',
'manifest_types.json',
'media_galleries.idl',
@@ -123,6 +124,7 @@
['OS!="chromeos"', {
'schema_files!': [
'file_browser_handler_internal.json',
+ 'log_private.idl',
'rtc_private.idl',
],
}],
diff --git a/chrome/common/extensions/api/log_private.idl b/chrome/common/extensions/api/log_private.idl
new file mode 100644
index 0000000..2194357
--- /dev/null
+++ b/chrome/common/extensions/api/log_private.idl
@@ -0,0 +1,52 @@
+// 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.
+
+// Use chrome.logPrivate API to retrieve log information from multiple
+// resources in a consistent format.
+namespace logPrivate {
+
+ // A filter class that filters log entries by different fields
+ dictionary Filter {
+ // Only logs from |sources| will be returned.
+ DOMString[] sources;
+ // Only logs created in [|start_timestamp|, |end_timestamp|] will
+ // be returned.
+ double start_timestamp;
+ double end_timestamp;
+ // Only logs have process name in |process| will be returned.
+ DOMString[] process;
+ // Only logs have level in |level| will be returned.
+ DOMString[] level;
+ };
+
+ // The class that contains log information.
+ dictionary LogEntry {
+ // The time of the log in milliseconds.
+ double timestamp;
+ // The raw text of log.
+ DOMString full_entry;
+ // The name of the process that the log associated with.
+ DOMString process;
+ // The ID of the process that the log associated with.
+ DOMString process_id;
+ // The log level.
+ DOMString level;
+ };
+
+ // The class that is returned to callback function.
+ dictionary Result {
+ // The filter specified to filter log result.
+ Filter filter;
+ // Log entries returned based on the filter.
+ LogEntry[] data;
+ };
+
+ callback GetHistoricalCallback = void (Result res);
+
+ interface Functions {
+ // Get the existing logs from ChromeOS system.
+ static void getHistorical(Filter filter, GetHistoricalCallback callback);
+ };
+
+};
diff --git a/chrome/common/extensions/permissions/api_permission.h b/chrome/common/extensions/permissions/api_permission.h
index d99616d..980be54 100644
--- a/chrome/common/extensions/permissions/api_permission.h
+++ b/chrome/common/extensions/permissions/api_permission.h
@@ -91,6 +91,7 @@ class APIPermission {
kInput,
kInputMethodPrivate,
kLocation,
+ kLogPrivate,
kManagement,
kMediaGalleries,
kMediaGalleriesPrivate,
@@ -141,6 +142,8 @@ class APIPermission {
kWebView,
kSystemCpu,
kSystemMemory,
+ kSystemInfoCpu,
+ kSystemInfoMemory,
kEnumBoundary
};
diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc
index 6562f9c..0b368f8 100644
--- a/chrome/common/extensions/permissions/chrome_api_permissions.cc
+++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc
@@ -166,6 +166,7 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions()
APIPermissionInfo::kFlagCannotBeOptional },
{ APIPermission::kIdentityPrivate, "identityPrivate",
APIPermissionInfo::kFlagCannotBeOptional },
+ { APIPermission::kLogPrivate, "logPrivate"},
{ APIPermission::kNetworkingPrivate, "networkingPrivate",
APIPermissionInfo::kFlagCannotBeOptional,
IDS_EXTENSION_PROMPT_WARNING_NETWORKING_PRIVATE,
diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc
index 366843e5..f5adabd 100644
--- a/chrome/common/extensions/permissions/permission_set_unittest.cc
+++ b/chrome/common/extensions/permissions/permission_set_unittest.cc
@@ -647,6 +647,7 @@ TEST(PermissionsTest, PermissionMessages) {
skip.insert(APIPermission::kFontSettings);
skip.insert(APIPermission::kFullscreen);
skip.insert(APIPermission::kIdle);
+ skip.insert(APIPermission::kLogPrivate);
skip.insert(APIPermission::kNotification);
skip.insert(APIPermission::kPointerLock);
skip.insert(APIPermission::kPower);