OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/network/network_event_log.h" | 5 #include "chromeos/network/network_event_log.h" |
6 | 6 |
7 #include "base/i18n/time_formatting.h" | 7 #include "base/i18n/time_formatting.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
11 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
12 #include "base/values.h" | |
12 | 13 |
13 namespace chromeos { | 14 namespace chromeos { |
14 | 15 |
15 namespace network_event_log { | 16 namespace network_event_log { |
16 | 17 |
17 namespace { | 18 namespace { |
18 | 19 |
19 struct LogEntry { | 20 struct LogEntry { |
20 LogEntry(const std::string& module, | 21 LogEntry(const std::string& file, |
22 int file_line, | |
23 int log_level, | |
gauravsh
2013/05/13 00:34:51
Why is this an int instead of a log-level? std::mi
stevenjb
2013/05/13 19:36:39
Done.
| |
21 const std::string& event, | 24 const std::string& event, |
22 const std::string& description); | 25 const std::string& description); |
23 | 26 |
24 std::string ToString() const; | 27 std::string ToString(const std::string& format) const; |
gauravsh
2013/05/13 00:34:51
Comment for the format of |format|?
stevenjb
2013/05/13 19:36:39
Changed to use bools
| |
25 | 28 |
26 bool ContentEquals(const LogEntry& other) const; | 29 bool ContentEquals(const LogEntry& other) const; |
27 | 30 |
28 std::string module; | 31 std::string file; |
pneubeck (no reviews)
2013/05/13 13:16:25
base::Location
stevenjb
2013/05/13 19:36:39
Again, more complexity than I think we want, see S
pneubeck (no reviews)
2013/05/16 08:21:07
With base::Location, the filename would not have t
| |
32 int file_line; | |
33 int log_level; | |
29 std::string event; | 34 std::string event; |
30 std::string description; | 35 std::string description; |
31 base::Time time; | 36 base::Time time; |
32 int count; | 37 int count; |
33 }; | 38 }; |
34 | 39 |
35 LogEntry::LogEntry(const std::string& module, | 40 LogEntry::LogEntry(const std::string& file, |
41 int file_line, | |
42 int log_level, | |
36 const std::string& event, | 43 const std::string& event, |
37 const std::string& description) | 44 const std::string& description) |
38 : module(module), | 45 : file(file), |
46 file_line(file_line), | |
47 log_level(log_level), | |
39 event(event), | 48 event(event), |
40 description(description), | 49 description(description), |
41 time(base::Time::Now()), | 50 time(base::Time::Now()), |
42 count(1) { | 51 count(1) { |
43 } | 52 } |
44 | 53 |
45 std::string LogEntry::ToString() const { | 54 std::string LogEntry::ToString(const std::string& format) const { |
46 std::string line; | 55 std::string line; |
47 line += "[" + UTF16ToUTF8(base::TimeFormatShortDateAndTime(time)) + "]"; | 56 if (format.find("time") != std::string::npos) |
48 line += " " + module + ":" + event; | 57 line += "[" + UTF16ToUTF8(base::TimeFormatShortDateAndTime(time)) + "] "; |
49 if (!description.empty()) | 58 if (format.find("file") != std::string::npos) |
59 line += base::StringPrintf("%s:%d ", file.c_str(), file_line); | |
60 bool italic = (log_level == LOG_LEVEL_DEBUG && | |
61 format.find("html") != std::string::npos); | |
62 bool bold = (log_level == LOG_LEVEL_ERROR && | |
63 format.find("html") != std::string::npos); | |
64 if (italic) | |
65 line += "<i>"; | |
66 if (bold) | |
67 line += "<b>"; | |
68 line += event; | |
69 if ((format.find("desc") != std::string::npos) && !description.empty()) | |
50 line += ": " + description; | 70 line += ": " + description; |
71 if (bold) | |
72 line += "</b>"; | |
73 if (italic) | |
74 line += "</i>"; | |
75 | |
51 if (count > 1) | 76 if (count > 1) |
52 line += base::StringPrintf(" (%d)", count); | 77 line += base::StringPrintf(" (%d)", count); |
53 line += "\n"; | 78 line += "\n"; |
54 return line; | 79 return line; |
55 } | 80 } |
56 | 81 |
57 bool LogEntry::ContentEquals(const LogEntry& other) const { | 82 bool LogEntry::ContentEquals(const LogEntry& other) const { |
58 return module == other.module && | 83 return file == other.file && |
84 file_line == other.file_line && | |
59 event == other.event && | 85 event == other.event && |
60 description == other.description; | 86 description == other.description; |
61 } | 87 } |
62 | 88 |
63 typedef std::deque<LogEntry> LogEntryList; | 89 typedef std::deque<LogEntry> LogEntryList; |
pneubeck (no reviews)
2013/05/13 13:16:25
depending on how frequent you expect log calls, th
stevenjb
2013/05/13 19:36:39
That doesn't really seem like a good code complexi
| |
64 | 90 |
65 class NetworkEventLog { | 91 class NetworkEventLog { |
66 public: | 92 public: |
67 NetworkEventLog() {} | 93 NetworkEventLog() {} |
68 ~NetworkEventLog() {} | 94 ~NetworkEventLog() {} |
69 | 95 |
70 void AddEntry(const LogEntry& entry); | 96 void AddLogEntry(const LogEntry& entry); |
71 | 97 |
72 std::string GetAsString(StringOrder order, | 98 std::string GetAsString(StringOrder order, |
99 const std::string& format, | |
100 int max_level, | |
gauravsh
2013/05/13 00:34:51
Why is this not a LogLevel?
stevenjb
2013/05/13 19:36:39
Done.
| |
73 size_t max_events); | 101 size_t max_events); |
74 | 102 |
75 private: | 103 private: |
76 LogEntryList entries_; | 104 LogEntryList entries_; |
77 | 105 |
78 DISALLOW_COPY_AND_ASSIGN(NetworkEventLog); | 106 DISALLOW_COPY_AND_ASSIGN(NetworkEventLog); |
79 }; | 107 }; |
80 | 108 |
81 void NetworkEventLog::AddEntry(const LogEntry& entry) { | 109 void NetworkEventLog::AddLogEntry(const LogEntry& entry) { |
82 if (!entries_.empty()) { | 110 if (!entries_.empty()) { |
83 LogEntry& last = entries_.back(); | 111 LogEntry& last = entries_.back(); |
84 if (last.ContentEquals(entry)) { | 112 if (last.ContentEquals(entry)) { |
85 // Update count and time for identical events to avoid log spam. | 113 // Update count and time for identical events to avoid log spam. |
86 ++last.count; | 114 ++last.count; |
115 last.log_level = std::min(last.log_level, entry.log_level); | |
87 last.time = base::Time::Now(); | 116 last.time = base::Time::Now(); |
88 return; | 117 return; |
89 } | 118 } |
90 } | 119 } |
91 if (entries_.size() >= kMaxNetworkEventLogEntries) | 120 if (entries_.size() >= kMaxNetworkEventLogEntries) |
92 entries_.pop_front(); | 121 entries_.pop_front(); |
93 entries_.push_back(entry); | 122 entries_.push_back(entry); |
94 VLOG(1) << entry.ToString(); | 123 if (entry.log_level == LOG_LEVEL_ERROR) |
124 LOG(ERROR) << entry.ToString("time,file,desc"); | |
125 else | |
126 VLOG(1) << entry.ToString("time,file,desc"); | |
95 } | 127 } |
96 | 128 |
97 std::string NetworkEventLog::GetAsString(StringOrder order, | 129 std::string NetworkEventLog::GetAsString(StringOrder order, |
130 const std::string& format, | |
131 int max_level, | |
98 size_t max_events) { | 132 size_t max_events) { |
99 if (entries_.empty()) | 133 if (entries_.empty()) |
100 return "No Log Entries."; | 134 return "No Log Entries."; |
101 | 135 |
102 std::string result; | 136 std::string result; |
103 if (order == OLDEST_FIRST) { | 137 if (order == OLDEST_FIRST) { |
104 size_t offset = 0; | 138 size_t offset = 0; |
105 if (max_events > 0 && max_events < entries_.size()) | 139 if (max_events > 0 && max_events < entries_.size()) { |
106 offset = entries_.size() - max_events; | 140 offset = entries_.size() - max_events; |
141 // Iterate backwards through the list, decramenting the offset for entries | |
gauravsh
2013/05/13 00:34:51
decrementing
stevenjb
2013/05/13 19:36:39
Done.
| |
142 // that will be skipped. | |
143 for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); | |
144 riter != entries_.rend(); ++riter) { | |
145 if (riter->log_level > max_level) { | |
146 if (--offset == 0) | |
gauravsh
2013/05/13 00:34:51
BUG? Wouldn't this end up decrementing the offset
stevenjb
2013/05/13 19:36:39
You're right, I need to check the shown events aga
| |
147 break; | |
148 } | |
149 } | |
150 } | |
107 for (LogEntryList::const_iterator iter = entries_.begin() + offset; | 151 for (LogEntryList::const_iterator iter = entries_.begin() + offset; |
108 iter != entries_.end(); ++iter) { | 152 iter != entries_.end(); ++iter) { |
109 result += (*iter).ToString(); | 153 if (iter->log_level > max_level) |
154 continue; | |
155 result += (*iter).ToString(format); | |
110 } | 156 } |
111 } else { | 157 } else { |
112 size_t nlines = 0; | 158 size_t nlines = 0; |
113 // Iterate backwards through the list to show the most recent entries first. | 159 // Iterate backwards through the list to show the most recent entries first. |
114 for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); | 160 for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); |
115 riter != entries_.rend(); ++riter) { | 161 riter != entries_.rend(); ++riter) { |
116 result += (*riter).ToString(); | 162 if (riter->log_level > max_level) |
163 continue; | |
164 result += (*riter).ToString(format); | |
117 if (max_events > 0 && ++nlines >= max_events) | 165 if (max_events > 0 && ++nlines >= max_events) |
118 break; | 166 break; |
119 } | 167 } |
120 } | 168 } |
121 return result; | 169 return result; |
122 } | 170 } |
123 | 171 |
124 } // namespace | 172 } // namespace |
125 | 173 |
126 NetworkEventLog* g_network_event_log = NULL; | 174 NetworkEventLog* g_network_event_log = NULL; |
175 const int kDefaultLogLevel = 1; | |
127 const size_t kMaxNetworkEventLogEntries = 1000; | 176 const size_t kMaxNetworkEventLogEntries = 1000; |
128 | 177 |
129 void Initialize() { | 178 void Initialize() { |
130 if (g_network_event_log) | 179 if (g_network_event_log) |
131 delete g_network_event_log; // reset log | 180 delete g_network_event_log; // reset log |
132 g_network_event_log = new NetworkEventLog(); | 181 g_network_event_log = new NetworkEventLog(); |
133 } | 182 } |
134 | 183 |
135 void Shutdown() { | 184 void Shutdown() { |
136 delete g_network_event_log; | 185 delete g_network_event_log; |
137 g_network_event_log = NULL; | 186 g_network_event_log = NULL; |
138 } | 187 } |
139 | 188 |
140 bool IsInitialized() { | 189 bool IsInitialized() { |
141 return g_network_event_log != NULL; | 190 return g_network_event_log != NULL; |
142 } | 191 } |
143 | 192 |
144 void AddEntry(const std::string& module, | 193 void AddEntry(const char* file, |
194 int file_line, | |
195 LogLevel log_level, | |
145 const std::string& event, | 196 const std::string& event, |
146 const std::string& description) { | 197 const std::string& description) { |
147 LogEntry entry(module, event, description); | 198 std::string filestr; |
pneubeck (no reviews)
2013/05/13 13:16:25
FilePath::BaseName()
stevenjb
2013/05/13 19:36:39
Done.
| |
199 if (file) { | |
200 filestr = std::string(file); | |
201 size_t n = filestr.find_last_of('/'); | |
202 if (n) | |
203 filestr = filestr.substr(n+1); | |
204 } | |
205 LogEntry entry(filestr, file_line, log_level, event, description); | |
148 if (!g_network_event_log) { | 206 if (!g_network_event_log) { |
149 VLOG(1) << entry.ToString(); | 207 VLOG(1) << entry.ToString("time,file,desc"); |
pneubeck (no reviews)
2013/05/13 13:16:25
this should respect the log level.
stevenjb
2013/05/13 19:36:39
Done.
| |
150 return; | 208 return; |
151 } | 209 } |
152 g_network_event_log->AddEntry(entry); | 210 g_network_event_log->AddLogEntry(entry); |
153 } | 211 } |
154 | 212 |
155 std::string GetAsString(StringOrder order, size_t max_events) { | 213 std::string GetAsString(StringOrder order, |
214 const std::string& format, | |
215 int max_level, | |
216 size_t max_events) { | |
156 if (!g_network_event_log) | 217 if (!g_network_event_log) |
157 return "NetworkEventLog not intitialized."; | 218 return "NetworkEventLog not intitialized."; |
158 return g_network_event_log->GetAsString(order, max_events); | 219 return g_network_event_log->GetAsString(order, format, max_level, max_events); |
220 } | |
221 | |
222 std::string DBusValueAsString(const base::Value& value) { | |
223 if (value.GetType() == base::Value::TYPE_BOOLEAN) { | |
224 bool bval = false; | |
225 value.GetAsBoolean(&bval); | |
226 return bval ? "true" : "false"; | |
227 } else if (value.GetType() == base::Value::TYPE_INTEGER) { | |
228 int intval = 0; | |
229 value.GetAsInteger(&intval); | |
230 return base::StringPrintf("%d", intval); | |
231 } else if (value.GetType() == base::Value::TYPE_DOUBLE) { | |
232 double dval = 0; | |
233 value.GetAsDouble(&dval); | |
234 return base::StringPrintf("%g", dval); | |
235 } else if (value.GetType() == base::Value::TYPE_STRING) { | |
236 std::string vstr; | |
237 value.GetAsString(&vstr); | |
238 return vstr; | |
239 } | |
240 return ""; | |
159 } | 241 } |
160 | 242 |
161 } // namespace network_event_log | 243 } // namespace network_event_log |
162 | 244 |
163 } // namespace chromeos | 245 } // namespace chromeos |
OLD | NEW |