nros C API
Lightweight ROS 2 client for embedded real-time systems
Loading...
Searching...
No Matches
Macros | Typedefs | Enumerations | Functions
log.h File Reference

Phase 88.12 — ROS 2 style leveled logging surface for the C API. More...

#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Include dependency graph for log.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define NROS_LOG_FMT_BUFFER_SIZE   256
 
#define RCLC_LOG_DEBUG(logger, ...)
 
#define RCLC_LOG_DEBUG_THROTTLE(logger, interval_ms, ...)    RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_DEBUG, (interval_ms), __VA_ARGS__)
 
#define RCLC_LOG_ERROR(logger, ...)
 
#define RCLC_LOG_ERROR_THROTTLE(logger, interval_ms, ...)    RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_ERROR, (interval_ms), __VA_ARGS__)
 
#define RCLC_LOG_FATAL(logger, ...)
 
#define RCLC_LOG_FATAL_THROTTLE(logger, interval_ms, ...)    RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_FATAL, (interval_ms), __VA_ARGS__)
 
#define RCLC_LOG_INFO(logger, ...)
 
#define RCLC_LOG_INFO_THROTTLE(logger, interval_ms, ...)    RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_INFO, (interval_ms), __VA_ARGS__)
 
#define RCLC_LOG_THROTTLE_AT(logger, severity, interval_ms, ...)
 
#define RCLC_LOG_TRACE(logger, ...)
 
#define RCLC_LOG_TRACE_THROTTLE(logger, interval_ms, ...)    RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_TRACE, (interval_ms), __VA_ARGS__)
 
#define RCLC_LOG_WARN(logger, ...)
 
#define RCLC_LOG_WARN_THROTTLE(logger, interval_ms, ...)    RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_WARN, (interval_ms), __VA_ARGS__)
 

Typedefs

typedef void(* rclc_log_sink_fn) (void *user_data, rcl_log_severity_t severity, const char *logger_name, size_t logger_name_len, const char *message, size_t message_len, const char *file, size_t file_len, uint32_t line, uint64_t timestamp_ns)
 
typedef const void * rclc_logger_t
 

Enumerations

enum  rcl_log_severity_t {
  RCLC_LOG_SEVERITY_UNSET = 0 , RCLC_LOG_SEVERITY_TRACE = 5 , RCLC_LOG_SEVERITY_DEBUG = 10 , RCLC_LOG_SEVERITY_INFO = 20 ,
  RCLC_LOG_SEVERITY_WARN = 30 , RCLC_LOG_SEVERITY_ERROR = 40 , RCLC_LOG_SEVERITY_FATAL = 50 , RCLC_LOG_SEVERITY_FORCE_INT_WIDTH_ = 0x7fffffff
}
 

Functions

bool rclc_log_add_sink (rclc_log_sink_fn sink, void *user_data)
 
rclc_logger_t rclc_log_default_logger (void)
 
void rclc_log_emit (rclc_logger_t logger, rcl_log_severity_t severity, const char *message, size_t message_len)
 
void void rclc_log_emit_at (rclc_logger_t logger, rcl_log_severity_t severity, const char *message, size_t message_len, const char *file, uint32_t line)
 
