network_event_log.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt// Use of this source code is governed by a BSD-style license that can be 3e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt// found in the LICENSE file. 4e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 5e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "chromeos/network/network_event_log.h" 6e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 7e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "base/i18n/time_formatting.h" 8e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "base/logging.h" 9e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "base/memory/scoped_ptr.h" 10e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "base/stringprintf.h" 11e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt#include "base/utf_string_conversions.h" 12e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 13e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtnamespace chromeos { 14e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 15e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtnamespace network_event_log { 16e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 17e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtnamespace { 18e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 19e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstruct LogEntry { 20e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt LogEntry(const std::string& module, 21e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const std::string& event, 22e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const std::string& description); 23e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 24e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt std::string ToString() const; 25e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 26e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt bool ContentEquals(const LogEntry& other) const; 27e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 28e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt std::string module; 29e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt std::string event; 30e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt std::string description; 31e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt base::Time time; 32e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt int count; 33e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}; 34e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt 35573ffd03049495be0921cc8c6461c32be5f0ee60Dan AlbertLogEntry::LogEntry(const std::string& module, 36573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert const std::string& event, 37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt const std::string& description) 38573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert : module(module), 39573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert event(event), 40573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert description(description), 41573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert time(base::Time::Now()), 42573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert count(1) { 43573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert} 44573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert 45573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albertstd::string LogEntry::ToString() const { 46573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert std::string line; 47573ffd03049495be0921cc8c6461c32be5f0ee60Dan Albert line += "[" + UTF16ToUTF8(base::TimeFormatShortDateAndTime(time)) + "]"; 48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt line += " " + module + ":" + event; 49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt if (!description.empty()) 50 line += ": " + description; 51 if (count > 1) 52 line += base::StringPrintf(" (%d)", count); 53 line += "\n"; 54 return line; 55} 56 57bool LogEntry::ContentEquals(const LogEntry& other) const { 58 return module == other.module && 59 event == other.event && 60 description == other.description; 61} 62 63typedef std::deque<LogEntry> LogEntryList; 64 65class NetworkEventLog { 66 public: 67 NetworkEventLog() {} 68 ~NetworkEventLog() {} 69 70 void AddEntry(const LogEntry& entry); 71 72 std::string GetAsString(StringOrder order, 73 size_t max_events); 74 75 private: 76 LogEntryList entries_; 77 78 DISALLOW_COPY_AND_ASSIGN(NetworkEventLog); 79}; 80 81void NetworkEventLog::AddEntry(const LogEntry& entry) { 82 if (!entries_.empty()) { 83 LogEntry& last = entries_.back(); 84 if (last.ContentEquals(entry)) { 85 // Update count and time for identical events to avoid log spam. 86 ++last.count; 87 last.time = base::Time::Now(); 88 return; 89 } 90 } 91 if (entries_.size() >= kMaxNetworkEventLogEntries) 92 entries_.pop_front(); 93 entries_.push_back(entry); 94 VLOG(1) << entry.ToString(); 95} 96 97std::string NetworkEventLog::GetAsString(StringOrder order, 98 size_t max_events) { 99 if (entries_.empty()) 100 return "No Log Entries."; 101 102 std::string result; 103 if (order == OLDEST_FIRST) { 104 size_t offset = 0; 105 if (max_events > 0 && max_events < entries_.size()) 106 offset = entries_.size() - max_events; 107 for (LogEntryList::const_iterator iter = entries_.begin() + offset; 108 iter != entries_.end(); ++iter) { 109 result += (*iter).ToString(); 110 } 111 } else { 112 size_t nlines = 0; 113 // Iterate backwards through the list to show the most recent entries first. 114 for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); 115 riter != entries_.rend(); ++riter) { 116 result += (*riter).ToString(); 117 if (max_events > 0 && ++nlines >= max_events) 118 break; 119 } 120 } 121 return result; 122} 123 124} // namespace 125 126NetworkEventLog* g_network_event_log = NULL; 127const size_t kMaxNetworkEventLogEntries = 1000; 128 129void Initialize() { 130 if (g_network_event_log) 131 delete g_network_event_log; // reset log 132 g_network_event_log = new NetworkEventLog(); 133} 134 135void Shutdown() { 136 delete g_network_event_log; 137 g_network_event_log = NULL; 138} 139 140bool IsInitialized() { 141 return g_network_event_log != NULL; 142} 143 144void AddEntry(const std::string& module, 145 const std::string& event, 146 const std::string& description) { 147 LogEntry entry(module, event, description); 148 if (!g_network_event_log) { 149 VLOG(1) << entry.ToString(); 150 return; 151 } 152 g_network_event_log->AddEntry(entry); 153} 154 155std::string GetAsString(StringOrder order, size_t max_events) { 156 if (!g_network_event_log) 157 return "NetworkEventLog not intitialized."; 158 return g_network_event_log->GetAsString(order, max_events); 159} 160 161} // namespace network_event_log 162 163} // namespace chromeos 164