Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Replace fc logging with spdlog 📦 #11062

Draft
wants to merge 32 commits into
base: csg-epe-291-update-eos-logging
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
15d8c0e
Test new fc logging macros
nickjjzhao Feb 3, 2022
476a593
Add a new fc logging macro
nickjjzhao Feb 4, 2022
526eceb
Update fc
nickjjzhao Feb 4, 2022
d74c87f
Test new fc macro fc_new_dlog
nickjjzhao Feb 8, 2022
8f19243
Update fc
nickjjzhao Feb 8, 2022
1ffe4a2
Access arguments by name
nickjjzhao Feb 8, 2022
6bfe7ef
Test new macro FC_FMT
nickjjzhao Feb 8, 2022
0ea081f
Update fc log macros to make them call spdlog macors
nickjjzhao Feb 14, 2022
cfb0398
Update spdlog submodule and fix errors caused by updated fc log macros
nickjjzhao Feb 14, 2022
ce5ca32
Use the latest commit of spdlog
nickjjzhao Feb 14, 2022
7594d8a
Update logging.json with some spdlog appenders
nickjjzhao Feb 14, 2022
d144b8e
Test the new format method created for the reflected types
nickjjzhao Feb 25, 2022
4f1cb32
Revert the last commit and add formatter struct in FC_REFLECT macro f…
nickjjzhao Feb 26, 2022
45716a6
Add friend declarations and replace BOOST_PP_SEQ_NIL with BOOST_PP_EM…
nickjjzhao Feb 28, 2022
d8ce70e
Update fc
nickjjzhao Mar 4, 2022
1632224
Update fc
nickjjzhao Mar 7, 2022
1179bd1
Add customized formatters for transaction type
nickjjzhao Mar 8, 2022
f0240b1
Add formatters for permission_object
nickjjzhao Mar 8, 2022
a53e81f
Add formatters for block_signing_authority
nickjjzhao Mar 9, 2022
4672f21
Add formatters for trx trace
nickjjzhao Mar 9, 2022
6c68328
Add formatters for unittests
nickjjzhao Mar 10, 2022
72bae5c
Add formatter for trx and trx trace
nickjjzhao Mar 14, 2022
aeceeb4
Revert "Add formatter for trx and trx trace" that breaks consensus af…
nickjjzhao Mar 15, 2022
04c67bc
Handle corner cases in custom formatters and remove extra quotes from…
nickjjzhao Mar 16, 2022
602807e
Convert a transaction into a string
nickjjzhao Mar 20, 2022
2fbf950
Update trx to string conversion
nickjjzhao Mar 20, 2022
d9f2669
Convert trx trace into log string
nickjjzhao Mar 21, 2022
c98413e
Remove dollar sign from new log format
nickjjzhao Mar 22, 2022
edaa443
Merge branch 'jjz-epe-291-update-eos-logging' of github.com:EOSIO/eos…
nickjjzhao Mar 22, 2022
383a0d1
Test new class to_string_visitor used for converting reflected types …
nickjjzhao Mar 22, 2022
bcd5055
Add a to_string.hpp which provides a way to get a loggable string for…
heifner Mar 23, 2022
a52f7f5
tmp hack test
heifner Mar 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,9 @@
[submodule "libraries/appbase"]
path = libraries/appbase
url = https://github.com/eosio/appbase
[submodule "libraries/spdlog"]
path = libraries/spdlog
url = https://github.com/gabime/spdlog
[submodule "libraries/fmt"]
path = libraries/fmt
url = https://github.com/fmtlib/fmt
10 changes: 10 additions & 0 deletions libraries/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,13 @@ option(AMQP-CPP_LINUX_TCP CACHE ON)
add_subdirectory( amqp-cpp EXCLUDE_FROM_ALL )
target_include_directories(amqpcpp PRIVATE "${OPENSSL_INCLUDE_DIR}")
remove_definitions( -w )

# Suppress warnings on 3rdParty Library
add_definitions( -w )
add_subdirectory( spdlog )
remove_definitions( -w )

