mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-05 03:35:51 +00:00
@@ -62,6 +62,7 @@ test.csf > xrpl.basics
|
||||
test.csf > xrpld.consensus
|
||||
test.csf > xrpl.json
|
||||
test.csf > xrpl.protocol
|
||||
test.csf > xrpl.telemetry
|
||||
test.json > test.jtx
|
||||
test.json > xrpl.json
|
||||
test.jtx > xrpl.basics
|
||||
@@ -138,7 +139,6 @@ test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.net
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
xrpl.ledger > xrpl.protocol
|
||||
@@ -148,9 +148,12 @@ xrpl.protocol > xrpl.json
|
||||
xrpl.resource > xrpl.basics
|
||||
xrpl.resource > xrpl.json
|
||||
xrpl.resource > xrpl.protocol
|
||||
xrpl.resource > xrpl.telemetry
|
||||
xrpl.server > xrpl.basics
|
||||
xrpl.server > xrpl.json
|
||||
xrpl.server > xrpl.protocol
|
||||
xrpl.server > xrpl.telemetry
|
||||
xrpl.telemetry > xrpl.json
|
||||
xrpld.app > test.unit_test
|
||||
xrpld.app > xrpl.basics
|
||||
xrpld.app > xrpld.conditions
|
||||
@@ -162,6 +165,7 @@ xrpld.app > xrpl.ledger
|
||||
xrpld.app > xrpl.net
|
||||
xrpld.app > xrpl.protocol
|
||||
xrpld.app > xrpl.resource
|
||||
xrpld.app > xrpl.telemetry
|
||||
xrpld.conditions > xrpl.basics
|
||||
xrpld.conditions > xrpl.protocol
|
||||
xrpld.consensus > xrpl.basics
|
||||
@@ -171,6 +175,10 @@ xrpld.core > xrpl.basics
|
||||
xrpld.core > xrpl.json
|
||||
xrpld.core > xrpl.net
|
||||
xrpld.core > xrpl.protocol
|
||||
xrpld.core > xrpl.telemetry
|
||||
xrpld.ledger > xrpl.basics
|
||||
xrpld.ledger > xrpl.json
|
||||
xrpld.ledger > xrpl.protocol
|
||||
xrpld.nodestore > xrpl.basics
|
||||
xrpld.nodestore > xrpld.core
|
||||
xrpld.nodestore > xrpld.unity
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_LOGGING_STRUCTUREDJOURNAL_H_INCLUDED
|
||||
#define RIPPLE_LOGGING_STRUCTUREDJOURNAL_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/json/Writer.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <source_location>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
namespace log {
|
||||
|
||||
template <typename T>
|
||||
class LogParameter
|
||||
{
|
||||
public:
|
||||
template <typename TArg>
|
||||
LogParameter(char const* name, TArg&& value)
|
||||
: name_(name), value_(std::forward<TArg>(value))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
char const* name_;
|
||||
T value_;
|
||||
|
||||
template <typename U>
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, LogParameter<U> const&);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class LogField
|
||||
{
|
||||
public:
|
||||
template <typename TArg>
|
||||
LogField(char const* name, TArg&& value)
|
||||
: name_(name), value_(std::forward<TArg>(value))
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
char const* name_;
|
||||
T value_;
|
||||
|
||||
template <typename U>
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, LogField<U> const&);
|
||||
};
|
||||
|
||||
class JsonLogAttributes : public beast::Journal::StructuredLogAttributes
|
||||
{
|
||||
public:
|
||||
using AttributeFields = std::unordered_map<std::string, Json::Value>;
|
||||
using Pair = AttributeFields::value_type;
|
||||
|
||||
explicit JsonLogAttributes(AttributeFields contextValues = {});
|
||||
|
||||
void
|
||||
setModuleName(std::string const& name) override;
|
||||
|
||||
std::unique_ptr<StructuredLogAttributes>
|
||||
clone() const override;
|
||||
|
||||
void
|
||||
combine(std::unique_ptr<StructuredLogAttributes> const& context) override;
|
||||
|
||||
void
|
||||
combine(std::unique_ptr<StructuredLogAttributes>&& context) override;
|
||||
|
||||
AttributeFields&
|
||||
contextValues()
|
||||
{
|
||||
return contextValues_;
|
||||
}
|
||||
|
||||
private:
|
||||
AttributeFields contextValues_;
|
||||
};
|
||||
|
||||
class JsonStructuredJournal : public beast::Journal::StructuredJournalImpl
|
||||
{
|
||||
private:
|
||||
struct Logger
|
||||
{
|
||||
std::source_location location = {};
|
||||
Json::Value messageParams;
|
||||
|
||||
Logger() = default;
|
||||
Logger(
|
||||
JsonStructuredJournal const* journal,
|
||||
std::source_location location);
|
||||
|
||||
void
|
||||
write(
|
||||
beast::Journal::Sink* sink,
|
||||
beast::severities::Severity level,
|
||||
std::string const& text,
|
||||
beast::Journal::StructuredLogAttributes* context) const;
|
||||
};
|
||||
|
||||
[[nodiscard]] Logger
|
||||
logger(std::source_location location) const;
|
||||
|
||||
static thread_local Logger currentLogger_;
|
||||
|
||||
template <typename T>
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, LogParameter<T> const&);
|
||||
|
||||
template <typename T>
|
||||
friend std::ostream&
|
||||
operator<<(std::ostream& os, LogField<T> const&);
|
||||
|
||||
public:
|
||||
void
|
||||
initMessageContext(std::source_location location) override;
|
||||
|
||||
void
|
||||
flush(
|
||||
beast::Journal::Sink* sink,
|
||||
beast::severities::Severity level,
|
||||
std::string const& text,
|
||||
beast::Journal::StructuredLogAttributes* context) override;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, LogParameter<T> const& param)
|
||||
{
|
||||
using ValueType = std::decay_t<T>;
|
||||
// TODO: Update the Json library to support 64-bit integer values.
|
||||
if constexpr (
|
||||
std::constructible_from<Json::Value, ValueType> &&
|
||||
(!std::is_integral_v<ValueType> ||
|
||||
sizeof(ValueType) <= sizeof(Json::Int)))
|
||||
{
|
||||
JsonStructuredJournal::currentLogger_.messageParams[param.name_] =
|
||||
Json::Value{param.value_};
|
||||
return os << param.value_;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << param.value_;
|
||||
|
||||
JsonStructuredJournal::currentLogger_.messageParams[param.name_] =
|
||||
oss.str();
|
||||
return os << oss.str();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, LogField<T> const& param)
|
||||
{
|
||||
using ValueType = std::decay_t<T>;
|
||||
// TODO: Update the Json library to support 64-bit integer values.
|
||||
if constexpr (
|
||||
std::constructible_from<Json::Value, ValueType> &&
|
||||
(!std::is_integral_v<ValueType> ||
|
||||
sizeof(ValueType) <= sizeof(Json::Int)))
|
||||
{
|
||||
JsonStructuredJournal::currentLogger_.messageParams[param.name_] =
|
||||
Json::Value{param.value_};
|
||||
}
|
||||
else
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << param.value_;
|
||||
|
||||
JsonStructuredJournal::currentLogger_.messageParams[param.name_] =
|
||||
oss.str();
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
LogParameter<T>
|
||||
param(char const* name, T&& value)
|
||||
{
|
||||
return LogParameter<T>{name, std::forward<T>(value)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
LogField<T>
|
||||
field(char const* name, T&& value)
|
||||
{
|
||||
return LogField<T>{name, std::forward<T>(value)};
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::unique_ptr<JsonLogAttributes>
|
||||
attributes(std::initializer_list<JsonLogAttributes::Pair> const& fields)
|
||||
{
|
||||
return std::make_unique<JsonLogAttributes>(fields);
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
@@ -23,12 +23,10 @@
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <source_location>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
namespace log {
|
||||
namespace ripple::log {
|
||||
|
||||
template <typename T>
|
||||
class LogParameter
|
||||
@@ -215,7 +213,6 @@ attributes(std::initializer_list<JsonLogAttributes::Pair> const& fields)
|
||||
return std::make_unique<JsonLogAttributes>(fields);
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
} // namespace ripple
|
||||
} // namespace ripple::log
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/json/to_string.h>
|
||||
#include <xrpl/telemetry/JsonLogs.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace log {
|
||||
|
||||
thread_local JsonStructuredJournal::Logger
|
||||
JsonStructuredJournal::currentLogger_{};
|
||||
|
||||
JsonLogAttributes::JsonLogAttributes(AttributeFields contextValues)
|
||||
: contextValues_(std::move(contextValues))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JsonLogAttributes::setModuleName(std::string const& name)
|
||||
{
|
||||
contextValues()["Module"] = name;
|
||||
}
|
||||
|
||||
std::unique_ptr<beast::Journal::StructuredLogAttributes>
|
||||
JsonLogAttributes::clone() const
|
||||
{
|
||||
return std::make_unique<JsonLogAttributes>(*this);
|
||||
}
|
||||
|
||||
void
|
||||
JsonLogAttributes::combine(
|
||||
std::unique_ptr<StructuredLogAttributes> const& context)
|
||||
{
|
||||
auto structuredContext =
|
||||
static_cast<JsonLogAttributes const*>(context.get());
|
||||
contextValues_.insert(
|
||||
structuredContext->contextValues_.begin(),
|
||||
structuredContext->contextValues_.end());
|
||||
}
|
||||
|
||||
void
|
||||
JsonLogAttributes::combine(std::unique_ptr<StructuredLogAttributes>&& context)
|
||||
{
|
||||
auto structuredContext =
|
||||
static_cast<JsonLogAttributes const*>(context.get());
|
||||
|
||||
if (contextValues_.empty())
|
||||
{
|
||||
contextValues_ = std::move(structuredContext->contextValues_);
|
||||
}
|
||||
else
|
||||
{
|
||||
contextValues_.insert(
|
||||
structuredContext->contextValues_.begin(),
|
||||
structuredContext->contextValues_.end());
|
||||
}
|
||||
}
|
||||
|
||||
JsonStructuredJournal::Logger::Logger(
|
||||
JsonStructuredJournal const* journal,
|
||||
std::source_location location)
|
||||
: location(location)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
JsonStructuredJournal::Logger::write(
|
||||
beast::Journal::Sink* sink,
|
||||
beast::severities::Severity level,
|
||||
std::string const& text,
|
||||
beast::Journal::StructuredLogAttributes* context) const
|
||||
{
|
||||
Json::Value globalContext;
|
||||
if (context)
|
||||
{
|
||||
auto jsonContext = static_cast<JsonLogAttributes*>(context);
|
||||
for (auto const& [key, value] : jsonContext->contextValues())
|
||||
{
|
||||
globalContext[key] = value;
|
||||
}
|
||||
}
|
||||
globalContext["Function"] = location.function_name();
|
||||
globalContext["File"] = location.file_name();
|
||||
globalContext["Line"] = location.line();
|
||||
std::stringstream threadIdStream;
|
||||
threadIdStream << std::this_thread::get_id();
|
||||
globalContext["ThreadId"] = threadIdStream.str();
|
||||
globalContext["Params"] = messageParams;
|
||||
globalContext["Level"] = beast::severities::to_string(level);
|
||||
globalContext["Message"] = text;
|
||||
globalContext["Time"] =
|
||||
to_string(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count());
|
||||
|
||||
sink->write(level, to_string(globalContext));
|
||||
}
|
||||
|
||||
JsonStructuredJournal::Logger
|
||||
JsonStructuredJournal::logger(std::source_location location) const
|
||||
{
|
||||
return Logger{this, location};
|
||||
}
|
||||
|
||||
void
|
||||
JsonStructuredJournal::initMessageContext(std::source_location location)
|
||||
{
|
||||
currentLogger_ = logger(location);
|
||||
}
|
||||
|
||||
void
|
||||
JsonStructuredJournal::flush(
|
||||
beast::Journal::Sink* sink,
|
||||
beast::severities::Severity level,
|
||||
std::string const& text,
|
||||
beast::Journal::StructuredLogAttributes* context)
|
||||
{
|
||||
currentLogger_.write(sink, level, text, context);
|
||||
}
|
||||
|
||||
} // namespace log
|
||||
} // namespace ripple
|
||||
Reference in New Issue
Block a user