Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iox-#1755 Redirect printing in the platform layer to the logger #2222

1 change: 1 addition & 0 deletions iceoryx_hoofs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ iox_add_library(
reporting/source/hoofs_error_reporting.cpp
reporting/source/console_logger.cpp
reporting/source/logger.cpp
reporting/source/logging.cpp
time/source/duration.cpp
utility/source/unique_id.cpp

Expand Down
16 changes: 9 additions & 7 deletions iceoryx_hoofs/primitives/include/iox/iceoryx_hoofs_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
/// @note since this file will be included by many other files, it should not include other header except
/// iceoryx_platform or STL header

#include "iceoryx_platform/logging.hpp"

#include <cstdint>

namespace iox
Expand All @@ -31,13 +33,13 @@ namespace log
/// @brief This enum defines the log levels used for logging.
enum class LogLevel : uint8_t
{
OFF = 0,
FATAL,
ERROR,
WARN,
INFO,
DEBUG,
TRACE
OFF = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_OFF,
FATAL = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_FATAL,
ERROR = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_ERROR,
WARN = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_WARN,
INFO = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_INFO,
DEBUG = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_DEBUG,
TRACE = IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_TRACE,
};

/// @brief converts LogLevel into a string literal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ inline void Logger<BaseLogger>::initLoggerInternal(const LogLevel logLevel) noex
{
BaseLogger::setLogLevel(logLevel);
BaseLogger::initLogger(logLevel);
iox_platform_set_log_backend(&platform_log_backend);
m_isFinalized.store(true, std::memory_order_relaxed);
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef IOX_HOOFS_REPORTING_LOG_BUILDING_BLOCKS_LOGGER_HPP
#define IOX_HOOFS_REPORTING_LOG_BUILDING_BLOCKS_LOGGER_HPP

#include "iceoryx_platform/logging.hpp"
#include "iox/iceoryx_hoofs_types.hpp"

#include <atomic>
Expand Down Expand Up @@ -52,6 +53,12 @@ LogLevel logLevelFromEnvOr(const LogLevel logLevel) noexcept;

namespace internal
{
/// @brief The backend for the platform logging frontend
/// @copydoc IceoryxPlatformLogBackend
/// @note Needs to be implemented in 'logging.cpp' in order to use the high level log API
void platform_log_backend(
const char* file, int line, const char* function, IceoryxPlatformLogLevel log_level, const char* msg);

/// @brief This class acts as common interface for the Logger. It provides the common functionality and inherits from
/// the BaseLogger which is provided as template parameter. Please have a look at the design document for more details.
/// @tparam[in] BaseLogger is the actual implementation
Expand Down
55 changes: 55 additions & 0 deletions iceoryx_hoofs/reporting/source/logging.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2024 by Mathias Kraus <[email protected]>. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#include "iox/logging.hpp"

namespace iox::log::internal
{
// NOLINTJUSTIFICATION Not used directly but as a function pointer to set the backend
// NOLINTNEXTLINE(readability-function-size)
void platform_log_backend(
const char* file, int line, const char* function, IceoryxPlatformLogLevel log_level, const char* msg)
{
auto level = LogLevel::TRACE;
switch (log_level)
{
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_OFF:
level = LogLevel::OFF;
break;
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_FATAL:
level = LogLevel::FATAL;
break;
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_ERROR:
level = LogLevel::ERROR;
break;
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_WARN:
level = LogLevel::WARN;
break;
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_INFO:
level = LogLevel::INFO;
break;
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_DEBUG:
level = LogLevel::DEBUG;
break;
case IceoryxPlatformLogLevel::IOX_PLATFORM_LOG_LEVEL_TRACE:
level = LogLevel::TRACE;
break;
default:
level = LogLevel::TRACE;
}
IOX_LOG_INTERNAL(file, line, function, level, msg);
}
} // namespace iox::log::internal
29 changes: 24 additions & 5 deletions iceoryx_hoofs/test/moduletests/test_reporting_logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_platform/logging.hpp"
#include "iox/logging.hpp"

#include "iceoryx_hoofs/testing/mocks/logger_mock.hpp"
#include "iceoryx_hoofs/testing/testing_logger.hpp"
#include "test.hpp"

namespace
{
using namespace ::testing;

void testLogLevelThreshold(const iox::log::LogLevel loggerLogLevel)
void testLogLevelThreshold(const iox::log::LogLevel loggerLogLevel,
const std::function<void(iox::log::LogLevel)>& loggerCall)
{
iox::log::Logger::setLogLevel(loggerLogLevel);

Expand All @@ -47,7 +48,6 @@ void testLogLevelThreshold(const iox::log::LogLevel loggerLogLevel)
{iox::log::LogLevel::DEBUG, "Debug"},
{iox::log::LogLevel::TRACE, "Trace"}};

iox::testing::Logger_Mock loggerMock;
for (const auto& logEntryLogLevel : logEntryLogLevels)
{
if (!iox::testing::TestingLogger::doesLoggerSupportLogLevel(logEntryLogLevel.value))
Expand All @@ -56,7 +56,7 @@ void testLogLevelThreshold(const iox::log::LogLevel loggerLogLevel)
}

dynamic_cast<iox::testing::TestingLogger&>(iox::log::Logger::get()).clearLogBuffer();
IOX_LOG_INTERNAL("", 0, "", logEntryLogLevel.value, "");
loggerCall(logEntryLogLevel.value);

if (logEntryLogLevel.value <= loggerLogLevel)
{
Expand Down Expand Up @@ -87,7 +87,26 @@ TEST(LoggingLogLevelThreshold_test, LogLevel)
{
SCOPED_TRACE(std::string("Logger LogLevel: ") + iox::log::asStringLiteral(loggerLogLevel));

testLogLevelThreshold(loggerLogLevel);
testLogLevelThreshold(loggerLogLevel, [](auto logLevel) { IOX_LOG_INTERNAL("", 0, "", logLevel, ""); });
}
}

TEST(LoggingLogLevelThreshold_test, LogLevelForPlatform)
{
::testing::Test::RecordProperty("TEST_ID", "574007ac-62ed-4cd1-95e8-e18a9f20e1e1");
for (const auto loggerLogLevel : {iox::log::LogLevel::OFF,
iox::log::LogLevel::FATAL,
iox::log::LogLevel::ERROR,
iox::log::LogLevel::WARN,
iox::log::LogLevel::INFO,
iox::log::LogLevel::DEBUG,
iox::log::LogLevel::TRACE})
{
SCOPED_TRACE(std::string("Logger LogLevel: ") + iox::log::asStringLiteral(loggerLogLevel));

testLogLevelThreshold(loggerLogLevel, [](auto logLevel) {
iox_platform_detail_log("", 0, "", static_cast<IceoryxPlatformLogLevel>(logLevel), "");
});
}
}

Expand Down
63 changes: 63 additions & 0 deletions iceoryx_platform/generic/include/iceoryx_platform/logging.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) 2024 by Mathias Kraus <[email protected]>. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_PLATFORM_LOGGING_HPP
#define IOX_PLATFORM_LOGGING_HPP

enum IceoryxPlatformLogLevel
{
IOX_PLATFORM_LOG_LEVEL_OFF = 0,
IOX_PLATFORM_LOG_LEVEL_FATAL,
IOX_PLATFORM_LOG_LEVEL_ERROR,
IOX_PLATFORM_LOG_LEVEL_WARN,
IOX_PLATFORM_LOG_LEVEL_INFO,
IOX_PLATFORM_LOG_LEVEL_DEBUG,
IOX_PLATFORM_LOG_LEVEL_TRACE
};

/// @brief Typedef to the platform log backend
/// @param[in] file should be the '__FILE__' compiler intrinsic
/// @param[in] line should be the '__LINE__' compiler intrinsic
/// @param[in] function should be the '__FUNCTION__' compiler intrinsic
/// @param[in] log_level is the log level to be used for the log message
/// @param[in] msg is the message to be logged
typedef void (*IceoryxPlatformLogBackend)(
const char* file, int line, const char* function, IceoryxPlatformLogLevel log_level, const char* msg);

/// @brief Sets the logging backend to the provided function
/// @param[in] log_backend to be used
/// @note The log_backend must have a static lifetime and must be thread-safe
void iox_platform_set_log_backend(IceoryxPlatformLogBackend log_backend);

/// @note Implementation detail! Do not use directly
void iox_platform_detail_log(
const char* file, int line, const char* function, IceoryxPlatformLogLevel log_level, const char* msg);

/// @note Implementation detail! Do not use directly
void iox_platform_detail_default_log_backend(
const char* file, int line, const char* function, IceoryxPlatformLogLevel log_level, const char* msg);

// NOLINTJUSTIFICATION The functionality of the macro (obtaining the source location) cannot be achieved with C++17
// NOLINTBEGIN(cppcoreguidelines-macro-usage)
/// @brief Frontend for logging in the iceoryx platform
/// @param[in] log_level is the log level to be used for the log message
/// @param[in] msg is the message to be logged
#define IOX_PLATFORM_LOG(log_level, msg) \
iox_platform_detail_log( \
__FILE__, __LINE__, static_cast<const char*>(__FUNCTION__), IceoryxPlatformLogLevel::log_level, msg)
// NOLINTEND(cppcoreguidelines-macro-usage)

#endif // IOX_PLATFORM_LOGGING_HPP
Loading
Loading