Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2009 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 // Implementation of a Windows event trace controller class.
      6 #include "base/event_trace_controller_win.h"
      7 #include "base/logging.h"
      8 
      9 EtwTraceController::EtwTraceController() : session_(NULL) {
     10 }
     11 
     12 EtwTraceController::~EtwTraceController() {
     13   Stop(NULL);
     14 }
     15 
     16 HRESULT EtwTraceController::Start(const wchar_t* session_name,
     17     EtwTraceProperties* prop) {
     18   DCHECK(NULL == session_ && session_name_.empty());
     19   EtwTraceProperties ignore;
     20   if (prop == NULL)
     21     prop = &ignore;
     22 
     23   HRESULT hr = Start(session_name, prop, &session_);
     24   if (SUCCEEDED(hr))
     25     session_name_ = session_name;
     26 
     27   return hr;
     28 }
     29 
     30 HRESULT EtwTraceController::StartFileSession(const wchar_t* session_name,
     31       const wchar_t* logfile_path, bool realtime) {
     32   DCHECK(NULL == session_ && session_name_.empty());
     33 
     34   EtwTraceProperties prop;
     35   prop.SetLoggerFileName(logfile_path);
     36   EVENT_TRACE_PROPERTIES& p = *prop.get();
     37   p.Wnode.ClientContext = 1;  // QPC timer accuracy.
     38   p.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;  // Sequential log.
     39   if (realtime)
     40     p.LogFileMode |= EVENT_TRACE_REAL_TIME_MODE;
     41 
     42   p.MaximumFileSize = 100;  // 100M file size.
     43   p.FlushTimer = 30;  // 30 seconds flush lag.
     44   return Start(session_name, &prop);
     45 }
     46 
     47 HRESULT EtwTraceController::StartRealtimeSession(const wchar_t* session_name,
     48     size_t buffer_size) {
     49   DCHECK(NULL == session_ && session_name_.empty());
     50   EtwTraceProperties prop;
     51   EVENT_TRACE_PROPERTIES& p = *prop.get();
     52   p.LogFileMode = EVENT_TRACE_REAL_TIME_MODE | EVENT_TRACE_USE_PAGED_MEMORY;
     53   p.FlushTimer = 1;  // flush every second.
     54   p.BufferSize = 16;  // 16 K buffers.
     55   p.LogFileNameOffset = 0;
     56   return Start(session_name, &prop);
     57 }
     58 
     59 HRESULT EtwTraceController::EnableProvider(REFGUID provider, UCHAR level,
     60     ULONG flags) {
     61   ULONG error = ::EnableTrace(TRUE, flags, level, &provider, session_);
     62   return HRESULT_FROM_WIN32(error);
     63 }
     64 
     65 HRESULT EtwTraceController::DisableProvider(REFGUID provider) {
     66   ULONG error = ::EnableTrace(FALSE, 0, 0, &provider, session_);
     67   return HRESULT_FROM_WIN32(error);
     68 }
     69 
     70 HRESULT EtwTraceController::Stop(EtwTraceProperties* properties) {
     71   EtwTraceProperties ignore;
     72   if (properties == NULL)
     73     properties = &ignore;
     74 
     75   ULONG error = ::ControlTrace(session_, NULL, properties->get(),
     76     EVENT_TRACE_CONTROL_STOP);
     77   if (ERROR_SUCCESS != error)
     78     return HRESULT_FROM_WIN32(error);
     79 
     80   session_ = NULL;
     81   session_name_.clear();
     82   return S_OK;
     83 }
     84 
     85 HRESULT EtwTraceController::Flush(EtwTraceProperties* properties) {
     86   EtwTraceProperties ignore;
     87   if (properties == NULL)
     88     properties = &ignore;
     89 
     90   ULONG error = ::ControlTrace(session_, NULL, properties->get(),
     91                                EVENT_TRACE_CONTROL_FLUSH);
     92   if (ERROR_SUCCESS != error)
     93     return HRESULT_FROM_WIN32(error);
     94 
     95   return S_OK;
     96 }
     97 
     98 HRESULT EtwTraceController::Start(const wchar_t* session_name,
     99     EtwTraceProperties* properties, TRACEHANDLE* session_handle) {
    100   ULONG err = ::StartTrace(session_handle, session_name, properties->get());
    101   return HRESULT_FROM_WIN32(err);
    102 }
    103 
    104 HRESULT EtwTraceController::Query(const wchar_t* session_name,
    105     EtwTraceProperties* properties) {
    106   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
    107                              EVENT_TRACE_CONTROL_QUERY);
    108   return HRESULT_FROM_WIN32(err);
    109 };
    110 
    111 HRESULT EtwTraceController::Update(const wchar_t* session_name,
    112     EtwTraceProperties* properties) {
    113   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
    114                              EVENT_TRACE_CONTROL_UPDATE);
    115   return HRESULT_FROM_WIN32(err);
    116 }
    117 
    118 HRESULT EtwTraceController::Stop(const wchar_t* session_name,
    119     EtwTraceProperties* properties) {
    120   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
    121                              EVENT_TRACE_CONTROL_STOP);
    122   return HRESULT_FROM_WIN32(err);
    123 }
    124 
    125 HRESULT EtwTraceController::Flush(const wchar_t* session_name,
    126     EtwTraceProperties* properties) {
    127   ULONG err = ::ControlTrace(NULL, session_name, properties->get(),
    128                              EVENT_TRACE_CONTROL_FLUSH);
    129   return HRESULT_FROM_WIN32(err);
    130 }
    131