libbclog 0.2.1

A betterC structured logger


To use this package, run the following command in your project's root directory:

Manual usage
Put the following dependency into your project's dependences section:

Overview

This is an extremely fast, allocationless, thread-safe*, betterC, structured logging library that supports custom log sinks.

(* Currently only on Posix since I need to setup a dev env for Windows. Also maybe not even on Posix since I haven't properly tested it yet.)

Features

  • Thread-Safe (see disclaimer)
  • Allocationless (except for whatever libc does internally)
  • Easy to use
  • Written with -betterC in mind
  • Supports custom logging sinks
  • Provides a Console sink
  • Provides a File sink
  • Provides a Filter sink to wrap around other sinks
  • Structured (built-in sinks output as JSON)
  • Helper function to output JSON into an output sink

Quick Start

Add this library via dub/meson/your preferred method.

import libbc.log;

struct Client
{
    string ip;
    ushort port;
}

void main()
{
    // Logger is not copyable, so make it global/put it on the heap.
    Logger!(
        IsShared.no, // Or .yes for a thread-safe logger.
        Sink!("file", FileSink),
        Sink!("console", ConsoleSink)
    ) logger;
    logger.file.open("log.log"); // File loggers have to be opened first.

    logger.trace("This is a trace");
    logger.debug_("Debug This Bug!");

    logger.info("This one has fields!", field!"service"("login"), field!"client"(Client("1.1.1.1", 420)));

    logger.warning("404 Life not found");
    logger.error("Not enough cheese");
    logger.fatal("Dog went 5 seconds without attention");
}

Produces:

{"level": "trace", "message": "This is a trace", "file": "source/libbc/log/core.d", "func": "libbc.log.core.__unittest_L237_C1", "line": 255, "timestamp": 1636142080}
{"level": "debug_", "message": "Debug This Bug!", "file": "source/libbc/log/core.d", "func": "libbc.log.core.__unittest_L237_C1", "line": 256, "timestamp": 1636142080}
{"level": "info", "message": "This one has fields!", "file": "source/libbc/log/core.d", "func": "libbc.log.core.__unittest_L237_C1", "line": 258, "timestamp": 1636142080, "service": "login", "client": {"ip": "1.1.1.1", "port": 420}}
{"level": "warning", "message": "404 Life not found", "file": "source/libbc/log/core.d", "func": "libbc.log.core.__unittest_L237_C1", "line": 260, "timestamp": 1636142080}
{"level": "error", "message": "Not enough cheese", "file": "source/libbc/log/core.d", "func": "libbc.log.core.__unittest_L237_C1", "line": 261, "timestamp": 1636142080}
{"level": "fatal", "message": "Dog went 5 seconds without attention", "file": "source/libbc/log/core.d", "func": "libbc.log.core.__unittest_L237_C1", "line": 262, "timestamp": 1636142080}

Filtering by log level

Simply wrap any sinks inside of FilterByLogLevelSink:

void main()
{
    Logger!(
        IsShared.no,
        Sink!("console", FilterByLogLevelSink!ConsoleSink)
    ) logger;

    logger.console.minLogLevel = LogLevel.debug_;
    logger.console.maxLogLevel = LogLevel.warning;
    // Use logger.console.sink to access the underlying sink if needed.

    logger.trace("This won't show up");
    logger.fatal("Neither will this");
    logger.info("But this will");
}

Performance

As is custom with benchmarks, take everything with a grain of salt.

There are currently two tests:

  • hello_world - A simple log.info("hello world")
  • 6_fields - Prints out 6 fields, all being different types for JSON serialisation

Across three sinks:

  • console - Uses printf
  • null - Performs serialisation, but doesn't output it anywhere
  • file - Outputs to a file

Result set 1 - Intel(R) Celeron(R) CPU N3350 @ 1.10GHz

Units: ns = nano seconds and us = micro seconds.

test+sinkiterationsns/opus/opns/totalus/totalsecs/total
console hello_world1000004189741418977437841424584.189774378
null hello_world1000002830283967925790.028396792
file hello_world100000248222482764512974870.248276451
console 6_fields1000009001289900127320889628599.001273208
null 6_fields10000057305736736441490.057367364
file 6_fields100000904189041639878640920.904163987

TODO

[ ] Make Windows thread-safe

[ ] Add more sinks

[ ] Add threading tests

[ ] Add a log rotater sink

[ ] ???

[x] profit

Authors:
  • Bradley Chatha
Dependencies:
libbcfmt, libbcds
Versions:
0.2.1 2021-Nov-08
0.2.0 2021-Nov-06
0.1.0 2021-Nov-05
~master 2021-Nov-08
Show all 4 versions
Download Stats:
  • 0 downloads today

  • 0 downloads this week

  • 2 downloads this month

  • 2 downloads total

Score:
0.5
Short URL:
libbclog.dub.pm