# Suppress warnings on 3rdParty Library
add_definitions( -w )
add_subdirectory( fmt )
remove_definitions( -w )
4 changes: 2 additions & 2 deletions libraries/amqp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ add_library(amqp
transactional_amqp_publisher.cpp
util.cpp
)
target_include_directories(amqp PUBLIC include)
target_link_libraries(amqp fc amqpcpp)
target_include_directories(amqp PUBLIC include ../spdlog/include)
target_link_libraries(amqp fc amqpcpp spdlog)
40 changes: 20 additions & 20 deletions libraries/amqp/include/eosio/amqp/amqp_handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class amqp_handler {
[this](AMQP::Channel* c){channel_ready(c);}, [this](){channel_failed();} )
, on_error_( std::move( on_err ) )
{
ilog( "Connecting to AMQP address ${a} ...", ("a", amqp_connection_.address()) );
ilog( "Connecting to AMQP address {a} ...", ("a", amqp_connection_.address()) );

wait();
}
Expand All @@ -65,19 +65,19 @@ class amqp_handler {
boost::asio::post( thread_pool_.get_executor(),[this, &cond, en=exchange_name, type]() {
try {
if( !channel_ ) {
elog( "AMQP not connected to channel ${a}", ("a", amqp_connection_.address()) );
elog( "AMQP not connected to channel {a}", ("a", amqp_connection_.address()) );
on_error( "AMQP not connected to channel" );
return;
}

auto& exchange = channel_->declareExchange( en, type, AMQP::durable);
exchange.onSuccess( [this, &cond, en]() {
dlog( "AMQP declare exchange successful, exchange ${e}, for ${a}",
dlog( "AMQP declare exchange successful, exchange {e}, for {a}",
("e", en)("a", amqp_connection_.address()) );
cond.set();
} );
exchange.onError([this, &cond, en](const char* error_message) {
elog( "AMQP unable to declare exchange ${e}, for ${a}", ("e", en)("a", amqp_connection_.address()) );
elog( "AMQP unable to declare exchange {e}, for {a}", ("e", en)("a", amqp_connection_.address()) );
on_error( std::string("AMQP Queue error: ") + error_message );
cond.set();
});
Expand All @@ -87,7 +87,7 @@ class amqp_handler {
} );

if( !cond.wait() ) {
elog( "AMQP timeout declaring exchange: ${q} for ${a}", ("q", exchange_name)("a", amqp_connection_.address()) );
elog( "AMQP timeout declaring exchange: {q} for {a}", ("q", exchange_name)("a", amqp_connection_.address()) );
on_error( "AMQP timeout declaring exchange: " + exchange_name );
}
}
Expand All @@ -99,20 +99,20 @@ class amqp_handler {
boost::asio::post( thread_pool_.get_executor(), [this, &cond, qn=queue_name]() mutable {
try {
if( !channel_ ) {
elog( "AMQP not connected to channel ${a}", ("a", amqp_connection_.address()) );
elog( "AMQP not connected to channel {a}", ("a", amqp_connection_.address()) );
on_error( "AMQP not connected to channel" );
return;
}

auto& queue = channel_->declareQueue( qn, AMQP::durable );
queue.onSuccess(
[this, &cond]( const std::string& name, uint32_t message_count, uint32_t consumer_count ) {
dlog( "AMQP queue ${q}, messages: ${mc}, consumers: ${cc}, for ${a}",
dlog( "AMQP queue {q}, messages: {mc}, consumers: {cc}, for {a}",
("q", name)("mc", message_count)("cc", consumer_count)("a", amqp_connection_.address()) );
cond.set();
} );
queue.onError( [this, &cond, qn]( const char* error_message ) {
elog( "AMQP error declaring queue ${q} for ${a}", ("q", qn)("a", amqp_connection_.address()) );
elog( "AMQP error declaring queue {q} for {a}", ("q", qn)("a", amqp_connection_.address()) );
on_error( error_message );
cond.set();
} );
Expand All @@ -122,7 +122,7 @@ class amqp_handler {
} );

if( !cond.wait() ) {
elog( "AMQP timeout declaring queue: ${q} for ${a}", ("q", queue_name)("a", amqp_connection_.address()) );
elog( "AMQP timeout declaring queue: {q} for {a}", ("q", queue_name)("a", amqp_connection_.address()) );
on_error( "AMQP timeout declaring queue: " + queue_name );
}
}
Expand All @@ -140,7 +140,7 @@ class amqp_handler {
cid=std::move(correlation_id), rt=std::move(reply_to), buf=std::move(buf)]() mutable {
try {
if( !my->channel_ ) {
elog( "AMQP not connected to channel ${a}", ("a", my->amqp_connection_.address()) );
elog( "AMQP not connected to channel {a}", ("a", my->amqp_connection_.address()) );
my->on_error( "AMQP not connected to channel" );
return;
}
Expand All @@ -162,7 +162,7 @@ class amqp_handler {
cid=std::move(correlation_id), rt=std::move(reply_to), f=std::move(f)]() mutable {
try {
if( !my->channel_ ) {
elog( "AMQP not connected to channel ${a}", ("a", my->amqp_connection_.address()) );
elog( "AMQP not connected to channel {a}", ("a", my->amqp_connection_.address()) );
my->on_error( "AMQP not connected to channel" );
return;
}
Expand Down Expand Up @@ -281,14 +281,14 @@ class amqp_handler {
// called from non-amqp thread
void wait() {
if( !first_connect_.wait() ) {
elog( "AMQP timeout connecting to: ${a}", ("a", amqp_connection_.address()) );
elog( "AMQP timeout connecting to: {a}", ("a", amqp_connection_.address()) );
on_error( "AMQP timeout connecting" );
}
}

// called from amqp thread
void channel_ready(AMQP::Channel* c) {
ilog( "AMQP Channel ready: ${id}, for ${a}", ("id", c ? c->id() : 0)("a", amqp_connection_.address()) );
ilog( "AMQP Channel ready: {id}, for {a}", ("id", c ? c->id() : 0)("a", amqp_connection_.address()) );
channel_ = c;
boost::system::error_code ec;
timer_.cancel(ec);
Expand All @@ -305,7 +305,7 @@ class amqp_handler {

// called from amqp thread
void channel_failed() {
wlog( "AMQP connection failed to: ${a}", ("a", amqp_connection_.address()) );
wlog( "AMQP connection failed to: {a}", ("a", amqp_connection_.address()) );
channel_ = nullptr;
// connection will automatically be retried by single_channel_retrying_amqp_connection

Expand All @@ -329,19 +329,19 @@ class amqp_handler {
channel_->recover(AMQP::requeue)
.onSuccess( [&]() { dlog( "successfully started channel recovery" ); } )
.onError( [&]( const char* message ) {
elog( "channel recovery failed ${e}", ("e", message) );
elog( "channel recovery failed {e}", ("e", message) );
on_error( "AMQP channel recovery failed" );
} );
}

auto& consumer = channel_->consume(queue_name_);
consumer.onSuccess([&](const std::string& consumer_tag) {
ilog("consume started, queue: ${q}, tag: ${tag}, for ${a}",
ilog("consume started, queue: {q}, tag: {tag}, for {a}",
("q", queue_name_)("tag", consumer_tag)("a", amqp_connection_.address()));
consumer_tag_ = consumer_tag;
});
consumer.onError([&](const char* message) {
elog("consume failed, queue ${q}, tag: ${t} error: ${e}, for ${a}",
elog("consume failed, queue {q}, tag: {t} error: {e}, for {a}",
("q", queue_name_)("t", consumer_tag_)("e", message)("a", amqp_connection_.address()));
consumer_tag_.clear();
});
Expand All @@ -355,21 +355,21 @@ class amqp_handler {
if( channel_ && on_consume_ && !consumer_tag_.empty() ) {
auto& consumer = channel_->cancel(consumer_tag_);
consumer.onSuccess([&, cb{std::move(on_cancel)}](const std::string& consumer_tag) {
ilog("consume stopped, queue: ${q}, tag: ${tag}, for ${a}",
ilog("consume stopped, queue: {q}, tag: {tag}, for {a}",
("q", queue_name_)("tag", consumer_tag)("a", amqp_connection_.address()));
consumer_tag_.clear();
on_consume_ = nullptr;
if( cb ) cb(consumer_tag);
});
consumer.onError([&](const char* message) {
elog("cancel consume failed, queue ${q}, tag: ${t} error: ${e}, for ${a}",
elog("cancel consume failed, queue {q}, tag: {t} error: {e}, for {a}",
("q", queue_name_)("t", consumer_tag_)("e", message)("a", amqp_connection_.address()));
consumer_tag_.clear();
on_consume_ = nullptr;
on_error(message);
});
} else {
wlog("Unable to stop consuming from queue: ${q}, tag: ${t}", ("q", queue_name_)("t", consumer_tag_));
wlog("Unable to stop consuming from queue: {q}, tag: {t}", ("q", queue_name_)("t", consumer_tag_));
}
}

Expand Down
15 changes: 15 additions & 0 deletions libraries/amqp/include/eosio/amqp/retrying_amqp_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,18 @@ struct single_channel_retrying_amqp_connection {
};

}

namespace fmt {
template<>
struct formatter<AMQP::Address> {
template<typename ParseContext>
constexpr auto parse( ParseContext& ctx ) { return ctx.begin(); }

template<typename FormatContext>
auto format( const AMQP::Address& p, FormatContext& ctx ) {
return format_to( ctx.out(), "{}", (std::string)p );
}
};
}


4 changes: 2 additions & 2 deletions libraries/amqp/reliable_amqp_publisher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ reliable_amqp_publisher_impl::reliable_amqp_publisher_impl(const std::string& ur
fc::raw::unpack(file, message_deque);
if( !message_deque.empty() )
batch_num = message_deque.back().num;
ilog("AMQP existing persistent file ${f} loaded with ${c} unconfirmed messages for ${a} publishing to \"${e}\".",
ilog("AMQP existing persistent file {f} loaded with {c} unconfirmed messages for {a} publishing to \"{e}\".",
("f", data_file_path.generic_string())("c",message_deque.size())("a", retrying_connection.address())("e", exchange));
} FC_RETHROW_EXCEPTIONS(error, "Failed to load previously unconfirmed AMQP messages from ${f}", ("f", (fc::path)data_file_path));
}
Expand Down Expand Up @@ -191,7 +191,7 @@ void reliable_amqp_publisher_impl::verify_max_queue_size() {
constexpr unsigned max_queued_messages = 1u << 20u;

if(message_deque.size() > max_queued_messages) {
elog("AMQP connection ${a} publishing to \"${e}\" has reached ${max} unconfirmed messages",
elog("AMQP connection {a} publishing to \"{e}\" has reached {max} unconfirmed messages",
("a", retrying_connection.address())("e", exchange)("max", max_queued_messages));
std::string err = "AMQP publishing to " + exchange + " has reached " + std::to_string(message_deque.size()) + " unconfirmed messages";
if( on_fatal_error) on_fatal_error(err);
Expand Down
20 changes: 10 additions & 10 deletions libraries/amqp/retrying_amqp_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct retrying_amqp_connection::impl : public AMQP::ConnectionHandler {
}

void onReady(AMQP::Connection* connection) override {
fc_ilog(_logger, "AMQP connection to ${s} is fully operational", ("s", _address));
fc_ilog(_logger, "AMQP connection to {s} is fully operational", ("s", _address));

_ready_callback(connection);
_indicated_ready = true;
Expand All @@ -34,20 +34,20 @@ struct retrying_amqp_connection::impl : public AMQP::ConnectionHandler {
}

void onError(AMQP::Connection* connection, const char* message) override {
fc_elog(_logger, "AMQP connection to ${s} suffered an error; will retry shortly: ${m}", ("s", _address)("m", message));
fc_elog(_logger, "AMQP connection to {s} suffered an error; will retry shortly: {m}", ("s", _address)("m", message));
schedule_retry();
}

void onClosed(AMQP::Connection *connection) override {
fc_wlog(_logger, "AMQP connection to ${s} closed AMQP connection", ("s", _address));
fc_wlog(_logger, "AMQP connection to {s} closed AMQP connection", ("s", _address));
schedule_retry();
}

void start_connection() {
_resolver.async_resolve(_address.hostname(), std::to_string(_address.port()), boost::asio::bind_executor(_strand, [this](const auto ec, const auto endpoints) {
if(ec) {
if(ec != boost::asio::error::operation_aborted) {
fc_wlog(_logger, "Failed resolving AMQP server ${s}; will retry shortly: ${m}", ("s", _address)("m", ec.message()));
fc_wlog(_logger, "Failed resolving AMQP server {s}; will retry shortly: {m}", ("s", _address)("m", ec.message()));
schedule_retry();
}
return;
Expand All @@ -58,12 +58,12 @@ struct retrying_amqp_connection::impl : public AMQP::ConnectionHandler {
boost::asio::async_connect(_sock, endpoints, boost::asio::bind_executor(_strand, [this](const auto ec, const auto endpoint) {
if(ec) {
if(ec != boost::asio::error::operation_aborted) {
fc_wlog(_logger, "Failed connecting AMQP server ${s}; will retry shortly: ${m}", ("s", _address)("m", ec.message()));
fc_wlog(_logger, "Failed connecting AMQP server {s}; will retry shortly: {m}", ("s", _address)("m", ec.message()));
schedule_retry();
}
return;
}
fc_ilog(_logger, "TCP connection to AMQP server at ${s} is up", ("s", _address));
fc_ilog(_logger, "TCP connection to AMQP server at {s} is up", ("s", _address));
receive_some();
_state->amqp_connection.emplace(this, _address.login(), _address.vhost());
}));
Expand Down Expand Up @@ -109,7 +109,7 @@ struct retrying_amqp_connection::impl : public AMQP::ConnectionHandler {
boost::asio::async_write(_sock, boost::asio::buffer(_state->outgoing_queue.front()), boost::asio::bind_executor(_strand, [this](const auto& ec, size_t wrote) {
if(ec) {
if(ec != boost::asio::error::operation_aborted) {
fc_wlog(_logger, "Failed writing to AMQP server ${s}; connection will retry shortly: ${m}", ("s", _address)("m", ec.message()));
fc_wlog(_logger, "Failed writing to AMQP server {s}; connection will retry shortly: {m}", ("s", _address)("m", ec.message()));
schedule_retry();
}
return;
Expand All @@ -124,7 +124,7 @@ struct retrying_amqp_connection::impl : public AMQP::ConnectionHandler {
_sock.async_read_some(boost::asio::buffer(_read_buff), boost::asio::bind_executor(_strand, [this](const auto& ec, size_t sz) {
if(ec) {
if(ec != boost::asio::error::operation_aborted) {
fc_wlog(_logger, "Failed reading from AMQP server ${s}; connection will retry shortly: ${m}", ("s", _address)("m", ec.message()));
fc_wlog(_logger, "Failed reading from AMQP server {s}; connection will retry shortly: {m}", ("s", _address)("m", ec.message()));
schedule_retry();
}
return;
Expand Down Expand Up @@ -213,11 +213,11 @@ struct single_channel_retrying_amqp_connection::impl {
_amqp_channel.emplace(_amqp_connection);
}
catch(...) {
fc_wlog(_logger, "AMQP channel could not start for AMQP connection ${c}; retrying", ("c", _connection.address()));
fc_wlog(_logger, "AMQP channel could not start for AMQP connection {c}; retrying", ("c", _connection.address()));
start_retry();
}
_amqp_channel->onError([this](const char* e) {
fc_wlog(_logger, "AMQP channel failure on AMQP connection ${c}; retrying : ${m}", ("c", _connection.address())("m", e));
fc_wlog(_logger, "AMQP channel failure on AMQP connection {c}; retrying : {m}", ("c", _connection.address())("m", e));
_failed();
start_retry();
});
Expand Down
8 changes: 8 additions & 0 deletions libraries/chain/abi_serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,14 @@ namespace eosio { namespace chain {
return _binary_to_variant(type, binary, ctx);
}

fc::variant abi_serializer::binary_to_log_variant( const std::string_view& type, const bytes& binary, const yield_function_t& yield, bool short_path )const {
impl::binary_to_variant_context ctx(*this, yield, type);
ctx.logging();
ctx.short_path = short_path;
return _binary_to_variant(type, binary, ctx);
}


void abi_serializer::_variant_to_binary( const std::string_view& type, const fc::variant& var, fc::datastream<char *>& ds, impl::variant_to_binary_context& ctx )const
{ try {
auto h = ctx.enter_scope();
Expand Down
Loading