Skip to content

Examples Precheck

Eduard Mishkurov edited this page Jun 3, 2026 · 6 revisions

Precheck example

Precheck

This example shows how Logme can skip unnecessary work before building a log record.

What it demonstrates

  • Early check for regular LogmeI(...) calls when the first argument is a ChannelPtr
  • LogmeI_Do(...) for preparation code that should run only when the record will really be emitted
  • The same idea for std::format style logging through fLogmeI_Do(...) when it is enabled
  • The practical difference between an inactive channel and an active visible channel

Why it matters

In a logging library, the expensive part is often not the final write. It is the work done before the logger decides whether the message should be emitted at all:

  • evaluating function calls used as log arguments
  • building temporary strings and other helper objects
  • running custom preparation code just to feed the logging macro

When you pass a ChannelPtr as the first argument, LogmeI(...) can check the channel state before evaluating the remaining arguments.

When you need even more control, LogmeI_Do(...) lets you put the preparation code directly into the macro. That code runs only if the logger has already decided that the message will be written.

Notes

  • Plain LogmeI("...", ...) cannot do this early channel-based check because there is no explicit ChannelPtr in the first argument.
  • LogmeI_Do(...) can work with either ChannelPtr or Logme::ID.
  • The example prints counters so the behavior is visible immediately when you run it.

Console output

2026-06-03 16:33:14:864   main(): Precheck example
2026-06-03 16:33:14:864   main(): ExpensiveText() was evaluated
2026-06-03 16:33:14:864   main(): ExpensiveText() calls after both messages: 1
2026-06-03 16:33:14:864   main(): PrepareValue() calls after inactive LogmeI_Do: 0
2026-06-03 16:33:14:864   main(): active prepared=42
2026-06-03 16:33:14:864   main(): PrepareValue() calls after active LogmeI_Do: 1
2026-06-03 16:33:14:864   main(): std::format prepared=42

Source code

Sources

Repository folder: examples/Precheck

Precheck.cpp

Open in repository

#include <Logme/Logme.h>

static Logme::ChannelPtr EnsureVisibleChannel(const Logme::ID& id)
{
  auto ch = Logme::Instance->CreateChannel(id);
  ch->AddLink(::CH);
  return ch;
}

static int ExpensiveTextCalls;
static int PrepareValueCalls;

static std::string ExpensiveText()
{
  ExpensiveTextCalls++;
  return "ExpensiveText() was evaluated";
}

static int PrepareValue()
{
  PrepareValueCalls++;
  return 42;
}

int main()
{
  auto active = EnsureVisibleChannel(Logme::ID{"precheck_active_example"});
  auto inactive = Logme::Instance->CreateChannel(Logme::ID{"precheck_inactive_example"});
  inactive->SetEnabled(false);

  LogmeI(active) << "Precheck example";

  // Passing ChannelPtr as the first argument lets Logme check the channel state
  // before evaluating the rest of the logging arguments.
  LogmeI(inactive, "%s", ExpensiveText().c_str());
  LogmeI(active, "%s", ExpensiveText().c_str());

  LogmeI("ExpensiveText() calls after both messages: %d", ExpensiveTextCalls);

  int prepared = 0;

  // The *_Do macro is meant for cases where some preparation code would be
  // wasteful unless the log record is really going to be emitted.
  LogmeI_Do(inactive->GetID(), prepared = PrepareValue(), "inactive prepared=%d", prepared);
  LogmeI("PrepareValue() calls after inactive LogmeI_Do: %d", PrepareValueCalls);

  LogmeI_Do(active->GetID(), prepared = PrepareValue(), "active prepared=%d", prepared);
  LogmeI("PrepareValue() calls after active LogmeI_Do: %d", PrepareValueCalls);

#ifndef LOGME_DISABLE_STD_FORMAT
  prepared = 0;
  fLogmeI_Do(active->GetID(), prepared = PrepareValue(), "std::format prepared={}", prepared);
#endif

  return 0;
}

Previous: Override | Next: Procedure

Clone this wiki locally