Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,16 @@ else()
endif()
endif()

# Used to route gRPC's internal logs into our logger.
set(_ABSEIL_LOG
absl::log
absl::log_entry
absl::log_globals
absl::log_initialize
absl::log_sink
absl::log_sink_registry
)

# Python3 Virtual Environment
if(USE_PYTHON_VIRTUALENV)
include(CreateVirtualEnvironment)
Expand Down Expand Up @@ -657,6 +667,7 @@ endif()

set(server_lib_deps
${_ABSEIL_SYNC}
${_ABSEIL_LOG}
${_GRPC_GPR}
${_GRPC_GRPCPP}
${_GRPC}
Expand Down
69 changes: 67 additions & 2 deletions source/server/client_connection_logger.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
#include "client_connection_logger.h"
#include "logging.h"

#include <absl/log/globals.h>
#include <absl/log/initialize.h>
#include <absl/log/log_entry.h>
#include <absl/log/log_sink.h>
#include <absl/log/log_sink_registry.h>
#include <absl/strings/match.h>

#include <grpc/grpc_security_constants.h>

namespace nidevice_grpc {
Expand All @@ -19,12 +26,12 @@ std::string describe_authentication(const grpc::AuthContext& auth_context)
description += transport_type.empty() ? "unknown transport" : std::string(transport_type[0].data(), transport_type[0].size());

if (!common_names.empty())
description += ", client cert CN:" + std::string(common_names[0].data(), common_names[0].size());
description += ", client cert CN: " + std::string(common_names[0].data(), common_names[0].size());

return description;
}

}
} // namespace

bool parse_peer(const std::string& peer, std::string& ip, std::string& port)
{
Expand Down Expand Up @@ -100,4 +107,62 @@ void register_client_connection_logger()
grpc::Server::SetGlobalCallbacks(new ClientConnectionLogger());
}

namespace {

// Converts absl's severity levels to our own.
logging::Level to_logging_level(absl::LogSeverity severity)
{
switch (severity) {
case absl::LogSeverity::kWarning:
return logging::Level_Warning;
case absl::LogSeverity::kError:
case absl::LogSeverity::kFatal:
return logging::Level_Error;
case absl::LogSeverity::kInfo:
default:
return logging::Level_Info;
}
}

// This sink captures gRPC's own internal logs and calls Send for each of them. We only use it to log handshake failures.
class AuditLogSinkWrapper {
public:
AuditLogSinkWrapper() {
absl::InitializeLog();
absl::AddLogSink(&sink_);
}
Comment thread
ryanwixon-emerson marked this conversation as resolved.
~AuditLogSinkWrapper() {
absl::RemoveLogSink(&sink_);
}

// Disable copy/move constructors and assignment operators.
AuditLogSinkWrapper(const AuditLogSinkWrapper&) = delete;
AuditLogSinkWrapper& operator=(const AuditLogSinkWrapper&) = delete;
AuditLogSinkWrapper(AuditLogSinkWrapper&&) = delete;
AuditLogSinkWrapper& operator=(AuditLogSinkWrapper&&) = delete;

private:
class AuditLogSink : public absl::LogSink {
public:
void Send(const absl::LogEntry& entry) override
{
if (!absl::StrContainsIgnoreCase(entry.text_message(), "handshake"))
Comment thread
ryanwixon-emerson marked this conversation as resolved.
Outdated
return;

const auto message = std::string(entry.text_message());
logging::log_to_audit_source(to_logging_level(entry.log_severity()), "%s", message.c_str());
}
};

AuditLogSink sink_;
};

} // namespace

void register_grpc_log_sink()
{
// The wrapper handles adding and removing the log sink from absl.
static AuditLogSinkWrapper sink;
}

} // namespace nidevice_grpc
3 changes: 3 additions & 0 deletions source/server/client_connection_logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class ClientConnectionLogger : public grpc::Server::GlobalCallbacks {
// Registers a process-wide ClientConnectionLogger with gRPC, must be called before any grpc::Server is built.
void register_client_connection_logger();

// Registers an absl::LogSink that captures all of gRPC's internal log messages; used for logging connection failures
void register_grpc_log_sink();

} // namespace nidevice_grpc

#endif // NIDEVICE_GRPC_CLIENT_CONNECTION_LOGGER_H
2 changes: 2 additions & 0 deletions source/server/core_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,8 @@ int main(int argc, char** argv)
nidevice_grpc::set_console_ctrl_handler(&StopServer);
#endif

nidevice_grpc::register_grpc_log_sink();

RunServer(config);
return EXIT_SUCCESS;
}
Loading