Skip to content
This repository has been archived by the owner on Jan 15, 2025. It is now read-only.

Commit

Permalink
Merge pull request #257 from nicklewis/PCP-906
Browse files Browse the repository at this point in the history
(PCP-906) Enable websocketpp logging
  • Loading branch information
beechtom authored Nov 1, 2021
2 parents 16c63f8 + 8779b1c commit 634b4d8
Show file tree
Hide file tree
Showing 19 changed files with 356 additions and 175 deletions.
16 changes: 16 additions & 0 deletions lib/inc/cpp-pcp-client/connector/client_metadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define CPP_PCP_CLIENT_SRC_CONNECTOR_CLIENT_METADATA_H_

#include <cpp-pcp-client/export.h>
#include <cpp-pcp-client/util/logging.hpp>

#include <string>
#include <cstdint>
Expand All @@ -25,6 +26,8 @@ class LIBCPP_PCP_CLIENT_EXPORT ClientMetadata {
long ws_connection_timeout_ms;
uint32_t pong_timeouts_before_retry;
long pong_timeout_ms;
leatherman::logging::log_level loglevel{};
std::ofstream* logstream;

/// Throws a connection_config_error in case: the client
/// certificate file does not exist or is invalid; it fails to
Expand Down Expand Up @@ -60,6 +63,19 @@ class LIBCPP_PCP_CLIENT_EXPORT ClientMetadata {
long _ws_connection_timeout_ms,
uint32_t _pong_timeouts_before_retry,
long _pong_timeout_ms);

// constructor logging addition
ClientMetadata(std::string _client_type,
std::string _ca,
std::string _crt,
std::string _key,
std::string _crl,
std::string proxy,
leatherman::logging::log_level loglevel,
std::ofstream* logstream,
long _ws_connection_timeout_ms,
uint32_t _pong_timeouts_before_retry,
long _pong_timeout_ms);
};

} // namespace PCPClient
Expand Down
15 changes: 10 additions & 5 deletions lib/inc/cpp-pcp-client/connector/connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

#include <cpp-pcp-client/connector/timings.hpp>
#include <cpp-pcp-client/connector/client_metadata.hpp>
#include <cpp-pcp-client/util/logging.hpp>
#include <cpp-pcp-client/util/thread.hpp>
#include <cpp-pcp-client/export.h>

#include <boost/nowide/fstream.hpp>

