mirror of https://github.com/gabime/spdlog.git
add udp_skin suport udp log
parent
fd5562eebe
commit
43b0462bb4
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#error include tcp_client-windows.h instead
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// tcp client helper
|
||||||
|
#include <spdlog/common.h>
|
||||||
|
#include <spdlog/details/os.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace details {
|
||||||
|
class udp_client
|
||||||
|
{
|
||||||
|
int socket_ = -1;
|
||||||
|
std::string m_svrIp;
|
||||||
|
int m_svrPort;
|
||||||
|
struct sockaddr_in sockAddr_;
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool init(const std::string &host, int port)
|
||||||
|
{
|
||||||
|
m_svrIp = host;
|
||||||
|
m_svrPort = port;
|
||||||
|
|
||||||
|
socket_ = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (socket_ < 0)
|
||||||
|
{
|
||||||
|
throw_spdlog_ex("error: Create Socket Failed!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockAddr_.sin_family = AF_INET;
|
||||||
|
sockAddr_.sin_port = htons(m_svrPort);
|
||||||
|
inet_aton(m_svrIp.c_str(), &sockAddr_.sin_addr);
|
||||||
|
|
||||||
|
memset(sockAddr_.sin_zero, 0x00, 8);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_init() const
|
||||||
|
{
|
||||||
|
return socket_ != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close()
|
||||||
|
{
|
||||||
|
if (is_init())
|
||||||
|
{
|
||||||
|
::close(socket_);
|
||||||
|
socket_ = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd() const
|
||||||
|
{
|
||||||
|
return socket_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~udp_client()
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send exactly n_bytes of the given data.
|
||||||
|
// On error close the connection and throw.
|
||||||
|
void send(const char *data, size_t n_bytes)
|
||||||
|
{
|
||||||
|
size_t toslen = 0;
|
||||||
|
size_t tolen = sizeof(struct sockaddr);
|
||||||
|
if (( toslen = sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) == -1)
|
||||||
|
{
|
||||||
|
throw_spdlog_ex("write(2) failed", errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace details
|
||||||
|
} // namespace spdlog
|
@ -0,0 +1,87 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <spdlog/common.h>
|
||||||
|
#include <spdlog/sinks/base_sink.h>
|
||||||
|
#include <spdlog/details/null_mutex.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <spdlog/details/tcp_client-windows.h>
|
||||||
|
#else
|
||||||
|
#include <spdlog/details/udp_client.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Simple tcp client sink
|
||||||
|
// Connects to remote address and send the formatted log.
|
||||||
|
// Will attempt to reconnect if connection drops.
|
||||||
|
// If more complicated behaviour is needed (i.e get responses), you can inherit it and override the sink_it_ method.
|
||||||
|
|
||||||
|
namespace spdlog {
|
||||||
|
namespace sinks {
|
||||||
|
|
||||||
|
struct udp_sink_config
|
||||||
|
{
|
||||||
|
std::string server_host;
|
||||||
|
int server_port;
|
||||||
|
|
||||||
|
udp_sink_config(std::string host, int port)
|
||||||
|
: server_host{std::move(host)}
|
||||||
|
, server_port{port}
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Mutex>
|
||||||
|
class udp_sink : public spdlog::sinks::base_sink<Mutex>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// connect to tcp host/port or throw if failed
|
||||||
|
// host can be hostname or ip address
|
||||||
|
|
||||||
|
explicit udp_sink(udp_sink_config sink_config)
|
||||||
|
: config_{std::move(sink_config)}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~udp_sink() override = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void sink_it_(const spdlog::details::log_msg &msg) override
|
||||||
|
{
|
||||||
|
spdlog::memory_buf_t formatted;
|
||||||
|
spdlog::sinks::base_sink<Mutex>::formatter_->format(msg, formatted);
|
||||||
|
if (!client_.is_init())
|
||||||
|
{
|
||||||
|
client_.init(config_.server_host, config_.server_port);
|
||||||
|
}
|
||||||
|
client_.send(formatted.data(), formatted.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void flush_() override {}
|
||||||
|
udp_sink_config config_;
|
||||||
|
details::udp_client client_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using udp_sink_mt = udp_sink<std::mutex>;
|
||||||
|
using udp_sink_st = udp_sink<spdlog::details::null_mutex>;
|
||||||
|
|
||||||
|
} // namespace sinks
|
||||||
|
|
||||||
|
//
|
||||||
|
// factory functions
|
||||||
|
//
|
||||||
|
template<typename Factory = spdlog::synchronous_factory>
|
||||||
|
inline std::shared_ptr<logger> udp_logger_mt(const std::string &logger_name, sinks::udp_sink_config skin_config)
|
||||||
|
{
|
||||||
|
return Factory::template create<sinks::udp_sink_mt>(logger_name, skin_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace spdlog
|
Loading…
Reference in New Issue