blob: 5b4ec366b8a6593c401758fc8e14f486f4336f79 [file] [log] [blame]
erikkay@google.com1fb73ba2008-09-03 01:42:15 +09001// 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
evanm@google.com874d1672008-10-31 08:54:04 +09007#include "base/file_path.h"
erikkay@google.com1fb73ba2008-09-03 01:42:15 +09008#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
17namespace base {
18
19static const char* kEventTypeNames[] = {
20 "BEGIN",
21 "END",
22 "INSTANT"
23};
24
evanm@google.com874d1672008-10-31 08:54:04 +090025static const FilePath::CharType* kLogFileName =
26 FILE_PATH_LITERAL("trace_%d.log");
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090027
28TraceLog::TraceLog() : enabled_(false), log_file_(NULL) {
brettw@google.comc60d9892008-11-14 12:25:15 +090029 base::ProcessHandle proc = base::GetCurrentProcessHandle();
30 process_metrics_.reset(base::ProcessMetrics::CreateProcessMetrics(proc));
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090031}
32
33TraceLog::~TraceLog() {
34 Stop();
35}
36
37// static
38bool TraceLog::IsTracing() {
39 TraceLog* trace = Singleton<TraceLog>::get();
40 return trace->enabled_;
41}
42
43// static
44bool TraceLog::StartTracing() {
45 TraceLog* trace = Singleton<TraceLog>::get();
46 return trace->Start();
47}
48
49bool TraceLog::Start() {
50 if (enabled_)
51 return true;
52 enabled_ = OpenLogFile();
erikkay@google.com66a4c3e2008-09-19 05:42:55 +090053 if (enabled_) {
phajdan.jr@chromium.org862ff1f2009-01-06 03:51:30 +090054 Log("var raw_trace_events = [\n");
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090055 trace_start_time_ = TimeTicks::Now();
erikkay@google.com66a4c3e2008-09-19 05:42:55 +090056 timer_.Start(TimeDelta::FromMilliseconds(250), this, &TraceLog::Heartbeat);
57 }
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090058 return enabled_;
59}
60
61// static
62void TraceLog::StopTracing() {
63 TraceLog* trace = Singleton<TraceLog>::get();
64 return trace->Stop();
65}
66
67void TraceLog::Stop() {
68 if (enabled_) {
69 enabled_ = false;
phajdan.jr@chromium.org862ff1f2009-01-06 03:51:30 +090070 Log("];\n");
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090071 CloseLogFile();
erikkay@google.com66a4c3e2008-09-19 05:42:55 +090072 timer_.Stop();
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090073 }
74}
75
erikkay@google.com66a4c3e2008-09-19 05:42:55 +090076void TraceLog::Heartbeat() {
77 std::string cpu = StringPrintf("%d", process_metrics_->GetCPUUsage());
78 TRACE_EVENT_INSTANT("heartbeat.cpu", 0, cpu);
79}
80
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090081void TraceLog::CloseLogFile() {
82 if (log_file_) {
mark@chromium.orgd1bafc62008-10-02 02:40:13 +090083 file_util::CloseFile(log_file_);
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090084 }
85}
86
87bool TraceLog::OpenLogFile() {
evanm@google.com874d1672008-10-31 08:54:04 +090088 FilePath::StringType pid_filename =
brettw@google.comc60d9892008-11-14 12:25:15 +090089 StringPrintf(kLogFileName, base::GetCurrentProcId());
evanm@google.com874d1672008-10-31 08:54:04 +090090 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");
mark@chromium.orgd1bafc62008-10-02 02:40:13 +090095 if (!log_file_) {
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090096 // try the current directory
evanm@google.com874d1672008-10-31 08:54:04 +090097 log_file_ = file_util::OpenFile(FilePath(pid_filename), "a");
mark@chromium.orgd1bafc62008-10-02 02:40:13 +090098 if (!log_file_) {
erikkay@google.com1fb73ba2008-09-03 01:42:15 +090099 return false;
100 }
101 }
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900102 return true;
103}
104
105void TraceLog::Trace(const std::string& name,
106 EventType type,
erikkay@google.com66a4c3e2008-09-19 05:42:55 +0900107 const void* id,
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900108 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
116void TraceLog::Trace(const std::string& name,
117 EventType type,
erikkay@google.com66a4c3e2008-09-19 05:42:55 +0900118 const void* id,
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900119 const std::string& extra,
120 const char* file,
121 int line) {
122 if (!enabled_)
123 return;
124
125#ifdef USE_UNRELIABLE_NOW
mbelshe@google.com556bc842008-09-26 12:00:00 +0900126 TimeTicks tick = TimeTicks::HighResNow();
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900127#else
128 TimeTicks tick = TimeTicks::Now();
129#endif
130 TimeDelta delta = tick - trace_start_time_;
131 int64 usec = delta.InMicroseconds();
132 std::string msg =
erikkay@google.com66a4c3e2008-09-19 05:42:55 +0900133 StringPrintf("{'pid':'0x%lx', 'tid':'0x%lx', 'type':'%s', "
134 "'name':'%s', 'id':'0x%lx', 'extra':'%s', 'file':'%s', "
phajdan.jr@chromium.org862ff1f2009-01-06 03:51:30 +0900135 "'line_number':'%d', 'usec_begin': %I64d},\n",
brettw@google.comc60d9892008-11-14 12:25:15 +0900136 base::GetCurrentProcId(),
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900137 PlatformThread::CurrentId(),
138 kEventTypeNames[type],
139 name.c_str(),
140 id,
141 extra.c_str(),
142 file,
erikkay@google.com66a4c3e2008-09-19 05:42:55 +0900143 line,
144 usec);
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900145
146 Log(msg);
147}
148
149void TraceLog::Log(const std::string& msg) {
150 AutoLock lock(file_lock_);
151
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900152 fprintf(log_file_, "%s", msg.c_str());
erikkay@google.com1fb73ba2008-09-03 01:42:15 +0900153}
154
155} // namespace base