#include <string>
#include <vector>
#include <memory>
Expand All @@ -26,10 +29,6 @@ namespace websocketpp {
template <typename T>
class client;

namespace config {
struct asio_tls_client;
}

namespace message_buffer {
namespace alloc {
template <typename message>
Expand All @@ -49,6 +48,8 @@ namespace websocketpp {

namespace PCPClient {

struct ws_config;

// Constants

static const std::string PING_PAYLOAD_DEFAULT { "" };
Expand All @@ -57,7 +58,7 @@ static const std::string DEFAULT_CLOSE_REASON { "Closed by client" };

// Configuration of the WebSocket transport layer

using WS_Client_Type = websocketpp::client<websocketpp::config::asio_tls_client>;
using WS_Client_Type = websocketpp::client<ws_config>;
using WS_Context_Ptr = websocketpp::lib::shared_ptr<boost::asio::ssl::context>;
using WS_Connection_Handle = websocketpp::connection_hdl;

Expand Down Expand Up @@ -119,6 +120,10 @@ class LIBCPP_PCP_CLIENT_EXPORT Connection {
/// Reset all the callbacks
void resetCallbacks();

/// WebSocket++ logging configuration
void setWebSocketLogLevel(leatherman::logging::log_level loglevel);
void setWebSocketLogStream(std::ofstream* logstream);

/// Check the state of the WebSocket connection; in case it's not
/// open, try to re-open it.
/// Try to reopen for max_connect_attempts times or indefinitely,
Expand Down
17 changes: 17 additions & 0 deletions lib/inc/cpp-pcp-client/connector/connector_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
#include <cpp-pcp-client/validator/validator.hpp>
#include <cpp-pcp-client/validator/schema.hpp>

#include <cpp-pcp-client/util/logging.hpp>
#include <cpp-pcp-client/util/thread.hpp>

#include <cpp-pcp-client/export.h>


namespace PCPClient {

//
Expand Down Expand Up @@ -60,6 +62,21 @@ class LIBCPP_PCP_CLIENT_EXPORT ConnectorBase {
uint32_t pong_timeouts_before_retry,
long ws_pong_timeout_ms);


// constructor logging addition
ConnectorBase(std::vector<std::string> broker_ws_uris,
std::string client_type,
std::string ca_crt_path,
std::string client_crt_path,
std::string client_key_path,
std::string client_crl_path,
std::string ws_proxy,
leatherman::logging::log_level loglevel,
std::ofstream* logstream,
long ws_connection_timeout_ms,
uint32_t pong_timeouts_before_retry,
long ws_pong_timeout_ms);

/// Calls stopMonitorTaskAndWait if the Monitoring Task thread is
/// still active. In case an exception was previously stored by
/// the Monitoring Task, the error message will be logged, but
Expand Down
16 changes: 16 additions & 0 deletions lib/inc/cpp-pcp-client/connector/v1/connector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ class LIBCPP_PCP_CLIENT_EXPORT Connector : public ConnectorBase {
uint32_t pong_timeouts_before_retry = 3,
long ws_pong_timeout_ms = 5000);

// constructor for logging addition
Connector(std::vector<std::string> broker_ws_uris,
std::string client_type,
std::string ca_crt_path,
std::string client_crt_path,
std::string client_key_path,
std::string client_crl_path,
std::string ws_proxy,
leatherman::logging::log_level loglevel,
std::ofstream* logstream,
long ws_connection_timeout_ms = 5000,
uint32_t association_timeout_s = 15,
uint32_t association_request_ttl_s = 10, // Unused
uint32_t pong_timeouts_before_retry = 3,
long ws_pong_timeout_ms = 5000);

/// Set an optional callback for associate responses
void setAssociateCallback(MessageCallback callback);

Expand Down
16 changes: 15 additions & 1 deletion lib/inc/cpp-pcp-client/connector/v2/connector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,28 @@ class LIBCPP_PCP_CLIENT_EXPORT Connector : public ConnectorBase {
uint32_t pong_timeouts_before_retry = 3,
long ws_pong_timeout_ms = 5000);

// constructor for proxy addition
// constructor for crl addition
Connector(std::vector<std::string> broker_ws_uris,
std::string client_type,
std::string ca_crt_path,
std::string client_crt_path,
std::string client_key_path,
std::string client_crl_path,
std::string ws_proxy,
long ws_connection_timeout_ms = 5000,
uint32_t pong_timeouts_before_retry = 3,
long ws_pong_timeout_ms = 5000);

// constructor for logging addition
Connector(std::vector<std::string> broker_ws_uris,
std::string client_type,
std::string ca_crt_path,
std::string client_crt_path,
std::string client_key_path,
std::string client_crl_path,
std::string ws_proxy,
leatherman::logging::log_level loglevel,
std::ofstream* logstream,
long ws_connection_timeout_ms = 5000,
uint32_t pong_timeouts_before_retry = 3,
long ws_pong_timeout_ms = 5000);
Expand Down
12 changes: 12 additions & 0 deletions lib/inc/cpp-pcp-client/ws_config.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#pragma once

#include <websocketpp/config/asio_client.hpp>

namespace PCPClient {
struct ws_config : public websocketpp::config::asio_tls_client {
static const websocketpp::log::level elog_level =
websocketpp::log::elevel::all;
static const websocketpp::log::level alog_level =
websocketpp::log::alevel::all;
};
}
34 changes: 34 additions & 0 deletions lib/src/connector/client_metadata.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace PCPClient {

namespace lth_loc = leatherman::locale;
namespace lth_log = leatherman::logging;

// Get rid of OSX 10.7 and greater deprecation warnings.
#if defined(__APPLE__) && defined(__clang__)
Expand Down Expand Up @@ -121,6 +122,7 @@ ClientMetadata::ClientMetadata(std::string _client_type,
ws_connection_timeout_ms { std::move(_ws_connection_timeout_ms) },
pong_timeouts_before_retry { std::move(_pong_timeouts_before_retry) },
pong_timeout_ms { std::move(_pong_timeout_ms) }

{
LOG_INFO("Retrieved common name from the certificate and determined "
"the client URI: {1}", uri);
Expand Down Expand Up @@ -183,4 +185,36 @@ ClientMetadata::ClientMetadata(std::string _client_type,
}


// constructor for logging addition
ClientMetadata::ClientMetadata(std::string _client_type,
std::string _ca,
std::string _crt,
std::string _key,
std::string _crl,
std::string _proxy,
lth_log::log_level _loglevel,
std::ofstream* _logstream,
long _ws_connection_timeout_ms,
uint32_t _pong_timeouts_before_retry,
long _pong_timeout_ms)
: ca { std::move(_ca) },
crt { std::move(_crt) },
key { std::move(_key) },
crl { std::move(_crl) },
proxy { std::move(_proxy) },
client_type { std::move(_client_type) },
common_name { getCommonNameFromCert(crt) },
uri { PCP_URI_SCHEME + common_name + "/" + client_type },
loglevel { std::move(_loglevel) },
logstream { _logstream },
ws_connection_timeout_ms { std::move(_ws_connection_timeout_ms) },
pong_timeouts_before_retry { std::move(_pong_timeouts_before_retry) },
pong_timeout_ms { std::move(_pong_timeout_ms) }
{
LOG_INFO("Retrieved common name from the certificate and determined "
"the client URI: {1}", uri);
validatePrivateKeyCertPair(key, crt);
LOG_DEBUG("Validated the private key / certificate pair");
}

} // namespace PCPClient
66 changes: 61 additions & 5 deletions lib/src/connector/connection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <cpp-pcp-client/protocol/v1/message.hpp>
#include <cpp-pcp-client/util/thread.hpp>
#include <cpp-pcp-client/util/chrono.hpp>
#include <cpp-pcp-client/ws_config.hpp>

// This is hacky because MinGW-w64 5.2 with Boost 1.58 is printing warnings that should be suppressed. Preserve the
// warnings elsewhere to make sure we have coverage of our code, but suppress for the whole file on Windows to avoid
Expand All @@ -22,7 +23,6 @@
#pragma GCC diagnostic ignored "-Wunused-variable"
#include <websocketpp/common/connection_hdl.hpp>
#include <websocketpp/client.hpp>
#include <websocketpp/config/asio_client.hpp>
#ifndef _WIN32
#pragma GCC diagnostic pop
#endif
Expand Down Expand Up @@ -54,6 +54,7 @@ namespace PCPClient {

namespace lth_util = leatherman::util;
namespace lth_loc = leatherman::locale;
namespace lth_log = leatherman::logging;

//
// Constants
Expand Down Expand Up @@ -84,12 +85,10 @@ Connection::Connection(std::vector<std::string> broker_ws_uris,
consecutive_pong_timeouts_ { 0 },
endpoint_ { new WS_Client_Type() }
{
// Turn off websocketpp logging to avoid runtime errors (see CTH-69)
endpoint_->clear_access_channels(websocketpp::log::alevel::all);
endpoint_->clear_error_channels(websocketpp::log::elevel::all);

// Initialize the transport system. Note that in perpetual mode,
// the event loop does not terminate when there are no connections
setWebSocketLogLevel(client_metadata_.loglevel);
setWebSocketLogStream(client_metadata_.logstream);
endpoint_->init_asio();
endpoint_->start_perpetual();

Expand Down Expand Up @@ -143,6 +142,63 @@ ConnectionState Connection::getConnectionState() const
return connection_state_.load();
}

//
// WebSocket logging configuration
//

void Connection::setWebSocketLogLevel(lth_log::log_level loglevel)
{
// Ensure all log channels are disabled
endpoint_->set_access_channels(websocketpp::log::alevel::none);
endpoint_->set_error_channels(websocketpp::log::elevel::none);

// WebSocket++ log levels are defined at
// https://raw.githubusercontent.com/zaphoyd/websocketpp/master/docs/logging.dox
// For any given log level, fallthrough and set logs at all higher levels.
// This could also be accomplished by defining a custom log package for each
// leatherman log level using a bitwise OR operator, but this is simpler.
switch (loglevel) {
case(lth_log::log_level::trace):
endpoint_->set_access_channels(websocketpp::log::alevel::devel |
websocketpp::log::alevel::frame_header);
endpoint_->set_error_channels(websocketpp::log::elevel::devel);

case(lth_log::log_level::debug):
endpoint_->set_access_channels(websocketpp::log::alevel::debug_handshake |
websocketpp::log::alevel::debug_close);
endpoint_->set_error_channels(websocketpp::log::elevel::library);

case(lth_log::log_level::info):
endpoint_->set_access_channels(websocketpp::log::alevel::connect |
websocketpp::log::alevel::disconnect);
endpoint_->set_error_channels(websocketpp::log::elevel::info);

case(lth_log::log_level::warning):
endpoint_->set_error_channels(websocketpp::log::elevel::warn);

case(lth_log::log_level::error):
endpoint_->set_error_channels(websocketpp::log::elevel::rerror);

case(lth_log::log_level::fatal):
endpoint_->set_error_channels(websocketpp::log::elevel::fatal);
break;

case(lth_log::log_level::none):
break; // All log channels already disabled, do nothing

default:
throw connection_config_error { lth_loc::format("invalid log level: '{1}'", loglevel) };
}
}

void Connection::setWebSocketLogStream(std::ofstream* logstream)
{
if (logstream != nullptr) {
endpoint_->get_alog().set_ostream(logstream);
endpoint_->get_elog().set_ostream(logstream);
}
}

//
// Callback modifiers
//
Expand Down
Loading

0 comments on commit 634b4d8

Please sign in to comment.