LoggerInterface Manual

About

The logger interface allows to create new custom loggers for specific tasks and to access existing loggers. Loggers are presented in the "Console" window in Cinema 4D and registered at the maxon::Loggers registry.

Messages can be sent to the default logger using ApplicationOutput().

Custom Loggers

A new custom logger can be created with maxon::LoggerRef::Create() and is then registered at maxon::Loggers. A logger type defines the target of the logger (see Logger Types).

A custom logger is configured with:

// This example creates a new custom logger and adds it to the registered loggers.
// g_exampleLogger is a maxon::LoggerRef instance.
// define logger ID
const maxon::Id loggerID("net.maxonexample.logger");
// check if a logger with that ID already exists
if (!maxon::Loggers::Get(loggerID))
{
// create the new logger and store it in a global variable for later access
// make sure to set this object to nullptr when Cinema shuts down
iferr (g_exampleLogger = maxon::LoggerRef::Create())
{
// if the logger could not be created, use the default logger instead
g_exampleLogger = maxon::Loggers::Default();
}
else
{
// if the logger could be created
// add the logger type "Application" to display logged messags in the "Console" window
g_exampleLogger.AddLoggerType(maxon::TARGETAUDIENCE::ALL, maxon::LoggerTypes::Application()) iferr_return;
// define logger name
g_exampleLogger.SetName("Example Logger"_s);
// insert the logger in the "Loggers" registry
maxon::Loggers::Insert(loggerID, g_exampleLogger) iferr_return;
// this message must be send to update the console window
const maxon::Int32 BFM_REBUILDCONSOLETREE = 334295845;
SpecialEventAdd(BFM_REBUILDCONSOLETREE);
}
}
// This example shows how to free the logger reference.
static void FreeExampleLogger()
{
g_exampleLogger = nullptr; // reference must be freed
// make sure to also remove the entry of your logger from Loggers.
maxon::Loggers::Erase(maxon::Id("net.maxonexample.logger")) iferr_ignore("");
}
MAXON_INITIALIZATION(nullptr, FreeExampleLogger);

Using Custom Loggers

A message is sent to a custom logger using the Write() function:

// This example writes a message to a custom logger.
// write to a custom logger referenced in g_exampleLogger
// or write to the logger by getting the logger using the logger ID
// get logger
const maxon::Id loggerId("net.maxonexample.logger");
const maxon::LoggerRef logger = maxon::Loggers::Get(loggerId);

Built-In Loggers

All existing loggers are registered at maxon::Loggers. These three loggers are there for public use:

  • maxon::Loggers::Default: The default logger (published object for direct use).
  • maxon::ID_LOGGER_PYTHON: The Python logger's ID, defined in python.framework, cpython.h.
  • maxon::Loggers::Process: The IDE console logger (published object for direct use).
Note
The default logger is used with ApplicationOutput().
// This example sends a message to the default logger.
ApplicationOutput("Some Message."_s);

Logger Types

A logger type implements the actual processing of a given message e.g. if that message is displayed in the GUI or written to a file.

Logger types are based on maxon::LoggerTypeInterface:

// This example adds an observer to the given logger. This observer
// will be called if a message is sent to that logger.
for (const auto& loggerTypeAudience : logger.GetLoggerTypes())
{
const maxon::LoggerTypeRef loggerType = loggerTypeAudience.GetFirst(); // get first element of the pair
loggerType.ObservableLoggerNotify().AddObserver(LoggerCallback) iferr_return;
}

maxon::UserLoggerTypeInterface is the logger type that displays the message in Cinema 4D's "Console" window:

maxon::FileLoggerTypeInterface is the logger type that writes the message to a file:

// This example accesses the default logger and gets all displayed lines.
// get default logger
const maxon::LoggerRef defaultLogger = maxon::Loggers::Default();
for (const auto& logger : defaultLogger.GetLoggerTypes())
{
const maxon::LoggerTypeRef loggerType = logger.GetFirst(); // get first element of the pair
if (loggerType.IsInstanceOf<maxon::UserLoggerTypeRef>())
{
const maxon::UserLoggerTypeRef userLoggerType = maxon::Cast<maxon::UserLoggerTypeRef>(loggerType);
// iterate over all lines sent to the logger
userLoggerType.Iterate([](maxon::LoggerLine& line) -> maxon::Result<void>
{
DiagnosticOutput("Line: @", line._str);
return maxon::OK;
}
}

Further Reading