13#define LOG_INITIAL_QUEUE_SIZE 32
14#define LOG_MAX_QUEUE_SIZE 262144
16extern atomic(
bool) _log_running;
17extern Mutex _log_run_lock;
26typedef struct LogFilterRule {
42 LogFilterRule* subrules;
85typedef struct LogEntry LogEntry;
92typedef struct LogQueueNode LogQueueNode;
93typedef struct LogQueueNode {
99typedef struct LogEntry {
118 LogQueueNode inlnode;
147_meta_inline
bool logQueueNodeIsInline(_In_
const LogQueueNode* node)
149 return node == &node->ent->inlnode;
163typedef struct LogRouting {
174#define LOG_QUIESCENT 0
175typedef struct LogDrain {
176 atomic(uint32) epoch;
183typedef struct LogGroup {
196 atomic(uint32) depth;
206extern atomic(uint32) _log_ngroups;
211extern Mutex _log_op_lock;
212extern sa_LogDest _log_dests;
213extern hashtable _log_channels;
214extern sa_LogChannel _log_chans;
225uint64 logNextSeq(
void);
233_meta_inline
bool logSeqBefore(uint64 a, uint64 b)
235 return (int64)(a - b) < 0;
238void logCheckInit(
void);
244_Ret_opt_valid_ LogEntry*
245logEntryCreate(
int level, int64 timestamp, _In_
LogChannel* chan, _In_opt_
const LogSite* site,
246 _In_opt_ strref tmpl,
int nargs, _In_opt_
stvar* args, _In_opt_
LogCtx* ctx);
249void logEntryToRecord(_Out_
LogRecord* rec, _In_
const LogEntry* ent, uint32 batchid,
250 _In_opt_ LogRenderCache* cache);
258void logFanout(_In_opt_ LogEntry* head,
bool fresh);
261_Ret_valid_ LogEntry* logEntryAcquire(_In_ LogEntry* ent);
262void logEntryRelease(_In_ LogEntry* ent);
268void logQueueAdd(_In_ LogGroup* group, _In_ LogQueueNode* head, uint32 nents);
270void logQueueFreeNodes(_In_opt_ LogQueueNode* head);
272uint32 logQueueCount(_In_opt_ LogQueueNode* head);
276void logGroupInit(
void);
277void logGroupStartAll(
void);
278void logGroupStopAll(
void);
279void logGroupShutdown(
void);
280int logGroupThread(_Inout_ Thread* self);
285void logDispatchRecord(_In_ LogGroup* grp, _In_opt_ LogRouting* routing, _In_
const LogRecord* rec,
286 _Inout_ sa_LogDest* sent);
289_Ret_opt_valid_ LogRouting* logRoutingCurrentUnsafe(
void);
292extern atomic(uint64) _log_stat_enqueued;
293extern atomic(uint64) _log_stat_dropped;
294extern atomic(uint64) _log_stat_sampled;
295extern atomic(uint64) _log_stat_suppressed;
296extern atomic(uint64) _log_stat_sync;
297extern atomic(int32) _log_synclevel;
301bool logSamplePasses(_In_
LogChannel* chan,
int level, _Out_ uint32* rate);
305bool logDedupPasses(_In_ LogGroup* grp, _In_
const LogRecord* rec);
307void logDedupFlush(_In_ LogGroup* grp, _In_opt_ LogRouting* routing, _Inout_ sa_LogDest* sent,
309void logDedupDestroy(_Inout_ LogGroup* grp);
311int64 logDedupWait(_In_ LogGroup* grp);
315void logStatsTick(_In_ LogGroup* grp);
322typedef struct LogRing LogRing;
323_Ret_valid_ LogRing* logRingCreate(
int maxlevel, uint32 cap, uint64 maxbytes,
int trigger,
325int logRingMaxLevel(_In_ LogRing* ring);
326void logRingDestroy(_Inout_ LogRing** pring);
327void logRingClear(_Inout_ LogRing* ring);
328void logRingReconfigure(_Inout_ LogRing* ring,
int maxlevel, uint32 cap, uint64 maxbytes,
330uint32 logRingCount(_Inout_ LogRing* ring);
332bool logRingPush(_Inout_ LogRing* ring, _In_ LogEntry* ent);
335uint32 logRingTake(_Inout_ LogRing* ring, _Outptr_ LogEntry*** out,
bool drain);
336void logRingFreeTaken(_Pre_valid_ _Post_invalid_ LogEntry** ents, uint32 n);
340extern atomic(int32) _log_bootlevel;
343void logRingCapture(_In_ LogEntry* ent);
347void logRingReplay(_In_ LogDest* dest);
349void logRingTick(_In_ LogGroup* grp);
350void logRingShutdown(
void);
354void logWriteSync(_In_ LogGroup* grp, _In_opt_ LogQueueNode* head,
int minlevel);
359bool logInLocalScope(
void);
364_Ret_valid_
LogCtx* logCtxCreate(_In_opt_
LogCtx* parent,
int n, _In_opt_
const stvar* vars);
367void logChanInit(
void);
370bool logChanIsTransport(_In_
const LogChannel* chan);
373_Ret_opt_valid_
LogChannel* logChanApplyRemote(_In_ strref path, flags_t flags);
374uint32 logChanLitDepth(_In_ strref pattern);
375bool logChanMatch(_In_ strref pattern, _In_opt_ strref path);
378void logChanSplitPath(_Inout_ sa_string* _Nonnull out, _In_opt_ strref path);
380bool logChanRuleMatch(_In_ LogDest* dest, _In_
LogChannel* chan);
383bool logChanRuleMatchComps(_In_ LogDest* dest, _In_
LogChannel* chan, _In_ sa_string* _Nonnull comps);
387void logRoutingInit(
void);
391uint32 logRoutingPublish(
void);
394void logRoutingAddChan(_Inout_
LogChannel* chan);
395void logRoutingRetireDest(_In_ LogDest* dest, uint32 gen);
396bool logRoutingSlotPending(uint32 idx);
398void logRoutingSweep(
void);
400void logRoutingShutdown(
void);
402_Ret_opt_valid_ LogDrain* logDrainRegister(
void);
403void logDrainUnregister(_Pre_valid_ _Post_invalid_ LogDrain* drain);
406_Ret_opt_valid_ LogRouting* logDrainEnter(_Inout_ LogDrain* drain);
407void logDrainIdle(_Inout_ LogDrain* drain);
412logRegisterRemoteDest(
int maxlevel, _In_opt_ strref chanfilter, _In_
LogDestMsg msgfunc,
414 _In_opt_
void* userdata);
417bool logUnregisterDestLocked(_In_ LogDest* dhandle);
419void logDestInsertLocked(_In_ LogDest* dest);
420void logDestAddRuleLocked(_Inout_ LogDest* dest, _In_opt_ strref pattern,
bool exclude);
421void logDestFreeRules(_Inout_ LogDest* dest);
424void logDestSetSubRulesLocked(_Inout_ LogDest* dest, _In_opt_
const sa_string* patterns);
426bool logDestSetSubFilter(_In_ LogDest* dhandle, _In_opt_
const sa_string* patterns);
430bool logDestSubscribe(_In_ LogDest* dhandle, _In_opt_
const sa_string* patterns,
int maxlevel);
Generic type-safe containers with runtime type system integration.
#define saDeclarePtr(name)
struct LogDest LogDest
Opaque handle to a registered log destination.
void(* LogDestBatchDone)(uint32 batchid, void *userdata)
struct LogCtx LogCtx
Opaque handle to a log context; see logctx.h.
void(* LogDestMsg)(const LogRecord *rec, void *userdata)
void(* LogDestClose)(void *userdata)
#define stvar(typen, val)
Threading system aggregated header.
Thread-safe lazy initialization.
Per-thread log context: fields every record on this thread inherits.
Drain groups: which thread does a destination's work.
Bounded retention rings: the boot window, and the retroactive debug ring.
Log record serializers, independent of where the result is written.
Volume control: what happens when there is too much to log.
State tracker for lazy initialization.