captcha2: CLI 标准化(--host/--config/--log-level/--instance + LogC 级别过滤)

- 新增 --host(别名 --addr/-a)覆盖 [server] host
- 新增 --config 覆盖 confs 拉取的配置名(默认 captcha.ini)
- 新增 --log-level debug|info|warn|error(LogC 加级别过滤)
- 新增 --instance 实例名(注册中心用)
- LogC.hpp: 新增 set_level() + push() 级别过滤(atomic 阈值,大写兼容)
- 配置优先级: CLI > ENV > confs > 默认值
- services.yaml: captcha2 声明 --instance 和 --log-level
This commit is contained in:
qing committed 2026-08-10 12:00:34 +08:00
1 parent 8eb14cad4a
commit 29eac70f24
3 files changed
+54 -8

No files matched your search

+25 -7
View File
@@ -70,12 +70,13 @@ struct CaptchaConfig {
int rate_limit_per_min = 600; // P1-1: 全局限流仅作最后防线,主要限流由 gateway 按 IP 负责
};
// 从 confs 拉取 captcha.ini 全文,阻塞等待 confs 就绪
static std::string fetch_config_from_confs(const std::string& confs_host, int confs_port) {
// 从 confs 拉取指定名称的配置文件全文,阻塞等待 confs 就绪
static std::string fetch_config_from_confs(const std::string& confs_host, int confs_port,
const std::string& config_name) {
pmc::net::RpcClient client(confs_host, confs_port, "captcha2",
/*timeout=*/5.0, /*retry_on_refused=*/true);
try {
auto data = client.call("get", {{"name", "captcha.ini"}});
auto data = client.call("get", {{"name", config_name}});
auto* content = data.as_object().if_contains("content");
if (!content || !content->is_string()) {
std::cerr << "[captcha2] confs 返回的 captcha.ini 无 content 字段" << std::endl;
@@ -531,6 +532,9 @@ int main(int argc, char* argv[]) {
// ── 命令行参数 ──
std::string confs_host = "127.0.0.1";
int confs_port = 8010;
std::string confs_config_name = "captcha.ini"; // --config 覆盖
std::string instance = "captcha2"; // --instance 覆盖
std::string log_level = "info"; // --log-level 覆盖
{
const char* env;
if ((env = std::getenv("CONFS_HOST"))) confs_host = env;
@@ -540,9 +544,13 @@ int main(int argc, char* argv[]) {
po::options_description desc("captcha2 — pymsg 验证码服务");
desc.add_options()
("help,h", "显示帮助")
("addr,a", po::value<std::string>(), "监听地址(覆盖 confs)")
("addr,a", po::value<std::string>(), "监听地址(覆盖 confs,别名 --host)")
("host", po::value<std::string>(), "监听地址(覆盖 confs,别名 --addr/-a)")
("port,p", po::value<int>(), "监听端口(覆盖 confs)")
("workers,w", po::value<int>(), "工作线程数(覆盖 confs)");
("workers,w", po::value<int>(), "工作线程数(覆盖 confs)")
("config", po::value<std::string>(), "confs 拉取的配置名(默认 captcha.ini)")
("log-level", po::value<std::string>(), "日志级别 debug|info|warn|error,默认 info")
("instance", po::value<std::string>(), "实例名(注册中心用,默认 captcha2)");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
@@ -552,20 +560,30 @@ int main(int argc, char* argv[]) {
return 0;
}
// 预扫描 --config / --instance / --log-level / --host(confs 拉取前处理)
if (vm.count("config")) confs_config_name = vm["config"].as<std::string>();
if (vm.count("instance")) instance = vm["instance"].as<std::string>();
if (vm.count("log-level")) log_level = vm["log-level"].as<std::string>();
// ── 配置加载:confs → env → 命令行 ──
std::string ini_text = fetch_config_from_confs(confs_host, confs_port);
std::string ini_text = fetch_config_from_confs(confs_host, confs_port, confs_config_name);
merge_ini(g_config, ini_text);
apply_env_overrides(g_config);
if (vm.count("addr")) g_config.host = vm["addr"].as<std::string>();
if (vm.count("host")) g_config.host = vm["host"].as<std::string>();
if (vm.count("port")) g_config.port = vm["port"].as<int>();
if (vm.count("workers")) g_config.workers = vm["workers"].as<int>();
validate_config(g_config);
std::cerr << "[captcha2] 配置来源: confs captcha.ini @ "
g_log.set_level(log_level);
std::cerr << "[captcha2] 配置来源: confs " << confs_config_name << " @ "
<< confs_host << ":" << confs_port << std::endl;
std::cerr << "[captcha2] instance=" << instance
<< " log-level=" << log_level << std::endl;
std::cerr << "[captcha2] captcha_len=" << g_config.len
<< " ttl=" << g_config.ttl
<< " max_store=" << g_config.max_store