FCF 2.0 development in progress...
> > > > > > > >
[News] [C++ Libraries API] [C++ Downloads] [Donate to the project] [Contacts]

dataFactory from class fcf::NTest::Logger::Prefix

Property: dataFactory

Type: fcf::NTest::Logger::DataFactory

Class: fcf::NTest::Logger::Prefix

Package: fcfTest

File: test.hpp

Available from version: 1.2.1

A factory function used to initialize and provide a unique fcf::NTest::SharedPtrAny data object for a specific fcf::NTest::Logger::OutputTarget and fcf::NTest::Logger::Prefix combination.

The dataFactory property is a callback function that allows for lazy and dynamic initialization of metadata for a logger target for a given prefix. Instead of providing a static object, you provide a factory that is invoked only when the logger needs to create the data container for a specific output target.

This is particularly useful when:

  • The metadata object is expensive to construct and should only be created if the target is actually used.
  • The metadata needs to be unique for every different fcf::NTest::Logger::OutputTarget (e.g., different file streams or different console settings).
  • The metadata depends on runtime information available only during the logger's initialization phase.

Example: Dynamic Metadata Initialization via Data Factory

Demonstrating how to use the dataFactory to inject a custom object into the logger's context, which is then retrieved by a custom formatter.

#define FCF_TEST_IMPLEMENTATION #include <fcfTest/test.hpp> #include <iostream> #include <string> // Define a custom structure that we want to attach to the logger context struct SessionInfo { std::string sessionId; int userLevel; }; FCF_TEST_DECLARE("FactoryDemo", "Logger", "DataFactoryTest") { // Trigger a log message fcf::NTest::log() << "Hello with dynamic metadata!" << std::endl; FCF_TEST(true); } int main(int a_argc, char* a_argv[]) { fcf::NTest::Logger::Prefix prefix; prefix.name = "session-prefix"; prefix.category = fcf::NTest::LMC_USER_GROUP; // Use the dataFactory to create the object on demand prefix.dataFactory = []( fcf::NTest::Logger&, fcf::NTest::Logger::OutputTarget&) { // This lambda is called when the logger first encounters this format for a target return fcf::NTest::SharedPtrAny::make<SessionInfo>(SessionInfo{"ABC-123", 5}); }; prefix.handler = []( fcf::NTest::Logger&, fcf::NTest::Logger::MessageContext& a_context) { // Cast the type-erased pointer back to our SessionInfo type SessionInfo* info = a_context.data->cast<SessionInfo>(); // Check if the data exists in the context if (info) { return std::string() + "[Session: " + info->sessionId + "] "; } return std::string(); }; // Apply the prefix to the logger fcf::NTest::logger().appendPrefix(prefix); bool error = false; fcf::NTest::cmdRun(a_argc, a_argv, fcf::NTest::CRM_RUN, &error); return error ? 1 : 0; }

Output:

Performing the test: "FactoryDemo" -> "Logger" -> "DataFactoryTest" ... > [Session: ABC-123] Hello with dynamic metadata! [SUCCESS] Test completed successfully (0.000`017`259 sec) [SUCCESS] All tests were completed. Tests: 1 passed, 0 failed, 0 skipped, 1 total Duration: 0.000`017`259 sec

The dataFactory allowed us to inject a SessionInfo object into the logging pipeline without manually managing its lifecycle for every single log call. The logger handled the creation and destruction of the object via the fcf::NTest::SharedPtrAny mechanism.