Program Listing for File Logging.h
↰ Return to documentation for file (/tmp/ws/src/fastrtps/include/fastdds/rtps/security/logging/Logging.h
)
// Copyright 2020 Canonical ltd.
//
// 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.
#ifndef _FASTDDS_RTPS_SECURITY_LOGGING_LOGGING_H_
#define _FASTDDS_RTPS_SECURITY_LOGGING_LOGGING_H_
#include <limits>
#include <iomanip>
#include <fastdds/dds/log/Log.hpp>
#include <fastdds/rtps/security/logging/LogOptions.h>
#include <fastdds/rtps/security/logging/BuiltinLoggingType.h>
#include <fastdds/rtps/security/exceptions/SecurityException.h>
#include <fastdds/rtps/common/Guid.h>
namespace eprosima {
namespace fastrtps {
namespace rtps {
namespace security {
class LoggerListener
{
LoggerListener() = default;
~LoggerListener() = default;
};
class Logging
{
public:
Logging();
virtual ~Logging() = default;
bool set_log_options(
const LogOptions& log_options,
SecurityException& exception);
bool get_log_options(
LogOptions& log_options,
SecurityException& exception) const;
bool enable_logging(
SecurityException& exception);
bool set_listener(
LoggerListener* listener,
SecurityException& exception);
void log(
const LoggingLevel log_level,
const std::string& message,
const std::string& category,
SecurityException& exception) const;
bool options_set() const
{
return options_set_;
}
bool enabled() const
{
return logging_enabled_;
}
LoggerListener const* get_listener() const
{
return listener_;
}
bool set_guid(
const GUID_t& guid,
SecurityException& exception);
bool set_domain_id(
const uint32_t id,
SecurityException& exception);
protected:
virtual bool enable_logging_impl(
SecurityException& /*exception*/)
{
return true;
}
virtual bool convert(
const LoggingLevel log_level,
const std::string& message,
const std::string& category,
BuiltinLoggingType& builtin_msg,
SecurityException& exception) const;
template <typename Stream>
bool compose_header(
Stream& header,
const BuiltinLoggingType& builtin_msg,
SecurityException& exception) const;
virtual void log_impl(
const BuiltinLoggingType& message,
SecurityException& exception) const = 0;
private:
LoggerListener* listener_;
bool logging_enabled_ = false;
bool options_set_ = false;
LogOptions log_options_;
GUID_t guid_;
std::string guid_str_;
uint32_t domain_id_ = std::numeric_limits<uint32_t>::max();
std::string domain_id_str_;
};
template <typename Stream>
bool Logging::compose_header(
Stream& header,
const BuiltinLoggingType& builtin_msg,
SecurityException& exception) const
{
const auto it = builtin_msg.structured_data.find("DDS");
if (builtin_msg.structured_data.end() == it)
{
exception = SecurityException("Could not find expected DDS field.");
return false;
}
std::string severity;
if (!LogLevel_to_string(builtin_msg.severity, severity, exception))
{
return false;
}
// header format is:
// [stamp] [severity] <guid> <domain_id> <plugin_class::plugin_method>
header << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< "[" << builtin_msg.timestamp << "] "
<< "[" << severity << "] "
<< it->second.at(0).value << " "
<< it->second.at(1).value << " "
<< it->second.at(2).value << "::" << it->second.at(3).value;
return true;
}
} //namespace security
} //namespace rtps
} //namespace fastrtps
} //namespace eprosima
// gcc expands __VA_ARGS___ before passing it into the macro.
// Visual Studio expands __VA_ARGS__ after passing it.
// This macro is a workaround to support both
#define __FASTRTPS_EXPAND(x) x
#define __FASTRTPS_SECURITY_LOGGING(LEVEL, CLASS, MESSAGE, EXCEPTION) \
do { \
auto logger = get_logger(); \
if (logger){ \
logger->log(LEVEL, \
MESSAGE, \
std::string(CLASS ",") + __func__, \
EXCEPTION); \
} \
else { \
switch (LEVEL){ \
case LoggingLevel::EMERGENCY_LEVEL: \
case LoggingLevel::ALERT_LEVEL: \
case LoggingLevel::CRITICAL_LEVEL: \
case LoggingLevel::ERROR_LEVEL: \
EPROSIMA_LOG_ERROR(SECURITY, MESSAGE); \
break; \
case LoggingLevel::WARNING_LEVEL: \
EPROSIMA_LOG_WARNING(SECURITY, MESSAGE); \
break; \
case LoggingLevel::NOTICE_LEVEL: \
case LoggingLevel::INFORMATIONAL_LEVEL: \
case LoggingLevel::DEBUG_LEVEL: \
EPROSIMA_LOG_INFO(SECURITY, MESSAGE); \
break; \
} \
} \
} while (0);
#define __FASTRTPS_SECURITY_LOGGING_EX(LEVEL, CLASS, MESSAGE) \
do { \
eprosima::fastrtps::rtps::security::SecurityException lexception; \
__FASTRTPS_SECURITY_LOGGING(LEVEL, CLASS, MESSAGE, lexception); \
} while (0);
#define __FASTRTPS_MACRO_SELECTOR(_1, _2, _3, _4, NAME, ...) NAME
#define SECURITY_LOGGING(...) \
__FASTRTPS_EXPAND( \
__FASTRTPS_MACRO_SELECTOR(__VA_ARGS__, \
__FASTRTPS_SECURITY_LOGGING, \
__FASTRTPS_SECURITY_LOGGING_EX, \
_UNUSED)(__VA_ARGS__))
#define EMERGENCY_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::EMERGENCY_LEVEL, __VA_ARGS__)
#define ALERT_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::ALERT_LEVEL, __VA_ARGS__)
#define CRITICAL_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::CRITICAL_LEVEL, __VA_ARGS__)
#define ERROR_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::ERROR_LEVEL, __VA_ARGS__)
#define WARNING_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::WARNING_LEVEL, __VA_ARGS__)
#define NOTICE_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::NOTICE_LEVEL, __VA_ARGS__)
#define INFORMATIONAL_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::INFORMATIONAL_LEVEL, __VA_ARGS__)
#define DEBUG_SECURITY_LOGGING(...) SECURITY_LOGGING(LoggingLevel::DEBUG_LEVEL, __VA_ARGS__)
#endif // _FASTDDS_RTPS_SECURITY_LOGGING_LOGGING_H_