feat(liblogc): 统一集中式日志客户端库 + 全量迁移

新增:
- liblogc/: C++ 统一日志库 (libus_logc.so),支持 set_endpoint/set_service_name/set_level
- pymsg/pymsg/logc.py: Python 统一日志模块,基于 AsyncRpcQueue

C++ 迁移 (删除 6 份本地 LogC.hpp 副本):
- ca, gateway: <us/LogC.hpp> + set_service_name
- captcha2, confs2, smtp3: using qing::LogC + set_service_name
- core: ConfsLogC → qing::LogC (ConfsTask.cpp)
- 所有 Makefile 添加 -lus_logc

Python 迁移 (6 个 log_client.py → 4 行薄包装):
- smtp, redirect80, confs, captcha, dnfs, static
- 全部委托到 pymsg.logc.LogClient

Go (waf): 保持现状,自成体系
This commit is contained in:
qing committed 2026-08-10 04:51:43 +00:00
1 parent 01ae877673
commit aa3741b861
32 files changed
+608 -2129

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
CXX := g++
CXXFLAGS := -std=c++20 -Wall -Wextra -O2
INCS := -I./inc
LIBS := -lus_msg -lboost_json -lboost_program_options -lssl -lcrypto -lpthread
LIBS := -lus_msg -lus_logc -lboost_json -lboost_program_options -lssl -lcrypto -lpthread
TARGET := smtp3.bin
SRC := src/main.cpp
-124
View File
@@ -1,124 +0,0 @@
/*
* LogC.hpp — smtp3 异步日志客户端(简化版)
*
* 基于 libmsg AsyncQueue,异步批量推送日志到 db:8005 的 Logs 表。
* - 内存队列 + 后台线程攒批(满 50 条或 2 秒 flush)
* - fail-safe:db 不可用时静默丢弃
* - P3-5: 长连接复用(底层 openConnection + pmsg_send/recv),
* 不再每批新建 TCP 连接;连接故障时关闭重建,本批丢弃
* - API: info() / warning() / error()
*/
#pragma once
#include <us/Msg.hpp>
#include <us/AsyncQueue.hpp>
#include <boost/json.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <chrono>
#include <cstdlib>
#include <unistd.h>
namespace smtp3 {
struct LogEntry {
std::string ts;
std::string service;
std::string level;
std::string message;
std::string trace_id;
std::string extra;
};
class LogC {
public:
static LogC& instance() {
static LogC inst;
return inst;
}
void info(const std::string& svc, const std::string& msg) {
push(svc, "INFO", msg);
}
void warning(const std::string& svc, const std::string& msg) {
push(svc, "WARNING", msg);
}
void error(const std::string& svc, const std::string& msg) {
push(svc, "ERROR", msg);
}
private:
LogC() {
const char* host = std::getenv("DB_HOST");
const char* port = std::getenv("DB_PORT");
db_host_ = host ? host : "127.0.0.1";
db_port_ = port ? std::atoi(port) : 8005;
queue_ = std::make_unique<pmc::net::AsyncQueue<LogEntry>>(
[this](std::vector<LogEntry>&& batch) { send_batch(std::move(batch)); },
pmc::net::AsyncQueueConfig{.batch_size = 50, .flush_interval = 2.0, .max_queue_size = 10000},
[](const std::exception& e, std::vector<LogEntry>&&) {
std::cerr << "[smtp3/log] send failed: " << e.what() << std::endl;
});
queue_->start();
}
~LogC() {
if (queue_) queue_->shutdown();
if (fd_ >= 0) ::close(fd_);
}
void push(const std::string& svc, const std::string& level, const std::string& msg) {
auto now = std::chrono::system_clock::now();
auto t = std::chrono::system_clock::to_time_t(now);
char buf[32];
std::strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", std::gmtime(&t));
LogEntry e;
e.ts = buf;
e.service = svc;
e.level = level;
e.message = msg;
queue_->push(std::move(e));
}
// P3-5: 长连接复用——同一 fd 上逐条 pmsg_send + pmsg_recv(db 对每条
// execute 都回复,须消费以保持帧同步);任一异常即关闭连接、丢弃本批
void send_batch(std::vector<LogEntry>&& batch) {
try {
if (fd_ < 0)
fd_ = pmc::net::detail::openConnection(db_host_, db_port_, 1.0);
for (auto& e : batch) {
boost::json::object vals;
vals["ts"] = e.ts;
vals["service"] = e.service;
vals["level"] = e.level;
vals["message"] = e.message;
vals["trace_id"] = e.trace_id.empty() ? nullptr : boost::json::value(e.trace_id);
vals["extra"] = e.extra.empty() ? nullptr : boost::json::value(e.extra);
boost::json::object req;
req["_route"] = "execute";
req["action"] = "insert";
req["table"] = "Logs";
req["values"] = vals;
// 与 MsgClient::call 线路格式一致:无前缀,逐条请求-应答
pmc::net::pmsg_send(fd_, boost::json::serialize(req));
(void)pmc::net::pmsg_recv(fd_, 1.0);
}
} catch (const std::exception& e) {
if (fd_ >= 0) { ::close(fd_); fd_ = -1; }
std::cerr << "[smtp3/log] batch drop: " << e.what() << std::endl;
}
}
std::string db_host_;
int db_port_;
std::unique_ptr<pmc::net::AsyncQueue<LogEntry>> queue_;
int fd_ = -1; // 长连接 fd(仅后台 flush 线程访问,无并发)
};
} // namespace smtp3
+3 -2
View File
@@ -59,12 +59,12 @@
#include <sys/socket.h>
#include <unistd.h>
#include "LogC.hpp"
#include <us/LogC.hpp>
namespace json = boost::json;
namespace po = boost::program_options;
using namespace smtp3;
using qing::LogC;
// ═══════════════════════════════════════════════════════════════════════════
// 辅助: 安全的 stoi
@@ -716,6 +716,7 @@ static SendLimiter g_limiter;
static std::unordered_map<std::string, double> g_cooldown;
static std::mutex g_cooldown_mtx;
static auto& g_log = LogC::instance();
static const auto _log_init = (LogC::instance().set_service_name("smtp3-log"), true);
// ═══════════════════════════════════════════════════════════════════════════
// 8. main() — RpcServer 启动