Beispiel #1
0
USING_YJJ_NAMESPACE

/**
 * entrance for journal tool
 */
int main(int argc, const char* argv[])
{
    options_description desc{"Options"};
    string format("%Y%m%d-%H:%M:%S");
    desc.add_options()
            ("help,h", "Help screen")
            ("folder,f", value<string>(), "Journal Folder")
            ("name,n", value<string>(), "Journal Name")
            ("page,p", "Just Page Header")
            ("verify,v", "Verify hash code")
            ("keep,k", "keep listening")
            ("time,t", "time visualized")
            ("detail,d", "data details")
            ("current,c", "start from current")
            ("length,l", value<int>()->default_value(20), "Char num of frame data to print")
            ("msgtype,m", value<string>()->default_value(""), "Message type printed, -eg: -m 10,11")
            ("rmsgtype,r", value<string>()->default_value(""), "Message type not printed, -eg: -r 10,11")
            ("start_time,s", value<string>()->default_value("20000101-13:30:00"), "start time (%Y%m%d-%H:%M:%S)")
            ("end_time,e", value<string>()->default_value("20200101-00:00:00"), "end time (%Y%m%d-%H:%M:%S)");

    variables_map vm;
    store(parse_command_line(argc, argv, desc), vm);
    notify(vm);

    if (vm.count("help"))
    {
        std::cout << desc << '\n';
        std::cout << "----frame tags----" << std::endl;
        std::cout << " (st): status" << std::endl;
        std::cout << " (so): source" << std::endl;
        std::cout << " (na): nano time" << std::endl;
        std::cout << " (en): extra nano time" << std::endl;
        std::cout << " (vn): visualized nano (-t only)" << std::endl;
        std::cout << " (fl): frame length" << std::endl;
        std::cout << " (dl): data length" << std::endl;
        std::cout << " (hl): header length" << std::endl;
        std::cout << " (hs): hash code" << std::endl;
        std::cout << " (mt): msg type" << std::endl;
        std::cout << " (lf): last flag" << std::endl;
        std::cout << " (id): request id" << std::endl;
        std::cout << " (er): error id" << std::endl;
        std::cout << " (em): error message" << std::endl;
        std::cout << " (cn): data content" << std::endl;
        std::cout << std::endl;
        std::cout << "----page tags----" << std::endl;
        std::cout << " (ST): page status" << std::endl;
        std::cout << " (JN): journal name" << std::endl;
        std::cout << " (PN): page number" << std::endl;
        std::cout << " (FN): total number of frame in this page" << std::endl;
        std::cout << " (LP): last position" << std::endl;
        std::cout << " (FV): frame version" << std::endl;
        std::cout << " (SN): start nano" << std::endl;
        std::cout << " (CN): close nano" << std::endl;
        return 0;
    }
    string start_time = vm.count("current") ? parseNano(getNanoTime(), format.c_str()) : vm["start_time"].as<string>();
    if (vm.count("start_time"))
    {
        std::cout << "StartTime:\t" << start_time << std::endl;
    }
    if (vm.count("end_time"))
    {
        std::cout << "EndTime:\t" << vm["end_time"].as<string>() << std::endl;
    }
    if (vm.count("folder"))
    {
        std::cout << "Folder:\t" << vm["folder"].as<string>() << std::endl;
    }
    if (vm.count("name"))
    {
        std::cout << "ShortName:\t" << vm["name"].as<string>() << std::endl;
    }

    string folder = vm["folder"].as<string>();
    string jname = vm["name"].as<string>();

    if (vm.count("page"))
    {
        vector<short> pageNums = PageUtil::GetPageNums(folder, jname);

        for (size_t idx = 0; idx < pageNums.size(); idx++)
        {
            PageHeader header = PageUtil::GetPageHeader(folder, jname, pageNums[idx]);
            std::cout << "[" << pageNums[idx] << "]"
                      << " (ST)" << (short)header.status
                      << " (JN)" << header.journal_name
                      << " (PN)" << header.page_num
                      << " (FN)" << header.frame_num
                      << " (LP)" << header.last_pos
                      << " (FV)" << header.frame_version
                      << " (SN)" << header.start_nano << "[" << parseNano(header.start_nano, format.c_str()) << "]"
                      << " (CN)" << header.close_nano << "[" << parseNano(header.close_nano, format.c_str()) << "]";
            std::cout << std::endl;
        }
    }
    else
    {
        bool toVerify = vm.count("verify");
        bool toTimeVisual = vm.count("time");
        bool needDetail = vm.count("detail");
        long sn = parseTime(start_time.c_str(), format.c_str());
        long en = parseTime(vm["end_time"].as<string>().c_str(), format.c_str());
        int dataLengthToPrint = vm["length"].as<int>();

        map<short, bool> doMsgTypes, nonMsgTypes;
        string doMtStr = vm["msgtype"].as<string>();
        bool mtDoList = doMtStr.length() > 0;
        if (mtDoList)
        {
            std::stringstream ss(doMtStr);
            int i;
            while (ss >> i)
            {
                doMsgTypes[i] = true;
                if (ss.peek() == ',')
                    ss.ignore();
            }
            std::cout << "MsgType to Print:";
            for (auto& item: doMsgTypes)
            {
                std::cout << " " << item.first;
            }
            std::cout << std::endl;
        }
        string nonMtStr = vm["rmsgtype"].as<string>();
        bool mtNonList = nonMtStr.length() > 0;
        if (mtNonList)
        {
            std::stringstream ss(nonMtStr);
            int i;
            while (ss >> i)
            {
                nonMsgTypes[i] = true;
                if (ss.peek() == ',')
                {
                    ss.ignore();
                }
            }
            std::cout << "MsgType to Skip:";
            for (auto& item: nonMsgTypes)
            {
                std::cout << " " << item.first;
            }
            std::cout << std::endl;
        }
        JournalReaderPtr reader = JournalReader::create(folder, jname, sn, "JournalPrinter");
        int i = 0;
        do
        {
            FramePtr frame = reader->getNextFrame();
            while (frame.get() != nullptr && en > frame->getNano())
            {
                short msgType = frame->getMsgType();
                bool toPrint = true;
                if ((mtDoList && doMsgTypes.find(msgType) == doMsgTypes.end())
                    || (mtNonList && nonMsgTypes.find(msgType) != nonMsgTypes.end()))
                {
                    toPrint = false;
                }
                if (toPrint)
                {
                    std::cout << "[" << i++ << "]"
                              << " (st)" << (short)frame->getStatus()
                              << " (so)" << frame->getSource()
                              << " (na)" << frame->getNano()
                              << " (en)" << frame->getExtraNano();
                    if (toTimeVisual)
                    {
                        std::cout << " (vn)" << parseNano(frame->getNano(), format.c_str());
                    }
                    std::cout << " (fl)" << frame->getFrameLength()
                              << " (dl)" << frame->getDataLength()
                              << " (hl)" << frame->getHeaderLength()
                              << " (hs)" << frame->getHashCode()
                              << " (mt)" << frame->getMsgType()
                              << " (lf)" << (short)frame->getLastFlag()
                              << " (id)" << frame->getRequestId()
                              << " (er)" << frame->getErrorId();
                    if (frame->getErrorMsg() != nullptr)
                    {
                        std::cout << " (em)" << frame->getErrorMsg();
                    }
                    if (dataLengthToPrint > 0)
                    {
                        std::cout << " (cn)" << string((char*)frame->getData(), std::min(dataLengthToPrint, frame->getDataLength()));
                    }
                    if (toVerify)
                    {
                        FH_TYPE_HASHNM hash = MurmurHash2(frame->getData(), frame->getDataLength(), HASH_SEED);
                        if (hash != frame->getHashCode())
                        {
                            std::cerr << std::endl << std::endl
                                      << "Hash Code mismatch: "
                                      << "[frame] " << frame->getHashCode()
                                      << "  [actual] " << hash << std::endl;
                            return -1;
                        }
                        else
                        {
                            std::cout << " (*)";
                        }
                    }
                    std::cout << std::endl;
                    if (needDetail)
                    {
                        printData(frame->getData(), msgType);
                    }
                }
                frame = reader->getNextFrame();
            }
        }
        while (vm.count("keep"));
    }
    return 0;
}