ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
Loading...
Searching...
No Matches
log.h File Reference

Abstract logging whose disabled levels cost nothing at all (PC_LOG_LEVEL). More...

#include "protocore_config.h"
#include "shared_primitives/frame.h"
#include <stdint.h>

Go to the source code of this file.

Macros

#define PC_LOG_DISCARD(...)
 The discarded form: marks arguments used, emits nothing.
 
#define PC_LOGD(...)   pc_log_frame(PC_LOG_LEVEL_DEBUG, __VA_ARGS__)
 
#define PC_LOGI(...)   pc_log_frame(PC_LOG_LEVEL_INFO, __VA_ARGS__)
 
#define PC_LOGW(...)   pc_log_frame(PC_LOG_LEVEL_WARN, __VA_ARGS__)
 
#define PC_LOGE(...)   pc_log_frame(PC_LOG_LEVEL_ERROR, __VA_ARGS__)
 

Typedefs

typedef void(* pc_log_sink_fn) (uint8_t level, const char *line)
 Receives an emitted line, already formatted. level is a PC_LOG_LEVEL_* value.
 

Functions

int pc_log_discard_args (const pc_field *spec,...)
 Declared, never defined: only ever named inside sizeof, so no call is ever generated.
 

Detailed Description

Abstract logging whose disabled levels cost nothing at all (PC_LOG_LEVEL).

Instrumentation is only worth leaving in the source permanently if a build that does not want it pays nothing for it - not a branch, not a call, and not a format string sitting in flash. A runtime if (level >= threshold) fails that last part: every message is still linked in, and on a device flash is the scarce resource.

So the filter is the preprocessor. A call below PC_LOG_LEVEL expands to a form that names its arguments only inside sizeof(...) - an unevaluated context - which emits no code and no string literal, yet still runs the compiler's printf format checking over them and marks the arguments used (so a variable read only by a log does not warn). Enable the level and the same line starts logging, with no source change.

Where an emitted line goes is the caller's choice: it is handed to services/system/logbuf's ring when PC_ENABLE_LOGBUF is on, and to a sink callback registered with pc_log_set_sink() (Serial, syslog, a websocket console) if there is one.

Author
Douglas Quigg (dstroy0)
Date
2026

Definition in file log.h.

Macro Definition Documentation

◆ PC_LOG_DISCARD

#define PC_LOG_DISCARD (   ...)
Value:
do \
{ \
(void)sizeof(pc_log_discard_args(__VA_ARGS__)); \
} while (0)
int pc_log_discard_args(const pc_field *spec,...)
Declared, never defined: only ever named inside sizeof, so no call is ever generated.

The discarded form: marks arguments used, emits nothing.

Definition at line 46 of file log.h.

◆ PC_LOGD

#define PC_LOGD (   ...)    pc_log_frame(PC_LOG_LEVEL_DEBUG, __VA_ARGS__)

Definition at line 77 of file log.h.

◆ PC_LOGI

#define PC_LOGI (   ...)    pc_log_frame(PC_LOG_LEVEL_INFO, __VA_ARGS__)

Definition at line 83 of file log.h.

◆ PC_LOGW

#define PC_LOGW (   ...)    pc_log_frame(PC_LOG_LEVEL_WARN, __VA_ARGS__)

Definition at line 89 of file log.h.

◆ PC_LOGE

#define PC_LOGE (   ...)    pc_log_frame(PC_LOG_LEVEL_ERROR, __VA_ARGS__)

Definition at line 95 of file log.h.

Typedef Documentation

◆ pc_log_sink_fn

typedef void(* pc_log_sink_fn) (uint8_t level, const char *line)

Receives an emitted line, already formatted. level is a PC_LOG_LEVEL_* value.

Definition at line 35 of file log.h.

Function Documentation

◆ pc_log_discard_args()

int pc_log_discard_args ( const pc_field spec,
  ... 
)

Declared, never defined: only ever named inside sizeof, so no call is ever generated.

It exists to mark a discarded statement's arguments as used, so a variable read only by a log does not warn its way into being deleted.