Drill

ProblemsC++ › monitoring

Count log lines by level

mediummonitoringHash mapsStringsParsingC++

A log summariser reports how many lines came in at each level. The level is the first word on the line, and the file is not always tidy.

countByLevel(lines: list<string>) → map<string, int>

C++ needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.

Solve it in Python →

Where you start

std::map<std::string, int> countByLevel(std::vector<std::string> lines) {
    
}

Worked examples

CallResult
countByLevel(std::vector<std::string>{std::string("ERROR disk full"), std::string("warn retrying"), std::string("ERROR timeout")})std::map<std::string, int>{{std::string("ERROR"), 2}, {std::string("WARN"), 1}}
countByLevel(std::vector<std::string>{std::string("INFO ok")})std::map<std::string, int>{{std::string("INFO"), 1}}
countByLevel(std::vector<std::string>{std::string(""), std::string(" ")})std::map<std::string, int>{}
countByLevel(std::vector<std::string>{std::string("DEBUG")})std::map<std::string, int>{{std::string("DEBUG"), 1}}

Hint

Trim the line, take everything up to the first space, upper-case it.

Reference solution in C++
std::map<std::string, int> countByLevel(std::vector<std::string> lines) {
    std::map<string, int> result;
    for (const auto& line : lines) {
        istringstream in(line);
        string level;
        if (!(in >> level)) continue;
        for (auto& c : level) c = static_cast<char>(toupper(static_cast<unsigned char>(c)));
        result[level]++;
    }
    return result;
}

The same problem in another language

More monitoring problems in C++