You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
use embedded_logger::prelude::*;use embedded_logger::sink::console::{ConsoleSink,ConsoleStream};use embedded_logger::logger::{LoggerBuilder, init_global};fnmain(){// 1. Build the loggerlet logger = LoggerBuilder::new().sink(Box::new(ConsoleSink::new(ConsoleStream::Stderr))).filter_spec("info,myapp::nav=debug").build();// 2. Install as globalinit_global(logger).expect("logger already initialized");// 3. Define per-module context (DLT-style)constCTX:LogContext = LogContext::new("ECU1","NAVI","ROUT");// 4. Log!elog_info!(CTX,"Navigation module initialized");elog_debug!(CTX,"Using map version {}","2025.Q4");elog_warn!(CTX,"GPS signal degraded: accuracy={}m",15);elog_error!(CTX,"Route calculation failed: {}","no path found");}
With File Rotation
use embedded_logger::sink::file::{FileSink,FileSinkConfig};use std::path::PathBuf;let file_config = FileSinkConfig{path:PathBuf::from("/var/log/myapp/application.log"),max_file_size:50*1024*1024,// 50 MiBmax_backups:10,buffer_size:64*1024,fsync_interval:100,// fsync every 100 records};let file_sink = FileSink::new(file_config).expect("failed to open log file");let logger = LoggerBuilder::new().sink(Box::new(ConsoleSink::new(ConsoleStream::Split))).sink(Box::new(file_sink)).filter_spec("info").build();
With Syslog
use embedded_logger::sink::syslog::{SyslogSink,SyslogFacility};let syslog = SyslogSink::new("myapp",SyslogFacility::Daemon).expect("failed to open syslog");let logger = LoggerBuilder::new().sink(Box::new(syslog)).level(LogLevel::Warn).build();
use embedded_logger::logger::global;// Change global level at runtime (e.g., from a diagnostic command)global().filter().set_default_level(LogLevel::Debug);// Enable verbose logging for a specific moduleglobal().filter().set_module_level("myapp::perception",LogLevel::Verbose);
Context Identifiers (DLT)
Following the AUTOSAR DLT standard, each log message carries three 4-character identifiers:
Field
Description
Example
ecu_id
Electronic Control Unit
"HPC1"
app_id
Application / Process
"NAVI"
ctx_id
Context / Module
"ROUT"
// Full contextconstCTX:LogContext = LogContext::new("HPC1","NAVI","ROUT");// Minimal (no ECU, auto-detected)constCTX2:LogContext = LogContext::app("SENS","CAM0");
Feature Flags
Flag
Default
Description
std
yes
Standard library support
console-sink
yes
Console (stdout/stderr) sink
file-sink
yes
File sink with rotation
syslog-sink
yes
POSIX syslog sink
async-logging
yes
Background drain thread (disable for synchronous mode)
dlt-format
no
AUTOSAR DLT binary formatter
json-format
no
NDJSON structured output
no-color
no
Disable ANSI color codes
Overflow Policies
Policy
Behavior
Use When
DropNewest
Discard the message being pushed
Default; zero blocking, no data corruption
DropOldest
Overwrite oldest unread message
Prefer latest data (sensor streams)
Block
Spin-wait for space
Message loss is unacceptable (safety logs)
Performance
Measured on ARM Cortex-A76 (automotive SoC), release build:
Operation
Latency
elog_info!() (filtered out)
~5 ns
elog_info!() (push to ring)
~150 ns
Full pipeline (push + drain + file write)
~2 μs
Platform Support
Platform
Status
Linux (x86_64, aarch64)
Fully supported
QNX 7.1+ (aarch64)
Fully supported (POSIX)
QNX 8.0 (aarch64)
Fully supported (POSIX)
Graceful Shutdown
Always shut down the logger before process exit to avoid losing buffered messages:
use embedded_logger::logger::global;// Option 1: Explicit flush (if you don't own the logger)global().flush();// Option 2: Full shutdown (if you own the Logger instance)// logger.shutdown();