libASPL
Loading...
Searching...
No Matches
Tracer.hpp
Go to the documentation of this file.
1// Copyright (c) libASPL authors
2// Licensed under MIT
3
4//! @file aspl/Tracer.hpp
5//! @brief Operation tracer.
6
7#pragma once
8
9#include <CoreAudio/AudioServerPlugIn.h>
10
11#include <pthread.h>
12#include <unistd.h>
13
14#include <string>
15
16namespace aspl {
17
18//! Operation tracer.
19//!
20//! All objects use tracer to report operations issued by HAL. By default,
21//! tracer sends messages to syslog with "[aspl]" prefix.
22//!
23//! Tracer maintains per-thread operations depth counter. Nested operations
24//! are automatically indented.
25//!
26//! If you want to change formatting, you can use one of the predefined
27//! styles or override FormatXXX() methods.
28//!
29//! If you want to change tracer output, you can use one of the predefined
30//! modes or override Print() method.
31//!
32//! If you want to exclude some operations from trace, you can override
33//! ShouldIgnore() method.
34class Tracer
35{
36public:
37 //! Tracing mode.
38 enum class Mode
39 {
40 //! No operation.
41 //! Don't perform any tracing.
42 Noop,
43
44 //! Standard error stream.
45 //! Send all messages to stderr.
46 Stderr,
47
48 //! System log.
49 //! Send all messages to syslog().
50 Syslog,
51
52 //! Custom mode.
53 //! Use if derived class does something different.
54 Custom,
55 };
56
57 //! Tracing style.
58 enum class Style
59 {
60 //! Indent nested operations.
62
63 //! No indentation.
64 Flat,
65 };
66
67 //! Operation flags.
68 struct Flags
69 {
70 //! This operation is read-only, i.e. doesn't change object state.
71 static constexpr UInt32 Readonly = (1 << 0);
72
73 //! This operation is intended to be called on real-time thread on hot path.
74 //! Such operations are traced only if the user enabled the option
75 //! DeviceParameters::EnableRealtimeTracing
76 static constexpr UInt32 Realtime = (1 << 1);
77 };
78
79 //! Operation info.
80 struct Operation
81 {
82 //! Operation name.
83 const char* Name = nullptr;
84
85 //! Operation flags.
87
88 //! ID of object for which operation was initiated.
90
91 //! PID of client which initiated operation.
93
94 //! Address of property.
95 //! May be null.
97
98 //! Qualifier size.
99 //! May be zero.
101
102 //! Qualifier data.
103 //! May be null.
104 const void* QualifierData = nullptr;
105
106 //! Input size.
107 //! Non-zero for operations that have input or output data.
109
110 //! Input data.
111 //! Non-null for operations that have input data.
112 const void* InData = nullptr;
113
114 //! Output size.
115 //! Non-null for operations that have output data.
116 const UInt32* OutDataSize = nullptr;
117
118 //! Output data.
119 //! Non-null for operations that have output data.
120 const void* OutData = nullptr;
121 };
122
123 //! Initialize tracer.
124 //! Mode defines where to send messages.
125 //! Style defines how to format messages.
127
128 Tracer(const Tracer&) = delete;
129 Tracer& operator=(const Tracer&) = delete;
130
131 virtual ~Tracer() = default;
132
133 //! Called when an operations starts.
134 //! Default implementation formats arguments and calls Print().
135 virtual void OperationBegin(const Operation& operation);
136
137 //! Called to print message to log.
138 //! Default implementation formats arguments and calls Print().
139 virtual void Message(const char* format, ...) __attribute__((format(printf, 2, 3)));
140
141 //! Called when an operations completes.
142 //! Zero status indicates operation success.
143 //! Default implementation formats arguments and calls Print().
145
147 //! Format operation begin message into string.
148 //! Called by default implementation of OperationBegin().
150
151 //! Format message into string.
152 //! Called by default implementation of Message().
154
155 //! Format operation end message into string.
156 //! Called by default implementation of OperationEnd().
159 UInt32 depth);
160
161 //! Print message somewhere.
162 //! Default implementation sends message to syslog if mode is Mode::Syslog,
163 //! or does nothing if mode is Mode::Noop.
165
166 //! Check whether the operation should be excluded from tracing.
167 //! If this method returns true, the operation itself, as well as
168 //! all nested operations, are not printed.
169 //! Default implementation always returns false.
171
172private:
173 struct ThreadLocalState
174 {
175 UInt32 DepthCounter = 0;
176 UInt32 IgnoreCounter = 0;
177 };
178
179 static void* CreateThreadLocalState();
180 static void DestroyThreadLocalState(void*);
181
182 ThreadLocalState& GetThreadLocalState();
183
184 static constexpr size_t MaxMessageLen = 1024;
185
186 const Mode mode_;
187 const Style style_;
188
189 pthread_key_t threadKey_;
190};
191
192} // namespace aspl
Doubly-buffered value with non-blocking read and blocking write.
Operation tracer.
Definition Tracer.hpp:35
Mode
Tracing mode.
Definition Tracer.hpp:39
@ Noop
No operation. Don't perform any tracing.
@ Syslog
System log. Send all messages to syslog().
@ Stderr
Standard error stream. Send all messages to stderr.
@ Custom
Custom mode. Use if derived class does something different.
virtual std::string FormatOperationEnd(const Operation &operation, OSStatus status, UInt32 depth)
Format operation end message into string. Called by default implementation of OperationEnd().
virtual void Message(const char *format,...) __attribute__((format(printf
Called to print message to log. Default implementation formats arguments and calls Print().
Style
Tracing style.
Definition Tracer.hpp:59
@ Hierarchical
Indent nested operations.
@ Flat
No indentation.
virtual void Print(const char *message)
Print message somewhere. Default implementation sends message to syslog if mode is Mode::Syslog,...
virtual void virtual void OperationEnd(const Operation &operation, OSStatus status)
Called when an operations completes. Zero status indicates operation success. Default implementation ...
virtual void OperationBegin(const Operation &operation)
Called when an operations starts. Default implementation formats arguments and calls Print().
virtual bool ShouldIgnore(const Operation &operation)
Check whether the operation should be excluded from tracing. If this method returns true,...
Tracer(Mode mode=Mode::Syslog, Style style=Style::Hierarchical)
Initialize tracer. Mode defines where to send messages. Style defines how to format messages.
virtual std::string FormatOperationBegin(const Operation &operation, UInt32 depth)
Format operation begin message into string. Called by default implementation of OperationBegin().
virtual std::string FormatMessage(const char *message, UInt32 depth)
Format message into string. Called by default implementation of Message().
Operation flags.
Definition Tracer.hpp:69
static constexpr UInt32 Realtime
This operation is intended to be called on real-time thread on hot path. Such operations are traced o...
Definition Tracer.hpp:76
static constexpr UInt32 Readonly
This operation is read-only, i.e. doesn't change object state.
Definition Tracer.hpp:71
Operation info.
Definition Tracer.hpp:81
UInt32 InDataSize
Input size. Non-zero for operations that have input or output data.
Definition Tracer.hpp:108
UInt32 QualifierDataSize
Qualifier size. May be zero.
Definition Tracer.hpp:100
const void * QualifierData
Qualifier data. May be null.
Definition Tracer.hpp:104
const void * InData
Input data. Non-null for operations that have input data.
Definition Tracer.hpp:112
const AudioObjectPropertyAddress * PropertyAddress
Address of property. May be null.
Definition Tracer.hpp:96
const char * Name
Operation name.
Definition Tracer.hpp:83
const void * OutData
Output data. Non-null for operations that have output data.
Definition Tracer.hpp:120
AudioObjectID ObjectID
ID of object for which operation was initiated.
Definition Tracer.hpp:89
pid_t ClientPID
PID of client which initiated operation.
Definition Tracer.hpp:92
const UInt32 * OutDataSize
Output size. Non-null for operations that have output data.
Definition Tracer.hpp:116