mirror of
https://github.com/tstack/lnav
synced 2024-11-17 15:29:40 +00:00
[json_log] auto detect the required width for a column
Related to #1146
This commit is contained in:
parent
cd59577324
commit
822eaf5a1a
9
NEWS.md
9
NEWS.md
@ -7,6 +7,15 @@ Features:
|
||||
operate on the selected line instead.
|
||||
* Added CTRL-D and CTRL-U hotkeys to move down/up by half
|
||||
a page.
|
||||
* Added an `auto-width` flag to the elements of the
|
||||
`line-format` array that indicates that the width of the
|
||||
field should automatically be determined by the observed
|
||||
values.
|
||||
* Number fields used in a `line-format` now default to
|
||||
being right-aligned.
|
||||
|
||||
Bug Fixes:
|
||||
* Hidden values in JSON logs are now hidden by default.
|
||||
|
||||
## lnav v0.11.1
|
||||
|
||||
|
@ -472,6 +472,11 @@
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"auto-width": {
|
||||
"title": "/<format_name>/line-format/auto-width",
|
||||
"description": "Automatically detect the necessary width of the field based on the observed values",
|
||||
"type": "boolean"
|
||||
},
|
||||
"max-width": {
|
||||
"title": "/<format_name>/line-format/max-width",
|
||||
"description": "The maximum width of the field",
|
||||
|
@ -138,7 +138,7 @@ object with the following fields:
|
||||
converted from the raw JSON encoding into this format. Each element
|
||||
is either an object that defines which fields should be inserted into
|
||||
the final message string and or a string constant that should be
|
||||
inserted. For example, the following configuration will tranform each
|
||||
inserted. For example, the following configuration will transform each
|
||||
log message object into a string that contains the timestamp, followed
|
||||
by a space, and then the message body:
|
||||
|
||||
@ -164,6 +164,8 @@ object with the following fields:
|
||||
:max-width: The maximum width for the field. If the value for the field
|
||||
in a given log message is longer, the overflow algorithm will be applied
|
||||
to try and shorten the field. (v0.8.2+)
|
||||
:auto-width: Flag that indicates that the width of the field should
|
||||
automatically be set to the widest value seen. (v0.11.2)
|
||||
:align: Specifies the alignment for the field, either "left" or "right".
|
||||
If "left", padding to meet the minimum-width will be added on the right.
|
||||
If "right", padding will be added on the left. (v0.8.2+)
|
||||
|
@ -459,17 +459,27 @@ read_json_bool(yajlpp_parse_context* ypc, int val)
|
||||
}
|
||||
|
||||
static int
|
||||
read_json_int(yajlpp_parse_context* ypc, long long val)
|
||||
read_json_number(yajlpp_parse_context* ypc,
|
||||
const char* numberVal,
|
||||
size_t numberLen)
|
||||
{
|
||||
json_log_userdata* jlu = (json_log_userdata*) ypc->ypc_userdata;
|
||||
const intern_string_t field_name = ypc->get_path();
|
||||
|
||||
auto number_frag = string_fragment::from_bytes(numberVal, numberLen);
|
||||
auto scan_res = scn::scan_value<double>(number_frag.to_string_view());
|
||||
if (!scan_res) {
|
||||
log_error("invalid number %.*s", numberLen, numberVal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto val = scan_res.value();
|
||||
if (jlu->jlu_format->lf_timestamp_field == field_name) {
|
||||
long long divisor = jlu->jlu_format->elf_timestamp_divisor;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = val / divisor;
|
||||
tv.tv_usec = (val % divisor) * (1000000.0 / divisor);
|
||||
tv.tv_usec = fmod(val, divisor) * (1000000.0 / divisor);
|
||||
if (jlu->jlu_format->lf_date_time.dts_local_time) {
|
||||
struct tm ltm;
|
||||
localtime_r(&tv.tv_sec, <m);
|
||||
@ -488,34 +498,26 @@ read_json_int(yajlpp_parse_context* ypc, long long val)
|
||||
break;
|
||||
case log_format::subsecond_unit::micro:
|
||||
millis = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::microseconds(val))
|
||||
std::chrono::microseconds((int64_t) val))
|
||||
.count();
|
||||
break;
|
||||
case log_format::subsecond_unit::nano:
|
||||
millis = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::nanoseconds(val))
|
||||
std::chrono::nanoseconds((int64_t) val))
|
||||
.count();
|
||||
break;
|
||||
}
|
||||
jlu->jlu_base_line->set_millis(millis);
|
||||
} else if (jlu->jlu_format->elf_level_field == field_name) {
|
||||
if (jlu->jlu_format->elf_level_pairs.empty()) {
|
||||
char level_buf[128];
|
||||
|
||||
snprintf(level_buf, sizeof(level_buf), "%lld", val);
|
||||
|
||||
jlu->jlu_base_line->set_level(jlu->jlu_format->convert_level(
|
||||
string_fragment::from_c_str(level_buf),
|
||||
jlu->jlu_batch_context));
|
||||
number_frag, jlu->jlu_batch_context));
|
||||
} else {
|
||||
std::vector<std::pair<int64_t, log_level_t>>::iterator iter;
|
||||
int64_t level_int = val;
|
||||
|
||||
for (iter = jlu->jlu_format->elf_level_pairs.begin();
|
||||
iter != jlu->jlu_format->elf_level_pairs.end();
|
||||
++iter)
|
||||
{
|
||||
if (iter->first == val) {
|
||||
jlu->jlu_base_line->set_level(iter->second);
|
||||
for (const auto& pair : jlu->jlu_format->elf_level_pairs) {
|
||||
if (pair.first == level_int) {
|
||||
jlu->jlu_base_line->set_level(pair.second);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -523,7 +525,11 @@ read_json_int(yajlpp_parse_context* ypc, long long val)
|
||||
}
|
||||
|
||||
jlu->jlu_sub_line_count
|
||||
+= jlu->jlu_format->value_line_count(field_name, ypc->is_level(1));
|
||||
+= jlu->jlu_format->value_line_count(field_name,
|
||||
ypc->is_level(1),
|
||||
val,
|
||||
(const unsigned char*) numberVal,
|
||||
numberLen);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -553,7 +559,7 @@ read_json_double(yajlpp_parse_context* ypc, double val)
|
||||
}
|
||||
|
||||
jlu->jlu_sub_line_count
|
||||
+= jlu->jlu_format->value_line_count(field_name, ypc->is_level(1));
|
||||
+= jlu->jlu_format->value_line_count(field_name, ypc->is_level(1), val);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -599,8 +605,7 @@ static const struct json_path_container json_log_handlers = {
|
||||
yajlpp::pattern_property_handler("\\w+")
|
||||
.add_cb(read_json_null)
|
||||
.add_cb(read_json_bool)
|
||||
.add_cb(read_json_int)
|
||||
.add_cb(read_json_double)
|
||||
.add_cb(read_json_number)
|
||||
.add_cb(read_json_field),
|
||||
};
|
||||
|
||||
@ -965,6 +970,23 @@ external_log_format::scan(logfile& lf,
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& ivd : fpat->p_value_by_index) {
|
||||
if (!ivd.ivd_value_def->vd_meta.lvm_values_index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto cap = md[ivd.ivd_index];
|
||||
|
||||
if (cap && cap->is_valid()) {
|
||||
auto& lvs = this->lf_value_stats[ivd.ivd_value_def->vd_meta
|
||||
.lvm_values_index.value()];
|
||||
|
||||
if (cap->length() > lvs.lvs_width) {
|
||||
lvs.lvs_width = cap->length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto value_index : fpat->p_numeric_value_indexes) {
|
||||
const indexed_value_def& ivd = fpat->p_value_by_index[value_index];
|
||||
const value_def& vd = *ivd.ivd_value_def;
|
||||
@ -996,7 +1018,8 @@ external_log_format::scan(logfile& lf,
|
||||
if (scaling != nullptr) {
|
||||
scaling->scale(dvalue);
|
||||
}
|
||||
this->lf_value_stats[vd.vd_values_index].add_value(dvalue);
|
||||
this->lf_value_stats[vd.vd_meta.lvm_values_index.value()]
|
||||
.add_value(dvalue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1344,7 +1367,7 @@ read_json_field(yajlpp_parse_context* ypc, const unsigned char* str, size_t len)
|
||||
}
|
||||
|
||||
jlu->jlu_sub_line_count += jlu->jlu_format->value_line_count(
|
||||
field_name, ypc->is_level(1), str, len);
|
||||
field_name, ypc->is_level(1), nonstd::nullopt, str, len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1579,9 +1602,18 @@ external_log_format::get_subline(const logline& ll,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
value_def* vd = nullptr;
|
||||
|
||||
if (lv_iter->lv_meta.lvm_values_index) {
|
||||
vd = this->elf_value_def_order
|
||||
[lv_iter->lv_meta.lvm_values_index
|
||||
.value()]
|
||||
.get();
|
||||
}
|
||||
sub_offset
|
||||
+= count(str.begin(), str.end(), '\n');
|
||||
this->json_append(jfe, str.c_str(), str.size());
|
||||
+= std::count(str.begin(), str.end(), '\n');
|
||||
this->json_append(
|
||||
jfe, vd, str.c_str(), str.size());
|
||||
}
|
||||
|
||||
if (nl_pos == std::string::npos || full_message) {
|
||||
@ -1650,9 +1682,11 @@ external_log_format::get_subline(const logline& ll,
|
||||
|| jfe.jfe_value.pp_value
|
||||
== this->elf_level_field)
|
||||
{
|
||||
this->json_append(jfe, ll.get_level_name(), -1);
|
||||
this->json_append(
|
||||
jfe, nullptr, ll.get_level_name(), -1);
|
||||
} else {
|
||||
this->json_append(jfe,
|
||||
nullptr,
|
||||
jfe.jfe_default_value.c_str(),
|
||||
jfe.jfe_default_value.size());
|
||||
}
|
||||
@ -2448,27 +2482,27 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& elf_value_def : this->elf_value_defs) {
|
||||
if (elf_value_def.second->vd_foreign_key
|
||||
|| elf_value_def.second->vd_meta.lvm_identifier)
|
||||
size_t value_def_index = 0;
|
||||
for (auto& elf_value_def : this->elf_value_def_order) {
|
||||
elf_value_def->vd_meta.lvm_values_index
|
||||
= nonstd::make_optional(value_def_index++);
|
||||
|
||||
if (elf_value_def->vd_foreign_key
|
||||
|| elf_value_def->vd_meta.lvm_identifier)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (elf_value_def.second->vd_meta.lvm_kind) {
|
||||
switch (elf_value_def->vd_meta.lvm_kind) {
|
||||
case value_kind_t::VALUE_INTEGER:
|
||||
case value_kind_t::VALUE_FLOAT:
|
||||
elf_value_def.second->vd_values_index
|
||||
= this->elf_numeric_value_defs.size();
|
||||
this->elf_numeric_value_defs.push_back(elf_value_def.second);
|
||||
this->elf_numeric_value_defs.push_back(elf_value_def);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->lf_value_stats.resize(this->elf_numeric_value_defs.size());
|
||||
|
||||
int format_index = 0;
|
||||
for (auto iter = this->jlf_line_format.begin();
|
||||
iter != this->jlf_line_format.end();
|
||||
@ -2522,6 +2556,20 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
.append_quoted(jfe.jfe_value.pp_value)
|
||||
.append(" is not a defined value"))
|
||||
.with_snippet(jfe.jfe_value.to_snippet()));
|
||||
} else {
|
||||
switch (vd_iter->second->vd_meta.lvm_kind) {
|
||||
case value_kind_t::VALUE_INTEGER:
|
||||
case value_kind_t::VALUE_FLOAT:
|
||||
if (jfe.jfe_align
|
||||
== json_format_element::align_t::NONE)
|
||||
{
|
||||
jfe.jfe_align
|
||||
= json_format_element::align_t::RIGHT;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -2595,6 +2643,8 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
|
||||
.with_attrs(attrs);
|
||||
}
|
||||
}
|
||||
|
||||
this->lf_value_stats.resize(this->elf_value_defs.size());
|
||||
}
|
||||
|
||||
void
|
||||
@ -2811,7 +2861,7 @@ external_log_format::specialized(int fmt_lock)
|
||||
}
|
||||
|
||||
this->lf_value_stats.clear();
|
||||
this->lf_value_stats.resize(this->elf_numeric_value_defs.size());
|
||||
this->lf_value_stats.resize(this->elf_value_defs.size());
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -2841,8 +2891,9 @@ external_log_format::match_mime_type(const file_format_t ff) const
|
||||
long
|
||||
external_log_format::value_line_count(const intern_string_t ist,
|
||||
bool top_level,
|
||||
nonstd::optional<double> val,
|
||||
const unsigned char* str,
|
||||
ssize_t len) const
|
||||
ssize_t len)
|
||||
{
|
||||
const auto iter = this->elf_value_defs.find(ist);
|
||||
long line_count
|
||||
@ -2852,6 +2903,16 @@ external_log_format::value_line_count(const intern_string_t ist,
|
||||
return (this->jlf_hide_extra || !top_level) ? 0 : line_count;
|
||||
}
|
||||
|
||||
if (iter->second->vd_meta.lvm_values_index) {
|
||||
auto& lvs = this->lf_value_stats[iter->second->vd_meta.lvm_values_index
|
||||
.value()];
|
||||
if (len > lvs.lvs_width) {
|
||||
lvs.lvs_width = len;
|
||||
}
|
||||
if (val) {
|
||||
lvs.add_value(val.value());
|
||||
}
|
||||
}
|
||||
if (iter->second->vd_meta.is_hidden()) {
|
||||
return 0;
|
||||
}
|
||||
@ -2951,6 +3012,7 @@ external_log_format::get_value_meta(intern_string_t field_name,
|
||||
void
|
||||
external_log_format::json_append(
|
||||
const external_log_format::json_format_element& jfe,
|
||||
const value_def* vd,
|
||||
const char* value,
|
||||
ssize_t len)
|
||||
{
|
||||
@ -2960,12 +3022,32 @@ external_log_format::json_append(
|
||||
if (jfe.jfe_align == json_format_element::align_t::RIGHT) {
|
||||
if (len < jfe.jfe_min_width) {
|
||||
this->json_append_to_cache(jfe.jfe_min_width - len);
|
||||
} else if (jfe.jfe_auto_width && vd != nullptr
|
||||
&& len < this->lf_value_stats[vd->vd_meta.lvm_values_index
|
||||
.value()]
|
||||
.lvs_width)
|
||||
{
|
||||
this->json_append_to_cache(
|
||||
this->lf_value_stats[vd->vd_meta.lvm_values_index.value()]
|
||||
.lvs_width
|
||||
- len);
|
||||
}
|
||||
}
|
||||
this->json_append_to_cache(value, len);
|
||||
if (jfe.jfe_align == json_format_element::align_t::LEFT) {
|
||||
if (jfe.jfe_align == json_format_element::align_t::LEFT
|
||||
|| jfe.jfe_align == json_format_element::align_t::NONE)
|
||||
{
|
||||
if (len < jfe.jfe_min_width) {
|
||||
this->json_append_to_cache(jfe.jfe_min_width - len);
|
||||
} else if (jfe.jfe_auto_width && vd != nullptr
|
||||
&& len < this->lf_value_stats[vd->vd_meta.lvm_values_index
|
||||
.value()]
|
||||
.lvs_width)
|
||||
{
|
||||
this->json_append_to_cache(
|
||||
this->lf_value_stats[vd->vd_meta.lvm_values_index.value()]
|
||||
.lvs_width
|
||||
- len);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3043,6 +3125,9 @@ logline_value_stats::merge(const logline_value_stats& other)
|
||||
|
||||
require(other.lvs_min_value <= other.lvs_max_value);
|
||||
|
||||
if (other.lvs_width > this->lvs_width) {
|
||||
this->lvs_width = other.lvs_width;
|
||||
}
|
||||
if (other.lvs_min_value < this->lvs_min_value) {
|
||||
this->lvs_min_value = other.lvs_min_value;
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ struct logline_value_meta {
|
||||
intern_string_t lvm_name;
|
||||
value_kind_t lvm_kind;
|
||||
int lvm_column{-1};
|
||||
nonstd::optional<size_t> lvm_values_index;
|
||||
bool lvm_identifier{false};
|
||||
bool lvm_hidden{false};
|
||||
bool lvm_user_hidden{false};
|
||||
@ -258,6 +259,7 @@ struct logline_value_stats {
|
||||
|
||||
void clear()
|
||||
{
|
||||
this->lvs_width = 0;
|
||||
this->lvs_count = 0;
|
||||
this->lvs_total = 0;
|
||||
this->lvs_min_value = std::numeric_limits<double>::max();
|
||||
@ -268,6 +270,7 @@ struct logline_value_stats {
|
||||
|
||||
void add_value(double value);
|
||||
|
||||
int64_t lvs_width;
|
||||
int64_t lvs_count;
|
||||
double lvs_total;
|
||||
double lvs_min_value;
|
||||
|
@ -71,7 +71,6 @@ public:
|
||||
bool vd_foreign_key{false};
|
||||
intern_string_t vd_unit_field;
|
||||
std::map<const intern_string_t, scaling_factor> vd_unit_scaling;
|
||||
ssize_t vd_values_index{-1};
|
||||
bool vd_internal{false};
|
||||
std::vector<std::string> vd_action_list;
|
||||
std::string vd_rewriter;
|
||||
@ -186,18 +185,15 @@ public:
|
||||
const logline_value_stats* stats_for_value(
|
||||
const intern_string_t& name) const
|
||||
{
|
||||
const logline_value_stats* retval = nullptr;
|
||||
|
||||
for (size_t lpc = 0; lpc < this->elf_numeric_value_defs.size(); lpc++) {
|
||||
value_def& vd = *this->elf_numeric_value_defs[lpc];
|
||||
|
||||
if (vd.vd_meta.lvm_name == name) {
|
||||
retval = &this->lf_value_stats[lpc];
|
||||
break;
|
||||
}
|
||||
auto iter = this->elf_value_defs.find(name);
|
||||
if (iter != this->elf_value_defs.end()
|
||||
&& iter->second->vd_meta.lvm_values_index)
|
||||
{
|
||||
return &this->lf_value_stats[iter->second->vd_meta.lvm_values_index
|
||||
.value()];
|
||||
}
|
||||
|
||||
return retval;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void get_subline(const logline& ll,
|
||||
@ -232,6 +228,7 @@ public:
|
||||
|
||||
struct json_format_element {
|
||||
enum class align_t {
|
||||
NONE,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
};
|
||||
@ -253,8 +250,9 @@ public:
|
||||
positioned_property<intern_string_t> jfe_value;
|
||||
std::string jfe_default_value{"-"};
|
||||
long long jfe_min_width{0};
|
||||
bool jfe_auto_width{false};
|
||||
long long jfe_max_width{LLONG_MAX};
|
||||
align_t jfe_align{align_t::LEFT};
|
||||
align_t jfe_align{align_t::NONE};
|
||||
overflow_t jfe_overflow{overflow_t::ABBREV};
|
||||
transform_t jfe_text_transform{transform_t::NONE};
|
||||
std::string jfe_ts_format;
|
||||
@ -286,8 +284,9 @@ public:
|
||||
|
||||
long value_line_count(const intern_string_t ist,
|
||||
bool top_level,
|
||||
nonstd::optional<double> val = nonstd::nullopt,
|
||||
const unsigned char* str = nullptr,
|
||||
ssize_t len = -1) const;
|
||||
ssize_t len = -1);
|
||||
|
||||
bool has_value_def(const intern_string_t ist) const
|
||||
{
|
||||
@ -397,6 +396,7 @@ public:
|
||||
}
|
||||
|
||||
void json_append(const json_format_element& jfe,
|
||||
const value_def* vd,
|
||||
const char* value,
|
||||
ssize_t len);
|
||||
|
||||
|
@ -480,6 +480,11 @@ static const struct json_path_container line_format_handlers = {
|
||||
.with_description("The minimum width of the field")
|
||||
.for_field(&external_log_format::json_format_element::jfe_min_width),
|
||||
|
||||
yajlpp::property_handler("auto-width")
|
||||
.with_description("Automatically detect the necessary width of the "
|
||||
"field based on the observed values")
|
||||
.for_field(&external_log_format::json_format_element::jfe_auto_width),
|
||||
|
||||
yajlpp::property_handler("max-width")
|
||||
.with_min_value(0)
|
||||
.with_synopsis("<size>")
|
||||
|
@ -764,6 +764,9 @@ yajlpp_parse_context::update_callbacks(const json_path_container* orig_handlers,
|
||||
this->ypc_callbacks.yajl_integer
|
||||
= jph.jph_callbacks.yajl_integer;
|
||||
}
|
||||
if (jph.jph_callbacks.yajl_number != nullptr) {
|
||||
this->ypc_callbacks.yajl_number = jph.jph_callbacks.yajl_number;
|
||||
}
|
||||
if (jph.jph_callbacks.yajl_double != nullptr) {
|
||||
this->ypc_callbacks.yajl_double = jph.jph_callbacks.yajl_double;
|
||||
}
|
||||
@ -1125,6 +1128,11 @@ yajlpp_parse_context::set_static_handler(const json_path_handler_base& jph)
|
||||
if (jph.jph_callbacks.yajl_integer != nullptr) {
|
||||
this->ypc_callbacks.yajl_integer = jph.jph_callbacks.yajl_integer;
|
||||
}
|
||||
if (jph.jph_callbacks.yajl_number != nullptr) {
|
||||
this->ypc_callbacks.yajl_number = jph.jph_callbacks.yajl_number;
|
||||
} else {
|
||||
this->ypc_callbacks.yajl_number = nullptr;
|
||||
}
|
||||
if (jph.jph_callbacks.yajl_double != nullptr) {
|
||||
this->ypc_callbacks.yajl_double = jph.jph_callbacks.yajl_double;
|
||||
}
|
||||
|
@ -79,6 +79,17 @@ struct json_path_handler : public json_path_handler_base {
|
||||
this->jph_callbacks.yajl_double = (int (*)(void*, double)) double_func;
|
||||
}
|
||||
|
||||
template<typename P>
|
||||
json_path_handler(P path,
|
||||
int (*number_func)(yajlpp_parse_context*,
|
||||
const char* numberVal,
|
||||
size_t numberLen))
|
||||
: json_path_handler_base(path)
|
||||
{
|
||||
this->jph_callbacks.yajl_number
|
||||
= (int (*)(void*, const char*, size_t)) number_func;
|
||||
}
|
||||
|
||||
template<typename P>
|
||||
json_path_handler(P path) : json_path_handler_base(path)
|
||||
{
|
||||
@ -125,6 +136,15 @@ struct json_path_handler : public json_path_handler_base {
|
||||
return *this;
|
||||
}
|
||||
|
||||
json_path_handler& add_cb(int (*number_func)(yajlpp_parse_context*,
|
||||
const char*,
|
||||
size_t))
|
||||
{
|
||||
this->jph_callbacks.yajl_number
|
||||
= (int (*)(void*, const char*, size_t)) number_func;
|
||||
return *this;
|
||||
}
|
||||
|
||||
json_path_handler& add_cb(int (*str_func)(yajlpp_parse_context*,
|
||||
const unsigned char*,
|
||||
size_t))
|
||||
|
@ -1,3 +1,3 @@
|
||||
2017-03-24T20:06:26.240 1.1.1.1 GET 200 /example/uri/5
|
||||
[31m2017-03-24T20:12:47.764[0m[31m [0m[31m1.1.1.1[0m[31m [0m[31mGET[0m[31m 500 [0m[31m/example/uri/5[0m
|
||||
[33m2017-03-24T20:15:31.694[0m[33m [0m[33m1.1.1.1[0m[33m [0m[33mGET[0m[33m 400 [0m[33m/example/uri/5[0m
|
||||
2017-03-24T20:06:26.240 1.1.1.1 GET 200 443 /example/uri/5
|
||||
[31m2017-03-24T20:12:47.764[0m[31m [0m[31m1.1.1.1[0m[31m [0m[31mGET[0m[31m 500 4433 [0m[31m/example/uri/5[0m
|
||||
[33m2017-03-24T20:15:31.694[0m[33m [0m[33m1.1.1.1[0m[33m [0m[33mGET[0m[33m 400 44345 [0m[33m/example/uri/5[0m
|
||||
|
@ -1,29 +1,29 @@
|
||||
|
||||
[2013-09-06T20:00:48.124] TRACE trace test
|
||||
[2013-09-06T20:00:48.124] TRACE trace test
|
||||
|
||||
[2013-09-06T20:00:49.124] INFO Starting up service
|
||||
[2013-09-06T20:00:49.124] INFO Starting up service
|
||||
|
||||
[2013-09-06T22:00:49.124] INFO Shutting down service
|
||||
[2013-09-06T22:00:49.124] INFO Shutting down service
|
||||
user: steve@example.com
|
||||
|
||||
[2013-09-06T22:00:59.124] DEBUG5 Details...
|
||||
[2013-09-06T22:00:59.124] DEBUG5 Details...
|
||||
|
||||
[2013-09-06T22:00:59.124] DEBUG4 Details...
|
||||
[2013-09-06T22:00:59.124] DEBUG4 Details...
|
||||
|
||||
[2013-09-06T22:00:59.124] DEBUG3 Details...
|
||||
[2013-09-06T22:00:59.124] DEBUG3 Details...
|
||||
|
||||
[2013-09-06T22:00:59.124] DEBUG2 Details...
|
||||
[2013-09-06T22:00:59.124] DEBUG2 Details...
|
||||
|
||||
[2013-09-06T22:00:59.124] DEBUG Details...
|
||||
[2013-09-06T22:00:59.124] DEBUG Details...
|
||||
|
||||
[2013-09-06T22:01:49.124] STATS 1 beat per second
|
||||
[2013-09-06T22:01:49.124] STATS 1 beat per second
|
||||
|
||||
[33m[2013-09-06T22:01:49.124] WARNING not looking good[0m
|
||||
[33m[2013-09-06T22:01:49.124] WARNING not looking good[0m
|
||||
|
||||
[31m[2013-09-06T22:01:49.124] ERROR looking bad[0m
|
||||
[31m[2013-09-06T22:01:49.124] ERROR looking bad[0m
|
||||
|
||||
[31m[2013-09-06T22:01:49.124] CRITICAL sooo bad[0m
|
||||
|
||||
[31m[2013-09-06T22:01:49.124] FATAL shoot[0m
|
||||
[31m[2013-09-06T22:01:49.124] FATAL shoot[0m
|
||||
[31m obj: { "field1" : "hi", "field2": 2 }[0m
|
||||
[31m arr: ["hi", {"sub1": true}][0m
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
[-09-06T22:00:49.124] INFO Shutting down service
|
||||
[-09-06T22:00:49.124] INFO Shutting down service
|
||||
user: steve@example.com
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
log_line,log_part,log_time,log_idle_msecs,log_level,log_mark,log_comment,log_tags,log_filters,client_ip,request/method,request/uri,request/size,response/status,details1,details2,details3
|
||||
0,<NULL>,2017-03-24 20:06:26.240,0,info,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,200,<NULL>,<NULL>,<NULL>
|
||||
1,<NULL>,2017-03-24 20:12:47.764,381524,critical,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,500,<NULL>,<NULL>,<NULL>
|
||||
2,<NULL>,2017-03-24 20:15:31.694,163930,warning,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,400,"{""foo"": ""bar""}","{""foo"": ""bar""}","{""foo"": ""bar""}"
|
||||
log_line,log_part,log_time,log_idle_msecs,log_level,log_mark,log_comment,log_tags,log_filters,client_ip,request/method,request/uri,request/size,response/status,response/size,details1,details2,details3
|
||||
0,<NULL>,2017-03-24 20:06:26.240,0,info,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,200,443,<NULL>,<NULL>,<NULL>
|
||||
1,<NULL>,2017-03-24 20:12:47.764,381524,critical,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,500,4433,<NULL>,<NULL>,<NULL>
|
||||
2,<NULL>,2017-03-24 20:15:31.694,163930,warning,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,400,44345,"{""foo"": ""bar""}","{""foo"": ""bar""}","{""foo"": ""bar""}"
|
||||
|
@ -1,3 +1,3 @@
|
||||
2017-03-24T16:06:26.240 1.1.1.1 GET 200 /example/uri/5
|
||||
[31m2017-03-24T16:12:47.764[0m[31m [0m[31m1.1.1.1[0m[31m [0m[31mGET[0m[31m 500 [0m[31m/example/uri/5[0m
|
||||
[33m2017-03-24T16:15:31.694[0m[33m [0m[33m1.1.1.1[0m[33m [0m[33mGET[0m[33m 400 [0m[33m/example/uri/5[0m
|
||||
2017-03-24T16:06:26.240 1.1.1.1 GET 200 443 /example/uri/5
|
||||
[31m2017-03-24T16:12:47.764[0m[31m [0m[31m1.1.1.1[0m[31m [0m[31mGET[0m[31m 500 4433 [0m[31m/example/uri/5[0m
|
||||
[33m2017-03-24T16:15:31.694[0m[33m [0m[33m1.1.1.1[0m[33m [0m[33mGET[0m[33m 400 44345 [0m[33m/example/uri/5[0m
|
||||
|
@ -1,4 +1,4 @@
|
||||
log_line,log_part,log_time,log_idle_msecs,log_level,log_mark,log_comment,log_tags,log_filters,client_ip,request/method,request/uri,request/size,response/status,details1,details2,details3
|
||||
0,<NULL>,2017-03-24 16:06:26.240,0,info,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,200,<NULL>,<NULL>,<NULL>
|
||||
1,<NULL>,2017-03-24 16:12:47.764,381524,critical,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,500,<NULL>,<NULL>,<NULL>
|
||||
2,<NULL>,2017-03-24 16:15:31.694,163930,warning,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,400,"{""foo"": ""bar""}","{""foo"": ""bar""}","{""foo"": ""bar""}"
|
||||
log_line,log_part,log_time,log_idle_msecs,log_level,log_mark,log_comment,log_tags,log_filters,client_ip,request/method,request/uri,request/size,response/status,response/size,details1,details2,details3
|
||||
0,<NULL>,2017-03-24 16:06:26.240,0,info,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,200,443,<NULL>,<NULL>,<NULL>
|
||||
1,<NULL>,2017-03-24 16:12:47.764,381524,critical,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,500,4433,<NULL>,<NULL>,<NULL>
|
||||
2,<NULL>,2017-03-24 16:15:31.694,163930,warning,0,<NULL>,<NULL>,<NULL>,1.1.1.1,GET,/example/uri/5,166,400,44345,"{""foo"": ""bar""}","{""foo"": ""bar""}","{""foo"": ""bar""}"
|
||||
|
@ -12,7 +12,8 @@
|
||||
},
|
||||
"] ",
|
||||
{
|
||||
"field": "lvl"
|
||||
"field": "lvl",
|
||||
"auto-width": true
|
||||
},
|
||||
" ",
|
||||
{
|
||||
|
@ -24,6 +24,11 @@
|
||||
"field": "response/status"
|
||||
},
|
||||
" ",
|
||||
{
|
||||
"field": "response/size",
|
||||
"auto-width": true
|
||||
},
|
||||
" ",
|
||||
{
|
||||
"field": "request/uri"
|
||||
}
|
||||
@ -51,7 +56,11 @@
|
||||
"hidden": true
|
||||
},
|
||||
"response/status": {
|
||||
"kind": "string"
|
||||
"kind": "integer",
|
||||
"foreign-key": true
|
||||
},
|
||||
"response/size": {
|
||||
"kind": "integer"
|
||||
},
|
||||
"details1": {
|
||||
"hidden": true
|
||||
|
@ -1,3 +1,3 @@
|
||||
{ "started_at": 1490385986240, "response": { "status": 200, "size": "443", "headers": { "server": "nginx\/1.11.10", "content-type": "application\/json", "connection": "close", "cache-control": "max-age=0, must-revalidate, no-cache, no-store, private" } }, "request": { "method": "GET", "uri": "\/example\/uri\/5", "size": "166", "querystring": {}, "headers": { "host": "example.com" } }, "client_ip": "1.1.1.1" }
|
||||
{ "started_at": 1490386367764.0, "response": { "status": 500, "size": "443", "headers": { "server": "nginx\/1.11.10", "content-type": "application\/json", "connection": "close", "cache-control": "max-age=0, must-revalidate, no-cache, no-store, private" } }, "request": { "method": "GET", "uri": "\/example\/uri\/5", "size": "166", "querystring": {}, "headers": { "host": "example.com" } }, "client_ip": "1.1.1.1" }
|
||||
{ "started_at": 1490386531694, "response": { "status": 400, "size": "443", "headers": { "server": "nginx\/1.11.10", "content-type": "application\/json", "connection": "close", "cache-control": "max-age=0, must-revalidate, no-cache, no-store, private" } }, "request": { "method": "GET", "uri": "\/example\/uri\/5", "size": "166", "querystring": {}, "headers": { "host": "example.com" } }, "client_ip": "1.1.1.1", "details1": {"foo": "bar"}, "details2": {"foo": "bar"}, "details3": {"foo": "bar"} }
|
||||
{ "started_at": 1490385986240, "response": { "status": 200, "size": 443, "headers": { "server": "nginx\/1.11.10", "content-type": "application\/json", "connection": "close", "cache-control": "max-age=0, must-revalidate, no-cache, no-store, private" } }, "request": { "method": "GET", "uri": "\/example\/uri\/5", "size": "166", "querystring": {}, "headers": { "host": "example.com" } }, "client_ip": "1.1.1.1" }
|
||||
{ "started_at": 1490386367764.0, "response": { "status": 500, "size": 4433, "headers": { "server": "nginx\/1.11.10", "content-type": "application\/json", "connection": "close", "cache-control": "max-age=0, must-revalidate, no-cache, no-store, private" } }, "request": { "method": "GET", "uri": "\/example\/uri\/5", "size": "166", "querystring": {}, "headers": { "host": "example.com" } }, "client_ip": "1.1.1.1" }
|
||||
{ "started_at": 1490386531694, "response": { "status": 400, "size": 44345, "headers": { "server": "nginx\/1.11.10", "content-type": "application\/json", "connection": "close", "cache-control": "max-age=0, must-revalidate, no-cache, no-store, private" } }, "request": { "method": "GET", "uri": "\/example\/uri\/5", "size": "166", "querystring": {}, "headers": { "host": "example.com" } }, "client_ip": "1.1.1.1", "details1": {"foo": "bar"}, "details2": {"foo": "bar"}, "details3": {"foo": "bar"} }
|
||||
|
Loading…
Reference in New Issue
Block a user