1111#include < pthread.h>
1212#include < unistd.h>
1313
14+ #include < string>
15+
1416namespace aspl {
1517
1618// ! Operation tracer.
1719// !
18- // ! All objects use tracer to report operations issues by HAL. By default,
19- // ! tracers sends messages to syslog with "[aspl]" prefix.
20+ // ! All objects use tracer to report operations issued by HAL. By default,
21+ // ! tracer sends messages to syslog with "[aspl]" prefix.
2022// !
2123// ! Tracer maintains per-thread operations depth counter. Nested operations
22- // ! are indented in output messages.
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.
2328// !
2429// ! If you want to change tracer output, you can use one of the predefined
25- // ! modes or override Print() method. All other methods use it.
30+ // ! modes or override Print() method.
2631// !
27- // ! If you want to change formatting of the operations , you can override
28- // ! other public methods .
32+ // ! If you want to exclude some operations from trace , you can override
33+ // ! ShouldIgnore() method .
2934class Tracer
3035{
3136public:
@@ -43,6 +48,32 @@ class Tracer
4348 // ! System log.
4449 // ! Send all messages to syslog().
4550 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.
61+ Hierarchical,
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 );
4677 };
4778
4879 // ! Operation info.
@@ -51,6 +82,9 @@ class Tracer
5182 // ! Operation name.
5283 const char * Name = nullptr ;
5384
85+ // ! Operation flags.
86+ UInt32 Flags = 0 ;
87+
5488 // ! ID of object for which operation was initiated.
5589 AudioObjectID ObjectID = 0 ;
5690
@@ -88,7 +122,8 @@ class Tracer
88122
89123 // ! Initialize tracer.
90124 // ! Mode defines where to send messages.
91- explicit Tracer (Mode mode = Mode::Syslog);
125+ // ! Style defines how to format messages.
126+ explicit Tracer (Mode mode = Mode::Syslog, Style style = Style::Hierarchical);
92127
93128 Tracer (const Tracer&) = delete ;
94129 Tracer& operator =(const Tracer&) = delete ;
@@ -109,17 +144,49 @@ class Tracer
109144 virtual void OperationEnd (const Operation& operation, OSStatus status);
110145
111146protected:
147+ // ! Format operation begin message into string.
148+ // ! Called by default implementation of OperationBegin().
149+ virtual std::string FormatOperationBegin (const Operation& operation, UInt32 depth);
150+
151+ // ! Format message into string.
152+ // ! Called by default implementation of Message().
153+ virtual std::string FormatMessage (const char * message, UInt32 depth);
154+
155+ // ! Format operation end message into string.
156+ // ! Called by default implementation of OperationEnd().
157+ virtual std::string FormatOperationEnd (const Operation& operation,
158+ OSStatus status,
159+ UInt32 depth);
160+
112161 // ! Print message somewhere.
113162 // ! Default implementation sends message to syslog if mode is Mode::Syslog,
114163 // ! or does nothing if mode is Mode::Noop.
115164 virtual void Print (const char * message);
116165
166+ // ! Check whethe 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.
170+ virtual bool ShouldIgnore (const Operation& operation);
171+
117172private:
118- // Returns thread-local operation depth counter
119- int & GetDepthCounter ();
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 ;
120185
121186 const Mode mode_;
122- pthread_key_t depthCounter_;
187+ const Style style_;
188+
189+ pthread_key_t threadKey_;
123190};
124191
125192} // namespace aspl
0 commit comments