以下是一个基于 glog(Google Logging Library)的示例代码,结合 Windows UDP Socket 实现本地日志记录的同时支持远程发送日志的功能。
功能说明
- 本地日志:使用
glog
记录到文件。 - 远程日志:通过
UDP
发送日志到指定的服务器。
完整代码
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include <string>
#include <glog/logging.h>
#pragma comment(lib, "ws2_32.lib")
class UDPLogger {
public:
UDPLogger(const std::string& remote_ip, int remote_port) : remote_ip_(remote_ip), remote_port_(remote_port) {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
LOG(ERROR) << "Failed to initialize Winsock";
return;
}
sock_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock_ == INVALID_SOCKET) {
LOG(ERROR) << "Failed to create socket: " << WSAGetLastError();
WSACleanup();
return;
}
memset(&server_addr_, 0, sizeof(server_addr_));
server_addr_.sin_family = AF_INET;
server_addr_.sin_port = htons(remote_port_);
inet_pton(AF_INET, remote_ip_.c_str(), &server_addr_.sin_addr);
}
~UDPLogger() {
if (sock_ != INVALID_SOCKET)
closesocket(sock_);
WSACleanup();
}
void SendLog(const std::string& log_msg) {
if (sendto(sock_, log_msg.c_str(), log_msg.size(), 0,
(struct sockaddr*)&server_addr_, sizeof(server_addr_)) == SOCKET_ERROR) {
LOG(WARNING) << "Failed to send log via UDP: " << WSAGetLastError();
}
}
private:
SOCKET sock_{INVALID_SOCKET};
struct sockaddr_in server_addr_;
std::string remote_ip_;
int remote_port_;
};
// Custom Google Log sink to send logs via UDP
class RemoteLogSink : public google::LogSink {
public:
explicit RemoteLogSink(UDPLogger* udp_logger) : udp_logger_(udp_logger) {}
void send(google::LogSeverity severity, const char* full_filename,
const char* base_filename, int line,
const struct ::tm* tm_time,
const char* message, size_t message_len) override {
// Format the log message
std::ostringstream oss;
oss << google::GetLogSeverityName(severity)
<< " [" << base_filename << ":" << line << "] "
<< message;
// Send via UDP
udp_logger_->SendLog(oss.str());
}
private:
UDPLogger* udp_logger_;
};
int main(int argc, char* argv[]) {
// Initialize glog
google::InitGoogleLogging(argv[0]);
// Local file logging
FLAGS_log_dir = "./logs"; // Log directory
FLAGS_minloglevel = google::INFO; // Minimum log level
// Initialize UDP logger for remote logging
UDPLogger udp_logger("127.0.0.1", 514); // Replace with your server IP and port
// Add custom sink for sending logs remotely
RemoteLogSink remote_sink(&udp_logger);
#if defined(GLOG_CUSTOM_PREFIX_SUPPORT)
#else
#define GLOG_CUSTOM_PREFIX_SUPPORT 1 // Ensure custom prefix is supported in older glog versions
#endif
#if GLOG_CUSTOM_PREFIX_SUPPORT > 0
google::AddLogSink(&remote_sink); // Register our custom sink
#endif
LOG(INFO) << "This is an INFO log.";
LOG(WARNING) << "This is a WARNING log.";
LOG(ERROR) << "This is an ERROR log.";
google::ShutdownGoogleLogging();
return EXIT_SUCCESS;
}
关键点解析
UDPLogger
类:- 封装了 Windows Socket (
Winsock2
) ,用于发送 UDP 数据包。 SendLog()
:将日志内容发送到指定服务器。
- 封装了 Windows Socket (
RemoteLogSink
类:- 继承自
google::LogSink
,自定义日志输出方式。 send()
方法:格式化日志并调用UDPLogger.SendLog()
。
- 继承自
主程序逻辑:
google::InitGoogleLogging()
:初始化 glog。FLAGS_log_dir="./logs"
:设置本地日志存储目录。google::AddLogSink(&remote_sink)
:注册自定义的远程日志处理器。
编译运行:
g++ main.cpp -lglog -lws2_32 -o app.exe && ./app.exe
适用场景
- ✅ Windows平台下的C++服务端开发
- ✅ Glog + UDP远程日志收集(如 ELK、Graylog、Syslog)
- ✅ Debug/Release环境统一管理
如果需要更稳定的传输(如 TCP),可以改用 Boost.Asio/WinHTTP。
内容由零声教学AI助手提供,问题来源于学员提问