aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/utils/log/ut/log_parser.h
blob: 87cf52ed8b351360778129cdb9b302afd95b7244 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#pragma once

#include <yql/essentials/utils/log/log.h>

#include <library/cpp/testing/unittest/registar.h>

#include <util/datetime/base.h>

#include <regex>


namespace NYql {
namespace NLog {

struct TLogRow {
    TInstant Time;
    ELevel Level;
    TString ProcName;
    pid_t ProcId;
    ui64 ThreadId;
    EComponent Component;
    TString FileName;
    ui32 LineNumber;
    TString Message;
};

static TLogRow ParseLogRow(const TString& str) {
    static std::regex rowRe(
                "^([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\\.[0-9]{3}) " // (1) time
                "([A-Z ]{5}) "                                                         // (2) level
                "([a-zA-Z0-9_\\.-]+)"                                                  // (3) process name
                ".pid=([0-9]+),"                                                       // (4) process id
                " tid=(0?x?[0-9a-fA-F]+). "                                            // (5) thread id
                ".([a-zA-Z0-9_\\. ]+). "                                               // (6) component name
                "([^:]+):"                                                             // (7) file name
                "([0-9]+): "                                                           // (8) line number
                "([^\n]*)\n?$"                                                         // (9) message
                , std::regex_constants::extended);

    std::cmatch match;
    bool isMatch = std::regex_match(str.c_str(), match, rowRe);

    UNIT_ASSERT_C(isMatch, "log row does not match format: '" << str << '\'');
    UNIT_ASSERT_EQUAL_C(match.size(), 10, "expected 10 groups in log row: '" << str << '\'');

    TLogRow logRow;
    logRow.Time = TInstant::ParseIso8601(match[1].str()) - TDuration::Hours(4);
    logRow.Level = ELevelHelpers::FromString(match[2].str());
    logRow.ProcName = match[3].str();
    logRow.ProcId = FromString<pid_t>(match[4].str());
    logRow.ThreadId = match[5].str().substr(0, 2) == "0x" ?
        IntFromString<ui64, 16, TStringBuf>(match[5].str().substr(2)) :
        IntFromString<ui64, 10, TStringBuf>(match[5].str());
    logRow.Component = EComponentHelpers::FromString(match[6].str());
    logRow.FileName = match[7].str();
    logRow.LineNumber = FromString<ui32>(match[8].str());
    logRow.Message = match[9].str();
    return logRow;
}

} // namspace NLog
} // namspace NYql