Logging

Enabling Logging

SDK logging is controlled through free functions in RealtimeCore/Common/LogUtils.h, in the RealtimeCore::Common namespace. LogEnable(level) and LogDisable(level) switch levels on and off, and IsLogEnabled(level) queries the current state. Messages are only delivered once at least one log output is registered with AddLogOutput.

A typical startup sequence registers an output and enables the levels of interest.

C++
C

C++

using namespace RealtimeCore::Common;

// ConsoleLogOutput is a user-defined LogOutput implementation, shown further down this page.
static ConsoleLogOutput consoleLog;

AddLogOutput(&consoleLog);
LogEnable(LogLevel::Info | LogLevel::Warning | LogLevel::Error);

C

/* Not available: LogUtils.h has no C entry points, so SDK logging cannot be
   enabled or routed over the ABI. A C client logs what it observes itself. */
if (e->type == RT_Error)
{
    fprintf(stderr, "[Photon][ERROR] code %u: %.*s\n",
            e->origin, (int)e->blobLength,
            (e->blobOffset >= 0) ? (const char*)(blob + e->blobOffset) : "");
}
else if (e->type == RT_Warning)
{
    fprintf(stderr, "[Photon][WARN] code %u\n", e->origin);
}

/* SDK Logging Is C++ Only: LogEnable, LogDisable, IsLogEnabled,
   AddLogOutput and the rest of LogUtils.h are free functions in the common
   library and are not part of the C ABI. A C client cannot turn SDK log
   levels on or install a log output, so the SDK stays silent for it.
   Enable logging from a C++ translation unit in the same process, or log
   the Error (101) and Warning (113) events the queue delivers, as above. */

Log Levels

LogLevel is a bitmask enum with five levels: Trace, Debug, Info, Warning and Error and the usual bitwise operators, so any combination can be enabled or disabled at once. There is no implicit hierarchy: enabling Warning does not enable Error; combine exactly the levels you want.

SetLogLevelsFromBitmask(mask) applies a complete level set in one call. TryGetLogLevelFromString(name, outLevel) parses a level from text, which is handy for config files and command-line switches, and PrintLogLevels() logs the currently active set.

Level Typical Content
Trace Highest-volume detail, down to individual calls and wire activity.
Debug Internal state transitions and diagnostic detail for development builds.
Info Lifecycle milestones: connected, room joined, region selected.
Warning Unexpected but recoverable conditions worth investigating.
Error Failures; something did not work as requested.

Implementing a Log Output

A log output is a class deriving from the abstract RealtimeCore::Common::LogOutput, implementing one sink per level: LogTrace, LogDebug, LogInfo, LogWarning and LogError. Each sink receives the finished message as a UTF-8 const CharType*; route it to wherever your game's diagnostics live, a console, a file or an in-game overlay.

A minimal output writing every message to stderr.

C++
C

C++

class ConsoleLogOutput : public RealtimeCore::Common::LogOutput
{
public:
    void LogTrace(const RealtimeCore::Common::CharType* message) override { Print("TRACE", message); }
    void LogDebug(const RealtimeCore::Common::CharType* message) override { Print("DEBUG", message); }
    void LogInfo(const RealtimeCore::Common::CharType* message) override { Print("INFO", message); }
    void LogWarning(const RealtimeCore::Common::CharType* message) override { Print("WARN", message); }
    void LogError(const RealtimeCore::Common::CharType* message) override { Print("ERROR", message); }

private:
    static void Print(const char* level, const RealtimeCore::Common::CharType* message)
    {
        std::fprintf(stderr, "[Photon][%s] %s\n", level, reinterpret_cast<const char*>(message));
    }
};

C

/* A LogOutput is a C++ class deriving from RealtimeCore::Common::LogOutput and
   has no ABI representation, so there is nothing to implement from C.
   Register the output from C++ and the same sink receives the SDK's messages
   for the whole process, including the part driven through the C API. */

/* Nothing in this section is reachable from C. The C API page lists the
   other C++ features without an ABI equivalent. */

Registering Log Outputs

AddLogOutput(&output) registers a sink and RemoveLogOutput(&output) removes it, returning whether it was found. Several outputs can be active at the same time, LogOutputCount() reports how many, and every enabled message is delivered to all of them.

The registry stores a raw pointer, so the output object must stay alive for as long as it is registered. Give outputs static or application lifetime, or call RemoveLogOutput before destroying one.

Back to top