# g3log flushes what it has before the process dies

> g3log is an asynchronous C++ logger with three headline features, an intuitive LOG API, design by contract CHECK macros, and fatal crash handling that flushes pending log activity before letting the process die. It is written in plain C++14 with no external dependencies other than the test framework, and it is released into the public domain.

**KjellKod/g3log** — G3log is  an asynchronous, "crash safe", logger that is easy to use with default logging sinks or you can add your own.  G3log is made with plain C++14 (C++11 support up to release 1.3.2)  with no external libraries (except gtest used for unit tests). G3log is made to be cross-platform, currently running on OSX, Windows and several Linux distros.  See Readme below for details of usage.

- Repository: https://github.com/KjellKod/g3log
- Website: http://github.com/KjellKod/g3log
- Stars: 966 · Forks: 280
- Language: C++
- License: Unlicense
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/kjellkod-g3log

## Three features, and one header

The README lists the three main features, and they are a coherent set rather than a feature list. There is the intuitive LOG API, which is the thing every logging library claims and few deliver. There is design by contract CHECK functionality. And there is fatal crash handling for a graceful shutdown of the logged process without losing any log details up to the point of the crash. The API is reached through a single include, and the point of the design is to avoid deep dependency injection complexity:

```cpp
#include <g3log/g3log.hpp>
```

The project is written in plain C++14, with C++11 support up to release 1.3.2, and it has no external libraries other than the test framework used for the unit tests. It is meant to be cross-platform, currently running on macOS, Windows and several Linux distributions, and the code is plain C++ rather than C++ with a logging framework inside it, which is what keeps the dependency count at zero.

## Two call syntaxes, and a conditional form

Both the streaming syntax and the printf style are available, which is the first of the ergonomic decisions. The streaming form uses LOG and the print_f form uses LOGF:

```cpp
LOGF(INFO, "Hi log %d", 123);
LOG(INF) << "Hi log " << 123;
```

The point of having both is that the printf form is the right choice in a hot path where the arguments should not be evaluated when the level is disabled, while the streaming form is the readable one everywhere else. Conditional logging comes in the same pair, with the condition evaluated before the message is built:

```cpp
LOG_IF(INFO, (1 < 2)) << "If true this message will be logged";
LOGF_IF(INFO, (1 < 2), "If true, then this %s will be logged", "message");
```

The design by contract side is the same idea in a different register, and it is worth understanding that the two CHECK forms differ in severity rather than in kind. A plain CHECK is not fatal, and CHECK_F is the fatal variant, so a failed CHECK_F triggers a fatal message.

## What happens on a fatal event

This is the part of the library that justifies the asynchronous design, and the README is precise about the ordering. By default g3log captures fatal events such as LOG(FATAL) and CHECK(false), and otherwise fatal signals including SIGABRT, SIGFPE, SIGILL, SIGSEGV and SIGTERM. When a fatal event happens, the not yet written log activity is flushed to the logging sinks. Only when all logging activity up to the point of the fatal event has happened does g3log allow the fatal event to proceed and exit the process. The ordering is the guarantee, and it is what an asynchronous logger normally cannot offer, since a background writer thread will usually lose the last entries to a crash. If object symbols are available the fatal handler will attempt to push the stack trace up to the fatal reason to the logging sink, and the fatal handling can be overridden or extended with your own hooks through the API documentation.

## Levels, filtering and where the sinks live

The default logging levels are DEBUG, INFO, WARNING and FATAL, and you can define your own levels or replace the set entirely. Filtering is handled in g3log itself when dynamic logging levels are enabled in the configuration, and it can also be handled through the sink instead, which is what the separate g3sinks project is for. That project is where the richer sinks live, and the list the README gives is a good picture of what a real deployment wants. Log rotation. Logging to syslog. Colored terminal output. And log rotation with a filter. The default logging sink has no external third party dependencies at all, so the base install stays at zero, and the API documentation describes the steps for writing your own sink. The distinction between library side and sink side filtering is the one to be aware of, because the same effect can be had in two places with different costs.

## Instantiating the logger

The logger is created through a worker object, and with the default application name left as it is the creation looks like this:

```cpp
  const std::string directory = "./";
  const std::string name = "TestLogFile";
  auto worker = g3::LogWorker::createLogWorker();
  auto handle = worker->addDefaultLogger(name, directory);
```

