Library / SDK
SergiusTheBest/plog avatar
SergiusTheBest/plog

plog: a header-only C++ logging library that fits in about 1000 lines

Portable, simple and extensible C++ logging library

2,595 stars405 forksC++MIT

At a glance

What is it?
plog is a portable, header-only C++ logging library with no third-party dependencies, appenders for rolling files, console and EventLog, and TXT, CSV and message-only formatters. It is a reasonable fit for small binaries and embedded targets, and a poor fit if you need asynchronous logging or a large ecosystem.
Who is it for?
Adopt plog when you want a logging library you can drop into an existing include path without adding a build step, and when formats like CSV or targets like RTEMS and FreeRTOS matter. Do not adopt it if you need asynchronous logging, a plugin ecosystem or a project with a documented deprecation policy; the README does not describe any of those.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 55 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem plog solves: logging without a build step

Most C++ logging libraries ask you to build and link something. plog does not. It is header-only, has no third-party dependencies, and the README describes it as "slightly more than 1000 LOC". That combination is the whole pitch: you add an include path and start writing PLOGD << "..." in the same commit.

The audience is narrower than "all C++ projects". plog targets people who care about binary size, build simplicity and platform reach. The README lists Windows, Linux, FreeBSD, macOS, Android, RTEMS and FreeRTOS, with gcc, clang, msvc, mingw, mingw-w64, icc and c++builder. It also states that C++11 is not required, which matters if you are stuck on an older standard for toolchain reasons. If your project already depends on a larger framework that brings its own logging, plog is redundant.

How plog is put together: logger, record, formatter, converter, appender

The README documents a pipeline rather than a single class. A Logger owns a severity threshold and a list of appenders. A log macro builds a Record, which carries the severity, the message stream and metadata such as the thread id and the source location. The Record is handed to a Formatter, which produces the text line. A Converter can transform that text afterwards, for example UTF8Converter or NativeEOLConverter. The Appender finally writes it somewhere: RollingFileAppender, ConsoleAppender, ColorConsoleAppender, AndroidAppender, EventLogAppender, DebugOutputAppender or DynamicAppender.

Two details are worth knowing before you design around it. First, the README describes lazy stream evaluation, so the argument to a log macro is not formatted when the severity is below the threshold. Second, appenders can be combined: the README has a section on multiple appenders and another on multiple loggers, plus chained loggers and sharing log instances across modules (exe, dll, so, dylib). The default output format includes a timestamp, severity, thread id and a source tag such as [main@13], as the hello log sample shows.

Installing plog and writing your first log line

There is nothing to install in the package-manager sense for the copy-the-source route. The README's integration section describes copying the plog directory into your tree and adding its include directory to your search path. The repository also documents Git submodule, CMake add_subdirectory and FetchContent, and a package managers section, though the README excerpt here does not spell out the package names.

Once the headers are on the include path, the README's hello log sample is three steps: include Log.h and the rolling file initializer, call plog::init with a severity and a filename, then use a macro.

cpp
#include <plog/Log.h>
#include "plog/Initializers/RollingFileInitializer.h"

int main()
{
    plog::init(plog::debug, "Hello.txt");
    PLOGD << "Hello log!";
    return 0;
}

Running that produces lines in Hello.txt in the format the README shows: a timestamp, the severity, the thread id in brackets, and the function and line such as [main@13]. The equivalent CMake route the README documents is add_subdirectory or FetchContent; either way the target is consumed as a header-only interface, not a compiled library.

If you prefer to choose the appender yourself rather than let an initializer pick one, the README has a manual initialization path through Init.h. That is where you would attach a ConsoleAppender or a ColorConsoleAppender instead of a rolling file.

Where plog is the wrong tool

plog's design is synchronous by default. The README describes appenders and formatters, and the appender list contains no asynchronous or background-thread appender. If your logging volume is high enough that the write call is on a latency-critical path, plog gives you no built-in queue to move that work off the calling thread. You would have to write a custom appender, which the README does document as an extension point, but that is your code and your correctness problem.

