log.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// found in the LICENSE file. 4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <stdio.h> 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/json/json_reader.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/json/json_writer.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/stringprintf.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/values.h" 11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/test/chromedriver/logging.h" 12b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Truncates the given string to 200 characters, adding an ellipsis if 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// truncation was necessary. 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TruncateString(std::string* data) { 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const size_t kMaxLength = 200; 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (data->length() > kMaxLength) { 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data->resize(kMaxLength); 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) data->replace(kMaxLength - 3, 3, "..."); 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Truncates all strings contained in the given value. 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TruncateContainedStrings(base::Value* value) { 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ListValue* list = NULL; 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::DictionaryValue* dict = NULL; 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (value->GetAsDictionary(&dict)) { 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it.Advance()) { 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string data; 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it.value().GetAsString(&data)) { 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TruncateString(&data); 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dict->SetWithoutPathExpansion(it.key(), new base::StringValue(data)); 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Value* child = NULL; 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) dict->GetWithoutPathExpansion(it.key(), &child); 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TruncateContainedStrings(child); 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (value->GetAsList(&list)) { 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < list->GetSize(); ++i) { 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Value* child = NULL; 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!list->Get(i, &child)) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string data; 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (child->GetAsString(&data)) { 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TruncateString(&data); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) list->Set(i, new base::StringValue(data)); 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TruncateContainedStrings(child); 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Pretty prints encapsulated JSON and truncates long strings for display. 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string ConvertForDisplay(const std::string& input) { 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t left = input.find("{"); 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) size_t right = input.rfind("}"); 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (left == std::string::npos || right == std::string::npos) 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return input.substr(0, 10 << 10); 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<base::Value> value( 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::JSONReader::Read(input.substr(left, right - left + 1))); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!value) 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return input.substr(0, 10 << 10); 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TruncateContainedStrings(value.get()); 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string json; 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::JSONWriter::WriteWithOptions( 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) value.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string display = input.substr(0, left) + json; 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (input.length() > right) 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) display += input.substr(right + 1); 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return display; 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void Log::AddEntry(Log::Level level, const std::string& message) { 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return AddEntry(base::Time::Now(), level, message); 83b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Logger::Logger() : min_log_level_(kLog), start_(base::Time::Now()) {} 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Logger::Logger(Level min_log_level) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : min_log_level_(min_log_level), start_(base::Time::Now()) {} 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)Logger::~Logger() {} 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void Logger::AddEntry(const base::Time& time, 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Level level, 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& message) { 9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (level < min_log_level_) 9690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 9790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* level_name = "UNKNOWN"; 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (level) { 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kDebug: 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) level_name = "DEBUG"; 10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kLog: 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) level_name = "INFO"; 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kWarning: 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) level_name = "WARNING"; 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case kError: 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) level_name = "ERROR"; 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string entry = 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::StringPrintf("[%.3lf][%s]: %s", 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::TimeDelta(time - start_).InSecondsF(), 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) level_name, 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ConvertForDisplay(message).c_str()); 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* format = "%s\n"; 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (entry[entry.length() - 1] == '\n') 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) format = "%s"; 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fprintf(stderr, format, entry.c_str()); 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) fflush(stderr); 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 126