xref: /aosp_15_r20/external/openscreen/docs/trace_logging.md (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard# Trace Logging Library Usage
2*3f982cf4SFabien Sanglard
3*3f982cf4SFabien SanglardThe idea behind Trace Logging is that we can choose to trace a function and
4*3f982cf4SFabien Sanglardthen, with minimal additional code, determine how long function execution ran
5*3f982cf4SFabien Sanglardfor, whether the function was successful, and connect all of this information to
6*3f982cf4SFabien Sanglardany existing informational logs. The below provides information about how this
7*3f982cf4SFabien Sanglardcan be achieved with OSP's TraceLogging Infrastructure.
8*3f982cf4SFabien Sanglard
9*3f982cf4SFabien Sanglard## Compilation
10*3f982cf4SFabien Sanglard
11*3f982cf4SFabien SanglardBy default, TraceLogging is enabled as part of the build.
12*3f982cf4SFabien SanglardTo disable TraceLogging, include flag `--args="enable_trace_logging=false"`
13*3f982cf4SFabien Sanglardwhen calling `gn gen` as part of building this library.
14*3f982cf4SFabien Sanglard
15*3f982cf4SFabien Sanglard## Imports
16*3f982cf4SFabien Sanglard
17*3f982cf4SFabien SanglardTo use TraceLogging, import the following header file:
18*3f982cf4SFabien Sanglard  * *util/trace_logging.h*
19*3f982cf4SFabien SanglardThis file will import all other Trace Logging dependencies.
20*3f982cf4SFabien Sanglard
21*3f982cf4SFabien Sanglard## Trace IDs
22*3f982cf4SFabien Sanglard
23*3f982cf4SFabien SanglardWhen a Trace Log is created, a new unsigned integer is associated with this
24*3f982cf4SFabien Sanglardspecific trace, which will going forward be referred to as a Trace ID.
25*3f982cf4SFabien SanglardAssociating a Trace ID has the following benefits:
26*3f982cf4SFabien Sanglard
27*3f982cf4SFabien Sanglard* The same Trace ID can be associated with all Informational Logs generated
28*3f982cf4SFabien Sanglard  during this traced method’s execution. This will allow for all informational
29*3f982cf4SFabien Sanglard  logs to easily be associated with a method execution, so that if an unexpected
30*3f982cf4SFabien Sanglard  failure occurs or edge case pops up we will have additional information useful
31*3f982cf4SFabien Sanglard  in debugging this issue and can more easily determine the state of the system
32*3f982cf4SFabien Sanglard  leading to this issue.
33*3f982cf4SFabien Sanglard
34*3f982cf4SFabien Sanglard* If another Trace Log is created during the execution of this first traced
35*3f982cf4SFabien Sanglard  method, we will have a hierarchy of Trace IDs. This will allow us to easily
36*3f982cf4SFabien Sanglard  create an execution tree (through trivial scripting, preexisting tool, or
37*3f982cf4SFabien Sanglard  database operations) to get a better view of how execution is proceeding.
38*3f982cf4SFabien Sanglard  Together, the IDs associated with these calls form a Trace ID Hierarchy. The
39*3f982cf4SFabien Sanglard  Hierarchy has the following format:
40*3f982cf4SFabien Sanglard  * *Current Trace ID*: The ID of the function currently being traced.
41*3f982cf4SFabien Sanglard  * *Parent Trace ID*: The ID of the function which was being traced when this
42*3f982cf4SFabien Sanglard    Trace was initiated.
43*3f982cf4SFabien Sanglard  * *Root Trace ID*: The ID of the first traced function under which this the
44*3f982cf4SFabien Sanglard    current Trace was called.
45*3f982cf4SFabien Sanglard
46*3f982cf4SFabien SanglardAs an example:
47*3f982cf4SFabien Sanglard``` cpp
48*3f982cf4SFabien Sanglard    public void DoThings() {
49*3f982cf4SFabien Sanglard      TRACE_SCOPED(category, "outside");
50*3f982cf4SFabien Sanglard      {
51*3f982cf4SFabien Sanglard        TRACE_SCOPED(category, "middle");
52*3f982cf4SFabien Sanglard        {
53*3f982cf4SFabien Sanglard          TRACE_SCOPED(category, "inside");
54*3f982cf4SFabien Sanglard        }
55*3f982cf4SFabien Sanglard      }
56*3f982cf4SFabien Sanglard    }
57*3f982cf4SFabien Sanglard```
58*3f982cf4SFabien Sanglard
59*3f982cf4SFabien SanglardThis could result in the following Trace ID Information:
60*3f982cf4SFabien Sanglard
61*3f982cf4SFabien Sanglard| NAME    | ROOT ID  | PARENT ID  | TRACE ID  | RESULT  |
62*3f982cf4SFabien Sanglard|---------|----------|------------|-----------|---------|
63*3f982cf4SFabien Sanglard| outside | 100      | 0          | 100       | success |
64*3f982cf4SFabien Sanglard| middle  | 100      | 100        | 101       | success |
65*3f982cf4SFabien Sanglard| inside  | 100      | 101        | 102       | success |
66*3f982cf4SFabien Sanglard
67*3f982cf4SFabien SanglardNote that, prior to any trace calls, the Trace ID is considered to be 0x0 by
68*3f982cf4SFabien Sanglardconvention.
69*3f982cf4SFabien Sanglard
70*3f982cf4SFabien Sanglard## Trace Results
71*3f982cf4SFabien Sanglard
72*3f982cf4SFabien SanglardThe "result" of a trace is meant to indicate whether the traced function
73*3f982cf4SFabien Sanglardcompleted successfully or not. Results are handled differently for synchronous
74*3f982cf4SFabien Sanglardand asynchronous traces.
75*3f982cf4SFabien Sanglard
76*3f982cf4SFabien SanglardFor scoped traces, the trace is by default assumed to be successful. If an error
77*3f982cf4SFabien Sanglardstate is desired, this should be set using `TRACE_SET_RESULT(result)` where
78*3f982cf4SFabien Sanglardresult is some Error::Code enum value.
79*3f982cf4SFabien Sanglard
80*3f982cf4SFabien SanglardFor asynchronous calls, the result must be set as part of the `TRACE_ASYNC_END`
81*3f982cf4SFabien Sanglardcall. As with scoped traces, the result must be some Error::Code enum value.
82*3f982cf4SFabien Sanglard
83*3f982cf4SFabien Sanglard## Tracing Functions
84*3f982cf4SFabien SanglardAll of the below functions rely on the Platform Layer's IsTraceLoggingEnabled()
85*3f982cf4SFabien Sanglardfunction. When logging is disabled, either for the specific category of trace
86*3f982cf4SFabien Sanglardlogging which the Macro specifies or for TraceCategory::Any in all other cases,
87*3f982cf4SFabien Sanglardthe below functions will be treated as a NoOp.
88*3f982cf4SFabien Sanglard
89*3f982cf4SFabien Sanglard### Synchronous Tracing
90*3f982cf4SFabien Sanglard  ```c++
91*3f982cf4SFabien Sanglard  TRACE_SCOPED(category, name)
92*3f982cf4SFabien Sanglard  TRACE_SCOPED(category, name, traceId, parentId, rootId)
93*3f982cf4SFabien Sanglard  TRACE_SCOPED(category, name, traceIdHierarchy)
94*3f982cf4SFabien Sanglard  ```
95*3f982cf4SFabien Sanglard  If logging is enabled for the provided |category|, trace the current scope. The scope
96*3f982cf4SFabien Sanglard  should encompass the operation described by |name|. The latter two uses of this macro are
97*3f982cf4SFabien Sanglard  for manually providing the trace ID hierarchy; the first auto-generates a new trace ID for
98*3f982cf4SFabien Sanglard  this scope and sets its parent trace ID to that of the encompassing scope (if any).
99*3f982cf4SFabien Sanglard
100*3f982cf4SFabien Sanglard  ```c++
101*3f982cf4SFabien Sanglard  TRACE_DEFAULT_SCOPED(category)
102*3f982cf4SFabien Sanglard  TRACE_DEFAULT_SCOPED(category, traceId, parentId, rootId)
103*3f982cf4SFabien Sanglard  TRACE_DEFAULT_SCOPED(category, traceIdHierarchy)
104*3f982cf4SFabien Sanglard  ```
105*3f982cf4SFabien Sanglard  Same as TRACE_SCOPED(), but use the current function/method signature as the operation
106*3f982cf4SFabien Sanglard  name.
107*3f982cf4SFabien Sanglard
108*3f982cf4SFabien Sanglard### Asynchronous Tracing
109*3f982cf4SFabien Sanglard  `TRACE_ASYNC_START(category, name)`
110*3f982cf4SFabien Sanglard    If logging is enabled for the provided category, this function will initiate
111*3f982cf4SFabien Sanglard    a new asynchronous function trace with name as provided. It will not end
112*3f982cf4SFabien Sanglard    until TRACE_ASYNC_END is called with the same Trace ID generated for this
113*3f982cf4SFabien Sanglard    async trace. When this call is used, the Trace ID Hierarchy will be
114*3f982cf4SFabien Sanglard    determined automatically and the caller does not need to worry about it and,
115*3f982cf4SFabien Sanglard    as such, **this call should be used in the majority of asynchronous tracing
116*3f982cf4SFabien Sanglard    cases**.
117*3f982cf4SFabien Sanglard
118*3f982cf4SFabien Sanglard  `TRACE_ASYNC_START(category, name, traceId, parentId, rootId)`
119*3f982cf4SFabien Sanglard    If logging is enabled for the provided category, this function will initiate
120*3f982cf4SFabien Sanglard    a new asynchronous function trace with name and full Trac ID Hierarchy as
121*3f982cf4SFabien Sanglard    provided. It will not end until TRACE_ASYNC_END is called with the same
122*3f982cf4SFabien Sanglard    Trace ID provided for this async trace. Each of trace ID, parent ID, and
123*3f982cf4SFabien Sanglard    root ID is optional, so providing only a subset of these values is also
124*3f982cf4SFabien Sanglard    valid if the caller only desires to set specific ones.
125*3f982cf4SFabien Sanglard
126*3f982cf4SFabien Sanglard  `TRACE_ASYNC_START(category, name, traceIdHierarchy)`
127*3f982cf4SFabien Sanglard    This call is intended for use in conjunction with the TRACE_HIERARCHY macro
128*3f982cf4SFabien Sanglard    (as described below). this function will initiate a new asynchronous
129*3f982cf4SFabien Sanglard    function trace with name and full Trace ID Hierarchy as provided. It will
130*3f982cf4SFabien Sanglard    not end until TRACE_ASYNC_END is called with the same Trace ID provided for
131*3f982cf4SFabien Sanglard    this async trace.
132*3f982cf4SFabien Sanglard
133*3f982cf4SFabien Sanglard  `TRACE_ASYNC_END(category, id, result)`
134*3f982cf4SFabien Sanglard    This call will end a trace initiated by TRACE_ASYNC_START (as described
135*3f982cf4SFabien Sanglard    above) if logging is enabled for the associated category. The id is expected
136*3f982cf4SFabien Sanglard    to match that used by an TRACE_ASYNC_START call, and result is the same as
137*3f982cf4SFabien Sanglard    TRACE_SET_RESULT's argument.
138*3f982cf4SFabien Sanglard
139*3f982cf4SFabien Sanglard### Other Tracing Macros
140*3f982cf4SFabien Sanglard  `TRACE_CURRENT_ID`
141*3f982cf4SFabien Sanglard    This macro returns the current Trace ID at this point in time.
142*3f982cf4SFabien Sanglard
143*3f982cf4SFabien Sanglard  `TRACE_ROOT_ID`
144*3f982cf4SFabien Sanglard    This macro returns the root Trace ID at this point in time.
145*3f982cf4SFabien Sanglard
146*3f982cf4SFabien Sanglard  `TRACE_HIERARCHY`
147*3f982cf4SFabien Sanglard    This macro returns an instance of struct Trace ID Hierarchy containing the
148*3f982cf4SFabien Sanglard    current Trace ID Hierarchy. This is intended to be used with
149*3f982cf4SFabien Sanglard    `TRACE_SET_HIERARCHY` (described below) so that Trace ID Hierarchy can be
150*3f982cf4SFabien Sanglard    maintained when crossing thread or machine boundaries.
151*3f982cf4SFabien Sanglard
152*3f982cf4SFabien Sanglard  `TRACE_SET_HIERARCHY(ids)`
153*3f982cf4SFabien Sanglard    This macro sets the current Trace Id Hierarchy without initiating a scoped
154*3f982cf4SFabien Sanglard    trace. The set ids will cease to apply when the current scope ends. This is
155*3f982cf4SFabien Sanglard    intended to be used with `TRACE_HIERARCHY` (described above) so that Trace
156*3f982cf4SFabien Sanglard    ID Hierarchy can be maintained when crossing thread or machine boundaries.
157*3f982cf4SFabien Sanglard
158*3f982cf4SFabien Sanglard  `TRACE_SET_RESULT(result)`
159*3f982cf4SFabien Sanglard    Sets the current scoped trace's result to be the same as the Error::Code
160*3f982cf4SFabien Sanglard    argument provided.
161*3f982cf4SFabien Sanglard
162*3f982cf4SFabien Sanglard### Example Code
163*3f982cf4SFabien SanglardSynchronous Tracing:
164*3f982cf4SFabien Sanglard``` cpp
165*3f982cf4SFabien Sanglard    public void DoThings() {
166*3f982cf4SFabien Sanglard      TRACE_SCOPED(category, "DoThings");
167*3f982cf4SFabien Sanglard
168*3f982cf4SFabien Sanglard      // Do Things.
169*3f982cf4SFabien Sanglard      // A trace log is generated when the scope containing the above call ends.
170*3f982cf4SFabien Sanglard
171*3f982cf4SFabien Sanglard      TRACE_SET_RESULT(Error::Code::kNone);
172*3f982cf4SFabien Sanglard    }
173*3f982cf4SFabien Sanglard```
174*3f982cf4SFabien Sanglard
175*3f982cf4SFabien SanglardAsynchronous tracing with known Trace ID (recommended):
176*3f982cf4SFabien SanglardThis approach allows for asynchronous tracing when the function being traced can
177*3f982cf4SFabien Sanglardbe associated with a known Trace ID. For instance, a packet ID, a request ID, or
178*3f982cf4SFabien Sanglardanother ID which will live for the duration of the trace but will not need to be
179*3f982cf4SFabien Sanglardpassed around separately.
180*3f982cf4SFabien Sanglard``` cpp
181*3f982cf4SFabien Sanglard    public void DoThingsStart() {
182*3f982cf4SFabien Sanglard      TRACE_ASYNC_START(category, "DoThings", kKnownId);
183*3f982cf4SFabien Sanglard    }
184*3f982cf4SFabien Sanglard
185*3f982cf4SFabien Sanglard    public void DoThingsEnd() {
186*3f982cf4SFabien Sanglard      TRACE_ASYNC_END(category, kKnownId, Error::Code::kNone);
187*3f982cf4SFabien Sanglard    }
188*3f982cf4SFabien Sanglard```
189*3f982cf4SFabien Sanglard
190*3f982cf4SFabien SanglardAsynchronous tracing with unknown Trace ID (not recommended):
191*3f982cf4SFabien SanglardThis approach allows for asynchronous tracing even when no existing ID can be
192*3f982cf4SFabien Sanglardassociated with the trace.
193*3f982cf4SFabien Sanglard``` cpp
194*3f982cf4SFabien Sanglard    public TraceId DoThingsStart() {
195*3f982cf4SFabien Sanglard      TRACE_ASYNC_START(category, "DoThings");
196*3f982cf4SFabien Sanglard      return TRACE_CURRENT_ID;
197*3f982cf4SFabien Sanglard    }
198*3f982cf4SFabien Sanglard
199*3f982cf4SFabien Sanglard    public void DoThingsEnd(TraceId trace_id) {
200*3f982cf4SFabien Sanglard      TRACE_ASYNC_END(category, trace_id, Error::Code::kNone);
201*3f982cf4SFabien Sanglard    }
202*3f982cf4SFabien Sanglard```
203*3f982cf4SFabien Sanglard
204*3f982cf4SFabien Sanglard## File Division
205*3f982cf4SFabien SanglardThe code for Trace Logging is divided up as follows:
206*3f982cf4SFabien Sanglard  * *util/trace_logging.h*: the macros Open Screen library code is expected to
207*3f982cf4SFabien Sanglard      use to log trace events.
208*3f982cf4SFabien Sanglard  * *platform/base/trace_logging_types.h*: the types/enums used in the platform
209*3f982cf4SFabien Sanglard      API as well as internal library code.
210*3f982cf4SFabien Sanglard  * *util/trace_logging/*: the internal infrastructure backing the macros in
211*3f982cf4SFabien Sanglard      *trace_logging.h*, and connecting it to the platform API.
212*3f982cf4SFabien Sanglard  * *platform/api/trace_logging_platform.h*: the platform implementation that is
213*3f982cf4SFabien Sanglard      used as the trace logging destination while tracing is active.
214*3f982cf4SFabien SanglardThis information is intended to be only eplanatory for embedders - only the one
215*3f982cf4SFabien Sanglardfile mentioned above in Imports must be imported.
216*3f982cf4SFabien Sanglard
217*3f982cf4SFabien Sanglard## Embedder-Specific Tracing Implementations
218*3f982cf4SFabien Sanglard
219*3f982cf4SFabien SanglardFor an embedder to create a custom TraceLogging implementation:
220*3f982cf4SFabien Sanglard
221*3f982cf4SFabien Sanglard1. *Create a TraceLoggingPlatform*
222*3f982cf4SFabien Sanglard  In platform/api/trace_logging_platform.h, the interface TraceLoggingPlatform
223*3f982cf4SFabien Sanglard  is defined. An embedder must define a class implementing this interface. The
224*3f982cf4SFabien Sanglard  methods should be as performance-optimal as possible, since they might be
225*3f982cf4SFabien Sanglard  called frequently (especially `IsLoggingEnabled(TraceCategory)`) and are often
226*3f982cf4SFabien Sanglard  in the critical execution path of the library's code.
227*3f982cf4SFabien Sanglard
228*3f982cf4SFabien Sanglard2. *Call `openscreen::StartTracing()` and `StopTracing()`*
229*3f982cf4SFabien Sanglard  These activate/deactivate tracing by providing the TraceLoggingPlatform
230*3f982cf4SFabien Sanglard  instance and later clearing references to it.
231*3f982cf4SFabien Sanglard
232*3f982cf4SFabien Sanglard**The default implementation of this layer can be seen in
233*3f982cf4SFabien Sanglardplatform/impl/trace_logging_platform.cc.**
234