1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Trace events to track application performance. Events consist of a name 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// a type (BEGIN, END or INSTANT), a tracking id and extra string data. 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// In addition, the current process id, thread id, a timestamp down to the 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// microsecond and a file and line number of the calling location. 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The current implementation logs these events into a log file of the form 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// trace_<pid>.log where it's designed to be post-processed to generate a 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// trace report. In the future, it may use another mechansim to facilitate 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// real-time analysis. 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 15513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#ifndef BASE_DEBUG_TRACE_EVENT_H_ 16513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#define BASE_DEBUG_TRACE_EVENT_H_ 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "build/build_config.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#if defined(OS_WIN) 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// On Windows we always pull in an alternative implementation 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// which logs to Event Tracing for Windows. 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note that the Windows implementation is always enabled, irrespective the 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// value of the CHROMIUM_ENABLE_TRACE_EVENT define. The Windows implementation 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// is controlled by Event Tracing for Windows, which will turn tracing on only 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// if there is someone listening for the events it generates. 29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "base/debug/trace_event_win.h" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else // defined(OS_WIN) 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/synchronization/lock.h" 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/time.h" 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/timer.h" 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef CHROMIUM_ENABLE_TRACE_EVENT 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TRACE_EVENT_BEGIN(name, id, extra) ((void) 0) 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TRACE_EVENT_END(name, id, extra) ((void) 0) 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TRACE_EVENT_INSTANT(name, id, extra) ((void) 0) 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#else // CHROMIUM_ENABLE_TRACE_EVENT 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use the following macros rather than using the TraceLog class directly as the 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// underlying implementation may change in the future. Here's a sample usage: 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TRACE_EVENT_BEGIN("v8.run", documentId, scriptLocation); 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// RunScript(script); 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// TRACE_EVENT_END("v8.run", documentId, scriptLocation); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Record that an event (of name, id) has begun. All BEGIN events should have 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// corresponding END events with a matching (name, id). 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TRACE_EVENT_BEGIN(name, id, extra) \ 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::debug::TraceLog::GetInstance()->Trace( \ 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch name, \ 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::debug::TraceLog::EVENT_BEGIN, \ 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch reinterpret_cast<const void*>(id), \ 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch extra, \ 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch __FILE__, \ 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch __LINE__) 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Record that an event (of name, id) has ended. All END events should have 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// corresponding BEGIN events with a matching (name, id). 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TRACE_EVENT_END(name, id, extra) \ 6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::debug::TraceLog::GetInstance()->Trace( \ 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch name, \ 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::debug::TraceLog::EVENT_END, \ 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch reinterpret_cast<const void*>(id), \ 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch extra, \ 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch __FILE__, \ 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch __LINE__) 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Record that an event (of name, id) with no duration has happened. 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define TRACE_EVENT_INSTANT(name, id, extra) \ 7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen base::debug::TraceLog::GetInstance()->Trace( \ 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch name, \ 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch base::debug::TraceLog::EVENT_INSTANT, \ 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch reinterpret_cast<const void*>(id), \ 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch extra, \ 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch __FILE__, \ 82513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch __LINE__) 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif // CHROMIUM_ENABLE_TRACE_EVENT 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass ProcessMetrics; 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89513209b27ff55e2841eac0e4120199c23acce758Ben Murdochnamespace debug { 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass TraceLog { 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum EventType { 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVENT_BEGIN, 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVENT_END, 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EVENT_INSTANT 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen static TraceLog* GetInstance(); 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Is tracing currently enabled. 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool IsTracing(); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Start logging trace events. 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool StartTracing(); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Stop logging trace events. 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void StopTracing(); 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Log a trace event of (name, type, id) with the optional extra string. 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Trace(const std::string& name, 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EventType type, 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const void* id, 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::wstring& extra, 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* file, 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int line); 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Trace(const std::string& name, 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EventType type, 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const void* id, 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::string& extra, 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const char* file, 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int line); 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // This allows constructor and destructor to be private and usable only 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // by the Singleton class. 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend struct DefaultSingletonTraits<TraceLog>; 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TraceLog(); 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ~TraceLog(); 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool OpenLogFile(); 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CloseLogFile(); 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool Start(); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Stop(); 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Heartbeat(); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Log(const std::string& msg); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool enabled_; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILE* log_file_; 13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::Lock file_lock_; 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TimeTicks trace_start_time_; 14000d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#ifndef ANDROID 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<base::ProcessMetrics> process_metrics_; 14200d26a728db2814620f390b418a7d6325ce5aca6Ben Murdoch#endif 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RepeatingTimer<TraceLog> timer_; 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} // namespace debug 147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} // namespace base 148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // defined(OS_WIN) 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#endif // BASE_DEBUG_TRACE_EVENT_H_ 152