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