| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 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 "base/trace_event.h" | |
| 6 | |
| 7 #include "base/format_macros.h" | |
| 8 #include "base/file_path.h" | |
| 9 #include "base/file_util.h" | |
| 10 #include "base/path_service.h" | |
| 11 #include "base/platform_thread.h" | |
| 12 #include "base/process_util.h" | |
| 13 #include "base/stringprintf.h" | |
| 14 #include "base/utf_string_conversions.h" | |
| 15 #include "base/time.h" | |
| 16 | |
| 17 #define USE_UNRELIABLE_NOW | |
| 18 | |
| 19 namespace base { | |
| 20 | |
| 21 static const char* kEventTypeNames[] = { | |
| 22 "BEGIN", | |
| 23 "END", | |
| 24 "INSTANT" | |
| 25 }; | |
| 26 | |
| 27 static const FilePath::CharType* kLogFileName = | |
| 28 FILE_PATH_LITERAL("trace_%d.log"); | |
| 29 | |
| 30 TraceLog::TraceLog() : enabled_(false), log_file_(NULL) { | |
| 31 base::ProcessHandle proc = base::GetCurrentProcessHandle(); | |
| 32 #if !defined(OS_MACOSX) | |
| 33 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(proc)); | |
| 34 #else | |
| 35 // The default port provider is sufficient to get data for the current | |
| 36 // process. | |
| 37 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(proc, | |
| 38 NULL)); | |
| 39 #endif | |
| 40 } | |
| 41 | |
| 42 TraceLog::~TraceLog() { | |
| 43 Stop(); | |
| 44 } | |
| 45 | |
| 46 // static | |
| 47 bool TraceLog::IsTracing() { | |
| 48 TraceLog* trace = Singleton<TraceLog>::get(); | |
| 49 return trace->enabled_; | |
| 50 } | |
| 51 | |
| 52 // static | |
| 53 bool TraceLog::StartTracing() { | |
| 54 TraceLog* trace = Singleton<TraceLog>::get(); | |
| 55 return trace->Start(); | |
| 56 } | |
| 57 | |
| 58 bool TraceLog::Start() { | |
| 59 if (enabled_) | |
| 60 return true; | |
| 61 enabled_ = OpenLogFile(); | |
| 62 if (enabled_) { | |
| 63 Log("var raw_trace_events = [\n"); | |
| 64 trace_start_time_ = TimeTicks::Now(); | |
| 65 timer_.Start(TimeDelta::FromMilliseconds(250), this, &TraceLog::Heartbeat); | |
| 66 } | |
| 67 return enabled_; | |
| 68 } | |
| 69 | |
| 70 // static | |
| 71 void TraceLog::StopTracing() { | |
| 72 TraceLog* trace = Singleton<TraceLog>::get(); | |
| 73 return trace->Stop(); | |
| 74 } | |
| 75 | |
| 76 void TraceLog::Stop() { | |
| 77 if (enabled_) { | |
| 78 enabled_ = false; | |
| 79 Log("];\n"); | |
| 80 CloseLogFile(); | |
| 81 timer_.Stop(); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 void TraceLog::Heartbeat() { | |
| 86 std::string cpu = StringPrintf("%.0f", process_metrics_->GetCPUUsage()); | |
| 87 TRACE_EVENT_INSTANT("heartbeat.cpu", 0, cpu); | |
| 88 } | |
| 89 | |
| 90 void TraceLog::CloseLogFile() { | |
| 91 if (log_file_) { | |
| 92 file_util::CloseFile(log_file_); | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 bool TraceLog::OpenLogFile() { | |
| 97 FilePath::StringType pid_filename = | |
| 98 StringPrintf(kLogFileName, base::GetCurrentProcId()); | |
| 99 FilePath log_file_path; | |
| 100 if (!PathService::Get(base::DIR_EXE, &log_file_path)) | |
| 101 return false; | |
| 102 log_file_path = log_file_path.Append(pid_filename); | |
| 103 log_file_ = file_util::OpenFile(log_file_path, "a"); | |
| 104 if (!log_file_) { | |
| 105 // try the current directory | |
| 106 log_file_ = file_util::OpenFile(FilePath(pid_filename), "a"); | |
| 107 if (!log_file_) { | |
| 108 return false; | |
| 109 } | |
| 110 } | |
| 111 return true; | |
| 112 } | |
| 113 | |
| 114 void TraceLog::Trace(const std::string& name, | |
| 115 EventType type, | |
| 116 const void* id, | |
| 117 const std::wstring& extra, | |
| 118 const char* file, | |
| 119 int line) { | |
| 120 if (!enabled_) | |
| 121 return; | |
| 122 Trace(name, type, id, WideToUTF8(extra), file, line); | |
| 123 } | |
| 124 | |
| 125 void TraceLog::Trace(const std::string& name, | |
| 126 EventType type, | |
| 127 const void* id, | |
| 128 const std::string& extra, | |
| 129 const char* file, | |
| 130 int line) { | |
| 131 if (!enabled_) | |
| 132 return; | |
| 133 | |
| 134 #ifdef USE_UNRELIABLE_NOW | |
| 135 TimeTicks tick = TimeTicks::HighResNow(); | |
| 136 #else | |
| 137 TimeTicks tick = TimeTicks::Now(); | |
| 138 #endif | |
| 139 TimeDelta delta = tick - trace_start_time_; | |
| 140 int64 usec = delta.InMicroseconds(); | |
| 141 std::string msg = | |
| 142 StringPrintf("{'pid':'0x%lx', 'tid':'0x%lx', 'type':'%s', " | |
| 143 "'name':'%s', 'id':'%p', 'extra':'%s', 'file':'%s', " | |
| 144 "'line_number':'%d', 'usec_begin': %" PRId64 "},\n", | |
| 145 static_cast<unsigned long>(base::GetCurrentProcId()), | |
| 146 static_cast<unsigned long>(PlatformThread::CurrentId()), | |
| 147 kEventTypeNames[type], | |
| 148 name.c_str(), | |
| 149 id, | |
| 150 extra.c_str(), | |
| 151 file, | |
| 152 line, | |
| 153 usec); | |
| 154 | |
| 155 Log(msg); | |
| 156 } | |
| 157 | |
| 158 void TraceLog::Log(const std::string& msg) { | |
| 159 AutoLock lock(file_lock_); | |
| 160 | |
| 161 fprintf(log_file_, "%s", msg.c_str()); | |
| 162 } | |
| 163 | |
| 164 } // namespace base | |
| OLD | NEW |