GELF infrastructure

This commit is contained in:
2022-11-13 00:16:43 -05:00
parent f4af8e4a89
commit 883913b92d
14 changed files with 1053 additions and 4 deletions
@@ -0,0 +1,64 @@
#pragma once
#include <gelfcpp/GelfMessage.hpp>
#include <gelfcpp/detail/DocumentAccessor.hpp>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <ostream>
namespace gelfcpp
{
namespace output
{
/**
* \brief Writes GelfMessages as JSON to given std::ostream
*
* Uses short notation, which minimizes the space requirements
* No newline is appended, the output is not flushed.
*/
class GelfJSONOutput
{
public:
/**
* \brief Constructs a new output on the given stream
*
* \param output underlying stream
*/
GelfJSONOutput(std::ostream& output) :
output_(output) {}
/**
* \brief Serializes a message to the underlying stream
*
* \param message the message
*/
void Write(const GelfMessage& message)
{
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
detail::DocumentAccessor::get(message).Accept(writer);
output_.write(buffer.GetString(), buffer.GetSize());
}
private:
std::ostream& output_;
};
}
/**
* \brief Serializes a message to the given stream
*
* \param os the stream
* \param message the message
* \return the stream
* \see GelfJSONOutput
*/
inline std::ostream& operator<<(std::ostream& os, const GelfMessage& message)
{
output::GelfJSONOutput(os).Write(message);
return os;
}
}
@@ -0,0 +1,58 @@
#pragma once
#include <gelfcpp/GelfMessage.hpp>
#include <gelfcpp/detail/GelfSerializer.hpp>
#include <boost/asio/ip/udp.hpp>
#include <string>
#include <cstdint>
namespace gelfcpp
{
namespace output
{
/**
* \brief Writes GelfMessages to an UDP socket
*
* Serializes and sends messages to e.g. an Graylog Node, sending is non-blocking.
*
* Uses chunking for big messages due to size limitations of UDP.
* Additionally uses compression if enabled (by setting \c GELFCPP_WITH_COMPRESSION in CMake).
*/
class GelfUDPOutput
{
public:
/**
* \brief Creates an new output socket to given host and port
*
* \param host remote hostname
* \param port remote UDP port
*/
GelfUDPOutput(const std::string& host, uint16_t port)
{
boost::asio::ip::udp::resolver resolver(service_);
boost::asio::ip::udp::resolver::query query(host, std::to_string(port));
endpoint_ = *resolver.resolve(query);
socket_.reset(new boost::asio::ip::udp::socket(service_, endpoint_.protocol()));
}
/**
* \brief Serializes a message to the UDP stream
*
* \param message the message
*/
void Write(const GelfMessage& message)
{
for (const std::string& chunk : serializer_.Serialize(message))
socket_->async_send_to(boost::asio::buffer(chunk), endpoint_, [](const boost::system::error_code&, unsigned long int) {});
}
private:
detail::GelfSerializer serializer_;
boost::asio::io_context service_;
boost::asio::ip::udp::endpoint endpoint_;
std::unique_ptr<boost::asio::ip::udp::socket> socket_;
};
}
}