SkillAgentSearch skills...

Microlog

A lightweight, universal logging library in C. Just two files. Compatible with C++, embedded projects, and most major compilers. Covered by unit tests.

Install / Use

/learn @an-dr/Microlog
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

microlog - Extensible and configurable logging library for embedded and desktop applications

License: MIT Latest Tests

main_pic

  • Easy to use - simple API, works out of the box
  • Advanced filtering and log levels per topic or output
  • Thread-safety via external locking injection
  • Customization - only data you need
  • Extensible - add your own features via public API, set of predefined extensions
  • Support for embedded systems static allocation, small size
  • Easy to install two files for copy-paste and support for many build systems
  • For everyone - C and C++ support, works with any compiler, any platform, commercial or open-source use

In the default configuration it looks like this:

|<img src="doc/README/demo0.png" width="800">| |-| |Picture 1 - default configuration: no time, long default levels, source location, no topics, no colors|

...but in can be very minimalistic :

|<img src="doc/README/demo1.png" width="800">| |-| |Picture 2 - short levels, no colors, no time, no source location|

... or feature-rich:

|<img src="doc/README/demo2.png" width="800"> | |-| |Picture 3 - time, custom prefix for MsgID, custom syslog levels, topics, source location, colors|

The project is based on the following core principles:

  • Universal for embedded and desktop applications
  • No feature - no code for compilation
  • Shallow learning curve, works out of box
  • No dependencies
  • Two files for core functionality.
  • Extensions as recipes for your own features.

Table of Contents

Quick Start

1. Install

Option 1 - Sources:

  • Download a Source Package from Releases
  • Add sources to your system manually

Option 2 - CMake Package (recommended CMake > 3.15.0):

  • Download a CMake Package from Releases
  • Specify the install location:
    • Specify package storage cmake -B./build -DCMAKE_PREFIX_PATH="~/MyCmakePackages" or
    • Set microlog_DIR variable with path to the package microlog_DIR=~/microlog-1.2.3-cmake
  • Use in your project:
find_package(microlog 1.2.3 REQUIRED)

add_executable(example_package example.cpp)
target_link_libraries(example_package PRIVATE microlog::microlog)

target_compile_definitions(microlog PRIVATE ULOG_BUILD_COLOR=1) # configuration

# Or use a user-defined configuration header `ulog_config.h`:
# target_compile_definitions(microlog PRIVATE ULOG_BUILD_CONFIG_HEADER_ENABLED=1)
# target_include_directories(microlog PRIVATE path/to/directory/containing/ulog_config.h)

Option 3 - Meson Package:

  • Download a Meson Package from Releases
  • Copy the content to MyMesonProject/subprojects
  • Add to your dependencies:
add_global_arguments('-DULOG_BUILD_COLOR=1', language: ['cpp', 'c']) # configuration

# Or use a user-defined configuration header `ulog_config.h`:
# add_global_arguments('-DULOG_BUILD_CONFIG_HEADER_ENABLED=1', language: ['cpp', 'c'])
# And add include directory where ulog_config.h is located:
# add_global_arguments('-Ipath/to/directory/containing/ulog_config.h', language: ['cpp', 'c'])

exe = executable(
    meson.project_name(),
    src,
    include_directories: include,
    dependencies: dependency('microlog'),
)

Option 4 - Meson Wrap File:

  • Download the wrap file from Releases
  • Place microlog.wrap in your MyMesonProject/subprojects/ directory
  • Add to your dependencies as in Option 3

