omni/structuredlog/IStructuredLog.h

File members: omni/structuredlog/IStructuredLog.h

// Copyright (c) 2020-2023, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once

#include "StructuredLogCommon.h"

#include "../core/BuiltIn.h"
#include "../core/IObject.h"
#include "../core/Api.h"

#ifdef STRUCTUREDLOG_STANDALONE_MODE
#    include "../../carb/extras/Library.h"
#endif

#include <vector>

namespace omni
{
namespace structuredlog
{

class IStructuredLog;

// ******************************* enums, types, and constants ************************************
constexpr const char* OMNI_ATTR("no_py") kStructuredLogPluginName = "omni.structuredlog.plugin";

using ParserVersion = uint16_t;

using AllocHandle = void*;

constexpr size_t kNullTerminatedString = SIZE_MAX;

constexpr ParserVersion kParserVersion = 0;

constexpr size_t kMaxMessageLength = (10000000 - 256);

constexpr size_t kMaxMessageLengthBase64 = (kMaxMessageLength * 6) / 8;

using SchemaFlags OMNI_ATTR("flag, prefix=fSchemaFlag") = uint32_t;

constexpr SchemaFlags fSchemaFlagKeepLogOpen = 0x00000001;

constexpr SchemaFlags fSchemaFlagLogWithProcessId = 0x00000002;

using EventFlags OMNI_ATTR("flag, prefix=fEventFlag") = uint32_t;

constexpr EventFlags fEventFlagUseLocalLog = 0x00000001;

constexpr EventFlags fEventFlagCriticalEvent = 0x00000002;

constexpr EventFlags fEventFlagOutputToStderr = 0x00000010;

constexpr EventFlags fEventFlagOutputToStdout = 0x00000020;

constexpr EventFlags fEventFlagSkipLog = 0x00000040;

using EnableFlags OMNI_ATTR("flag, prefix=fEnableFlag") = uint32_t;

constexpr EnableFlags fEnableFlagWholeSchema = 0x00000002;

constexpr EnableFlags fEnableFlagOverrideEnableState = 0x00000004;

constexpr EnableFlags fEnableFlagAll = 0x00000008;

using AllocFlags OMNI_ATTR("flag, prefix=fAllocFlag") = uint32_t;

constexpr AllocFlags fAllocFlagOnlyQueue = 0x00000010;

struct EventInfo
{
    const char* eventName;

    EventFlags flags;

    ParserVersion parserVersion;

    uint64_t eventId;

    const void* schema;
};

// ********************************* IStructuredLog interface *************************************
class IStructuredLog_abi
    : public omni::core::Inherits<omni::core::IObject, OMNI_TYPE_ID("omni.structuredlog.IStructuredLog")>
{
protected:
    virtual bool isEnabled_abi(EventId eventId) noexcept = 0;

    virtual void setEnabled_abi(EventId eventId, EnableFlags flags, bool enabled) noexcept = 0;

    // ****** schema registration function ******
    virtual uint8_t* allocSchema_abi(OMNI_ATTR("c_str, in, not_null") const char* schemaName,
                                     OMNI_ATTR("c_str, in, not_null") const char* schemaVersion,
                                     SchemaFlags flags,
                                     size_t size,
                                     OMNI_ATTR("out") AllocHandle* outHandle) noexcept = 0;

    virtual SchemaResult commitSchema_abi(OMNI_ATTR("in, out, not_null") AllocHandle schemaBlock,
                                          OMNI_ATTR("in, *in, count=eventCount, not_null") const EventInfo* events,
                                          size_t eventCount) noexcept = 0;

    // ****** event message generation functions ******
    virtual uint8_t* allocEvent_abi(ParserVersion version,
                                    EventId eventId,
                                    AllocFlags flags,
                                    size_t payloadSize,
                                    OMNI_ATTR("out") AllocHandle* outHandle) noexcept = 0;

    virtual void commitEvent_abi(OMNI_ATTR("in, not_null") const AllocHandle handle) noexcept = 0;
};

// skipping this because exhale can't handle the function pointer type
#ifndef DOXYGEN_SHOULD_SKIP_THIS
using SchemaAddFn = bool (*)(IStructuredLog*);

inline std::vector<SchemaAddFn>& getModuleSchemas()
{
    static std::vector<SchemaAddFn> sSchemas;
    return sSchemas;
}
#endif

} // namespace structuredlog
} // namespace omni

#ifdef OMNI_COMPILE_AS_DYNAMIC_LIBRARY
OMNI_API omni::structuredlog::IStructuredLog* omniGetStructuredLogWithoutAcquire();
#else
#    ifndef STRUCTUREDLOG_STANDALONE_MODE
inline omni::structuredlog::IStructuredLog* omniGetStructuredLogWithoutAcquire()
{
    return static_cast<omni::structuredlog::IStructuredLog*>(omniGetBuiltInWithoutAcquire(OmniBuiltIn::eIStructuredLog));
}
#    else
inline omni::structuredlog::IStructuredLog* omniGetStructuredLogWithoutAcquire()
{
    using GetFunc = omni::structuredlog::IStructuredLog* (*)();
    static GetFunc s_get = nullptr;

    if (s_get == nullptr)
    {
        carb::extras::LibraryHandle module = carb::extras::loadLibrary(
            omni::structuredlog::kStructuredLogPluginName, carb::extras::fLibFlagMakeFullLibName);

        s_get = carb::extras::getLibrarySymbol<GetFunc>(module, "omniGetStructuredLogWithoutAcquire_");

        if (s_get == nullptr)
            return nullptr;
    }

    return s_get();
}
#    endif
#endif

#define OMNI_BIND_INCLUDE_INTERFACE_DECL
#include "IStructuredLog.gen.h"

#define OMNI_STRUCTURED_LOG(event_, ...)                                                                               \
    do                                                                                                                 \
    {                                                                                                                  \
        auto strucLog__ = omniGetStructuredLogWithoutAcquire();                                                        \
        if (strucLog__)                                                                                                \
        {                                                                                                              \
            if (event_##_isEnabled(strucLog__))                                                                        \
            {                                                                                                          \
                event_##_sendEvent(strucLog__, ##__VA_ARGS__);                                                         \
            }                                                                                                          \
        }                                                                                                              \
    } while (0)

namespace omni
{
namespace structuredlog
{

inline void addModulesSchemas() noexcept
{
    auto strucLog = omniGetStructuredLogWithoutAcquire();

    if (strucLog == nullptr)
        return;

    for (auto& schemaAddFn : getModuleSchemas())
    {
        schemaAddFn(strucLog);
    }
}

} // namespace structuredlog
} // namespace omni

class omni::structuredlog::IStructuredLog : public omni::core::Generated<omni::structuredlog::IStructuredLog_abi>
{
};

#define OMNI_BIND_INCLUDE_INTERFACE_IMPL
#include "IStructuredLog.gen.h"