The resulting filename is something like ./TestLogFile.g3log.20160217-001406.log, which shows the pattern, the application name, the logger name and a timestamp. The worker is the object that owns the background threads, and the handle is what you keep to add sinks. That structure is what lets several sinks be attached to one logger, and it is the reason the asynchronous behaviour is a property of the worker rather than of each call site.

## Performance is a design constraint, not a benchmark

The performance section states the goal rather than claiming a score. g3log aims to keep all background logging to sinks with as little log overhead as possible and with as small a worst case latency as possible, and the author argues that this makes it a good logger for systems that deal with critical tasks. The worst case latency is said to be kept stable with no extreme peaks in spite of sudden pressure, and the average logging overhead will differ by platform, with the author's own figure of about 2 microseconds for the average call, measured on a 2010 laptop during extreme performance testing. That number is dated and machine specific, so it should be read as an indication of the order of magnitude rather than a benchmark. The interesting property is the second half, since a stable worst case matters more than a good average for a system that has to stay responsive under load.

## Build, licence and current state

The build is CMake, with a top level CMakeLists.txt and a Build.cmake alongside an Options.cmake for the configuration, a CPackLists.txt for packaging, dedicated iOS build files, and a dev container definition. The continuous integration is on GitHub Actions, with a matrix covering Ubuntu, macOS and Windows plus documentation publishing, and the documentation is written in Markdown and rendered with mkdocs. There is even a Codespaces configuration so the project can be tried without setting up a local toolchain. The licence is the Unlicense, which is the public domain dedication, and the README says the logger is available for free and that all of its source code is public domain. The release history is steady, with 2.6.2 published on 2026-10-19, 2.6.1 on 2026-08-03 with warning hardening and an improved stack trace, and 2.6 in June 2025, so the project is maintained rather than merely preserved.

## Conclusion

g3log fits a C++ project that wants a logger with no dependency to argue about and a hard requirement that the last few log lines survive a crash, since the flush before exit is the feature the rest of the design serves. It does not fit a project that needs structured JSON logging out of the box, since the default sink writes text and the richer sinks live in a separate project. It does not fit a team that wants per-library log levels without writing a sink, because filtering is either a dynamic level feature or sink side work. Before you adopt it, read the sink list, because the default sink is deliberately minimal, and note the release state, where 2.6.2 was published on 2026-10-19 after 2.6.1 in August 2026 with warning hardening and an improved stack trace.

## FAQ

### What is g3log?

It is an asynchronous, crash safe logger for C++ with three main features: an intuitive LOG API, design by contract CHECK functionality, and fatal crash handling that lets the logged process shut down gracefully without losing log details up to the point of the crash.

### Does g3log depend on any other library?

No. It is written in plain C++14, with C++11 support up to release 1.3.2, and has no external libraries other than the test framework used for the unit tests. The default logging sink has no third party dependencies either.

### What happens to my logs when the process crashes?

On a fatal event, such as LOG(FATAL), a failed CHECK_F or a fatal signal like SIGSEGV, the not yet written log activity is flushed to the sinks first, and only when everything up to the fatal point has been written does g3log let the process exit. If object symbols are available it also pushes a stack trace to the sink.

### Which logging levels does g3log have?

DEBUG, INFO, WARNING and FATAL by default, and you can define your own levels or replace the set entirely. Filtering is handled inside g3log when dynamic logging levels are enabled, or through the sink, with the richer sinks such as rotation, syslog and colored terminal output in the separate g3sinks project.

### Is g3log still updated?

Yes. The last push was on 2026-10-19 with 2.6.2 published the same day, after 2.6.1 on 2026-08-03 which brought warning hardening and an improved stack trace, and 2.6 in June 2025. The code is released into the public domain under the Unlicense.

## Sources

- [KjellKod/g3log on GitHub](https://github.com/KjellKod/g3log)
- [License: Unlicense](https://github.com/KjellKod/g3log/blob/master/LICENSE)
- [Project website](http://github.com/KjellKod/g3log)
- [README](https://github.com/KjellKod/g3log/blob/master/README.md)
- [Releases](https://github.com/KjellKod/g3log/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kjellkod-g3log
