Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: graylog integration #3163

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions config.lua.dist
Original file line number Diff line number Diff line change
Expand Up @@ -588,3 +588,11 @@ metricsPrometheusAddress = "0.0.0.0:9464"
--- OStream
metricsEnableOstream = false
metricsOstreamInterval = 1000

-- Graylog
-- NOTE set graylogLevel: trace, debug, info, warning, error, critical, off (default: info).
graylogEnabled = true
graylogHostNameOrAddress = "127.0.0.1"
graylogSource = "Canary"
graylogPort = 12201
graylogLevel = "trace"
12 changes: 12 additions & 0 deletions src/canary_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "server/network/protocol/protocolstatus.hpp"
#include "server/network/webhook/webhook.hpp"
#include "creatures/players/vocations/vocation.hpp"
#include <lib/logging/gray_log_sink_options.hpp>

CanaryServer::CanaryServer(
Logger &logger,
Expand Down Expand Up @@ -137,6 +138,17 @@
logger.info("{} {}", g_configManager().getString(SERVER_NAME), "server online!");
g_logger().setLevel(g_configManager().getString(LOGLEVEL));

if (g_configManager().getBoolean(GRAYLOG_ENABLED)) {
GrayLogSinkOptions options {
g_configManager().getString(GRAYLOG_HOSTNAME_OR_ADDRESS),
g_configManager().getString(GRAYLOG_SOURCE),
g_configManager().getString(GRAYLOG_LEVEL),
g_configManager().getNumber(GRAYLOG_PORT)

Check warning on line 146 in src/canary_server.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-24.04-linux-release

narrowing conversion of ‘(&((ConfigManager& (*)())g_configManager)())->ConfigManager::getNumber(GRAYLOG_PORT, std::source_location::current(__builtin_source_location()))’ from ‘int32_t’ {aka ‘int’} to ‘short int’ [-Wnarrowing]

Check warning on line 146 in src/canary_server.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-22.04-linux-release

narrowing conversion of ‘(&((ConfigManager& (*)())g_configManager)())->ConfigManager::getNumber(GRAYLOG_PORT, std::source_location::current(__builtin_source_location()))’ from ‘int32_t’ {aka ‘int’} to ‘short int’ [-Wnarrowing]

Check warning on line 146 in src/canary_server.cpp

View workflow job for this annotation

GitHub Actions / windows-2022-windows-release

conversion from 'int32_t' to 'short' requires a narrowing conversion

Check warning on line 146 in src/canary_server.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-22.04-linux-debug

narrowing conversion of ‘(&((ConfigManager& (*)())g_configManager)())->ConfigManager::getNumber(GRAYLOG_PORT, std::source_location::current(__builtin_source_location()))’ from ‘int32_t’ {aka ‘int’} to ‘short int’ [-Wnarrowing]

Check warning on line 146 in src/canary_server.cpp

View workflow job for this annotation

GitHub Actions / ubuntu-24.04-linux-debug

narrowing conversion of ‘(&((ConfigManager& (*)())g_configManager)())->ConfigManager::getNumber(GRAYLOG_PORT, std::source_location::current(__builtin_source_location()))’ from ‘int32_t’ {aka ‘int’} to ‘short int’ [-Wnarrowing]
};

g_logger().enableGraylogSink(options);
}

serviceManager.run();

shutdown();
Expand Down
7 changes: 6 additions & 1 deletion src/config/config_enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,5 +325,10 @@ enum ConfigKey_t : uint16_t {
WHEEL_POINTS_PER_LEVEL,
WHITE_SKULL_TIME,
WORLD_TYPE,
XP_DISPLAY_MODE
XP_DISPLAY_MODE,
GRAYLOG_ENABLED,
GRAYLOG_HOSTNAME_OR_ADDRESS,
GRAYLOG_SOURCE,
GRAYLOG_PORT,
GRAYLOG_LEVEL
};
6 changes: 6 additions & 0 deletions src/config/configmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,12 @@ bool ConfigManager::load() {
loadStringConfig(L, WORLD_TYPE, "worldType", "pvp");
loadStringConfig(L, LOGLEVEL, "logLevel", "info");

loadBoolConfig(L, GRAYLOG_ENABLED, "graylogEnabled", false);
loadStringConfig(L, GRAYLOG_HOSTNAME_OR_ADDRESS, "graylogHostNameOrAddress", "127.0.0.1");
loadStringConfig(L, GRAYLOG_SOURCE, "graylogSource", "Canary");
loadStringConfig(L, GRAYLOG_LEVEL, "graylogLevel", "info");
loadIntConfig(L, GRAYLOG_PORT, "graylogPort", 12201);

loaded = true;
lua_close(L);
return true;
Expand Down
82 changes: 82 additions & 0 deletions src/lib/logging/gray_log_sink.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* Canary - A free and open-source MMORPG server emulator
* Copyright (©) 2019-2024 OpenTibiaBR <[email protected]>
* Repository: https://github.com/opentibiabr/canary
* License: https://github.com/opentibiabr/canary/blob/main/LICENSE
* Contributors: https://github.com/opentibiabr/canary/graphs/contributors
* Website: https://docs.opentibiabr.com/
*/

#pragma once

#include <spdlog/sinks/base_sink.h>
#include <asio.hpp>
#include <nlohmann/json.hpp>
#include <chrono>
#include <iostream>
#include "gray_log_sink_options.hpp"

class GrayLogSink : public spdlog::sinks::base_sink<std::mutex> {
public:
GrayLogSink(const GrayLogSinkOptions &options) :

Check warning on line 21 in src/lib/logging/gray_log_sink.hpp

View workflow job for this annotation

GitHub Actions / cppcheck

[cppcheck] reported by reviewdog 🐶 Class 'GrayLogSink' has a constructor with 1 argument that is not explicit. Raw Output: src/lib/logging/gray_log_sink.hpp:21:Class 'GrayLogSink' has a constructor with 1 argument that is not explicit.
_io_context(),
_socket(_io_context, asio::ip::udp::v4()),
_endpoint(asio::ip::make_address(options.hostNameOrAddress), options.port),
_options(options) { }

protected:
void sink_it_(const spdlog::details::log_msg &msg) override {
try {

if (spdlog::level::from_str(_options.level) > msg.level) {
return;
}

nlohmann::json gelf_message;
gelf_message["version"] = "1.0";
gelf_message["host"] = _options.source;
gelf_message["short_message"] = std::string(msg.payload.begin(), msg.payload.end());

auto now = std::chrono::system_clock::now();
auto duration = now.time_since_epoch();
double timestamp = std::chrono::duration_cast<std::chrono::seconds>(duration).count() + (std::chrono::duration_cast<std::chrono::microseconds>(duration).count() % 1000000) / 1e6;

gelf_message["timestamp"] = timestamp;
gelf_message["level"] = mapLogLevel(msg.level);

std::string serialized_message = gelf_message.dump();

_socket.send_to(asio::buffer(serialized_message), _endpoint);
} catch (const std::exception &ex) {
std::cerr << "Graylog sink send message error: " << ex.what() << std::endl;
}
}

void flush_() override {
}

private:
asio::io_context _io_context;
asio::ip::udp::socket _socket;
asio::ip::udp::endpoint _endpoint;
GrayLogSinkOptions _options;

int mapLogLevel(spdlog::level::level_enum level) {
switch (level) {
case spdlog::level::trace:
return 7; // Debug
case spdlog::level::debug:
return 7; // Debug
case spdlog::level::info:
return 6; // Informational
case spdlog::level::warn:
return 4; // Warning
case spdlog::level::err:
return 3; // Error
case spdlog::level::critical:
return 2; // Critical
default:
return 1; // Alert
}
}
};
18 changes: 18 additions & 0 deletions src/lib/logging/gray_log_sink_options.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Canary - A free and open-source MMORPG server emulator
* Copyright (©) 2019-2024 OpenTibiaBR <[email protected]>
* Repository: https://github.com/opentibiabr/canary
* License: https://github.com/opentibiabr/canary/blob/main/LICENSE
* Contributors: https://github.com/opentibiabr/canary/graphs/contributors
* Website: https://docs.opentibiabr.com/
*/

#pragma once
#include <iostream>

struct GrayLogSinkOptions {
const std::string hostNameOrAddress;
const std::string source;
const std::string level;
short port;
};
21 changes: 21 additions & 0 deletions src/lib/logging/log_with_spd_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

#include <spdlog/spdlog.h>
#include "lib/di/container.hpp"
#include <spdlog/sinks/stdout_color_sinks.h>
#include "gray_log_sink_options.hpp"
#include "gray_log_sink.hpp"

LogWithSpdLog::LogWithSpdLog() {
setLevel("info");
Expand Down Expand Up @@ -50,6 +53,24 @@ void LogWithSpdLog::critical(const std::string &msg) const {
SPDLOG_CRITICAL(msg);
}

void LogWithSpdLog::enableGraylogSink(const GrayLogSinkOptions options) const {

// Criação do sink do console (já existente no logger padrão)
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();

// Criação do sink Graylog
auto graylog_sink = std::make_shared<GrayLogSink>(options);

// Combinar os dois sinks em um logger
auto combined_logger = std::make_shared<spdlog::logger>(
"",
spdlog::sinks_init_list { console_sink, graylog_sink }
);

// Registrar o logger combinado como o logger padrão
spdlog::set_default_logger(combined_logger);
}

#if defined(DEBUG_LOG)
void LogWithSpdLog::debug(const std::string &msg) const {
SPDLOG_DEBUG(msg);
Expand Down
2 changes: 2 additions & 0 deletions src/lib/logging/log_with_spd_log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class LogWithSpdLog final : public Logger {
void error(const std::string &msg) const override;
void critical(const std::string &msg) const override;

void enableGraylogSink(const GrayLogSinkOptions options) const override;

#if defined(DEBUG_LOG)
void debug(const std::string &msg) const override;
void trace(const std::string &msg) const override;
Expand Down
2 changes: 2 additions & 0 deletions src/lib/logging/logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include "utils/transparent_string_hash.hpp"
#include "gray_log_sink_options.hpp"

namespace spdlog {
class logger;
Expand All @@ -25,6 +26,7 @@ class Logger {

virtual void setLevel(const std::string &name) const = 0;
virtual std::string getLevel() const = 0;
virtual void enableGraylogSink(const GrayLogSinkOptions options) const = 0;

/**
* @brief Logs the execution time of a given operation to a profile log file.
Expand Down
3 changes: 3 additions & 0 deletions vcproj/canary.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@
<ClInclude Include="..\src\lib\di\runtime_provider.hpp" />
<ClInclude Include="..\src\lib\di\shared.hpp" />
<ClInclude Include="..\src\lib\di\soft_singleton.hpp" />
<ClInclude Include="..\src\lib\logging\gray_log_sink.hpp" />
<ClInclude Include="..\src\lib\logging\gray_log_sink_options.hpp" />
<ClInclude Include="..\src\lib\logging\logger.hpp" />
<ClInclude Include="..\src\lib\logging\log_with_spd_log.hpp" />
<ClInclude Include="..\src\lib\metrics\metrics.hpp" />
Expand Down Expand Up @@ -315,6 +317,7 @@
<ClCompile Include="..\src\kv\kv_sql.cpp" />
<ClCompile Include="..\src\kv\kv.cpp" />
<ClCompile Include="..\src\lib\di\soft_singleton.cpp" />
<ClCompile Include="..\src\lib\logging\gray_log_sink.cpp" />
<ClCompile Include="..\src\lib\logging\logger.cpp" />
<ClCompile Include="..\src\lib\logging\log_with_spd_log.cpp" />
<ClCompile Include="..\src\lib\metrics\metrics.cpp" />
Expand Down
Loading