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 |