12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/network/network_event_log.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <list> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/files/file_path.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/i18n/time_formatting.h" 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/json/json_writer.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_tokenizer.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/values.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/escape.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos { 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace network_event_log { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class NetworkEventLog; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)NetworkEventLog* g_network_event_log = NULL; 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochsize_t g_max_network_event_log_entries = 4000; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct LogEntry { 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogEntry(const std::string& file, 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int file_line, 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel log_level, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& event, 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& description); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string ToString(bool show_time, 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool show_file, 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool show_desc, 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool format_html) const; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string GetNormalText(bool show_desc) const; 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string GetHtmlText(bool show_desc) const; 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void SendToVLogOrErrorLog() const; 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ContentEquals(const LogEntry& other) const; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string file; 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int file_line; 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel log_level; 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string event; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string description; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time time; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int count; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)LogEntry::LogEntry(const std::string& file, 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int file_line, 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel log_level, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& event, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& description) 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : file(file), 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) file_line(file_line), 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) log_level(log_level), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event(event), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) description(description), 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) time(base::Time::Now()), 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count(1) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string LogEntry::ToString(bool show_time, 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool show_file, 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool show_desc, 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool format_html) const { 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string line; 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (show_time) 777c720b7466665b17575e0fd6976f9321c6bff489Torne (Richard Coles) line += "[" + UTF16ToUTF8(base::TimeFormatTimeOfDay(time)) + "] "; 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (show_file) { 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string filestr = format_html ? net::EscapeForHTML(file) : file; 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) line += base::StringPrintf("%s:%d ", filestr.c_str(), file_line); 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) line += format_html ? GetHtmlText(show_desc) : GetNormalText(show_desc); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count > 1) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) line += base::StringPrintf(" (%d)", count); 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return line; 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string LogEntry::GetNormalText(bool show_desc) const { 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string text = event; 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (show_desc && !description.empty()) 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += ": " + description; 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return text; 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string LogEntry::GetHtmlText(bool show_desc) const { 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string text; 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (log_level == LOG_LEVEL_DEBUG) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += "<i>"; 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else if (log_level == LOG_LEVEL_USER) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += "<b>"; 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else if (log_level == LOG_LEVEL_ERROR) 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) text += "<b><i>"; 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += event; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (show_desc && !description.empty()) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += ": " + net::EscapeForHTML(description); 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (log_level == LOG_LEVEL_DEBUG) 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += "</i>"; 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else if (log_level == LOG_LEVEL_USER) 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) text += "</b>"; 112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) else if (log_level == LOG_LEVEL_ERROR) 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) text += "</i></b>"; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return text; 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void LogEntry::SendToVLogOrErrorLog() const { 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool show_time = true; 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool show_file = true; 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool show_desc = true; 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const bool format_html = false; 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string output = ToString(show_time, show_file, show_desc, format_html); 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (log_level == LOG_LEVEL_ERROR) 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(ERROR) << output; 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) VLOG(1) << output; 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool LogEntry::ContentEquals(const LogEntry& other) const { 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return file == other.file && 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) file_line == other.file_line && 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event == other.event && 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) description == other.description; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GetFormat(const std::string& format_string, 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* show_time, 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* show_file, 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* show_desc, 14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool* format_html) { 14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringTokenizer tokens(format_string, ","); 14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *show_time = false; 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *show_file = false; 14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *show_desc = false; 14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *format_html = false; 14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) while (tokens.GetNext()) { 14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string tok(tokens.token()); 14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (tok == "time") 14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *show_time = true; 15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (tok == "file") 15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *show_file = true; 15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (tok == "desc") 15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *show_desc = true; 15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (tok == "html") 15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *format_html = true; 15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)typedef std::list<LogEntry> LogEntryList; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NetworkEventLog { 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NetworkEventLog() {} 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~NetworkEventLog() {} 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) void AddLogEntry(const LogEntry& entry); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string GetAsString(StringOrder order, 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& format, 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel max_level, 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t max_events); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogEntryList& entries() { return entries_; } 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LogEntryList entries_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NetworkEventLog); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void NetworkEventLog::AddLogEntry(const LogEntry& entry) { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!entries_.empty()) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LogEntry& last = entries_.back(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (last.ContentEquals(entry)) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update count and time for identical events to avoid log spam. 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++last.count; 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) last.log_level = std::min(last.log_level, entry.log_level); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last.time = base::Time::Now(); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entries_.size() >= g_max_network_event_log_entries) { 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t max_error_entries = g_max_network_event_log_entries / 2; 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Remove the first (oldest) non-error entry, or the oldest entry if more 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // than half the entries are errors. 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t error_count = 0; 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (LogEntryList::iterator iter = entries_.begin(); 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) iter != entries_.end(); ++iter) { 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (iter->log_level != LOG_LEVEL_ERROR) { 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entries_.erase(iter); 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (++error_count > max_error_entries) { 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Too many error entries, remove the oldest entry. 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entries_.pop_front(); 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entries_.push_back(entry); 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry.SendToVLogOrErrorLog(); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string NetworkEventLog::GetAsString(StringOrder order, 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& format, 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel max_level, 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t max_events) { 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (entries_.empty()) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "No Log Entries."; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool show_time, show_file, show_desc, format_html; 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetFormat(format, &show_time, &show_file, &show_desc, &format_html); 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string result; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (order == OLDEST_FIRST) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t offset = 0; 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (max_events > 0 && max_events < entries_.size()) { 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Iterate backwards through the list skipping uninteresting entries to 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // determine the first entry to include. 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t shown_events = 0; 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t num_entries = 0; 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) riter != entries_.rend(); ++riter) { 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++num_entries; 23590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (riter->log_level > max_level) 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (++shown_events >= max_events) 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) offset = entries_.size() - num_entries; 24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (LogEntryList::const_iterator iter = entries_.begin(); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != entries_.end(); ++iter) { 24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (offset > 0) { 24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) --offset; 24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (iter->log_level > max_level) 24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result += (*iter).ToString(show_time, show_file, show_desc, format_html); 251558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch result += "\n"; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t nlines = 0; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Iterate backwards through the list to show the most recent entries first. 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (LogEntryList::const_reverse_iterator riter = entries_.rbegin(); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) riter != entries_.rend(); ++riter) { 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (riter->log_level > max_level) 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) result += (*riter).ToString(show_time, show_file, show_desc, format_html); 261558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch result += "\n"; 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (max_events > 0 && ++nlines >= max_events) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return result; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const LogLevel kDefaultLogLevel = LOG_LEVEL_EVENT; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Initialize() { 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (g_network_event_log) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete g_network_event_log; // reset log 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_network_event_log = new NetworkEventLog(); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Shutdown() { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete g_network_event_log; 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) g_network_event_log = NULL; 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool IsInitialized() { 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return g_network_event_log != NULL; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace internal { 28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t GetMaxLogEntries() { 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return g_max_network_event_log_entries; 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void SetMaxLogEntries(size_t max_entries) { 29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) g_max_network_event_log_entries = max_entries; 29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!g_network_event_log) 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) while (g_network_event_log->entries().size() > max_entries) 29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) g_network_event_log->entries().pop_front(); 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AddEntry(const char* file, 30390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int file_line, 30490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel log_level, 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& event, 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& description) { 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string filestr; 30890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (file) 30990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) filestr = base::FilePath(std::string(file)).BaseName().value(); 31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogEntry entry(filestr, file_line, log_level, event, description); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!g_network_event_log) { 31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) entry.SendToVLogOrErrorLog(); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) g_network_event_log->AddLogEntry(entry); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace internal 31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string GetAsString(StringOrder order, 32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& format, 32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LogLevel max_level, 32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t max_events) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!g_network_event_log) 32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return "NetworkEventLog not initialized."; 32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return g_network_event_log->GetAsString(order, format, max_level, max_events); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string ValueAsString(const base::Value& value) { 33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string vstr; 33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::JSONWriter::WriteWithOptions( 33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &value, base::JSONWriter::OPTIONS_OMIT_BINARY_VALUES, &vstr); 33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return vstr.empty() ? "''" : vstr; 33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace network_event_log 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace chromeos 338