Skip to content

Commit

Permalink
Merge pull request #31 from ess-dmsc/improve_dependency_handling_in_c…
Browse files Browse the repository at this point in the history
…make

Improve dependency handling in cmake
  • Loading branch information
matthew-d-jones authored Jun 7, 2019
2 parents 6024fec + da4ca26 commit 23d38bc
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 51 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ else()
add_definitions(-D_WIN32_WINNT=0x0A00)
endif(NOT WIN32)

find_package(ASIO REQUIRED MODULE)

add_subdirectory(src)

option(BUILD_EVERYTHING "Build UnitTests & Console Logger" ON)
Expand Down
11 changes: 11 additions & 0 deletions cmake/FindASIO.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ mark_as_advanced(
ASIO_ROOT_DIR
ASIO_INCLUDE_DIR
)

if(ASIO_FOUND)
set(ASIO_INCLUDE_DIRS ${ASIO_INCLUDE_DIR})
endif()

if(ASIO_FOUND AND NOT TARGET ASIO::ASIO)
add_library(ASIO::ASIO INTERFACE IMPORTED)
set_target_properties(ASIO::ASIO PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${ASIO_INCLUDE_DIR}"
)
endif()
8 changes: 6 additions & 2 deletions cmake/GraylogLoggerConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
get_filename_component(GraylogLogger_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(GraylogLogger_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
include(CMakeFindDependencyMacro)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/../cmake/")

find_dependency(Threads REQUIRED)

if(NOT TARGET GraylogLogger::graylog_logger)
include("${GraylogLogger_CMAKE_DIR}/GraylogLoggerTargets.cmake")
endif()

set(GraylogLogger_LIBRARIES GraylogLogger::graylog_logger)
set(GraylogLogger_LIBRARIES GraylogLogger::graylog_logger)
2 changes: 1 addition & 1 deletion conanfile.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ asio/1.13.0@bincrafters/stable
jsonformoderncpp/3.6.1@vthiery/stable

[options]
gtest:shared=True
gtest:shared=False

[generators]
cmake
Expand Down
18 changes: 18 additions & 0 deletions include/graylog_logger/ConnectionStatus.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/* Copyright (C) 2019 European Spallation Source, ERIC. See LICENSE file */
//===----------------------------------------------------------------------===//
///
/// \file
///
/// \brief Graylog connection status.
///
//===----------------------------------------------------------------------===//
#pragma once

namespace Log {
enum class Status {
ADDR_LOOKUP,
ADDR_RETRY_WAIT,
CONNECT,
SEND_LOOP,
};
} // namespace Log
19 changes: 15 additions & 4 deletions include/graylog_logger/GraylogInterface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,32 @@

#pragma once

#include "graylog_logger/GraylogConnection.hpp"
#include "graylog_logger/ConnectionStatus.hpp"
#include "graylog_logger/LogUtil.hpp"

namespace Log {
class GraylogConnection {
public:
using Status = Log::Status;
GraylogConnection(std::string Host, int Port);
virtual ~GraylogConnection();
virtual void sendMessage(std::string Msg);
virtual Status getConnectionStatus() const;
virtual bool messageQueueEmpty();
virtual size_t messageQueueSize();

class GraylogInterface : public BaseLogHandler, private GraylogConnection {
private:
class Impl;
std::unique_ptr<Impl> Pimpl;
};
class GraylogInterface : public BaseLogHandler, public GraylogConnection {
public:
GraylogInterface(const std::string &Host, int Port,
size_t MaxQueueLength = 100);
~GraylogInterface() override = default;
void addMessage(const LogMessage &Message) override;
bool emptyQueue() override;
size_t queueSize() override;
using GraylogConnection::Status;
using GraylogConnection::getConnectionStatus;

protected:
std::string logMsgToJSON(const LogMessage &Message);
Expand Down
19 changes: 13 additions & 6 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
find_package(Threads REQUIRED)
find_package(nlohmann_json REQUIRED)

set(Graylog_SRC
ConsoleInterface.cpp
Expand All @@ -15,19 +16,21 @@ set(Graylog_INC
../include/graylog_logger/ConcurrentQueue.hpp
../include/graylog_logger/ConsoleInterface.hpp
../include/graylog_logger/FileInterface.hpp
../include/graylog_logger/GraylogConnection.hpp
GraylogConnection.hpp
../include/graylog_logger/GraylogInterface.hpp
../include/graylog_logger/Log.hpp
../include/graylog_logger/Logger.hpp
../include/graylog_logger/LoggingBase.hpp
../include/graylog_logger/LogUtil.hpp
../include/graylog_logger/ThreadedExecutor.hpp
)

../include/graylog_logger/ConnectionStatus.hpp)
set(common_libs
Threads::Threads
CONAN_PKG::asio
CONAN_PKG::jsonformoderncpp)
PUBLIC
Threads::Threads
)

get_target_property(JSON_INCLUDE_DIR nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)

add_library(graylog_logger SHARED ${Graylog_SRC} ${Graylog_INC})
add_library(GraylogLogger::graylog_logger ALIAS graylog_logger)
Expand All @@ -38,6 +41,8 @@ target_include_directories(graylog_logger
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
PRIVATE
"."
${ASIO_INCLUDE_DIR}
${JSON_INCLUDE_DIR}
)

add_library(graylog_logger_static STATIC ${Graylog_SRC} ${Graylog_INC} ${Graylog_private_INC})
Expand All @@ -49,6 +54,8 @@ target_include_directories(graylog_logger_static
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
PRIVATE
"."
${ASIO_INCLUDE_DIR}
${JSON_INCLUDE_DIR}
)

set_target_properties(graylog_logger PROPERTIES VERSION ${PROJECT_VERSION})
Expand Down
42 changes: 22 additions & 20 deletions src/GraylogConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
///
//===----------------------------------------------------------------------===//

#include "graylog_logger/GraylogConnection.hpp"
#include "GraylogConnection.hpp"
#include <chrono>
#include <ciso646>
#include <utility>

namespace {
#define UNUSED_ARG(x) (void)x;
}
} // namespace

namespace Log {

Expand Down Expand Up @@ -46,7 +46,7 @@ struct QueryResult {
int NextEndpoint{0};
};

void GraylogConnection::tryConnect(QueryResult AllEndpoints) {
void GraylogConnection::Impl::tryConnect(QueryResult AllEndpoints) {
asio::ip::tcp::endpoint CurrentEndpoint = AllEndpoints.getNextEndpoint();
auto HandlerGlue = [this, AllEndpoints](auto &Err) {
this->connectHandler(Err, AllEndpoints);
Expand All @@ -55,15 +55,15 @@ void GraylogConnection::tryConnect(QueryResult AllEndpoints) {
setState(Status::CONNECT);
}

GraylogConnection::GraylogConnection(std::string Host, int Port)
GraylogConnection::Impl::Impl(std::string Host, int Port)
: HostAddress(std::move(Host)), HostPort(std::to_string(Port)), Service(),
Work(std::make_unique<asio::io_service::work>(Service)), Socket(Service),
Resolver(Service), ReconnectTimeout(Service, 10s) {
doAddressQuery();
AsioThread = std::thread(&GraylogConnection::threadFunction, this);
AsioThread = std::thread(&GraylogConnection::Impl::threadFunction, this);
}

void GraylogConnection::resolverHandler(
void GraylogConnection::Impl::resolverHandler(
const asio::error_code &Error,
asio::ip::tcp::resolver::iterator EndpointIter) {
if (Error) {
Expand All @@ -75,8 +75,8 @@ void GraylogConnection::resolverHandler(
tryConnect(AllEndpoints);
}

void GraylogConnection::connectHandler(const asio::error_code &Error,
const QueryResult &AllEndpoints) {
void GraylogConnection::Impl::connectHandler(const asio::error_code &Error,
const QueryResult &AllEndpoints) {
if (!Error) {
setState(Status::SEND_LOOP);
auto HandlerGlue = [this](auto &Error, auto Size) {
Expand All @@ -94,7 +94,7 @@ void GraylogConnection::connectHandler(const asio::error_code &Error,
tryConnect(AllEndpoints);
}

void GraylogConnection::reConnect(ReconnectDelay Delay) {
void GraylogConnection::Impl::reConnect(ReconnectDelay Delay) {
auto HandlerGlue = [this](auto &Err) { this->doAddressQuery(); };
switch (Delay) {
case ReconnectDelay::SHORT:
Expand All @@ -109,8 +109,8 @@ void GraylogConnection::reConnect(ReconnectDelay Delay) {
setState(Status::ADDR_RETRY_WAIT);
}

void GraylogConnection::receiveHandler(const asio::error_code &Error,
std::size_t BytesReceived) {
void GraylogConnection::Impl::receiveHandler(const asio::error_code &Error,
std::size_t BytesReceived) {
UNUSED_ARG(BytesReceived);
if (Error) {
Socket.close();
Expand All @@ -123,7 +123,7 @@ void GraylogConnection::receiveHandler(const asio::error_code &Error,
Socket.async_receive(asio::buffer(InputBuffer), HandlerGlue);
}

void GraylogConnection::trySendMessage() {
void GraylogConnection::Impl::trySendMessage() {
if (not Socket.is_open()) {
return;
}
Expand All @@ -149,8 +149,8 @@ void GraylogConnection::trySendMessage() {
}
}

void GraylogConnection::sentMessageHandler(const asio::error_code &Error,
std::size_t BytesSent) {
void GraylogConnection::Impl::sentMessageHandler(const asio::error_code &Error,
std::size_t BytesSent) {
if (BytesSent == MessageBuffer.size()) {
MessageBuffer.clear();
} else if (BytesSent > 0) {
Expand All @@ -166,7 +166,7 @@ void GraylogConnection::sentMessageHandler(const asio::error_code &Error,
trySendMessage();
}

void GraylogConnection::waitForMessage() {
void GraylogConnection::Impl::waitForMessage() {
if (not Socket.is_open()) {
return;
}
Expand All @@ -179,7 +179,7 @@ void GraylogConnection::waitForMessage() {
Service.post([this]() { this->waitForMessage(); });
}

void GraylogConnection::doAddressQuery() {
void GraylogConnection::Impl::doAddressQuery() {
setState(Status::ADDR_LOOKUP);
asio::ip::tcp::resolver::query Query(HostAddress, HostPort);
auto HandlerGlue = [this](auto &Error, auto EndpointIter) {
Expand All @@ -188,7 +188,7 @@ void GraylogConnection::doAddressQuery() {
Resolver.async_resolve(Query, HandlerGlue);
}

GraylogConnection::~GraylogConnection() {
GraylogConnection::Impl::~Impl() {
Service.stop();
AsioThread.join();
try {
Expand All @@ -198,13 +198,15 @@ GraylogConnection::~GraylogConnection() {
}
}

GraylogConnection::Status GraylogConnection::getConnectionStatus() const {
GraylogConnection::Impl::Status
GraylogConnection::Impl::getConnectionStatus() const {
return ConnectionState;
}

void GraylogConnection::threadFunction() { Service.run(); }
void GraylogConnection::Impl::threadFunction() { Service.run(); }

void GraylogConnection::setState(GraylogConnection::Status NewState) {
void GraylogConnection::Impl::setState(
GraylogConnection::Impl::Status NewState) {
ConnectionState = NewState;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#pragma once

#include "graylog_logger/ConcurrentQueue.hpp"
#include "graylog_logger/ConnectionStatus.hpp"
#include "graylog_logger/GraylogInterface.hpp"
#include <array>
#include <asio.hpp>
#include <atomic>
Expand All @@ -24,18 +26,15 @@ struct QueryResult;
/// \todo Implement timeouts in the ASIO code in case we ever have problems with
/// bad connections.

class GraylogConnection {
class GraylogConnection::Impl {
public:
GraylogConnection(std::string Host, int Port);
virtual ~GraylogConnection();
virtual void sendMessage(std::string msg) { LogMessages.push(msg); };
enum class Status {
ADDR_LOOKUP,
ADDR_RETRY_WAIT,
CONNECT,
SEND_LOOP,
};
using Status = Log::Status;
Impl(std::string Host, int Port);
virtual ~Impl();
virtual void sendMessage(std::string Msg) { LogMessages.push(Msg); };
Status getConnectionStatus() const;
bool messageQueueEmpty() { return LogMessages.empty(); }
size_t messageQueueSize() { return LogMessages.size(); }

protected:
enum class ReconnectDelay { LONG, SHORT };
Expand Down
32 changes: 25 additions & 7 deletions src/GraylogInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,44 @@
//===----------------------------------------------------------------------===//

#include "graylog_logger/GraylogInterface.hpp"
#include "GraylogConnection.hpp"
#include <ciso646>
#include <cstring>
#include <nlohmann/json.hpp>

namespace Log {

GraylogConnection::GraylogConnection(std::string Host, int Port)
: Pimpl(std::make_unique<GraylogConnection::Impl>(std::move(Host), Port)) {}

void GraylogConnection::sendMessage(std::string Msg) {
Pimpl->sendMessage(Msg);
}

Status GraylogConnection::getConnectionStatus() const {
return Pimpl->getConnectionStatus();
}

bool GraylogConnection::messageQueueEmpty() {
return Pimpl->messageQueueEmpty();
}

size_t GraylogConnection::messageQueueSize() {
return Pimpl->messageQueueSize();
}

GraylogConnection::~GraylogConnection() {}

GraylogInterface::GraylogInterface(const std::string &Host, const int Port,
const size_t MaxQueueLength)
: BaseLogHandler(MaxQueueLength), GraylogConnection(Host, Port) {}

bool GraylogInterface::emptyQueue() {
return GraylogConnection::LogMessages.empty();
}
bool GraylogInterface::emptyQueue() { return messageQueueEmpty(); }

size_t GraylogInterface::queueSize() {
return GraylogConnection::LogMessages.size();
}
size_t GraylogInterface::queueSize() { return messageQueueSize(); }

void GraylogInterface::addMessage(const LogMessage &Message) {
if (GraylogConnection::LogMessages.size() < BaseLogHandler::QueueLength) {
if (messageQueueSize() < BaseLogHandler::QueueLength) {
sendMessage(logMsgToJSON(Message));
}
}
Expand Down
4 changes: 3 additions & 1 deletion unit_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ add_executable(unit_tests ${UnitTest_SRC} ${UnitTest_INC})

target_link_libraries(unit_tests
GraylogLogger::graylog_logger_static
CONAN_PKG::gtest)
CONAN_PKG::jsonformoderncpp
CONAN_PKG::gtest
ASIO::ASIO)

add_test(TestAll unit_tests)
Loading

0 comments on commit 23d38bc

Please sign in to comment.