void rclc_log_emit_fmt (rclc_logger_t logger, rcl_log_severity_t severity, const char *fmt,...) __attribute__((format(printf
 
void rclc_log_emit_fmt_at (rclc_logger_t logger, rcl_log_severity_t severity, const char *file, uint32_t line, const char *fmt,...) __attribute__((format(printf
 
rcl_log_severity_t rclc_log_get_default_level (void)
 
rclc_logger_t rclc_log_get_logger (const char *name)
 
void rclc_log_init (void)
 
void rclc_log_set_default_level (rcl_log_severity_t severity)
 
bool rclc_log_throttle_admit (uint64_t *last_ns, uint64_t interval_ms)
 
bool rclc_log_timestamp_available (void)
 
rclc_logger_t rclc_logger_get_child (rclc_logger_t logger, const char *suffix)
 
rcl_log_severity_t rclc_logger_get_level (rclc_logger_t logger)
 
size_t rclc_logger_get_name (rclc_logger_t logger, char *buf, size_t buf_len)
 
bool rclc_logger_is_enabled (rclc_logger_t logger, rcl_log_severity_t severity)
 
bool rclc_logger_set_level (rclc_logger_t logger, rcl_log_severity_t severity)
 

Detailed Description

Phase 88.12 — ROS 2 style leveled logging surface for the C API.

Mirrors the Rust [nros_log] facade. Each rcl_node_t exposes a &'static nros_log::Logger via rclc_node_get_logger(node); the NROS_LOG_* macros render the message, attach severity + line info, and dispatch through the same per-platform sink chain as Rust call sites (see Phase 88.5 onwards).

Usage:

RCLC_LOG_INFO(logger, "started; domain=%u", domain_id);
RCLC_LOG_WARN(logger, "queue depth %u exceeds soft limit", depth);
#define RCLC_LOG_WARN(logger,...)
Definition log.h:225
const void * rclc_logger_t
Definition log.h:138
#define RCLC_LOG_INFO(logger,...)
Definition log.h:222
const void * rclc_node_get_logger(const struct rcl_node_t *node)

Per-platform delivery (POSIX stderr / Zephyr LOG / ESP-IDF esp_log_write / NuttX syslog / FreeRTOS+ThreadX+bare-metal board fn-ptr) is invisible at the C API layer — the dispatcher routes through nros_platform_log_write (declared in <nros/platform.h>).

Macro Definition Documentation

◆ NROS_LOG_FMT_BUFFER_SIZE

#define NROS_LOG_FMT_BUFFER_SIZE   256

Stack buffer the located printf-style entry point below renders into.

NOT the NROS_LOG_BUFFER_SIZE knob (issue 1037): c-stubs/log_fmt.c renders into this from a header with no per-build value to read, so its frame stays 256. The knob sizes nros-log's Rust formatter and the slots that store records, so a C record is bounded by the smaller of the two.

◆ RCLC_LOG_DEBUG

#define RCLC_LOG_DEBUG (   logger,
  ... 
)
Value:
rclc_log_emit_fmt_at((logger), RCLC_LOG_SEVERITY_DEBUG, __FILE__, (uint32_t)__LINE__, \
__VA_ARGS__)
@ RCLC_LOG_SEVERITY_DEBUG
Definition log.h:90
void rclc_log_emit_fmt_at(rclc_logger_t logger, rcl_log_severity_t severity, const char *file, uint32_t line, const char *fmt,...) __attribute__((format(printf

◆ RCLC_LOG_DEBUG_THROTTLE

#define RCLC_LOG_DEBUG_THROTTLE (   logger,
  interval_ms,
  ... 
)     RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_DEBUG, (interval_ms), __VA_ARGS__)

◆ RCLC_LOG_ERROR

#define RCLC_LOG_ERROR (   logger,
  ... 
)
Value:
rclc_log_emit_fmt_at((logger), RCLC_LOG_SEVERITY_ERROR, __FILE__, (uint32_t)__LINE__, \
__VA_ARGS__)
@ RCLC_LOG_SEVERITY_ERROR
Definition log.h:93

◆ RCLC_LOG_ERROR_THROTTLE

#define RCLC_LOG_ERROR_THROTTLE (   logger,
  interval_ms,
  ... 
)     RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_ERROR, (interval_ms), __VA_ARGS__)

◆ RCLC_LOG_FATAL

#define RCLC_LOG_FATAL (   logger,
  ... 
)
Value:
rclc_log_emit_fmt_at((logger), RCLC_LOG_SEVERITY_FATAL, __FILE__, (uint32_t)__LINE__, \
__VA_ARGS__)
@ RCLC_LOG_SEVERITY_FATAL
Definition log.h:94

◆ RCLC_LOG_FATAL_THROTTLE

#define RCLC_LOG_FATAL_THROTTLE (   logger,
  interval_ms,
  ... 
)     RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_FATAL, (interval_ms), __VA_ARGS__)

◆ RCLC_LOG_INFO

#define RCLC_LOG_INFO (   logger,
  ... 
)
Value:
rclc_log_emit_fmt_at((logger), RCLC_LOG_SEVERITY_INFO, __FILE__, (uint32_t)__LINE__, \
__VA_ARGS__)
@ RCLC_LOG_SEVERITY_INFO
Definition log.h:91

◆ RCLC_LOG_INFO_THROTTLE

#define RCLC_LOG_INFO_THROTTLE (   logger,
  interval_ms,
  ... 
)     RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_INFO, (interval_ms), __VA_ARGS__)

