1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "content/shell/shell_net_log.h" 6 7 #include <stdio.h> 8 9 #include "base/command_line.h" 10 #include "base/files/file_path.h" 11 #include "base/values.h" 12 #include "content/public/common/content_switches.h" 13 #include "net/base/net_log_logger.h" 14 15 namespace content { 16 17 namespace { 18 19 base::DictionaryValue* GetShellConstants() { 20 base::DictionaryValue* constants_dict = net::NetLogLogger::GetConstants(); 21 22 // Add a dictionary with client information 23 base::DictionaryValue* dict = new DictionaryValue(); 24 25 dict->SetString("name", "content_shell"); 26 dict->SetString("command_line", 27 CommandLine::ForCurrentProcess()->GetCommandLineString()); 28 29 constants_dict->Set("clientInfo", dict); 30 31 return constants_dict; 32 } 33 34 } // namespace 35 36 ShellNetLog::ShellNetLog() { 37 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 38 39 if (command_line->HasSwitch(switches::kLogNetLog)) { 40 base::FilePath log_path = 41 command_line->GetSwitchValuePath(switches::kLogNetLog); 42 // Much like logging.h, bypass threading restrictions by using fopen 43 // directly. Have to write on a thread that's shutdown to handle events on 44 // shutdown properly, and posting events to another thread as they occur 45 // would result in an unbounded buffer size, so not much can be gained by 46 // doing this on another thread. It's only used when debugging, so 47 // performance is not a big concern. 48 FILE* file = NULL; 49 #if defined(OS_WIN) 50 file = _wfopen(log_path.value().c_str(), L"w"); 51 #elif defined(OS_POSIX) 52 file = fopen(log_path.value().c_str(), "w"); 53 #endif 54 55 if (file == NULL) { 56 LOG(ERROR) << "Could not open file " << log_path.value() 57 << " for net logging"; 58 } else { 59 scoped_ptr<base::Value> constants(GetShellConstants()); 60 net_log_logger_.reset(new net::NetLogLogger(file, *constants)); 61 net_log_logger_->StartObserving(this); 62 } 63 } 64 } 65 66 ShellNetLog::~ShellNetLog() { 67 // Remove the observer we own before we're destroyed. 68 if (net_log_logger_) 69 RemoveThreadSafeObserver(net_log_logger_.get()); 70 } 71 72 } // namespace content 73