Mastering log.c: A Lightweight C99 Logging Library for Embedded Systems

This article introduces log.c, a compact C99 logging library suitable for any platform—including embedded systems—covers its key features, demonstrates usage with code examples, and explains how to configure log levels, file output, callbacks, multithreading, and colored output.

Open Source Linux
Open Source Linux
Open Source Linux
Mastering log.c: A Lightweight C99 Logging Library for Embedded Systems

log.c Introduction

GitHub link: https://github.com/rxi/log.c (MIT license)

log.c is a lightweight logging library written in C99, meaning it can be compiled and run on any platform that supports the C99 standard, such as embedded systems.

Features

Uses the C99 standard, suitable for embedded environments.

Supports silent mode.

Allows setting log levels.

Provides ANSI color codes.

Thread‑safe design with configurable lock mechanism.

Usage Example

Add log.c and log.h to your project. log.c defines six macros for different log levels:

#include "log.h"
int main(void) {
    // Trace log
    log_trace("Trace message: %d", 42);

    // Debug log
    log_debug("Debug message: %s", "This is a debug message");

    // Info log
    log_info("Info message: %s", "This is an info message");

    // Warn log
    log_warn("Warn message: %s", "This is a warning message");

    // Error log
    log_error("Error message: %s", "This is an error message");

    // Fatal log
    log_fatal("Fatal message: %s", "This is a fatal message");
    return 0;
}

Each macro accepts a printf -style format string and additional arguments; the formatted message is written to stderr.

Setting Log Level

Use log_set_level to define the minimum level that will be output to stderr:

log_set_level(LOG_ERROR); // only error and fatal logs are printed

Output to File

Call log_add_fp to direct logs to a file:

#include "log.h"
int main(void) {
    FILE* file = fopen("log.txt", "w");
    if (file != NULL) {
        log_add_fp(file, LOG_INFO); // log INFO and above to file
    }
    log_trace("Trace message: %d", 42);
    log_debug("Debug message: %s", "This is a debug message");
    log_info("Info message: %s", "This is an info message");
    log_warn("Warn message: %s", "This is a warning message");
    log_error("Error message: %s", "This is an error message");
    log_fatal("Fatal message: %s", "This is a fatal message");
    return 0;
}

Using a Callback Function

Register a callback with log_add_callback to customize log formatting, for example to prepend timestamps:

#include "log.h"
static const char *s_level_strings[] = {"TRACE","DEBUG","INFO","WARN","ERROR","FATAL"};
static void my_log_callback(log_Event *ev) {
    char buf[64];
    buf[strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", ev->time)] = '\0';
    fprintf(ev->udata, "%s %-5s %s:%d: ", buf, s_level_strings[ev->level], ev->file, ev->line);
    vfprintf(ev->udata, ev->fmt, ev->ap);
    fprintf(ev->udata, "
");
    fflush(ev->udata);
}
int main(void) {
    log_add_callback(my_log_callback, stderr, LOG_FATAL);
    log_trace("Trace message: %d", 42);
    log_debug("Debug message: %s", "This is a debug message");
    log_info("Info message: %s", "This is an info message");
    log_warn("Warn message: %s", "This is a warning message");
    log_error("Error message: %s", "This is an error message");
    log_fatal("Fatal message: %s", "This is a fatal message");
    return 0;
}

Multithreaded Use

In a multithreaded environment, set a lock function with log_set_lock:

void lock_function(bool lock, void *udata) {
    if (lock) {
        // acquire lock
    } else {
        // release lock
    }
}
log_set_lock(lock_function, NULL);

Using Colors

Define LOG_USE_COLOR at compile time to enable ANSI color output:

gcc log.c test.c -DLOG_USE_COLOR
CembeddedC99
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.