diff options
author | shinfan@chromium.org <shinfan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 22:56:29 +0000 |
---|---|---|
committer | shinfan@chromium.org <shinfan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 22:56:29 +0000 |
commit | 2901975cc78133241b9f46a9a758bbf0506d4362 (patch) | |
tree | 5fd9152355678c4e518f579233779e737b926eaf | |
parent | f9451a81caf32ebae0c5e13903698b6270ee4b9d (diff) | |
download | chromium_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
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); |