Count log lines by level
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.
- The level is the first whitespace-separated word, reported in upper case.
- Lines that are empty or only whitespace are skipped.
- Levels that never appear are not in the result.
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.
Where you start
std::map<std::string, int> countByLevel(std::vector<std::string> lines) {
}
Worked examples
| Call | Result |
|---|---|
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;
}