Program Listing for File logger.h
↰ Return to documentation for file (/tmp/B.puc0r6hi/BUILD/opentelemetry-cpp-1.27.0-build/opentelemetry-cpp-1.27.0/api/include/opentelemetry/logs/logger.h)
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdint.h>
#include <type_traits>
#include <utility>
#include "opentelemetry/context/context.h"
#include "opentelemetry/logs/event_id.h"
#include "opentelemetry/logs/logger_type_traits.h"
#include "opentelemetry/logs/severity.h"
#include "opentelemetry/nostd/string_view.h"
#include "opentelemetry/nostd/unique_ptr.h"
#include "opentelemetry/version.h"
OPENTELEMETRY_BEGIN_NAMESPACE
namespace common
{
class KeyValueIterable;
} // namespace common
namespace logs
{
class EventId;
class LogRecord;
class Logger
{
public:
Logger() = default;
Logger(const Logger &) = default;
Logger(Logger &&) noexcept = default;
Logger &operator=(const Logger &) = default;
Logger &operator=(Logger &&) noexcept = default;
virtual ~Logger() = default;
/* Returns the name of the logger */
virtual const nostd::string_view GetName() noexcept = 0;
virtual nostd::unique_ptr<LogRecord> CreateLogRecord() noexcept = 0;
virtual void EmitLogRecord(nostd::unique_ptr<LogRecord> &&log_record) noexcept = 0;
template <class... ArgumentType>
void EmitLogRecord(nostd::unique_ptr<LogRecord> &&log_record, ArgumentType &&...args)
{
if (!log_record)
{
return;
}
//
// Keep the parameter pack unpacking order from left to right because left
// ones are usually more important like severity and event_id than the
// attributes. The left to right unpack order could pass the more important
// data to processors to avoid caching and memory allocating.
//
#if __cplusplus <= 201402L
// C++14 does not support fold expressions for parameter pack expansion.
int dummy[] = {(detail::LogRecordSetterTrait<typename std::decay<ArgumentType>::type>::Set(
log_record.get(), std::forward<ArgumentType>(args)),
0)...};
IgnoreTraitResult(dummy);
#else
IgnoreTraitResult((detail::LogRecordSetterTrait<typename std::decay<ArgumentType>::type>::Set(
log_record.get(), std::forward<ArgumentType>(args)),
...));
#endif
EmitLogRecord(std::move(log_record));
}
template <class... ArgumentType>
void EmitLogRecord(ArgumentType &&...args)
{
nostd::unique_ptr<LogRecord> log_record = CreateLogRecord();
EmitLogRecord(std::move(log_record), std::forward<ArgumentType>(args)...);
}
template <class... ArgumentType>
void Trace(ArgumentType &&...args) noexcept
{
static_assert(
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value,
"Severity is already set.");
this->EmitLogRecord(Severity::kTrace, std::forward<ArgumentType>(args)...);
}
template <class... ArgumentType>
void Debug(ArgumentType &&...args) noexcept
{
static_assert(
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value,
"Severity is already set.");
this->EmitLogRecord(Severity::kDebug, std::forward<ArgumentType>(args)...);
}
template <class... ArgumentType>
void Info(ArgumentType &&...args) noexcept
{
static_assert(
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value,
"Severity is already set.");
this->EmitLogRecord(Severity::kInfo, std::forward<ArgumentType>(args)...);
}
template <class... ArgumentType>
void Warn(ArgumentType &&...args) noexcept
{
static_assert(
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value,
"Severity is already set.");
this->EmitLogRecord(Severity::kWarn, std::forward<ArgumentType>(args)...);
}
template <class... ArgumentType>
void Error(ArgumentType &&...args) noexcept
{
static_assert(
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value,
"Severity is already set.");
this->EmitLogRecord(Severity::kError, std::forward<ArgumentType>(args)...);
}
template <class... ArgumentType>
void Fatal(ArgumentType &&...args) noexcept
{
static_assert(
!detail::LogRecordHasType<Severity, typename std::decay<ArgumentType>::type...>::value,
"Severity is already set.");
this->EmitLogRecord(Severity::kFatal, std::forward<ArgumentType>(args)...);
}
//
// OpenTelemetry C++ user-facing Logs API
//
#if OPENTELEMETRY_ABI_VERSION_NO >= 2
inline bool Enabled(const opentelemetry::context::Context &context,
Severity severity = Severity::kInvalid) const noexcept
{
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(context, severity);
}
inline bool Enabled(const opentelemetry::context::Context &context,
Severity severity,
const EventId &event_id) const noexcept
{
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(context, severity, event_id);
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2
inline bool Enabled(Severity severity, const EventId &event_id) const noexcept
{
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(severity, event_id);
}
inline bool Enabled(Severity severity, int64_t event_id) const noexcept
{
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(severity, event_id);
}
inline bool Enabled(Severity severity) const noexcept
{
return static_cast<uint8_t>(severity) >= OPENTELEMETRY_ATOMIC_READ_8(&minimum_severity_);
}
virtual void Log(Severity severity,
const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->EmitLogRecord(severity, event_id, format, attributes);
}
virtual void Log(Severity severity,
int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->EmitLogRecord(severity, EventId{event_id}, format, attributes);
}
virtual void Log(Severity severity,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->EmitLogRecord(severity, format, attributes);
}
virtual void Log(Severity severity, nostd::string_view message) noexcept
{
this->EmitLogRecord(severity, message);
}
// Convenient wrappers based on virtual methods Log().
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/logs/data-model.md#field-severitynumber
inline void Trace(const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kTrace, event_id, format, attributes);
}
inline void Trace(int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kTrace, EventId{event_id}, format, attributes);
}
inline void Trace(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kTrace, format, attributes);
}
inline void Trace(nostd::string_view message) noexcept { this->Log(Severity::kTrace, message); }
inline void Debug(const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kDebug, event_id, format, attributes);
}
inline void Debug(int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kDebug, EventId{event_id}, format, attributes);
}
inline void Debug(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kDebug, format, attributes);
}
inline void Debug(nostd::string_view message) noexcept { this->Log(Severity::kDebug, message); }
inline void Info(const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kInfo, event_id, format, attributes);
}
inline void Info(int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kInfo, EventId{event_id}, format, attributes);
}
inline void Info(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kInfo, format, attributes);
}
inline void Info(nostd::string_view message) noexcept { this->Log(Severity::kInfo, message); }
inline void Warn(const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kWarn, event_id, format, attributes);
}
inline void Warn(int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kWarn, EventId{event_id}, format, attributes);
}
inline void Warn(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kWarn, format, attributes);
}
inline void Warn(nostd::string_view message) noexcept { this->Log(Severity::kWarn, message); }
inline void Error(const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kError, event_id, format, attributes);
}
inline void Error(int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kError, EventId{event_id}, format, attributes);
}
inline void Error(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kError, format, attributes);
}
inline void Error(nostd::string_view message) noexcept { this->Log(Severity::kError, message); }
inline void Fatal(const EventId &event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kFatal, event_id, format, attributes);
}
inline void Fatal(int64_t event_id,
nostd::string_view format,
const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kFatal, EventId{event_id}, format, attributes);
}
inline void Fatal(nostd::string_view format, const common::KeyValueIterable &attributes) noexcept
{
this->Log(Severity::kFatal, format, attributes);
}
inline void Fatal(nostd::string_view message) noexcept { this->Log(Severity::kFatal, message); }
//
// End of OpenTelemetry C++ user-facing Log API.
//
protected:
virtual bool EnabledImplementation(Severity /*severity*/,
const EventId & /*event_id*/) const noexcept
{
return false;
}
virtual bool EnabledImplementation(Severity /*severity*/, int64_t /*event_id*/) const noexcept
{
return false;
}
#if OPENTELEMETRY_ABI_VERSION_NO >= 2
virtual bool EnabledImplementation(const opentelemetry::context::Context & /*context*/,
Severity /*severity*/) const noexcept
{
return false;
}
virtual bool EnabledImplementation(const opentelemetry::context::Context & /*context*/,
Severity /*severity*/,
const EventId & /*event_id*/) const noexcept
{
return false;
}
#endif // OPENTELEMETRY_ABI_VERSION_NO >= 2
void SetMinimumSeverity(uint8_t severity_or_max) noexcept
{
OPENTELEMETRY_ATOMIC_WRITE_8(&minimum_severity_, severity_or_max);
}
private:
template <class... ValueType>
void IgnoreTraitResult(ValueType &&...)
{}
//
// minimum_severity_ can be updated concurrently by multiple threads/cores, so race condition on
// read/write should be handled. And std::atomic can not be used here because it is not ABI
// compatible for OpenTelemetry C++ API.
//
mutable uint8_t minimum_severity_{kMaxSeverity};
};
} // namespace logs
OPENTELEMETRY_END_NAMESPACE