Skip to content

Commit

Permalink
Extract gethostname into a dedicated module. Add unit test and better…
Browse files Browse the repository at this point in the history
… error management.
  • Loading branch information
sjanel committed Oct 22, 2023
1 parent 733fb06 commit b13d9f2
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 22 deletions.
5 changes: 3 additions & 2 deletions src/engine/src/coincentercommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
#include <filesystem>
#include <iostream>
#include <span>
#include <string_view>
#include <utility>

#include "cct_invalid_argument_exception.hpp"
#include "cct_log.hpp"
#include "cct_string.hpp"
#include "cct_vector.hpp"
#include "coincentercommand.hpp"
#include "coincentercommandtype.hpp"
#include "coincenteroptions.hpp"
#include "commandlineoptionsparser.hpp"
Expand All @@ -19,6 +19,7 @@
#include "monetaryamount.hpp"
#include "ordersconstraints.hpp"
#include "priceoptions.hpp"
#include "priceoptionsdef.hpp"
#include "stringoptionparser.hpp"
#include "timedef.hpp"
#include "tradedefinitions.hpp"
Expand Down
27 changes: 8 additions & 19 deletions src/monitoring/src/prometheusmetricgateway.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <cassert>
#include <chrono>
#include <exception>
#include <map>
#include <memory>
#include <mutex>
Expand All @@ -18,39 +19,27 @@
#include "abstractmetricgateway.hpp"
#include "cct_exception.hpp"
#include "cct_log.hpp"
#include "gethostname.hpp"
#include "metric.hpp"
#include "monitoringinfo.hpp"
#include "timedef.hpp"

#ifdef CCT_MSVC
#include <Winsock2.h>
#else
#include <unistd.h>
#endif

