/* This file is part of cpp-ethereum. cpp-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. cpp-ethereum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ /** @file StructuredLogger.h * @author Lefteris Karapetsas * @date 2015 * * A simple helper class for the structured logging */ #include "StructuredLogger.h" #include #if ETH_JSONRPC #include #endif #include #include "Guards.h" namespace ba = boost::asio; using namespace std; namespace dev { void StructuredLogger::initialize(bool _enabled, std::string const& _timeFormat, std::string const& _destinationURL) { m_enabled = _enabled; m_timeFormat = _timeFormat; if (_destinationURL.size() > 7 && _destinationURL.substr(0, 7) == "file://") m_out.open(_destinationURL.substr(7)); // TODO: support tcp:// } void StructuredLogger::outputJson(Json::Value const& _value, std::string const& _name) const { #if ETH_JSONRPC Json::Value event; static Mutex s_lock; Json::FastWriter fastWriter; Guard l(s_lock); event[_name] = _value; (m_out.is_open() ? m_out : cout) << fastWriter.write(event) << endl; #else (void)_value; (void)_name; #endif } void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersion) { #if ETH_JSONRPC if (get().m_enabled) { Json::Value event; event["client_impl"] = _clientImpl; event["eth_version"] = std::string(_ethVersion); // TODO net_version event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "starting"); } #else (void)_clientImpl; (void)_ethVersion; #endif } void StructuredLogger::stopping(string const& _clientImpl, const char* _ethVersion) { #if ETH_JSONRPC if (get().m_enabled) { Json::Value event; event["client_impl"] = _clientImpl; event["eth_version"] = std::string(_ethVersion); // TODO net_version event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "stopping"); } #else (void)_clientImpl; (void)_ethVersion; #endif } void StructuredLogger::p2pConnected( string const& _id, bi::tcp::endpoint const& _addr, chrono::system_clock::time_point const& _ts, string const& _remoteVersion, unsigned int _numConnections) { #if ETH_JSONRPC if (get().m_enabled) { std::stringstream addrStream; addrStream << _addr; Json::Value event; event["remote_version_string"] = _remoteVersion; event["remote_addr"] = addrStream.str(); event["remote_id"] = _id; event["num_connections"] = Json::Value(_numConnections); event["ts"] = dev::toString(_ts, get().m_timeFormat.c_str()); get().outputJson(event, "p2p.connected"); } #else (void)_id; (void)_addr; (void)_ts; (void)_remoteVersion; (void)_numConnections; #endif } void StructuredLogger::p2pDisconnected(string const& _id, bi::tcp::endpoint const& _addr, unsigned int _numConnections) { #if ETH_JSONRPC if (get().m_enabled) { std::stringstream addrStream; addrStream << _addr; Json::Value event; event["remote_addr"] = addrStream.str(); event["remote_id"] = _id; event["num_connections"] = Json::Value(_numConnections); event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "p2p.disconnected"); } #else (void)_id; (void)_addr; (void)_numConnections; #endif } void StructuredLogger::minedNewBlock( string const& _hash, string const& _blockNumber, string const& _chainHeadHash, string const& _prevHash) { #if ETH_JSONRPC if (get().m_enabled) { Json::Value event; event["block_hash"] = _hash; event["block_number"] = _blockNumber; event["chain_head_hash"] = _chainHeadHash; event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["block_prev_hash"] = _prevHash; get().outputJson(event, "eth.miner.new_block"); } #else (void)_hash; (void)_blockNumber; (void)_chainHeadHash; (void)_prevHash; #endif } void StructuredLogger::chainReceivedNewBlock( string const& _hash, string const& _blockNumber, string const& _chainHeadHash, string const& _remoteID, string const& _prevHash) { #if ETH_JSONRPC if (get().m_enabled) { Json::Value event; event["block_hash"] = _hash; event["block_number"] = _blockNumber; event["chain_head_hash"] = _chainHeadHash; event["remote_id"] = _remoteID; event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["block_prev_hash"] = _prevHash; get().outputJson(event, "eth.chain.received.new_block"); } #else (void)_hash; (void)_blockNumber; (void)_chainHeadHash; (void)_remoteID; (void)_prevHash; #endif } void StructuredLogger::chainNewHead( string const& _hash, string const& _blockNumber, string const& _chainHeadHash, string const& _prevHash) { #if ETH_JSONRPC if (get().m_enabled) { Json::Value event; event["block_hash"] = _hash; event["block_number"] = _blockNumber; event["chain_head_hash"] = _chainHeadHash; event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["block_prev_hash"] = _prevHash; get().outputJson(event, "eth.miner.new_block"); } #else (void)_hash; (void)_blockNumber; (void)_chainHeadHash; (void)_prevHash; #endif } void StructuredLogger::transactionReceived(string const& _hash, string const& _remoteId) { #if ETH_JSONRPC if (get().m_enabled) { Json::Value event; event["tx_hash"] = _hash; event["remote_id"] = _remoteId; event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "eth.tx.received"); } #else (void)_hash; (void)_remoteId; #endif } }