#include "Global.h" #include #include #include #include #include BaseLogger* server_logger = nullptr; Debug_Logger_Info_Manager debug_logger_info_manager; void Global::handle_old_logs() { auto mode = log_config.open_mode; std::string dirPath = get_exe_dir() + "/" + "logs"; namespace fs = std::filesystem; try { switch (mode) { case Log_Config::Open_Mode::Rename: { auto now = std::chrono::system_clock::now(); auto in_time_t = std::chrono::system_clock::to_time_t(now); std::ostringstream oss; oss << std::put_time(std::localtime(&in_time_t), "%Y-%m-%d_%H-%M-%S"); fs::path newDirPath = dirPath + "_" + oss.str(); if (fs::exists(newDirPath)) { std::cout << "New directory name already exists!" << std::endl; return; } fs::rename(dirPath, newDirPath); std::cout << "Directory renamed to: " << newDirPath << std::endl; break; } case Log_Config::Open_Mode::Delete: { if (fs::exists(dirPath)) { fs::remove_all(dirPath); // 删除目录及其所有内容 std::cout << "Directory and its contents deleted: " << dirPath << std::endl; } if (fs::create_directories(dirPath)) { std::cout << "Directory created: " << dirPath << std::endl; } else { std::cout << "创建目录失败: " << dirPath << std::endl; Psc::fail_fast(); } fs::permissions(dirPath, fs::perms::owner_all | fs::perms::group_all | fs::perms::others_all); break; } case Log_Config::Open_Mode::Append: break; default: std::cerr << "未知的打开模式!" << std::endl; break; } } catch (const std::exception& ex) { std::cerr << "Error: " + Psc::platform_2_utf8(ex.what()) + "\n"; } } Global::Global() : Config() { auto j = load(); from_log_json(j.get("log")); handle_old_logs(); Base_Logger_Manager::instance()->set_thread_num(1).set_flush_seconds(3).init(); int piece_num = log_config.piece_num; int size_MB = log_config.size_MB; int MB = 1024 * 1024; asio_socket::socket_logger = new BaseLogger("@/logs/socket", MB * size_MB, piece_num); serial::serial_logger = new BaseLogger("@/logs/serial", MB * size_MB, piece_num); SSR::mode_s_logger = new BaseLogger("@/logs/mode_s", MB * size_MB * 10, piece_num); dsp_logger = new BaseLogger("@/logs/dsp", MB * size_MB, piece_num); server_logger = new BaseLogger("@/logs/server", MB * size_MB, piece_num); SSR::parse_pos_call_back = nullptr; SSR::parse_ok_json = nullptr; asio_socket::socket_logger->set_redirect([](const BaseLogger::Log_Info& log_info) { auto msg = "[" + std::string("func") + "~" + log_info.func_pattern + "] " + log_info.log_type.to_string() + log_info.content; debug_logger_info_manager.push_info(msg); }); serial::serial_logger->set_redirect([](const BaseLogger::Log_Info& log_info) { auto msg = "[" + std::string("func") + "~" + log_info.func_pattern + "] " + log_info.log_type.to_string() + log_info.content; debug_logger_info_manager.push_info(msg); }); from_base_json(&j); #ifdef Cache_Some_Mode_S SSR::parse_ok_json = [](Aircraft_Info* aircraft_info, SSR::P_S mode_s_msg, Psc::JSON) { auto f = static_cast(aircraft_info); f->add_msg_limit(mode_s_msg); }; #endif SSR::cpr_cb = [](SSR::CPR_Type t, SSR::CPR_Ret_Type err_type, std::string_view log, SSR::P_S msg) { auto src = std::dynamic_pointer_cast(msg->source); Mode_S_Statistic_Data* ss = &src->mode_s_statistic; ss->add_cpr_error(t, err_type); if (err_type == SSR::CPR_Ret_Type::Speed_Error || err_type == SSR::CPR_Ret_Type::Inter_Error || err_type == SSR::CPR_Ret_Type::Time_Space_Too_Long || err_type == SSR::CPR_Ret_Type::Out_of_Maximum_Detection_Range) SSR::mode_s_logger->debug("CPR/" + to_string(t) + "/" + to_string(err_type), {}, log); }; // 处理错误 SSR::parse_call_back = [this](SSR::Parse_Call_Back_Type type, SSR::Aircraft_Info* info, std::string_view field_name, std::vector bds_list, void*, SSR::P_S msg) { auto src = std::dynamic_pointer_cast(msg->source); Mode_S_Statistic_Data* ss = &src->mode_s_statistic; if (type == SSR::Parse_Call_Back_Type::Unknown_DF) { // std::cout << "Unknown DF type!" << (int)(msg->df) << std::endl; return; } DF_Statistic_Data* dfs = ss->get_create_df_statistic_data(msg->df); dfs->add(); if (type == SSR::Parse_Call_Back_Type::Normal_Block) { dfs->add_sub_part(field_name); info->update(msg); } else if (type == SSR::Parse_Call_Back_Type::CRC_Error) { dfs->add_crc_error(); // std::cout << field_name << " :crc_error msg:" << msg->msg_hex << // " df:" << (int)msg->df << std::endl; } else if (type == SSR::Parse_Call_Back_Type::Length_Error) { ss->add_length_error(field_name); // std::cout << field_name << " :length_error msg:" << msg->msg_hex // << " df:" << (int)msg->df << std::endl; } // else if (type == Mode_S::Parse_Call_Back_Type::UNKNOWN_ERROR) {} else // {} }; auto str = toJson().to_json_string(); server_logger->debug("启动", {}, str); SSR::mode_s_logger->debug("启动", {}, str); std::cout << str << std::endl; init_web_server(); } Global::~Global() { std::cout << "Global::~Global()" << std::endl; } void Debug_Logger_Info_Manager::push_info(std::string_view c) { std::lock_guard g(mtx); std::string content = std::to_string(cur_serial_number) + ": " + std::string(c); size_t content_length = content.size(); info_list.push_back({cur_serial_number, content}); current_total_length += content_length; while (current_total_length > max_length && !info_list.empty()) { current_total_length -= info_list.front().content.size(); info_list.pop_front(); // 删除最早的记录 } cur_serial_number++; } Serial_Number_Type Debug_Logger_Info_Manager::get_cur_serial_number() { std::lock_guard g(mtx); return cur_serial_number; } JSON Debug_Logger_Info_Manager::to_json() { JSON ret = JSON::object(); ret.append({"cur_serial_number", cur_serial_number}); return ret; } bool Web_Server::listen(std::string_view host, int port) { drogon::HttpAppFramework* app = &drogon::app(); auto g = Global::instance(); Json::Value drogon_config; { auto jsonStr = g->drogon_config.to_json_string(); std::cout << "drogon::app().run(); " << jsonStr << std::endl; Json::CharReaderBuilder builder; std::string errs; auto reader = builder.newCharReader(); if (!reader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.size(), &drogon_config, &errs)) { // 解析失败 std::cout << "drogon 配置文件加载失败!json格式解析失败!" << jsonStr << std::endl; Psc::fail_fast(); } delete reader; } app->loadConfigJson(drogon_config); app->disableSigtermHandling(); // 关闭服务器信号处理 app->addListener(std::string(host), port); auto base_dir = get_exe_dir(); // app->setLogPath(base_dir + "/logs/drogon.log"); app->setUploadPath(base_dir + "/../drogon_uploads"); app->run(); return true; } Web_Server& Web_Server::Post(std::string_view pattern, Handler handler) { drogon::app().registerHandler( std::string(pattern), [handler](const drogon::HttpRequestPtr& request, std::function&& callback) { auto resp = drogon::HttpResponse::newHttpResponse(); resp->setContentTypeCode(drogon::CT_APPLICATION_JSON); handler(request, resp); callback(resp); }, {drogon::Post}); return *this; } Web_Server& Web_Server::Post_Coro(std::string_view pattern, CoroHandler handler) { drogon::app().registerHandler( std::string(pattern), [handler = std::move(handler)](const drogon::HttpRequestPtr& request, std::function&& callback) { auto resp = drogon::HttpResponse::newHttpResponse(); resp->setContentTypeCode(drogon::CT_APPLICATION_JSON); drogon::async_run([handler, request, resp, callback = std::move(callback)]() mutable -> drogon::Task<> { try { co_await handler(request, resp); } catch (const std::exception& error) { resp->setStatusCode(drogon::k500InternalServerError); resp->setBody(Psc::JSON::object({{"error", std::string(error.what())}}).to_json_string()); std::terminate(); } catch (...) { resp->setStatusCode(drogon::k500InternalServerError); resp->setBody(Psc::JSON::object({{"error", "unknown error"}}).to_json_string()); std::terminate(); } callback(resp); co_return; }); }, {drogon::Post}); return *this; } Web_Server& Web_Server::Get(std::string_view pattern, Handler handler) { drogon::app().registerHandlerViaRegex( std::string(pattern), [handler](const drogon::HttpRequestPtr& request, std::function&& callback) { auto resp = drogon::HttpResponse::newHttpResponse(); resp->setContentTypeCode(drogon::CT_APPLICATION_JSON); handler(request, resp); callback(resp); }, {drogon::Get}); return *this; } std::string Debug_Logger_Info_Manager::get_info(Serial_Number_Type serial_number) { std::lock_guard g(mtx); std::string result; if (serial_number == cur_serial_number) { return ""; } // 从后向前遍历 data 列表 for (auto it = info_list.rbegin(); it != info_list.rend(); ++it) { // std::cout << "max_length: " << max_length << " size: " << // info_list.size() << " serial_number " << serial_number << "cur_sequence" // << it->sequence << " content.size" << it->content.size() << std::endl; if (it->sequence >= serial_number) { result = it->content + result; // 叠加 content } else { break; } } return result; } std::string inet_address_to_string(const trantor::InetAddress& addr) { char buf[INET6_ADDRSTRLEN] = {0}; if (!addr.isIpV6()) { // IPv4 auto sa = reinterpret_cast(addr.getSockAddr()); inet_ntop(AF_INET, &(sa->sin_addr), buf, sizeof(buf)); uint16_t port = ntohs(sa->sin_port); return std::string(buf) + ":" + std::to_string(port); } else { // IPv6 auto sa6 = reinterpret_cast(addr.getSockAddr()); inet_ntop(AF_INET6, &(sa6->sin6_addr), buf, sizeof(buf)); uint16_t port = ntohs(sa6->sin6_port); return "[" + std::string(buf) + "]:" + std::to_string(port); } }