Index: chromeos/device_event_log_impl.cc |
diff --git a/chromeos/network/network_event_log.cc b/chromeos/device_event_log_impl.cc |
similarity index 41% |
rename from chromeos/network/network_event_log.cc |
rename to chromeos/device_event_log_impl.cc |
index 3f6d123f9ea4870c6c419768fcfe350df7eac4d3..06ee48e130dfdf6bf2bfcfeb58cbc970053e9791 100644 |
--- a/chromeos/network/network_event_log.cc |
+++ b/chromeos/device_event_log_impl.cc |
@@ -1,8 +1,8 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Copyright 2014 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 "chromeos/network/network_event_log.h" |
+#include "chromeos/device_event_log_impl.h" |
#include <cmath> |
#include <list> |
@@ -19,150 +19,106 @@ |
#include "net/base/escape.h" |
namespace chromeos { |
-namespace network_event_log { |
+ |
+namespace device_event_log { |
namespace { |
+const char* kLogLevelName[] = {"Error", "User", "Event", "Debug"}; |
+ |
+const char* kLogTypeNetworkDesc = "Network"; |
+const char* kLogTypePowerDesc = "Power"; |
+ |
+std::string GetLogTypeString(LogType type) { |
+ if (type == LOG_TYPE_NETWORK) |
+ return kLogTypeNetworkDesc; |
+ if (type == LOG_TYPE_POWER) |
+ return kLogTypePowerDesc; |
+ NOTREACHED(); |
+ return "Unknown"; |
+} |
+ |
std::string DateAndTimeWithMicroseconds(const base::Time& time) { |
base::Time::Exploded exploded; |
time.LocalExplode(&exploded); |
// base::Time::Exploded does not include microseconds, but sometimes we need |
// microseconds, so append '.' + usecs to the end of the formatted string. |
int usecs = static_cast<int>(fmod(time.ToDoubleT() * 1000000, 1000000)); |
- return base::StringPrintf("%04d/%02d/%02d %02d:%02d:%02d.%06d", |
- exploded.year, |
- exploded.month, |
- exploded.day_of_month, |
- exploded.hour, |
- exploded.minute, |
- exploded.second, |
+ return base::StringPrintf("%04d/%02d/%02d %02d:%02d:%02d.%06d", exploded.year, |
+ exploded.month, exploded.day_of_month, |
+ exploded.hour, exploded.minute, exploded.second, |
usecs); |
} |
std::string TimeWithSeconds(const base::Time& time) { |
base::Time::Exploded exploded; |
time.LocalExplode(&exploded); |
- return base::StringPrintf("%02d:%02d:%02d", |
- exploded.hour, |
- exploded.minute, |
+ return base::StringPrintf("%02d:%02d:%02d", exploded.hour, exploded.minute, |
exploded.second); |
} |
std::string TimeWithMillieconds(const base::Time& time) { |
base::Time::Exploded exploded; |
time.LocalExplode(&exploded); |
- return base::StringPrintf("%02d:%02d:%02d.%03d", |
- exploded.hour, |
- exploded.minute, |
- exploded.second, |
+ return base::StringPrintf("%02d:%02d:%02d.%03d", exploded.hour, |
+ exploded.minute, exploded.second, |
exploded.millisecond); |
} |
-class NetworkEventLog; |
-NetworkEventLog* g_network_event_log = NULL; |
-size_t g_max_network_event_log_entries = 4000; |
-const char* kLogLevelName[] = {"Error", "User", "Event", "Debug"}; |
+// Defined below for easier review. TODO(stevenjb): Move implementation here. |
+std::string GetHtmlText(LogLevel log_level, const std::string& event); |
-struct LogEntry { |
- LogEntry(const std::string& file, |
- int file_line, |
- LogLevel log_level, |
- const std::string& event, |
- const std::string& description); |
- |
- std::string ToString(bool show_time, |
- bool show_file, |
- bool show_level, |
- bool show_desc, |
- bool format_html) const; |
- void ToDictionary(base::DictionaryValue*) const; |
- |
- std::string GetNormalText(bool show_desc) const; |
- std::string GetHtmlText(bool show_desc) const; |
- std::string GetAsJSON() const; |
- |
- void SendToVLogOrErrorLog() const; |
- |
- bool ContentEquals(const LogEntry& other) const; |
- |
- std::string file; |
- int file_line; |
- LogLevel log_level; |
- std::string event; |
- std::string description; |
- base::Time time; |
- int count; |
-}; |
- |
-LogEntry::LogEntry(const std::string& file, |
- int file_line, |
- LogLevel log_level, |
- const std::string& event, |
- const std::string& description) |
- : file(file), |
- file_line(file_line), |
- log_level(log_level), |
- event(event), |
- description(description), |
- time(base::Time::Now()), |
- count(1) {} |
- |
-std::string LogEntry::ToString(bool show_time, |
- bool show_file, |
- bool show_level, |
- bool show_desc, |
- bool format_html) const { |
+std::string LogEntryToString(const DeviceEventLogImpl::LogEntry& log_entry, |
+ bool show_time, |
+ bool show_file, |
+ bool show_type, |
+ bool show_level, |
+ bool format_html) { |
std::string line; |
if (show_time) |
- line += "[" + TimeWithMillieconds(time) + "] "; |
+ line += "[" + TimeWithMillieconds(log_entry.time) + "] "; |
+ if (show_type) |
+ line += GetLogTypeString(log_entry.log_type) + ": "; |
if (show_level) { |
- const char* kLevelDesc[] = { |
- "ERROR", |
- "USER", |
- "EVENT", |
- "DEBUG" |
- }; |
- line += base::StringPrintf("%s: ", kLevelDesc[log_level]); |
+ const char* kLevelDesc[] = {"ERROR", "USER", "EVENT", "DEBUG"}; |
+ line += base::StringPrintf("%s: ", kLevelDesc[log_entry.log_level]); |
} |
if (show_file) { |
- std::string filestr = format_html ? net::EscapeForHTML(file) : file; |
- line += base::StringPrintf("%s:%d ", file.c_str(), file_line); |
+ std::string filestr = |
+ format_html ? net::EscapeForHTML(log_entry.file) : log_entry.file; |
+ line += base::StringPrintf("%s:%d ", log_entry.file.c_str(), |
+ log_entry.file_line); |
} |
- line += format_html ? GetHtmlText(show_desc) : GetNormalText(show_desc); |
- if (count > 1) |
- line += base::StringPrintf(" (%d)", count); |
+ line += format_html ? GetHtmlText(log_entry.log_level, log_entry.event) |
+ : log_entry.event; |
+ if (log_entry.count > 1) |
+ line += base::StringPrintf(" (%d)", log_entry.count); |
return line; |
} |
-void LogEntry::ToDictionary(base::DictionaryValue* output) const { |
- output->SetString("timestamp", DateAndTimeWithMicroseconds(time)); |
- output->SetString("timestampshort", TimeWithSeconds(time)); |
- output->SetString("level", kLogLevelName[log_level]); |
- output->SetString("file", |
- base::StringPrintf("%s:%d ", file.c_str(), file_line)); |
- output->SetString("event", event); |
- output->SetString("description", description); |
+void LogEntryToDictionary(const DeviceEventLogImpl::LogEntry& log_entry, |
+ base::DictionaryValue* output) { |
+ output->SetString("timestamp", DateAndTimeWithMicroseconds(log_entry.time)); |
+ output->SetString("timestampshort", TimeWithSeconds(log_entry.time)); |
+ output->SetString("level", kLogLevelName[log_entry.log_level]); |
+ output->SetString("type", GetLogTypeString(log_entry.log_type)); |
+ output->SetString("file", base::StringPrintf("%s:%d ", log_entry.file.c_str(), |
+ log_entry.file_line)); |
+ output->SetString("event", log_entry.event); |
} |
-std::string LogEntry::GetAsJSON() const { |
- base::DictionaryValue entry; |
- ToDictionary(&entry); |
+std::string LogEntryAsJSON(const DeviceEventLogImpl::LogEntry& log_entry) { |
+ base::DictionaryValue entry_dict; |
+ LogEntryToDictionary(log_entry, &entry_dict); |
std::string json; |
JSONStringValueSerializer serializer(&json); |
- if (!serializer.Serialize(entry)) { |
+ if (!serializer.Serialize(entry_dict)) { |
LOG(ERROR) << "Failed to serialize to JSON"; |
} |
return json; |
} |
-std::string LogEntry::GetNormalText(bool show_desc) const { |
- std::string text = event; |
- if (show_desc && !description.empty()) |
- text += ": " + description; |
- return text; |
-} |
- |
-std::string LogEntry::GetHtmlText(bool show_desc) const { |
+std::string GetHtmlText(LogLevel log_level, const std::string& event) { |
std::string text; |
if (log_level == LOG_LEVEL_DEBUG) |
text += "<i>"; |
@@ -171,9 +127,7 @@ std::string LogEntry::GetHtmlText(bool show_desc) const { |
else if (log_level == LOG_LEVEL_ERROR) |
text += "<b><i>"; |
- text += event; |
- if (show_desc && !description.empty()) |
- text += ": " + net::EscapeForHTML(description); |
+ text += net::EscapeForHTML(event); |
if (log_level == LOG_LEVEL_DEBUG) |
text += "</i>"; |
@@ -184,41 +138,51 @@ std::string LogEntry::GetHtmlText(bool show_desc) const { |
return text; |
} |
-void LogEntry::SendToVLogOrErrorLog() const { |
- if (log_level != LOG_LEVEL_ERROR && !VLOG_IS_ON(1)) |
+void SendLogEntryToVLogOrErrorLog( |
+ const DeviceEventLogImpl::LogEntry& log_entry) { |
+ if (log_entry.log_level != LOG_LEVEL_ERROR && !VLOG_IS_ON(1)) |
return; |
const bool show_time = true; |
const bool show_file = true; |
+ const bool show_type = true; |
const bool show_level = false; |
- const bool show_desc = true; |
const bool format_html = false; |
- std::string output = |
- ToString(show_time, show_file, show_level, show_desc, format_html); |
- if (log_level == LOG_LEVEL_ERROR) |
+ std::string output = LogEntryToString(log_entry, show_time, show_file, |
+ show_type, show_level, format_html); |
+ if (log_entry.log_level == LOG_LEVEL_ERROR) |
LOG(ERROR) << output; |
else |
VLOG(1) << output; |
} |
-bool LogEntry::ContentEquals(const LogEntry& other) const { |
- return file == other.file && |
- file_line == other.file_line && |
- event == other.event && |
- description == other.description; |
+bool LogEntryMatches(const DeviceEventLogImpl::LogEntry& first, |
+ const DeviceEventLogImpl::LogEntry& second) { |
+ return first.file == second.file && first.file_line == second.file_line && |
+ first.log_level == second.log_level && |
+ first.log_type == second.log_type && first.event == second.event; |
+} |
+ |
+bool LogEntryMatchesType(const DeviceEventLogImpl::LogEntry& entry, |
+ LogType type) { |
+ if (type == LOG_TYPE_ALL) |
+ return true; |
+ if (type == LOG_TYPE_NON_NETWORK && entry.log_type != LOG_TYPE_NETWORK) |
+ return true; |
+ return type == entry.log_type; |
} |
void GetFormat(const std::string& format_string, |
bool* show_time, |
bool* show_file, |
+ bool* show_type, |
bool* show_level, |
- bool* show_desc, |
bool* format_html, |
bool* format_json) { |
base::StringTokenizer tokens(format_string, ","); |
*show_time = false; |
*show_file = false; |
+ *show_type = false; |
*show_level = false; |
- *show_desc = false; |
*format_html = false; |
*format_json = false; |
while (tokens.GetNext()) { |
@@ -227,10 +191,10 @@ void GetFormat(const std::string& format_string, |
*show_time = true; |
if (tok == "file") |
*show_file = true; |
+ if (tok == "type") |
+ *show_type = true; |
if (tok == "level") |
*show_level = true; |
- if (tok == "desc") |
- *show_desc = true; |
if (tok == "html") |
*format_html = true; |
if (tok == "json") |
@@ -238,32 +202,38 @@ void GetFormat(const std::string& format_string, |
} |
} |
-typedef std::list<LogEntry> LogEntryList; |
- |
-class NetworkEventLog { |
- public: |
- NetworkEventLog() {} |
- ~NetworkEventLog() {} |
- |
- void AddLogEntry(const LogEntry& entry); |
+} // namespace |
- std::string GetAsString(StringOrder order, |
- const std::string& format, |
- LogLevel max_level, |
- size_t max_events); |
+// static |
+void DeviceEventLogImpl::SendToVLogOrErrorLog(const char* file, |
+ int file_line, |
+ LogType log_type, |
+ LogLevel log_level, |
+ const std::string& event) { |
+ LogEntry entry(file, file_line, log_type, log_level, event); |
+ SendLogEntryToVLogOrErrorLog(entry); |
+} |
- LogEntryList& entries() { return entries_; } |
+DeviceEventLogImpl::DeviceEventLogImpl(size_t max_entries) |
+ : max_entries_(max_entries) { |
+} |
- private: |
- LogEntryList entries_; |
+DeviceEventLogImpl::~DeviceEventLogImpl() { |
+} |
- DISALLOW_COPY_AND_ASSIGN(NetworkEventLog); |
-}; |
+void DeviceEventLogImpl::AddEntry(const char* file, |
+ int file_line, |
+ LogType log_type, |
+ LogLevel log_level, |
+ const std::string& event) { |
+ LogEntry entry(file, file_line, log_type, log_level, event); |
+ AddLogEntry(entry); |
+} |
-void NetworkEventLog::AddLogEntry(const LogEntry& entry) { |
+void DeviceEventLogImpl::AddLogEntry(const LogEntry& entry) { |
if (!entries_.empty()) { |
LogEntry& last = entries_.back(); |
- if (last.ContentEquals(entry)) { |
+ if (LogEntryMatches(last, entry)) { |
// Update count and time for identical events to avoid log spam. |
++last.count; |
last.log_level = std::min(last.log_level, entry.log_level); |
@@ -271,8 +241,8 @@ void NetworkEventLog::AddLogEntry(const LogEntry& entry) { |
return; |
} |
} |
- if (entries_.size() >= g_max_network_event_log_entries) { |
- const size_t max_error_entries = g_max_network_event_log_entries / 2; |
+ if (entries_.size() >= max_entries_) { |
+ const size_t max_error_entries = max_entries_ / 2; |
// Remove the first (oldest) non-error entry, or the oldest entry if more |
// than half the entries are errors. |
size_t error_count = 0; |
@@ -290,24 +260,20 @@ void NetworkEventLog::AddLogEntry(const LogEntry& entry) { |
} |
} |
entries_.push_back(entry); |
- entry.SendToVLogOrErrorLog(); |
+ SendLogEntryToVLogOrErrorLog(entry); |
} |
-std::string NetworkEventLog::GetAsString(StringOrder order, |
- const std::string& format, |
- LogLevel max_level, |
- size_t max_events) { |
+std::string DeviceEventLogImpl::GetAsString(StringOrder order, |
+ const std::string& format, |
+ LogType log_type, |
+ LogLevel max_level, |
+ size_t max_events) { |
if (entries_.empty()) |
return "No Log Entries."; |
- bool show_time, show_file, show_level, show_desc, format_html, format_json; |
- GetFormat(format, |
- &show_time, |
- &show_file, |
- &show_level, |
- &show_desc, |
- &format_html, |
- &format_json); |
+ bool show_time, show_file, show_type, show_level, format_html, format_json; |
+ GetFormat(format, &show_time, &show_file, &show_type, &show_level, |
+ &format_html, &format_json); |
std::string result; |
base::ListValue log_entries; |
@@ -319,9 +285,10 @@ std::string NetworkEventLog::GetAsString(StringOrder order, |
size_t shown_events = 0; |
size_t num_entries = 0; |
for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); |
- riter != entries_.rend(); |
- ++riter) { |
+ riter != entries_.rend(); ++riter) { |
++num_entries; |
+ if (!LogEntryMatchesType(*riter, log_type)) |
+ continue; |
if (riter->log_level > max_level) |
continue; |
if (++shown_events >= max_events) |
@@ -330,19 +297,20 @@ std::string NetworkEventLog::GetAsString(StringOrder order, |
offset = entries_.size() - num_entries; |
} |
for (LogEntryList::const_iterator iter = entries_.begin(); |
- iter != entries_.end(); |
- ++iter) { |
+ iter != entries_.end(); ++iter) { |
if (offset > 0) { |
--offset; |
continue; |
} |
+ if (!LogEntryMatchesType(*iter, log_type)) |
+ continue; |
if (iter->log_level > max_level) |
continue; |
if (format_json) { |
- log_entries.AppendString((*iter).GetAsJSON()); |
+ log_entries.AppendString(LogEntryAsJSON(*iter)); |
} else { |
- result += (*iter).ToString( |
- show_time, show_file, show_level, show_desc, format_html); |
+ result += LogEntryToString(*iter, show_time, show_file, show_type, |
+ show_level, format_html); |
result += "\n"; |
} |
} |
@@ -350,15 +318,16 @@ std::string NetworkEventLog::GetAsString(StringOrder order, |
size_t nlines = 0; |
// Iterate backwards through the list to show the most recent entries first. |
for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); |
- riter != entries_.rend(); |
- ++riter) { |
+ riter != entries_.rend(); ++riter) { |
+ if (!LogEntryMatchesType(*riter, log_type)) |
+ continue; |
if (riter->log_level > max_level) |
continue; |
if (format_json) { |
- log_entries.AppendString((*riter).GetAsJSON()); |
+ log_entries.AppendString(LogEntryAsJSON(*riter)); |
} else { |
- result += (*riter).ToString( |
- show_time, show_file, show_level, show_desc, format_html); |
+ result += LogEntryToString(*riter, show_time, show_file, show_type, |
+ show_level, format_html); |
result += "\n"; |
} |
if (max_events > 0 && ++nlines >= max_events) |
@@ -373,68 +342,21 @@ std::string NetworkEventLog::GetAsString(StringOrder order, |
return result; |
} |
-} // namespace |
- |
-const LogLevel kDefaultLogLevel = LOG_LEVEL_EVENT; |
- |
-void Initialize() { |
- if (g_network_event_log) |
- delete g_network_event_log; // reset log |
- g_network_event_log = new NetworkEventLog(); |
-} |
- |
-void Shutdown() { |
- delete g_network_event_log; |
- g_network_event_log = NULL; |
-} |
- |
-bool IsInitialized() { return g_network_event_log != NULL; } |
- |
-namespace internal { |
- |
-size_t GetMaxLogEntries() { return g_max_network_event_log_entries; } |
- |
-void SetMaxLogEntries(size_t max_entries) { |
- g_max_network_event_log_entries = max_entries; |
- if (!g_network_event_log) |
- return; |
- while (g_network_event_log->entries().size() > max_entries) |
- g_network_event_log->entries().pop_front(); |
-} |
- |
-void AddEntry(const char* file, |
- int file_line, |
- LogLevel log_level, |
- const std::string& event, |
- const std::string& description) { |
- std::string filestr; |
- if (file) |
- filestr = base::FilePath(std::string(file)).BaseName().value(); |
- LogEntry entry(filestr, file_line, log_level, event, description); |
- if (!g_network_event_log) { |
- entry.SendToVLogOrErrorLog(); |
- return; |
- } |
- g_network_event_log->AddLogEntry(entry); |
-} |
- |
-} // namespace internal |
- |
-std::string GetAsString(StringOrder order, |
- const std::string& format, |
- LogLevel max_level, |
- size_t max_events) { |
- if (!g_network_event_log) |
- return "NetworkEventLog not initialized."; |
- return g_network_event_log->GetAsString(order, format, max_level, max_events); |
+DeviceEventLogImpl::LogEntry::LogEntry(const char* filedesc, |
+ int file_line, |
+ LogType log_type, |
+ LogLevel log_level, |
+ const std::string& event) |
+ : file_line(file_line), |
+ log_type(log_type), |
+ log_level(log_level), |
+ event(event), |
+ time(base::Time::Now()), |
+ count(1) { |
+ if (filedesc) |
+ file = base::FilePath(std::string(filedesc)).BaseName().value(); |
} |
-std::string ValueAsString(const base::Value& value) { |
- std::string vstr; |
- base::JSONWriter::WriteWithOptions( |
- &value, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &vstr); |
- return vstr.empty() ? "''" : vstr; |
-} |
+} // namespace device_event_log |
-} // namespace network_event_log |
} // namespace chromeos |