Phosphor
|
#include <trace_log.h>
Public Member Functions | |
TraceLog (const TraceLogConfig &_config) | |
TraceLog () | |
void | configure (const TraceLogConfig &_config) |
void | start (const TraceConfig &_trace_config) |
void | start (std::lock_guard< TraceLog > &, const TraceConfig &_trace_config) |
void | stop (bool shutdown=false) |
void | stop (std::lock_guard< TraceLog > &, bool shutdown=false) |
template<typename T , typename U > | |
void | logEvent (const tracepoint_info *tpi, TraceEvent::Type type, T argA, U argB) |
template<typename T > | |
void | logEvent (const tracepoint_info *tpi, TraceEvent::Type type, T argA) |
void | logEvent (const tracepoint_info *tpi, TraceEvent::Type type) |
const AtomicCategoryStatus & | getCategoryStatus (const char *category_group) |
std::unique_ptr< TraceBuffer > | getBuffer () |
std::unique_ptr< TraceBuffer > | getBuffer (std::lock_guard< TraceLog > &) |
TraceContext | getTraceContext () |
TraceContext | getTraceContext (std::lock_guard< TraceLog > &) |
bool | isEnabled () const |
void | registerThread (const std::string &thread_name="") |
void | deregisterThread () |
void | lock () |
void | unlock () |
TraceConfig | getTraceConfig () const |
void | getStats (StatsCallback &addStats) const |
Static Public Member Functions | |
static TraceLog & | getInstance () |
Protected Member Functions | |
std::unique_lock< ChunkTenant > | getChunkTenant () |
bool | replaceChunk (ChunkTenant &ct) |
void | evictThreads (std::lock_guard< TraceLog > &lh) |
void | clearDeregisteredThreads () |
void | maybe_stop (size_t _generation) |
Protected Attributes | |
TraceConfig | trace_config |
std::atomic< bool > | enabled |
std::mutex | mutex |
std::unique_ptr< TraceBuffer > | buffer |
std::atomic< size_t > | generation |
std::unordered_set< ChunkTenant * > | registered_chunk_tenants |
CategoryRegistry | registry |
std::unordered_map< uint64_t, std::string > | thread_names |
std::set< uint64_t > | deregistered_threads |
The TraceLog class is the main public management interface of Phosphor. Generally the TraceLog is used as a singleton, this instance is acquired via TraceLog::getInstance().
Logging can be enabled by passing in a TraceConfig object with the desired options to the TraceConfig::start() method:
// Enable tracing with a fixed buffer, 5 megabytes in size TraceLog::getInstance().start(TraceConfig(BufferMode::fixed, 5 * 1024 * 1024))
Once enabled, tracing will be logged wherever code has been instrumented with the instrumentation API described in phosphor.h.
This class's public interface is generally thread-safe.
phosphor::TraceLog::TraceLog | ( | const TraceLogConfig & | _config | ) |
Constructor for creating a TraceLog with a specific log config
_config | The TraceLogConfig to be used by the TraceLog |
phosphor::TraceLog::TraceLog | ( | ) |
Constructor for generating a TraceLog from the current environment according to the rules set out in TraceLogConfig.
Will additionally start tracing if the PHOSPHOR_TRACING_START
environment variable is appropriately configured according to the rules for TraceConfig::fromString
|
protected |
Removes all threads from the thread_name map that are part of the deregistered threads set.
void phosphor::TraceLog::configure | ( | const TraceLogConfig & | _config | ) |
Used to perform a one-time configuration of the TraceLog
_config | The TraceLogConfig to be used by the TraceLog |
void phosphor::TraceLog::deregisterThread | ( | ) |
De-registers the current thread
De-registering will free up any resources associated with the thread. This MUST be called from registered threads before they shutdown to prevent memory-leaks as the only reference to resources they allocate are in thread local storage.
|
protected |
Used for evicting all ChunkTenants from the log
This will use the set of ChunkTenants established from the calls to registerThread and deregisterThread and call close() on them.
This will effectively send a message to all ChunkTenants that their current references to chunks in their possession are no longer valid.
Once this function returns the buffer that the TraceLog had SHOULD be safe to be freed / iterated etc.
std::unique_ptr< TraceBuffer > phosphor::TraceLog::getBuffer | ( | ) |
Transfers ownership of the current TraceBuffer to the caller
Should only be called while Tracing is disabled. The returned unique_ptr is not guaranteed to be non-null, and in fact will be null if the buffer has previously been retrieved.
std::logic_error | if tracing is currently enabled |
std::unique_ptr< TraceBuffer > phosphor::TraceLog::getBuffer | ( | std::lock_guard< TraceLog > & | ) |
Same as TraceLog::getBuffer() except with external locking
Lock | guard holding the external lock |
std::logic_error | if tracing is currently enabled |
const AtomicCategoryStatus & phosphor::TraceLog::getCategoryStatus | ( | const char * | category_group | ) |
Used to get a reference to a reusable CategoryStatus. This should generally be held in a block-scope static at a given trace point to verify if the category for that trace point is presently enabled.
category_group | The category group to check |
|
protected |
Gets a pointer to the appropriate ChunkTenant (or nullptr) with the lock acquired.
|
static |
void phosphor::TraceLog::getStats | ( | StatsCallback & | addStats | ) | const |
Invokes methods on the callback to supply various stats about the TraceLog, the active trace buffer and the category registry.
TraceContext phosphor::TraceLog::getTraceContext | ( | ) |
Returns a trace context object which can be used to generate a JSON export / iterated over
std::logic_error | if tracing is currently enabled |
TraceContext phosphor::TraceLog::getTraceContext | ( | std::lock_guard< TraceLog > & | ) |
Same as TraceLog::getTraceContext() except with external locking
std::logic_error | if tracing is currently enabled |
bool phosphor::TraceLog::isEnabled | ( | ) | const |
Get the current state of tracing of this TraceLog
|
inline |
Lock the trace log externally
Note: Prefer the internal locking on the methods
|
inline |
Logs an event in the current buffer (if applicable)
This method should not be used directly, instead the macros contained within phosphor.h should be used instead.
category | The category to log the event into. This (and the name) should usually be a string literal as the pointer should remain valid until the buffer is freed. |
name | The name of the event |
type | The type of the event |
argA | Argument to be saved with the event |
argB | Argument to be saved with the event |
|
inline |
Logs an event in the current buffer (if applicable)
This method should not be used directly, instead the macros contained within phosphor.h should be used instead.
category | The category to log the event into. This (and the name) should usually be a string literal as the pointer should remain valid until the buffer is freed. |
name | The name of the event |
type | The type of the event |
argA | Argument to be saved with the event |
|
inline |
Logs an event in the current buffer (if applicable)
This method should not be used directly, instead the macros contained within phosphor.h should be used instead.
category | The category to log the event into. This (and the name) should usually be a string literal as the pointer should remain valid until the buffer is freed. |
name | The name of the event |
type | The type of the event |
|
protected |
Attempts to stop tracing without waiting for internal lock
void phosphor::TraceLog::registerThread | ( | const std::string & | thread_name = "" | ) |
Registers the current thread for tracing (Optional)
Can also give a name to associate the thread's TID with a name for export purposes. Thread name is ignored if it's an empty string.
Registering a thread is used for a long-living thread and is used to give it a dedicated ChunkTenant and optionally a name. A registered thread MUST be de-registered before the thread is joined as the act of registering allocates resources only accessibly via thread -local storage.
Registering is desirable as the thread will otherwise share a ChunkTenant with all other non-registered threads. Because this involves acquiring locks that may be under contention this can be expensive.
thread_name | (optional) name of the thread to register |
std::logic_error | if the thread has already been registered |
|
protected |
Replaces the current chunk held by the ChunkTenant with a new chunk (typically because it is full).
This function must be called while the ChunkTenant lock is held.
ct | The ChunkTenant that should have it's chunk returned and replaced |
void phosphor::TraceLog::start | ( | const TraceConfig & | _trace_config | ) |
Start tracing with the specified config
_trace_config | TraceConfig to use for this tracing run |
void phosphor::TraceLog::start | ( | std::lock_guard< TraceLog > & | lh, |
const TraceConfig & | _trace_config | ||
) |
Start tracing with the specified config and using an external lock
lock | guard holding the external lock |
_trace_config | TraceConfig to use for this tracing run |
void phosphor::TraceLog::stop | ( | bool | shutdown = false | ) |
Immediately stops tracing
void phosphor::TraceLog::stop | ( | std::lock_guard< TraceLog > & | lh, |
bool | shutdown = false |
||
) |
Immediately stops tracing (With external locking)
Lock | guard holding the external lock |
|
inline |
Unlock the trace log externally
Note: Prefer the internal locking on the methods
|
protected |
buffer is the current buffer that is being used by the TraceLog.
While logging is enabled the buffer will have various chunks of the buffer loaned out.
This buffer may become NULL once tracing stops if a user asks for it as movement semantics are used and buffers are only created when tracing starts.
|
protected |
List of deregistered thread ids while tracing is running
|
protected |
Whether or not tracing is currently enabled
By transitioning this boolean to false no new trace events will be logged, but any threads currently in the process of tracing an event MAY finish tracing the event they're on.
|
protected |
The current tracing generation. This is incremented every-time tracing is stopped and is passed into the TraceBuffer when it is constructed in order to 'uniquely' identify it.
|
mutableprotected |
mutex is the 'global' lock for the TraceLog and should be acquired when modifying the TraceLog itself or the current TraceBuffer.
It is not required to be acquired when modifying a loaned out TraceChunk contained within a ChunkTenant, this is protected by the ChunkTenant's ChunkLock lock instead.
|
protected |
The set of ChunkTenants that have been registered to this TraceLog.
|
protected |
Category registry which manages the enabled / disabled categories
|
protected |
Map of registered thread TIDs to names
|
protected |
The current or last-used TraceConfig of the TraceLog, this is only ever set by the start() method.
This is a full copy of a TraceConfig rather than a reference to allow reuse / modification of a TraceConfig that was passed in by a user.