// 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.
//
#include "../common/TestHelpers.h"
#include "../omni.core/ScopedTypeFactory.h"
#include <omni/log/ILog.h>
#include <carb/dictionary/ISerializer.h>
// clang-format off, example-begin log-macros
#include <omni/log/ILog.h>
void logAtEachLevel()
{
OMNI_LOG_VERBOSE("This is verbose");
OMNI_LOG_INFO("Þetta eru upplýsingar");
OMNI_LOG_WARN("Սա նախազգուշացում է");
OMNI_LOG_ERROR("这是一个错误");
OMNI_LOG_FATAL("This is %s", "fatal");
}
// example-end log-macros, clang-format on
// example-begin add-channel
OMNI_LOG_ADD_CHANNEL(kMp3EncodeChannel, "audio.vorbis.encode", "Vorbis audio encoding.")
OMNI_LOG_ADD_CHANNEL(kMp3DecodeChannel, "audio.vorbis.decode", "Vorbis audio decoding.")
OMNI_LOG_ADD_CHANNEL(kSpatialChannel, "audio.spatial", "Spatial (3D) audio.")
// example-end add-channel
void logToChannelExample()
{
const char* filename = "rickroll.ogg";
float distance = 3.0f;
// example-begin log-to-channel
OMNI_LOG_ERROR(kMp3DecodeChannel, "failed to load '%s'", filename);
// ...
OMNI_LOG_VERBOSE(kSpatialChannel, "sound source is %f meters from listener", distance);
// example-end log-to-channel
}
// example-begin declare-channel
OMNI_LOG_DECLARE_CHANNEL(kMp3EncodeChannel)
// example-end declare-channel
void showMessageConsumer()
{
omniGetLogWithoutAcquire()->setEnabled(true);
// example-begin on-message-consumer
auto log = omniGetLogWithoutAcquire();
bool sawFatalMessage = false;
auto consumer = log->addMessageConsumer(
[&sawFatalMessage](const char* channel, omni::log::Level level, const char* moduleName, const char* fileName,
const char* functionName, uint32_t lineNumber, const char* msg, uint32_t pid, uint32_t tid,
uint64_t timestamp) noexcept {
if (omni::log::Level::eFatal == level)
{
sawFatalMessage = true;
}
});
OMNI_LOG_FATAL("this is a fatal message");
log->removeMessageConsumer(consumer);
REQUIRE(sawFatalMessage);
// example-end on-message-consumer
log->setEnabled(false);
}
void showChannelUpdateConsumer()
{
omniGetLogWithoutAcquire()->setEnabled(true);
// the output below should be:
/* example-begin on-channel-updated-consumer-output
<global>: enabled is now 1
<global>: level is now -1
audio.opus.encode channel added
audio.opus.encode: enabled is now 1[override]
audio.opus.encode: level is now -1[inherit]
audio.opus.encode: description is now OPUS audio codec encoding.
example-end on-channel-updated-consumer-output */
// example-begin on-channel-updated-consumer-code
auto log = omniGetLogWithoutAcquire();
log->setEnabled(false);
log->setLevel(omni::log::Level::eVerbose);
auto consumer = log->addChannelUpdateConsumer([](omni::log::ILog* log, omni::str::IReadOnlyCString* channel,
omni::log::ChannelUpdateReason reason) {
switch (reason)
{
case omni::log::ChannelUpdateReason::eChannelAdded:
OMNI_LOG_INFO("%s channel added", channel->getBuffer());
break;
case omni::log::ChannelUpdateReason::eChannelRemoved:
OMNI_LOG_INFO("%s channel removed", channel->getBuffer());
break;
case omni::log::ChannelUpdateReason::eLevelUpdated:
{
omni::log::Level level;
omni::log::SettingBehavior behavior;
if (channel)
{
if (OMNI_SUCCEEDED(log->getChannelLevel(channel->getBuffer(), &level, &behavior)))
{
OMNI_LOG_INFO("%s: level is now %d[%s]", channel->getBuffer(), int(level),
((omni::log::SettingBehavior::eInherit == behavior) ? "inherit" : "override"));
}
}
else
{
OMNI_LOG_INFO("<global>: level is now %d", int32_t(log->getLevel()));
}
break;
}
case omni::log::ChannelUpdateReason::eEnabledUpdated:
{
bool enabled;
omni::log::SettingBehavior behavior;
if (channel)
{
if (OMNI_SUCCEEDED(log->getChannelEnabled(channel->getBuffer(), &enabled, &behavior)))
{
OMNI_LOG_INFO("%s: enabled is now %d[%s]", channel->getBuffer(), int(enabled),
((omni::log::SettingBehavior::eInherit == behavior) ? "inherit" : "override"));
}
}
else
{
OMNI_LOG_VERBOSE("<global>: enabled is now %d", int(log->isEnabled()));
}
break;
}
case omni::log::ChannelUpdateReason::eDescriptionUpdated:
{
omni::core::ObjectPtr<omni::str::IReadOnlyCString> descObj;
if (OMNI_SUCCEEDED(log->getChannelDescription(channel->getBuffer(), descObj.put())))
{
const char* desc = "(null)";
if (descObj)
{
desc = descObj->getBuffer();
}
OMNI_LOG_INFO("%s: description is now %s", channel->getBuffer(), desc);
}
break;
}
default:
break;
}
});
log->setEnabled(true);
log->setLevel(omni::log::Level::eInfo);
// this first call will produce an eChannelAdded event since the channel has never been seen
log->setChannelEnabled("audio.opus.encode", false, omni::log::SettingBehavior::eInherit);
log->setChannelEnabled("audio.opus.encode", true, omni::log::SettingBehavior::eOverride);
log->setChannelLevel("audio.opus.encode", omni::log::Level::eInfo, omni::log::SettingBehavior::eInherit);
log->setChannelDescription("audio.opus.encode", "OPUS audio codec encoding.");
log->removeChannelUpdateConsumer(consumer);
// example-end on-channel-updated-consumer-code
log->setChannelEnabled("audio.opus.encode", false, omni::log::SettingBehavior::eInherit);
log->setChannelLevel("audio.opus.encode", omni::log::Level::eWarn, omni::log::SettingBehavior::eInherit);
log->setLevel(omni::log::Level::eWarn);
log->setEnabled(false);
}
TEST_CASE("tests for omni::log documentation", "ncournia", "[omni::log::ILog]")
{
test::ScopedTypeFactory scopedFactory;
auto log = omniGetLogWithoutAcquire();
REQUIRE(log);
log->setEnabled(false);
log->setChannelLevel(kDefaultChannel, omni::log::Level::eVerbose, omni::log::SettingBehavior::eInherit);
log->setChannelEnabled(kDefaultChannel, false, omni::log::SettingBehavior::eInherit);
logAtEachLevel();
logToChannelExample();
showMessageConsumer();
showChannelUpdateConsumer();
log->setEnabled(true);
}