namespace cct {

namespace {
constexpr int kHTTPSuccessReturnCode = 200;
constexpr auto kHTTPSuccessReturnCode = 200;

// Constants to control frequency of flushes to Prometheus instance
constexpr Duration kPrometheusAutoFlushPeriod = std::chrono::minutes(3);
constexpr int kCheckFlushCounter = 20;

std::string GetHostName() {
char hostname[1024];
if (::gethostname(hostname, sizeof(hostname)) != 0) {
hostname[0] = '\0';
}
return hostname;
}
constexpr auto kPrometheusAutoFlushPeriod = std::chrono::minutes(3);
constexpr auto kCheckFlushCounter = 20;

} // namespace

PrometheusMetricGateway::PrometheusMetricGateway(const MonitoringInfo& monitoringInfo)
: AbstractMetricGateway(monitoringInfo),
_gateway(std::string(monitoringInfo.address()), std::to_string(monitoringInfo.port()),
std::string(monitoringInfo.jobName()), prometheus::Gateway::GetInstanceLabel(GetHostName()),
std::string(monitoringInfo.jobName()),
prometheus::Gateway::GetInstanceLabel(HostNameGetter().getHostName().toStdString()),
std::string(monitoringInfo.username()), std::string(monitoringInfo.password())),
_registry(std::make_shared<Registry>()),
_lastFlushedTime(Clock::now()),
Expand All @@ -63,7 +52,7 @@ PrometheusMetricGateway::~PrometheusMetricGateway() {
// We should not throw in a destructor - catch any exception and do nothing, not even a log (it could throw)
try {
flush();
} catch (...) {
} catch (const std::exception&) {
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/objects/include/logginginfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace cct {
/// @brief Encapsulates loggers lifetime and set-up.
class LoggingInfo {
public:
static constexpr int64_t kDefaultFileSizeInBytes = 5 * 1024 * 1024;
static constexpr int64_t kDefaultFileSizeInBytes = 5L * 1024 * 1024;
static constexpr int32_t kDefaultNbMaxFiles = 10;
static constexpr char const *const kOutputLoggerName = "output";

Expand Down
23 changes: 23 additions & 0 deletions src/tech/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,29 @@ add_unit_test(
nlohmann_json::nlohmann_json
)



if(WIN32)
add_unit_test(
gethostname_test
src/gethostname.cpp
test/gethostname_test.cpp
DEFINITIONS
CCT_DISABLE_SPDLOG
LIBRARIES
wsock32
ws2_32
)
else()
add_unit_test(
gethostname_test
src/gethostname.cpp
test/gethostname_test.cpp
DEFINITIONS
CCT_DISABLE_SPDLOG
)
endif()

add_unit_test(
mathhelpers_test
test/mathhelpers_test.cpp
Expand Down
30 changes: 30 additions & 0 deletions src/tech/include/gethostname.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once

#include "cct_config.hpp"
#include "cct_string.hpp"

namespace cct {
class HostNameGetter {
public:
#ifdef CCT_MSVC
HostNameGetter();
#else
HostNameGetter() noexcept = default;
#endif

HostNameGetter(const HostNameGetter &) = delete;
HostNameGetter &operator=(const HostNameGetter &) = delete;
HostNameGetter(HostNameGetter &&) = delete;
HostNameGetter &operator=(HostNameGetter &&) = delete;

#ifdef CCT_MSVC
~HostNameGetter();
#else
~HostNameGetter() = default;
#endif

/// Safe version of gethostname, working in POSIX and Windows with similar behavior.
string getHostName() const;
};

} // namespace cct
74 changes: 74 additions & 0 deletions src/tech/src/gethostname.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "gethostname.hpp"

#include <iostream>

#include "cct_config.hpp"
#include "cct_exception.hpp"
#include "cct_string.hpp"
#ifdef CCT_MSVC
#include <Winsock2.h>
#include <winsock.h>
#else
#include <errno.h>
#include <unistd.h>
#endif

namespace cct {
#ifdef CCT_MSVC
HostNameGetter::HostNameGetter() {
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(2, 2);
auto errCode = WSAStartup(wVersionRequested, &wsaData);
if (errCode != 0) {
throw exception("Error {} in WSAStartup", errCode);
}
}

HostNameGetter::~HostNameGetter() { WSACleanup(); }
#endif

string HostNameGetter::getHostName() const {
string hostname(4U, '\0');
static constexpr std::size_t kMaxHostNameSize = 1024;
std::size_t nullTerminatedCharPos = 0;
do {
auto errorCode = ::gethostname(hostname.data(), hostname.size() - 1U);
if (errorCode != 0) {
#ifdef CCT_MSVC
// In Windows, too small buffer returns an error WSAEFAULT
std::cout << "errorCode = " << errorCode << std::endl;
std::cerr << "WSAGetLastError() = " << WSAGetLastError() << std::endl;
if (WSAGetLastError() == WSAEFAULT) {
#else
// In Posix, too small buffer returns an error ENAMETOOLONG set in errno
if (errno == ENAMETOOLONG) {
#endif
nullTerminatedCharPos = hostname.size() - 1U;
hostname.resize(2 * hostname.size(), '\0');
continue;
}
throw exception("Error {} in gethostname", errorCode);
}
#ifndef CCT_MSVC
if (hostname.back() != '\0') {
// In POSIX, if the null-terminated hostname is too large to fit, then the name is truncated, and no error is
// returned, meaning that last char has necessarily been written to
nullTerminatedCharPos = hostname.size() - 1U;
hostname.resize(2 * hostname.size(), '\0');
continue;
}
#endif
if (hostname.size() > kMaxHostNameSize) {
throw exception("Unexpected host name size length {}", hostname.size());
}
break;
} while (true);

auto hostnameSize = hostname.find('\0', nullTerminatedCharPos);
if (hostnameSize == string::npos) {
throw exception("Unexpected error in GetHostName algorithm");
}
hostname.resize(hostnameSize);
return hostname;
}
} // namespace cct
13 changes: 13 additions & 0 deletions src/tech/test/gethostname_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "gethostname.hpp"

#include <gtest/gtest.h>

namespace cct {
TEST(GetHostNameTest, Default) {
HostNameGetter hostNameGetter;
auto currentHostName = hostNameGetter.getHostName();

EXPECT_FALSE(currentHostName.empty());
EXPECT_EQ(currentHostName.find('\0'), string::npos);
}
} // namespace cct

0 comments on commit b13d9f2

Please sign in to comment.