Option 5 - CPM:

  • Download CPM (https://github.com/cpm-cmake/CPM.cmake)
  • Add microlog to your projects CMAKE file:
include(cpm/CPM.cmake)
CPMAddPackage("gh:an-dr/microlog@6.4.5")

target_link_libraries(${PROJECT_NAME} PUBLIC microlog::microlog)
target_compile_definitions( microlog PRIVATE ULOG_BUILD_COLOR=1) # configuration
    
# Or use a user-defined configuration header `ulog_config.h`:
# target_compile_definitions(microlog PRIVATE ULOG_BUILD_CONFIG_HEADER_ENABLED=1)
# target_include_directories(microlog PRIVATE path/to/directory/containing/ulog_config.h)

2. Use

#include "ulog.h"

int main() {
    ulog_info("Hello, World");
    return 0;
}

Output:

INFO  src/main.cpp:4: Hello, World

3. Extend

Add missing functionalities via API or use predefined extensions. See Extensions documentation.

Advanced Usage

User Manual in doc/features.md - detailed information about the available features.

Extensions - Optional add-ons that use only the public API to enhance functionality.

See the example for more features in action: example/main.cpp.

Contributing

Contributions are welcome! Please read the CONTRIBUTING.md for details, I tried to keep it simple.

Comparison with log.c

microlog started as a fork of rxi/log.c (~150 lines, 3.3k stars) but evolved into a fundamentally different architecture (~2,500 lines) optimized for embedded systems and advanced filtering. Thanks to compile-time feature stripping, unused features are excluded from the build—so a minimal microlog configuration can match log.c’s footprint in both size and performance.

Core Differences

rxi/log.c: Minimalist and ready to use. Fixed footprint, 6 levels, simple callbacks. microlog: Compile-time feature selection. Configurable footprint, 8 renameable levels, multi-dimensional filtering.

| Feature | log.c | microlog | | ------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------ | | Philosophy | Simple-to-use, Minimalist for average use | Simple-to-use, extensible and configurable for diverse needs | | Configuration | Color, verbosity | ✅ Compile-time feature selection + optional runtime | | Runtime Configuration | Only verbosity | ✅ Verbosity, color, time, prefix, source location, topics (Disablable feature) | | Zero-Overhead Disable | Arguments still evaluated | ✅ True no-op with ULOG_BUILD_DISABLED | | Log Levels | 6 fixed | 8, runtime renameable (e.g., syslog) | | Filtering | Global + per-callback | Per-output + per-topic + global | | Topics/Subsystems | Manual prefixes | ✅ Full support with filtering per topic and routing | | Output Routing | All outputs get all logs | ✅ Route topics to specific or all outputs | | Memory | Static | ✅ Static or dynamic (user choice) | | Build Systems | Manual integration | ✅ CMake, Meson, CPM packages | | Platform Helpers | DIY | ✅ FreeRTOS, Zephyr, ThreadX, pthread, Win32 |

TL;DR:

  • When to choose log.c:
    • Small projects needing basic logging with minimal setup.
  • When to choose microlog:
    • Same scenarios, as default setup is just as simple.
    • Plus: embedded systems, multi-subsystem applications, or projects requiring fine-grained control and advanced filtering.

Key Capabilities Unique to microlog

1. Multi-Dimensional Filtering - Per-output AND per-topic levels:

ulog_topic_add("Credentials", secure_file_only, ULOG_LEVEL_TRACE);
ulog_topic_add("Network", ULOG_OUTPUT_ALL, ULOG_LEVEL_DEBUG);
ulog_output_level_set(ULOG_OUTPUT_STDOUT, ULOG_LEVEL_ERROR); // Console: errors only

2. True Zero-Overhead Disable - Arguments not evaluated:

ulog_info("Result: %d", expensive()); // With ULOG_BUILD_DISABLED=1 → ((void)0)

3. Custom Log Levels - Redefine all 8 at runtime:

ulog_level_descriptor syslog = {ULOG_LEVEL_7,
    {"DEBUG", "INFO", "NOTICE", "WARN", "ERR", "CRIT", "ALERT", "EMERG"}};
ulog_level_set_new_levels(&syslog);

4. Fine-Grained Code Control - 12+ build flags to strip features:

-DULOG_BUILD_SOURCE_LOCATION=0  // Remove file:line
-DULOG_BUILD_TIME=0              // Remove timestamps
-DULOG_BUILD_COLOR=0             // Remove ANSI codes
...
View on GitHub
GitHub Stars164
CategoryDevelopment
Updated5d ago
Forks18

Languages

C

Security Score

100/100

Audited on Mar 27, 2026

No findings