[log-format] regex config format redux

pull/69/head
Timothy Stack 11 years ago
parent f716d5a533
commit 83f94cea86

@ -3,11 +3,17 @@
"title" : "Common Access Log",
"description" : "The default web access log format for servers like Apache.",
"url" : "http://en.wikipedia.org/wiki/Common_Log_Format",
"regex" : [
"^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?<c_ip>[^ ]+) (?<cs_username>[^ ]+) (?<cs_method>[A-Z]+) (?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))? (?:-1|\\d+) (?<sc_status>\\d+) \\d+",
"^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?<c_ip>[^ ]+) (?<cs_username>[^ ]+) (?<cs_method>[A-Z]+) \"(?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))?\" (?:-1|\\d+) (?<sc_status>\\d+) \\d+",
"^(?<c_ip>[\\w\\.:\\-]+) [\\w\\.\\-]+ (?<cs_username>[\\w\\.\\-]+) \\[(?<timestamp>[^\\]]+)\\] \"(?:\\-|(?<cs_method>\\w+) (?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))? (?<cs_version>[\\w/\\.]+))\" (?<sc_status>\\d+) (?<sc_bytes>\\d+|-)(?: \"(?<cs_referer>[^\"]+)\" \"(?<cs_user_agent>[^\"]+)\")?.*"
],
"regex" : {
"ts-first-noquotes" : {
"pattern" : "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?<c_ip>[^ ]+) (?<cs_username>[^ ]+) (?<cs_method>[A-Z]+) (?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))? (?:-1|\\d+) (?<sc_status>\\d+) \\d+"
},
"ts-first" : {
"pattern" : "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?<c_ip>[^ ]+) (?<cs_username>[^ ]+) (?<cs_method>[A-Z]+) \"(?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))?\" (?:-1|\\d+) (?<sc_status>\\d+) \\d+"
},
"std" : {
"pattern" : "^(?<c_ip>[\\w\\.:\\-]+) [\\w\\.\\-]+ (?<cs_username>[\\w\\.\\-]+) \\[(?<timestamp>[^\\]]+)\\] \"(?:\\-|(?<cs_method>\\w+) (?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))? (?<cs_version>[\\w/\\.]+))\" (?<sc_status>\\d+) (?<sc_bytes>\\d+|-)(?: \"(?<cs_referer>[^\"]+)\" \"(?<cs_user_agent>[^\"]+)\")?.*"
}
},
"level-field": "sc_status",
"level" : {
"error" : "^[^123]"
@ -62,9 +68,11 @@
"block_log" : {
"title" : "Generic Block",
"description" : "A generic format for logs, like cron, that have a date at the start of a block.",
"regex" : [
"^(?<timestamp>\\w{3} \\w{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\w+ \\d{4})$"
],
"regex" : {
"std" : {
"pattern" : "^(?<timestamp>\\w{3} \\w{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\w+ \\d{4})$"
}
},
"sample" : [
{
"line" : "Sat Apr 27 03:33:07 PDT 2013"
@ -74,9 +82,11 @@
"choose_repo_log" : {
"title" : "Yum choose_repo Log",
"description" : "The log format for the yum choose_repo tool.",
"regex" : [
"^\\[(?<level>\\w+):[^\\]]+] [^:]+:\\d+ (?<timestamp>\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?:[\\.,]\\d{3})?):(?<body>.*)"
],
"regex" : {
"std" : {
"pattern" : "^\\[(?<level>\\w+):[^\\]]+] [^:]+:\\d+ (?<timestamp>\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?:[\\.,]\\d{3})?):(?<body>.*)"
}
},
"level-field" : "level",
"level" : {
"error" : "ERROR",
@ -93,9 +103,11 @@
"dpkg_log" : {
"title" : "Dpkg Log",
"description" : "The debian dpkg log.",
"regex" : [
"^(?<timestamp>\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?:(?:(?<action>startup|status|configure|install|upgrade|trigproc|remove|purge)(?: (?<status>config-files|failed-config|half-configured|half-installed|installed|not-installed|post-inst-failed|removal-failed|triggers-awaited|triggers-pending|unpacked))? (?<package>[^ ]+) (?<installed_version>[^ ]+)(?: (?<available_version>[^ ]+))?)|update-alternatives: (?<body>.*))$"
],
"regex" : {
"std" : {
"pattern" : "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?:(?:(?<action>startup|status|configure|install|upgrade|trigproc|remove|purge)(?: (?<status>config-files|failed-config|half-configured|half-installed|installed|not-installed|post-inst-failed|removal-failed|triggers-awaited|triggers-pending|unpacked))? (?<package>[^ ]+) (?<installed_version>[^ ]+)(?: (?<available_version>[^ ]+))?)|update-alternatives: (?<body>.*))$"
}
},
"value" : {
"action" : {
"kind" : "string",
@ -131,9 +143,11 @@
"error_log" : {
"title" : "Common Error Log",
"description" : "The default web error log format for servers like Apache.",
"regex" : [
"^(?<level>\\w) \\[(?<timestamp>[^\\]]+)\\] (?<body>.*)"
],
"regex" : {
"cups" : {
"pattern" : "^(?<level>\\w) \\[(?<timestamp>[^\\]]+)\\] (?<body>.*)"
}
},
"level-field": "level",
"level" : {
"error" : "E",
@ -149,9 +163,11 @@
"fsck_hfs_log" : {
"title" : "Fsck_hfs Log",
"description" : "Log for the fsck_hfs tool on Mac OS X.",
"regex" : [
"^(?<device>[^:]+): fsck_hfs run at (?<timestamp>\\w{3} \\w{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4})"
],
"regex" : {
"std" : {
"pattern" : "^(?<device>[^:]+): fsck_hfs run at (?<timestamp>\\w{3} \\w{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2} \\d{4})"
}
},
"value" : {
"device" : {
"kind" : "string",
@ -168,9 +184,11 @@
"title" : "Glog",
"description" : "The google glog format.",
"url" : "https://code.google.com/p/google-glog/",
"regex" : [
"^(?<level>[IWECF])(?<timestamp>\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6}) (?<thread>\\d+) (?<src_file>[^:]+):(?<src_line>\\d+)\\] (?<body>(?:.|\\n)*)"
],
"regex" : {
"std" : {
"pattern" : "^(?<level>[IWECF])(?<timestamp>\\d{4} \\d{2}:\\d{2}:\\d{2}\\.\\d{6}) (?<thread>\\d+) (?<src_file>[^:]+):(?<src_line>\\d+)\\] (?<body>(?:.|\\n)*)"
}
},
"level-field" : "level",
"level" : {
"error" : "E",
@ -204,10 +222,14 @@
"title" : "CUPS Page Log",
"description" : "The CUPS server log of printed pages.",
"url" : "http://www.cups.org/documentation.php/doc-1.7/ref-page_log.html",
"regex" : [
"^(?<printer>[\\w_\\-\\.]+) (?<username>[\\w\\.\\-]+) (?<job_id>\\d+) \\[(?<timestamp>[^\\]]+)\\] (?<page_number>total|\\d+) (?<num_copies>\\d+) (?<job_billing>[^ ]+) (?<job_originating_hostname>[\\w\\.:\\-]+)$",
"^(?<printer>[\\w_\\-\\.]+) (?<username>[\\w\\.\\-]+) (?<job_id>\\d+) \\[(?<timestamp>[^\\]]+)\\] (?<page_number>total|\\d+) (?<num_copies>\\d+) (?<job_billing>[^ ]+) (?<job_originating_hostname>[\\w\\.:\\-]+) (?<job_name>.+) (?<media>[^ ]+) (?<sides>.+)$"
],
"regex" : {
"pre-1.7" : {
"pattern" : "^(?<printer>[\\w_\\-\\.]+) (?<username>[\\w\\.\\-]+) (?<job_id>\\d+) \\[(?<timestamp>[^\\]]+)\\] (?<page_number>total|\\d+) (?<num_copies>\\d+) (?<job_billing>[^ ]+) (?<job_originating_hostname>[\\w\\.:\\-]+)$"
},
"1.7" : {
"pattern" : "^(?<printer>[\\w_\\-\\.]+) (?<username>[\\w\\.\\-]+) (?<job_id>\\d+) \\[(?<timestamp>[^\\]]+)\\] (?<page_number>total|\\d+) (?<num_copies>\\d+) (?<job_billing>[^ ]+) (?<job_originating_hostname>[\\w\\.:\\-]+) (?<job_name>.+) (?<media>[^ ]+) (?<sides>.+)$"
}
},
"value" : {
"printer" : {
"kind" : "string",
@ -262,9 +284,11 @@
"title" : "SnapLogic Server Log",
"description" : "The SnapLogic server log format.",
"url" : "http://www.snaplogic.com/docs/user-guide/user-guide.htm",
"regex" : [
"^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?:(?:(?<level>\\w+) (?<logger>[^ ]+) (?<facility>[^ ]+) (?<msgid>[^ ]+) (?<pipe_rid>[^ \\.]+)(?:\\.(?<comp_rid>[^ ]+))? (?<resource_name>[^ ]+) (?<invoker>[^ ]+))|(?:(?:stdout|stderr): ))(?<body>.*)"
],
"regex" : {
"std" : {
"pattern" : "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{3})?) (?:(?:(?<level>\\w+) (?<logger>[^ ]+) (?<facility>[^ ]+) (?<msgid>[^ ]+) (?<pipe_rid>[^ \\.]+)(?:\\.(?<comp_rid>[^ ]+))? (?<resource_name>[^ ]+) (?<invoker>[^ ]+))|(?:(?:stdout|stderr): ))(?<body>.*)"
}
},
"level-field" : "level",
"level" : {
"error" : "ERROR",
@ -312,9 +336,11 @@
"title" : "Syslog",
"description" : "The system logger format found on most posix systems.",
"url" : "http://en.wikipedia.org/wiki/Syslog",
"regex" : [
"^(?<timestamp>\\w{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2})(?: (?<log_hostname>[a-zA-Z0-9:][^ ]+[a-zA-Z0-9]))?(?:(?: (?<log_procname>(?:[^ \\[:]+|[^:]+))(?:\\[(?<log_pid>\\d+)])?:(?<body>(?:.|\\n)*))$|:?(?:(?: ---)? last message repeated \\d+ times?(?: ---)?))"
],
"regex" : {
"std" : {
"pattern" : "^(?<timestamp>\\w{3}\\s+\\d{1,2} \\d{2}:\\d{2}:\\d{2})(?: (?<log_hostname>[a-zA-Z0-9:][^ ]+[a-zA-Z0-9]))?(?:(?: (?<log_procname>(?:[^ \\[:]+|[^:]+))(?:\\[(?<log_pid>\\d+)])?:(?<body>(?:.|\\n)*))$|:?(?:(?: ---)? last message repeated \\d+ times?(?: ---)?))"
}
},
"level-field" : "body",
"level" : {
"error" : "(?:failed|failure|error)",
@ -348,9 +374,11 @@
"title" : "TCSH History",
"description" : "The tcsh history file format.",
"local-time" : true,
"regex" : [
"^#(?<timestamp>\\+\\d+)\\n?(?<body>.*)?$"
],
"regex" : {
"std" : {
"pattern" : "^#(?<timestamp>\\+\\d+)\\n?(?<body>.*)?$"
}
},
"sample" : [
{
"line" : "#+1375138067\necho HELLO=BAR"
@ -360,9 +388,11 @@
"uwsgi_log" : {
"title" : "Uwsgi Log",
"description" : "The uwsgi log format.",
"regex" : [
"^\\[pid: (?<s_pid>\\d+)\\|app: (?<s_app>[\\-\\d]+)\\|req: (?<s_req>[\\-\\d]+)/(?<s_worker_reqs>\\d+)\\] (?<c_ip>[^ ]+) \\((?<cs_username>[^\\)]*)\\) \\{(?<cs_vars>\\d+) vars in (?<cs_bytes>\\d+) bytes\\} \\[(?<timestamp>[^\\]]+)\\] (?<cs_method>[A-Z]+) (?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))? => generated (?<sc_bytes>\\d+) bytes in (?<s_runtime>\\d+) (?<rt_unit>\\w+) \\((?<cs_version>[^ ]+) (?<sc_status>\\d+)\\) (?<sc_headers>\\d+) headers in (?<sc_header_bytes>\\d+) bytes \\((?<s_switches>\\d+) switches on core (?<s_core>\\d+)\\)"
],
"regex" : {
"std" : {
"pattern" : "^\\[pid: (?<s_pid>\\d+)\\|app: (?<s_app>[\\-\\d]+)\\|req: (?<s_req>[\\-\\d]+)/(?<s_worker_reqs>\\d+)\\] (?<c_ip>[^ ]+) \\((?<cs_username>[^\\)]*)\\) \\{(?<cs_vars>\\d+) vars in (?<cs_bytes>\\d+) bytes\\} \\[(?<timestamp>[^\\]]+)\\] (?<cs_method>[A-Z]+) (?<cs_uri_stem>[^ \\?]+)(?:\\?(?<cs_uri_query>[^ ]*))? => generated (?<sc_bytes>\\d+) bytes in (?<s_runtime>\\d+) (?<rt_unit>\\w+) \\((?<cs_version>[^ ]+) (?<sc_status>\\d+)\\) (?<sc_headers>\\d+) headers in (?<sc_header_bytes>\\d+) bytes \\((?<s_switches>\\d+) switches on core (?<s_core>\\d+)\\)"
}
},
"level-field": "sc_status",
"level" : {
"error" : "^[^123]"
@ -453,10 +483,14 @@
"title" : "VMware Logs",
"description" : "One of the log formats used in VMware's ESXi and vCenter software.",
"url" : "http://kb.vmware.com/kb/2004201",
"regex" : [
"^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z) \\[(?<tid>\\w+) (?<level>\\w+) '(?<comp>[^']+)'(?: opID=(?<opid>[^ \\]]+))?(?: user=(?<user>[\\w\\-]+))?\\](?<body>.*)$",
"^\\[(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) (?<tid>\\w+) (?<level>\\w+) '(?<comp>[^']+)'(?: opID=(?<opid>[^ \\]]+))?(?: user=(?<user>[\\w\\-]+))?\\](?<body>.*)$"
],
"regex" : {
"5.0+" : {
"pattern" : "^(?<timestamp>\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z) \\[(?<tid>\\w+) (?<level>\\w+) '(?<comp>[^']+)'(?: opID=(?<opid>[^ \\]]+))?(?: user=(?<user>[\\w\\-]+))?\\](?<body>.*)$"
},
"pre-5.0" : {
"pattern" : "^\\[(?<timestamp>\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d{3}) (?<tid>\\w+) (?<level>\\w+) '(?<comp>[^']+)'(?: opID=(?<opid>[^ \\]]+))?(?: user=(?<user>[\\w\\-]+))?\\](?<body>.*)$"
}
},
"level-field": "level",
"level" : {
"error" : "error",

@ -132,7 +132,7 @@ vector<log_format *> &log_format::get_root_formats(void)
return lf_root_formats;
}
static bool next_format(const std::vector<external_log_format::pattern> &patterns,
static bool next_format(const std::vector<external_log_format::pattern *> &patterns,
int &index,
int &locked_index)
{
@ -207,8 +207,8 @@ bool external_log_format::scan(std::vector<logline> &dst,
bool retval = false;
int curr_fmt = -1;
while (next_format(this->elf_patterns, curr_fmt, this->lf_fmt_lock)) {
if (!this->elf_patterns[curr_fmt].p_pcre->match(pc, pi)) {
while (next_format(this->elf_pattern_order, curr_fmt, this->lf_fmt_lock)) {
if (!this->elf_pattern_order[curr_fmt]->p_pcre->match(pc, pi)) {
continue;
}
@ -276,7 +276,9 @@ void external_log_format::annotate(const std::string &line,
struct line_range lr;
pcre_context::capture_t *cap;
if (!this->elf_patterns[this->lf_fmt_lock].p_pcre->match(pc, pi)) {
pattern &pat = *this->elf_pattern_order[this->lf_fmt_lock];
if (!pat.p_pcre->match(pc, pi)) {
return;
}
@ -298,8 +300,8 @@ void external_log_format::annotate(const std::string &line,
view_colors &vc = view_colors::singleton();
for (size_t lpc = 0; lpc < this->elf_patterns[this->lf_fmt_lock].p_value_by_index.size(); lpc++) {
const value_def &vd = this->elf_patterns[this->lf_fmt_lock].p_value_by_index[lpc];
for (size_t lpc = 0; lpc < pat.p_value_by_index.size(); lpc++) {
const value_def &vd = pat.p_value_by_index[lpc];
const struct scaling_factor *scaling = NULL;
if (vd.vd_unit_field_index >= 0) {
@ -334,11 +336,11 @@ void external_log_format::annotate(const std::string &line,
void external_log_format::build(std::vector<std::string> &errors)
{
for (std::vector<pattern>::iterator iter = this->elf_patterns.begin();
for (std::map<string, pattern>::iterator iter = this->elf_patterns.begin();
iter != this->elf_patterns.end();
++iter) {
try {
iter->p_pcre = new pcrepp(iter->p_string.c_str());
iter->second.p_pcre = new pcrepp(iter->second.p_string.c_str());
}
catch (const pcrepp::error &e) {
errors.push_back("error:" +
@ -347,21 +349,23 @@ void external_log_format::build(std::vector<std::string> &errors)
e.what());
continue;
}
for (pcre_named_capture::iterator name_iter = iter->p_pcre->named_begin();
name_iter != iter->p_pcre->named_end();
for (pcre_named_capture::iterator name_iter = iter->second.p_pcre->named_begin();
name_iter != iter->second.p_pcre->named_end();
++name_iter) {
std::map<std::string, value_def>::iterator value_iter;
value_iter = this->elf_value_defs.find(std::string(name_iter->pnc_name));
if (value_iter != this->elf_value_defs.end()) {
value_iter->second.vd_index = name_iter->index();
value_iter->second.vd_unit_field_index = iter->p_pcre->name_index(value_iter->second.vd_unit_field.c_str());
iter->p_value_by_index.push_back(value_iter->second);
value_iter->second.vd_unit_field_index = iter->second.p_pcre->name_index(value_iter->second.vd_unit_field.c_str());
iter->second.p_value_by_index.push_back(value_iter->second);
}
}
stable_sort(iter->p_value_by_index.begin(),
iter->p_value_by_index.end());
stable_sort(iter->second.p_value_by_index.begin(),
iter->second.p_value_by_index.end());
this->elf_pattern_order.push_back(&iter->second);
}
if (this->elf_patterns.empty()) {
@ -395,13 +399,15 @@ void external_log_format::build(std::vector<std::string> &errors)
pcre_input pi(iter->s_line);
bool found = false;
for (std::vector<pattern>::iterator pat_iter = this->elf_patterns.begin();
pat_iter != this->elf_patterns.end();
for (std::vector<pattern *>::iterator pat_iter = this->elf_pattern_order.begin();
pat_iter != this->elf_pattern_order.end();
++pat_iter) {
if (!pat_iter->p_pcre)
pattern &pat = *(*pat_iter);
if (!pat.p_pcre)
continue;
if (pat_iter->p_pcre->match(pc, pi)) {
if (pat.p_pcre->match(pc, pi)) {
found = true;
break;
}
@ -413,10 +419,12 @@ void external_log_format::build(std::vector<std::string> &errors)
":invalid sample -- " +
iter->s_line);
for (std::vector<pattern>::iterator pat_iter = this->elf_patterns.begin();
pat_iter != this->elf_patterns.end();
for (std::vector<pattern *>::iterator pat_iter = this->elf_pattern_order.begin();
pat_iter != this->elf_pattern_order.end();
++pat_iter) {
if (!pat_iter->p_pcre)
pattern &pat = *(*pat_iter);
if (!pat.p_pcre)
continue;
std::string line_partial = iter->s_line;
@ -424,7 +432,7 @@ void external_log_format::build(std::vector<std::string> &errors)
while (!line_partial.empty()) {
pcre_input pi_partial(line_partial);
if (pat_iter->p_pcre->match(pc, pi_partial, PCRE_PARTIAL)) {
if (pat.p_pcre->match(pc, pi_partial, PCRE_PARTIAL)) {
errors.push_back("error:" +
this->elf_name +
":partial sample matched -- " +
@ -454,8 +462,8 @@ public:
std::vector<external_log_format::value_def>::const_iterator iter;
const external_log_format &elf = this->elt_format;
for (iter = elf.elf_patterns[0].p_value_by_index.begin();
iter != elf.elf_patterns[0].p_value_by_index.end();
for (iter = elf.elf_pattern_order[0]->p_value_by_index.begin();
iter != elf.elf_pattern_order[0]->p_value_by_index.end();
++iter) {
int type;

@ -507,9 +507,10 @@ public:
};
struct pattern {
pattern(const std::string &str) : p_string(str), p_pcre(NULL) { };
pattern() : p_pcre(NULL) { };
std::string p_string;
std::vector<std::string> p_before_pattern;
pcrepp *p_pcre;
std::vector<value_def> p_value_by_index;
};
@ -550,7 +551,8 @@ public:
log_vtab_impl *get_vtab_impl(void) const;
std::vector<pattern> elf_patterns;
std::map<std::string, pattern> elf_patterns;
std::vector<pattern *> elf_pattern_order;
std::vector<sample> elf_samples;
std::map<std::string, value_def> elf_value_defs;
std::string elf_level_field;

@ -63,9 +63,10 @@ static external_log_format *ensure_format(const std::string &name)
static int read_format_regex(yajlpp_parse_context *ypc, const unsigned char *str, size_t len)
{
external_log_format *elf = ensure_format(ypc->get_path_fragment(0));
string regex_name = ypc->get_path_fragment(2);
string value = string((const char *)str, len);
elf->elf_patterns.insert(elf->elf_patterns.begin(), value);
elf->elf_patterns[regex_name].p_string = value;
return 1;
}
@ -202,7 +203,7 @@ static int read_sample_line(yajlpp_parse_context *ypc, const unsigned char *str,
}
static struct json_path_handler format_handlers[] = {
json_path_handler("/\\w+/regex#", read_format_regex),
json_path_handler("/\\w+/regex/[^/]+/pattern", read_format_regex),
json_path_handler("/\\w+/local-time", read_format_bool),
json_path_handler("/\\w+/(level-field|url|title|description)", read_format_field),
json_path_handler("/\\w+/level/"

Loading…
Cancel
Save