aboutsummaryrefslogtreecommitdiff
path: root/include/perfetto/tracing/track_event.h
blob: 83907ab740c3af68e30fd97827641f16a86f4a62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_
#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_

#include "perfetto/base/time.h"
#include "perfetto/tracing/internal/track_event_data_source.h"
#include "perfetto/tracing/internal/track_event_internal.h"
#include "perfetto/tracing/internal/track_event_macros.h"
#include "perfetto/tracing/track_event_category_registry.h"
#include "protos/perfetto/trace/track_event/track_event.pbzero.h"

// This file contains a set of macros designed for instrumenting applications
// with track event trace points. While the underlying TrackEvent API can also
// be used directly, doing so efficiently requires some care (e.g., to avoid
// evaluating arguments while tracing is disabled). These types of optimizations
// are abstracted away by the macros below.
//
// ================
// Quickstart guide
// ================
//
//   To add track events to your application, first define your categories in,
//   e.g., my_tracing.h:
//
//       PERFETTO_DEFINE_CATEGORIES(
//           PERFETTO_CATEGORY(base),
//           PERFETTO_CATEGORY(v8),
//           PERFETTO_CATEGORY(cc));
//
//   Then in a single .cc file, e.g., my_tracing.cc:
//
//       #include "my_tracing.h"
//       PERFETTO_TRACK_EVENT_STATIC_STORAGE();
//
//   Finally, register track events at startup, after which you can record
//   events with the TRACE_EVENT macros:
//
//       #include "my_tracing.h"
//
//       int main() {
//         perfetto::TrackEvent::Register();
//         TRACK_EVENT_BEGIN("category", "MyEvent");
//         TRACK_EVENT_END("category");
//         ...
//       }
//
// ====================
// Implementation notes
// ====================
//
// The track event library consists of the following layers and components. The
// classes the internal namespace shouldn't be considered part of the public
// API.
//                    .--------------------------------.
//               .----|  TRACE_EVENT                   |----.
//      write   |     |   - App instrumentation point  |     |  write
//      event   |     '--------------------------------'     |  arguments
//              V                                            V
//  .----------------------------------.    .-----------------------------.
//  | TrackEvent                       |    | TrackEventContext           |
//  |  - Registry of event categories  |    |  - One track event instance |
//  '----------------------------------'    '-----------------------------'
//              |                                            |
//              |                                            | look up
//              | is                                         | interning ids
//              V                                            V
//  .----------------------------------.    .-----------------------------.
//  | internal::TrackEventDataSource   |    | TrackEventInternedDataIndex |
//  | - Perfetto data source           |    | - Corresponds to a field in |
//  | - Has TrackEventIncrementalState |    |   in interned_data.proto    |
//  '----------------------------------'    '-----------------------------'
//              |                  |                         ^
//              |                  |       owns (1:many)     |
//              | write event      '-------------------------'
//              V
//  .----------------------------------.
//  | internal::TrackEventInternal     |
//  | - Outlined code to serialize     |
//  |   one track event                |
//  '----------------------------------'
//

// Each compilation unit can be in exactly one track event namespace,
// allowing the overall program to use multiple track event data sources and
// category lists if necessary. Use this macro to select the namespace for the
// current compilation unit.
//
// If the program uses multiple track event namespaces, category & track event
// registration (see quickstart above) needs to happen for both namespaces
// separately.
#ifndef PERFETTO_TRACK_EVENT_NAMESPACE
#define PERFETTO_TRACK_EVENT_NAMESPACE perfetto
#endif

// A name for a single category. Wrapped in a macro in case we need to introduce
// more fields in the future.
#define PERFETTO_CATEGORY(name) \
  { #name }

// Register the set of available categories by passing a list of categories to
// this macro: PERFETTO_CATEGORY(cat1), PERFETTO_CATEGORY(cat2), ...
#define PERFETTO_DEFINE_CATEGORIES(...)                        \
  namespace PERFETTO_TRACK_EVENT_NAMESPACE {                   \
  /* The list of category names */                             \
  PERFETTO_INTERNAL_DECLARE_CATEGORIES(__VA_ARGS__);           \
  /* The track event data source for this set of categories */ \
  PERFETTO_INTERNAL_DECLARE_TRACK_EVENT_DATA_SOURCE();         \
  }  // namespace PERFETTO_TRACK_EVENT_NAMESPACE

// Allocate storage for each category by using this macro once per track event
// namespace.
#define PERFETTO_TRACK_EVENT_STATIC_STORAGE() \
  namespace PERFETTO_TRACK_EVENT_NAMESPACE {  \
  PERFETTO_INTERNAL_CATEGORY_STORAGE();       \
  }  // namespace PERFETTO_TRACK_EVENT_NAMESPACE

// Begin a thread-scoped slice under |category| with the title |name|. Both
// strings must be static constants. The track event is only recorded if
// |category| is enabled for a tracing session.
#define TRACE_EVENT_BEGIN(category, name, ...) \
  PERFETTO_INTERNAL_TRACK_EVENT(               \
      category, name,                          \
      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN, ##__VA_ARGS__)

// End a thread-scoped slice under |category|.
#define TRACE_EVENT_END(category, ...) \
  PERFETTO_INTERNAL_TRACK_EVENT(       \
      category, nullptr,               \
      ::perfetto::protos::pbzero::TrackEvent::TYPE_SLICE_END, ##__VA_ARGS__)

// TODO(skyostil): Add arguments.
// TODO(skyostil): Add scoped events.
// TODO(skyostil): Add async events.
// TODO(skyostil): Add flow events.
// TODO(skyostil): Add instant events.
// TODO(skyostil): Add counters.

#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_H_