◆ RCLC_LOG_THROTTLE_AT

#define RCLC_LOG_THROTTLE_AT (   logger,
  severity,
  interval_ms,
  ... 
)
Value:
do { \
static uint64_t _nros_log_throttle_last = 0; \
if (rclc_logger_is_enabled((logger), (severity)) && \
rclc_log_throttle_admit(&_nros_log_throttle_last, (uint64_t)(interval_ms))) { \
rclc_log_emit_fmt_at((logger), (severity), __FILE__, (uint32_t)__LINE__, __VA_ARGS__); \
} \
} while (0)
bool rclc_logger_is_enabled(rclc_logger_t logger, rcl_log_severity_t severity)
bool rclc_log_throttle_admit(uint64_t *last_ns, uint64_t interval_ms)

◆ RCLC_LOG_TRACE

#define RCLC_LOG_TRACE (   logger,
  ... 
)
Value:
rclc_log_emit_fmt_at((logger), RCLC_LOG_SEVERITY_TRACE, __FILE__, (uint32_t)__LINE__, \
__VA_ARGS__)
@ RCLC_LOG_SEVERITY_TRACE
Definition log.h:89

◆ RCLC_LOG_TRACE_THROTTLE

#define RCLC_LOG_TRACE_THROTTLE (   logger,
  interval_ms,
  ... 
)     RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_TRACE, (interval_ms), __VA_ARGS__)

◆ RCLC_LOG_WARN

#define RCLC_LOG_WARN (   logger,
  ... 
)
Value:
rclc_log_emit_fmt_at((logger), RCLC_LOG_SEVERITY_WARN, __FILE__, (uint32_t)__LINE__, \
__VA_ARGS__)
@ RCLC_LOG_SEVERITY_WARN
Definition log.h:92

◆ RCLC_LOG_WARN_THROTTLE

#define RCLC_LOG_WARN_THROTTLE (   logger,
  interval_ms,
  ... 
)     RCLC_LOG_THROTTLE_AT((logger), RCLC_LOG_SEVERITY_WARN, (interval_ms), __VA_ARGS__)

Typedef Documentation

◆ rclc_log_sink_fn

typedef void(* rclc_log_sink_fn) (void *user_data, rcl_log_severity_t severity, const char *logger_name, size_t logger_name_len, const char *message, size_t message_len, const char *file, size_t file_len, uint32_t line, uint64_t timestamp_ns)

A C log sink — see rclc_log_add_sink.

Flat arguments rather than a const nros_log_record_t * on purpose: a struct crossing this FFI would be hand-mirrored (cbindgen skips the logging module), and a mirror that misses an appended field passes a SHORTER struct than the reader reads — issue 0160's class, which has bitten three times. With flat arguments an appended field changes this TYPE, so every sink fails to compile instead of reading stack garbage.

logger_name, message and file are pointer + length and are NOT NUL-terminated. They are valid only for the duration of the call.

timestamp_ns is 0 when no monotonic clock is linked — see rclc_log_timestamp_available().

◆ rclc_logger_t

typedef const void* rclc_logger_t

Opaque handle to a &'static nros_log::Logger. Obtain via rclc_node_get_logger(...). NEVER free.

Enumeration Type Documentation

◆ rcl_log_severity_t

Severity levels, on rcutils's number line. Lower value = more verbose.

phase-417 stage 3 (ledger row c:log_severity_t). rcutils — which rcl_log_severity_t mirrors — numbers UNSET=0, DEBUG=10, INFO=20, WARN=30, ERROR=40, FATAL=50, and these values cross ABIs as plain integers: read from a configuration file, read from the environment, or written by a ported file as an RCUTILS_LOG_SEVERITY_* constant. These were a dense 0..=5 until stage 3, so 0 collided with rcutils's UNSET and a ported UNSET silently selected the most verbose level.

The gaps are load-bearing — they are how a caller writes a threshold BETWEEN two named levels. A value in a gap resolves to the named level at or below it, and a value outside the range resolves rather than being rejected, so any int a C caller can produce here is defined.

RCLC_LOG_SEVERITY_TRACE is ours; rcutils has no trace level. It takes 5, inside rcutils's own UNSET..DEBUG gap, which is what that gap is for.

