|
ProtoCore v0.0.1
Deterministic, zero-heap network stack for embedded targets
|
Abstract logging whose disabled levels cost nothing at all (PC_LOG_LEVEL). More...
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. | |
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.
Definition in file log.h.
| #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__) |
| typedef void(* pc_log_sink_fn) (uint8_t level, const char *line) |
| 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.