You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中使用Boost直接解析含JSON片段的日志文件?

问题:直接用C++ Boost解析含JSON片段的日志文件

日志行示例如下:

[2020-08-23 19:19:29.137] [exchange_tools] [info] Get Object: {"type": "update","symbol": "BTC_USDT_20l","event_id": 1598210353212350,"event_time": 1598210365978240,"exchange_time": 1598210365818,"seq_num": 111529187624,"prev_seq_num": 111529187575,"asks": [],"bids": [[11666.14, 6.752865]]}

需要提取JSON片段中的type、event_time、asks、bids字段。当前方案是先用Python截取每行中"Object: "后的JSON内容并保存为JSON文件,再用Boost读取:

boost::property_tree::ptree pt;
std::ifstream json_in("outfile.json");
std::string line_json;

while (std::getline(json_in, line_json)) {

    std::stringstream ss;
    ss << line_json;

    boost::property_tree::read_json(ss, pt);
    std::cout << pt.get<std::string>("type") << std::endl;

}

希望去掉Python步骤,直接在C++中用Boost完成日志解析,该如何实现?


解决方案

核心思路是:读取日志文件的每一行,先定位并截取"Object: "之后的JSON内容,再用Boost.PropertyTree解析这段JSON并提取目标字段。

完整实现代码

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>

namespace pt = boost::property_tree;

int main() {
    // 打开目标日志文件
    std::ifstream log_file("your_log_file.log");
    if (!log_file.is_open()) {
        std::cerr << "无法打开日志文件!" << std::endl;
        return 1;
    }

    std::string log_line;
    const std::string marker = "Object: ";

    while (std::getline(log_file, log_line)) {
        // 定位JSON片段的起始位置
        size_t json_start_pos = log_line.find(marker);
        if (json_start_pos == std::string::npos) {
            // 跳过不包含目标JSON的行
            continue;
        }

        // 截取完整的JSON字符串
        std::string json_str = log_line.substr(json_start_pos + marker.length());

        // 解析JSON并提取字段
        pt::ptree pt;
        try {
            std::stringstream ss(json_str);
            pt::read_json(ss, pt);

            // 提取基础字段
            std::string type = pt.get<std::string>("type");
            uint64_t event_time = pt.get<uint64_t>("event_time");

            // 输出基础字段
            std::cout << "类型: " << type << std::endl;
            std::cout << "事件时间: " << event_time << std::endl;

            // 处理数组类型的asks
            std::cout << "卖单列表: [";
            for (const auto& ask : pt.get_child("asks")) {
                std::cout << "(";
                // 遍历数组内的元素(示例为数值类型)
                for (const auto& val : ask.second) {
                    std::cout << val.second.get_value<double>() << ", ";
                }
                std::cout << "), ";
            }
            std::cout << "]" << std::endl;

            // 处理二维数组类型的bids
            std::cout << "买单列表: [";
            for (const auto& bid : pt.get_child("bids")) {
                std::cout << "(";
                for (const auto& val : bid.second) {
                    std::cout << val.second.get_value<double>() << ", ";
                }
                std::cout << "), ";
            }
            std::cout << "]" << std::endl;

            std::cout << "-------------------------" << std::endl;
        } catch (const std::exception& e) {
            std::cerr << "解析JSON失败: " << e.what() << std::endl;
            continue;
        }
    }

    log_file.close();
    return 0;
}

关键说明

  1. 定位JSON片段:用std::string::find找到"Object: "的位置,再通过substr截取后续内容,自动跳过不符合格式的日志行。
  2. 异常处理:用try-catch包裹JSON解析逻辑,避免因日志格式错误导致程序崩溃。
  3. 数组字段处理:asks和bids为数组类型,通过遍历pt.get_child()返回的子节点集合访问元素,针对二维数组(如bids)做嵌套遍历。
  4. 编译注意:编译时需链接Boost库,例如GCC命令:g++ -o log_parser log_parser.cpp -lboost_system -lboost_property_tree

内容的提问来源于stack exchange,提问作者wwqeee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:45:41