The second limit is macro surface. The README has a dedicated section on LOG_XXX macro name clashes and notes that the LOGD, LOG_DEBUG and LOG(plog::debug) forms "may clash with other logging libraries". In a codebase that already uses LOG_DEBUG from somewhere else, the PLOG-prefixed macros are the safe ones. That is a real constraint on a shared header set, not a stylistic preference.

The third is the severity model. Severities are a fixed ordered scale, and the README documents changing severity at runtime and a logger severity checker. There is no documented support for structured fields, sampling or per-category thresholds beyond what multiple loggers give you. If your requirement is queryable structured events rather than text lines, plog is the wrong shape.

plog compared with spdlog

spdlog is the obvious alternative, and the difference is architectural rather than cosmetic. spdlog is built around asynchronous logging with a thread pool and a queue, and it is distributed as a library you compile or consume through a package manager. plog is header-only, has no third-party dependencies, and its documented appender set is synchronous.

That difference has consequences in both directions. If you need to keep the caller off the I/O path under load, spdlog's async sinks are the reason to pick it. If you need to add logging to a FreeRTOS or RTEMS target, or to a project where adding a compiled dependency is a review argument you do not want to have, plog's header-only model removes that argument entirely. The README lists RTEMS and FreeRTOS explicitly; spdlog's documented platform list is not covered here, so treat that as a question to check on the spdlog side rather than a settled point.

One thing plog offers that is unusual: a CSV formatter. The README lists CsvFormatter and CsvFormatterUtcTime, and describes CSV log format as one of the features that motivated the library. If your logs are consumed by a spreadsheet or a columnar pipeline, that is a concrete reason to choose plog over a text-only logger.

Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-08-07. The most recent release listed is 1.1.11 from 2025-08-10, after 1.1.10 in 2023 and 1.1.9 in 2022. The gap between 1.1.10 and 1.1.11 is roughly two years, so the release cadence is not fast. There is a SECURITY.md in the repository root, and CI is configured for GitHub Actions, AppVeyor and CircleCI.

Upgrade cost is low by construction. Because plog is header-only, upgrading means replacing the plog directory or moving the submodule or FetchContent reference. There is no ABI to preserve, since nothing is linked. The risk is source compatibility: if you use the short LOGD-style macros, a header change in a dependency can collide with them, which is exactly why the README documents the name-clash section. Pin a tag rather than tracking master if you want reproducible builds.

The licence is MIT, which the repository states in its LICENSE file and the README's licence section. MIT permits use in closed-source products provided the copyright notice and permission notice are retained. That is the general shape of the licence; whether it satisfies your organisation's policy is a question for your own review, not something to infer from this description.

Editorial conclusion

Adopt plog when you want a logging library you can drop into an existing include path without adding a build step, and when formats like CSV or targets like RTEMS and FreeRTOS matter. Do not adopt it if you need asynchronous logging, a plugin ecosystem or a project with a documented deprecation policy; the README does not describe any of those. Before committing, verify two things yourself: that your toolchain accepts the headers (the README lists gcc, clang, msvc, mingw, mingw-w64, icc and c++builder), and that the default severity threshold and appender set match what your binary needs, since plog::init sets both at once.

Frequently asked questions

Does plog require C++11?

No. The README lists "Doesn't require C++11" among the features, so it can be used in projects pinned to an older standard.

How do I add plog to a CMake project?

The README's integration section documents add_subdirectory and FetchContent as the two CMake routes. It also documents copying the plog directory into your tree and adding its include directory to the search path.

Does plog write logs asynchronously?

The documented appenders are synchronous; the README lists RollingFile, Console, ColorConsole, Android, EventLog, DebugOutput and DynamicAppender, with no asynchronous appender among them. Moving writes off the calling thread would require a custom appender.

What licence does plog use?

MIT. The repository includes a LICENSE file and the README has a licence section.

Can plog output CSV instead of plain text?

Yes. The README lists CsvFormatter and CsvFormatterUtcTime, and names CSV log format as one of the features that distinguishes the library.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. SergiusTheBest/plog on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sergiusthebest-plog.svg)](https://hysenlabs.com/projects/sergiusthebest-plog)