**UNSET MEANS INHERIT, NOT "THE FLOOR"** (phase-467; it meant the floor until then, and that was ledger row c:log_severity_t's whole debt). rclc_logger_set_level(logger, RCLC_LOG_SEVERITY_UNSET) takes away that logger's own level, after which it filters on its nearest ancestor's level (below), else the PROCESS DEFAULT — rclc_log_get_default_level(), RCLC_LOG_SEVERITY_INFO until rclc_log_set_default_level() moves it, which is the value and the starting point RCUTILS_DEFAULT_LOGGER_DEFAULT_LEVEL has upstream. A logger you never set a level on is already in that state.

ENVELOPE — dotted ancestry resolves through loggers that exist. As upstream, an unset logger takes the level of its nearest dotted ancestor (x.y.z → x.y → x) and only then the process default (RFC-0102 D2). Setting nav's level moves nav.costmap's too, unless nav.costmap has its own. The bound: upstream keys a level by NAME in an allocator-backed map, so an ancestor can carry a level without being a logger; here a level lives in a logger, so an ancestor carries one by EXISTING — and setting a level by name (rclc_log_get_logger("nav") then rclc_logger_set_level) creates it, which is the case that matters. The links are made when a logger is created, in either order, so the log path never parses a name. Names are capped at 48 bytes and the runtime-logger arena is bounded; see rclc_logger_get_child. (RFC-0089: the envelope is part of the API, not a footnote.)

UNSET is only special where a LEVEL IS STORED. Passed as a record's severity (rclc_log_emit) or as a threshold question (rclc_logger_is_enabled) it resolves by band like any other integer, which puts it at TRACE: "no level set" is not a level to emit at, upstream has no answer for that call either, and refusing it would make one of these entry points reject a value the other needs.

Enumerator
RCLC_LOG_SEVERITY_UNSET 
RCLC_LOG_SEVERITY_TRACE 
RCLC_LOG_SEVERITY_DEBUG 
RCLC_LOG_SEVERITY_INFO 
RCLC_LOG_SEVERITY_WARN 
RCLC_LOG_SEVERITY_ERROR 
RCLC_LOG_SEVERITY_FATAL 
RCLC_LOG_SEVERITY_FORCE_INT_WIDTH_ 

Function Documentation

◆ rclc_log_add_sink()

bool rclc_log_add_sink ( rclc_log_sink_fn  sink,
void *  user_data 
)

Install a C callback as a log sink.

Until phase-417 the C surface could not install a sink at all: rclc_log_init takes no arguments and hardcodes the platform default. This APPENDS, so a consumer teeing records to its own transport does not discard whatever the board installed.

Records raised before any sink existed are replayed into the first one installed, so a sink registered at boot still sees the boot story.

Parameters
sinkThe callback. NULL installs nothing and returns false.
user_dataPassed back untouched, never dereferenced here. Must outlive the program: a sink cannot be removed (the read path is lock-free).
Returns
false when sink is NULL or the registry is full. CHECK IT — a sink that was silently not installed is indistinguishable from one that never fires.

◆ rclc_log_default_logger()

rclc_logger_t rclc_log_default_logger ( void  )

Phase 88.16.H — opaque handle to the catch-all nros logger.

Lets C callers emit through NROS_LOG_* without standing up a full rcl_node_t (useful for boot diagnostics, panic hooks, smoke fixtures). The returned handle is 'static. Never free.

Returns
rclc_logger_t for the default ("nros") logger.

◆ rclc_log_emit()

void rclc_log_emit ( rclc_logger_t  logger,
rcl_log_severity_t  severity,
const char *  message,
size_t  message_len 
)

Low-level emit. Renders message (already-formatted UTF-8 text; NOT null-terminated by contract — pass an explicit length) at severity through the dispatcher.

Most users should use the NROS_LOG_* printf-style macros below rather than calling this directly.

Parameters
loggerLogger handle from rclc_node_get_logger. NULL = silently drops (kept total to simplify call sites).
severityOne of rcl_log_severity_t.
messageUTF-8 text; not required to be null-terminated.
message_lenLength of message in bytes.

◆ rclc_log_emit_at()

void void rclc_log_emit_at ( rclc_logger_t  logger,
rcl_log_severity_t  severity,
const char *  message,
size_t  message_len,
const char *  file,
uint32_t  line 
)

phase-417 W4.d — emit WITH the call site.

rclc_log_emit above hardcoded file = "<nros-c>", line = 0 and timestamp_ns = 0 into every record, contradicting this file's own header comment ("attach severity + line info"). Every C and C++ record in the tree therefore reached the sinks stripped of the two fields the sinks render.

Parameters
fileMust have STATIC storage duration — __FILE__. Borrowed for the life of the program, never copied. NULL = unknown.
line__LINE__.

The timestamp is NOT a parameter: it comes from nros_log's own clock, so a C record is stamped by the same clock at the same resolution as a Rust one. See rclc_log_timestamp_available().

◆ rclc_log_emit_fmt()

void rclc_log_emit_fmt ( rclc_logger_t  logger,
rcl_log_severity_t  severity,
const char *  fmt,
  ... 
)

Internal helper used by the macros. Formats fmt + args into a stack buffer, then calls rclc_log_emit. Buffer size = 256 bytes; overflow is truncated + appended ....

◆ rclc_log_emit_fmt_at()

void rclc_log_emit_fmt_at ( rclc_logger_t  logger,
rcl_log_severity_t  severity,
const char *  file,
uint32_t  line,
const char *  fmt,
  ... 
)

phase-417 W4.d — printf-style emit carrying __FILE__ / __LINE__.

Defined beside rclc_log_emit_fmt in c-stubs/log_fmt.c (the variadic entry point cannot be written in Rust: c_variadic is unstable), and rendered there into a NROS_LOG_FMT_BUFFER_SIZE stack buffer. It was a static inline here until phase-492, which made this header include <stdio.h> for vsnprintf; the C API's public headers are freestanding now, so formatting happens in the library, where a libc is linked anyway.

◆ rclc_log_get_default_level()

rcl_log_severity_t rclc_log_get_default_level ( void  )

The threshold every logger without a level of its own filters on.

RCLC_LOG_SEVERITY_INFO until rclc_log_set_default_level moves it.

◆ rclc_log_get_logger()

rclc_logger_t rclc_log_get_logger ( const char *  name)

Look up a logger by name, CREATING one if the name is new.

rclcpp::get_logger("x")'s shape. Until phase-417 the C surface had only rclc_log_default_logger(), so every C node in an image shared one logger and therefore one threshold.

Total — always returns a usable handle, 'static, never freed. A NULL or empty name, a name longer than 48 bytes, or an exhausted logger arena answers the CATCH-ALL logger and says so at WARN through that logger. Check the log before calling rclc_logger_set_level on a handle you did not verify: the catch-all's threshold is shared with every other unnamed logger.

Arena size is the NROS_LOG_DYNAMIC_LOGGERS knob (default 16; Linux host boards 32).

Parameters
nameNUL-terminated UTF-8. Copied; need not outlive the call.

◆ rclc_log_init()

void rclc_log_init ( void  )

Phase 88.16.H — explicit installation of the default sink list.

Cross-language no_std builds (FreeRTOS / NuttX / ThreadX C and C++ examples) must call this once after the board crate's platform-log writer is registered (typically right after rclc_node_init_default returns). Pins nros_log::init as a linker root so --gc-sections keeps it; without this, the lazy guard inside rclc_log_emit can be unreachable and every record silently drops.

Idempotent. Hosted POSIX consumers can skip this — the .init_array ctors already wire the dispatcher.

◆ rclc_log_set_default_level()

void rclc_log_set_default_level ( rcl_log_severity_t  severity)

Move the threshold that every logger WITHOUT a level of its own filters on.

phase-467. Retroactive: a logger interned long before this call follows it, because "no level of its own" is a stored state and not a value copied in at construction. A logger that states its own level is NOT overridden.

RCLC_LOG_SEVERITY_UNSET here restores RCLC_LOG_SEVERITY_INFO, which is rcutils_logging_set_default_logger_level's documented behaviour for the same argument. Every other value resolves by band, as everywhere else on this surface.

Not rclc_logger_set_level(rclc_log_default_logger(), ...): that moves the threshold of the one logger NAMED "nros", which is a different logger from "every logger that has not been given a level".

◆ rclc_log_throttle_admit()

bool rclc_log_throttle_admit ( uint64_t *  last_ns,
uint64_t  interval_ms 
)

Decide whether a throttled call site may emit now, and arm its window.

The NROS_LOG_*_THROTTLE macros call this; a hand-written call site can too.

Parameters
last_nsCaller-owned storage — a function-scope static uint64_t x = 0;, one per call site. Caller-owned rather than a handle into a pool because a pool needs a bound, and a throttled call site is not a resource anyone should have to budget. OPAQUE: 0 means "never emitted" and every other value is written by this function — read it as a timestamp and you will read it wrong (bit 0 is a flag; the timestamp sits above it, mod 2^63).
interval_msMinimum gap between emitted records at this site.
Returns
true when the record should be emitted. The FIRST record at a site always is (as in rclcpp). NULL last_ns returns true: a broken caller gets every record, never silence.

The rule itself is nros_log::throttle_decide — the same function the Rust nros_*_throttle! macros use. Only the storage differs. A clock that wraps still measures real elapsed time across the wrap; a clock that is STUCK (at any value, 0 included) admits once and then never (issue 1152).

Without a monotonic clock every timestamp is 0, the window can never elapse, and each site emits its first record and nothing after it; the first such call reports that at WARN rather than degrading quietly.

◆ rclc_log_timestamp_available()

bool rclc_log_timestamp_available ( void  )

Whether records carry a real timestamp_ns rather than a constant 0.

False means nros-log was built without the platform clock — neither the platform's [capabilities] clock nor its platform-clock feature (issue 1037) — so nothing derived from the timestamp — the throttle windows above all — has a time base. See rclc_log_throttle_admit.

◆ rclc_logger_get_child()

rclc_logger_t rclc_logger_get_child ( rclc_logger_t  logger,
const char *  suffix 
)

A logger that is a descendant of logger — rclcpp::Logger::get_child's C half (RFC-0102). Named <parent>.<suffix>; the catch-all's (rclc_log_default_logger()) children are top-level names (suffix).

A child with no level of its own filters at its nearest ancestor's, so rclc_logger_set_level(parent, RCLC_LOG_SEVERITY_DEBUG) reaches it. The same name answers the same handle, 'static, never freed.

Returns
the child, or NULL — warned once per process — when the full name is over 48 bytes or empty, or the runtime-logger arena is full. NULL, not the parent: the substitute is the caller's choice, and handing back the parent would make rclc_logger_set_level(child, ..) move the parent's threshold. rclcpp::Logger::get_child emits through the parent and refuses set_level in that case.
Parameters
suffixNUL-terminated UTF-8. Copied; need not outlive the call.

◆ rclc_logger_get_level()

rcl_log_severity_t rclc_logger_get_level ( rclc_logger_t  logger)

logger's EFFECTIVE runtime severity threshold — its own level if it has one, the process default if it does not.

rcutils_logging_get_logger_effective_level's answer rather than rcutils_logging_get_logger_level's: this is the number that decides whether a record is emitted, so it is never RCLC_LOG_SEVERITY_UNSET.

A NULL handle answers RCLC_LOG_SEVERITY_FATAL — the quiet end — so a dropped handle cannot read as "trace everything".

◆ rclc_logger_get_name()

size_t rclc_logger_get_name ( rclc_logger_t  logger,
char *  buf,
size_t  buf_len 
)

Copy logger's name into buf as a NUL-terminated string.

Returns
The name length in bytes EXCLUDING the NUL, whether or not it fit — snprintf's convention, so one call can size a buffer. 0 for a NULL logger. Writes nothing when buf is NULL or buf_len is 0.

A copy rather than a borrowed pointer because the Rust side holds a length-delimited &str: its pointer is not NUL-terminated, and handing it out would hand out a string every C function reads past the end of.

◆ rclc_logger_is_enabled()

bool rclc_logger_is_enabled ( rclc_logger_t  logger,
rcl_log_severity_t  severity 
)

Whether a record at severity would pass logger's threshold.

The NROS_LOG_*_THROTTLE macros call this so the severity test runs BEFORE the throttle window: a record the level filters must not consume the window. NULL handle answers false.

◆ rclc_logger_set_level()

bool rclc_logger_set_level ( rclc_logger_t  logger,
rcl_log_severity_t  severity 
)

Set logger's runtime severity threshold. Records below it are dropped before any sink sees them.

RCLC_LOG_SEVERITY_UNSET takes the level away again rather than setting one: the logger goes back to filtering on rclc_log_get_default_level(). See the rcl_log_severity_t comment for what that inheritance is and is not.

Returns
false for a NULL handle, true otherwise.