Skip to content

Commit

Permalink
Merge pull request #2222 from elBoberido/iox-1755-redirect-printing-i…
Browse files Browse the repository at this point in the history
…n-the-platform-layer-to-the-logger

iox-#1755 Redirect printing in the platform layer to the logger
  • Loading branch information
elBoberido authored Mar 12, 2024
2 parents 377bf0b + 9a62ad5 commit 1e17b23
Show file tree
Hide file tree
Showing 18 changed files with 574 additions and 69 deletions.
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

0 comments on commit 1e17b23

Please sign in to comment.