mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Add interval_as_double argument to control how intervals are converted to JSON
This commit is contained in:
parent
8ff10e4d21
commit
43e3de5c79
5 changed files with 54 additions and 14 deletions
31
src/Val.cc
31
src/Val.cc
|
@ -351,7 +351,7 @@ static bool UsesJSONStringType(const TypePtr& t) {
|
|||
// This is a static method in this file to avoid including rapidjson's headers
|
||||
// in Val.h, because they're huge.
|
||||
static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool only_loggable = false,
|
||||
RE_Matcher* re = nullptr, const string& key = "") {
|
||||
RE_Matcher* re = nullptr, const string& key = "", bool interval_as_double = false) {
|
||||
if ( ! key.empty() )
|
||||
writer.Key(key);
|
||||
|
||||
|
@ -387,7 +387,6 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
}
|
||||
|
||||
case TYPE_PATTERN:
|
||||
case TYPE_INTERVAL:
|
||||
case TYPE_ADDR:
|
||||
case TYPE_SUBNET: {
|
||||
ODesc d;
|
||||
|
@ -397,6 +396,18 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
break;
|
||||
}
|
||||
|
||||
case TYPE_INTERVAL: {
|
||||
if ( interval_as_double )
|
||||
writer.Double(val->AsInterval());
|
||||
else {
|
||||
ODesc d;
|
||||
d.SetStyle(RAW_STYLE);
|
||||
val->Describe(&d);
|
||||
writer.String(reinterpret_cast<const char*>(d.Bytes()), d.Len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_FILE:
|
||||
case TYPE_FUNC:
|
||||
case TYPE_ENUM:
|
||||
|
@ -433,11 +444,11 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
Val* entry_key = lv->Length() == 1 ? lv->Idx(0).get() : lv.get();
|
||||
|
||||
if ( tval->GetType()->IsSet() )
|
||||
BuildJSON(writer, entry_key, only_loggable, re);
|
||||
BuildJSON(writer, entry_key, only_loggable, re, "", interval_as_double);
|
||||
else {
|
||||
rapidjson::StringBuffer buffer;
|
||||
json::detail::NullDoubleWriter key_writer(buffer);
|
||||
BuildJSON(key_writer, entry_key, only_loggable, re);
|
||||
BuildJSON(key_writer, entry_key, only_loggable, re, "", interval_as_double);
|
||||
string key_str = buffer.GetString();
|
||||
|
||||
// Strip the quotes for any type we render as a string. This
|
||||
|
@ -446,7 +457,7 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
if ( UsesJSONStringType(entry_key->GetType()) )
|
||||
key_str = key_str.substr(1, key_str.length() - 2);
|
||||
|
||||
BuildJSON(writer, entry->GetVal().get(), only_loggable, re, key_str);
|
||||
BuildJSON(writer, entry->GetVal().get(), only_loggable, re, key_str, interval_as_double);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,7 +492,7 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
else
|
||||
key_str = field_name;
|
||||
|
||||
BuildJSON(writer, value.get(), only_loggable, re, key_str);
|
||||
BuildJSON(writer, value.get(), only_loggable, re, key_str, interval_as_double);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -495,7 +506,7 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
auto* lval = val->AsListVal();
|
||||
size_t size = lval->Length();
|
||||
for ( size_t i = 0; i < size; i++ )
|
||||
BuildJSON(writer, lval->Idx(i).get(), only_loggable, re);
|
||||
BuildJSON(writer, lval->Idx(i).get(), only_loggable, re, "", interval_as_double);
|
||||
|
||||
writer.EndArray();
|
||||
break;
|
||||
|
@ -507,7 +518,7 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
auto* vval = val->AsVectorVal();
|
||||
size_t size = vval->SizeVal()->AsCount();
|
||||
for ( size_t i = 0; i < size; i++ )
|
||||
BuildJSON(writer, vval->ValAt(i).get(), only_loggable, re);
|
||||
BuildJSON(writer, vval->ValAt(i).get(), only_loggable, re, "", interval_as_double);
|
||||
|
||||
writer.EndArray();
|
||||
break;
|
||||
|
@ -528,11 +539,11 @@ static void BuildJSON(json::detail::NullDoubleWriter& writer, Val* val, bool onl
|
|||
}
|
||||
}
|
||||
|
||||
StringValPtr Val::ToJSON(bool only_loggable, RE_Matcher* re) {
|
||||
StringValPtr Val::ToJSON(bool only_loggable, RE_Matcher* re, bool interval_as_double) {
|
||||
rapidjson::StringBuffer buffer;
|
||||
json::detail::NullDoubleWriter writer(buffer);
|
||||
|
||||
BuildJSON(writer, this, only_loggable, re, "");
|
||||
BuildJSON(writer, this, only_loggable, re, "", interval_as_double);
|
||||
|
||||
return make_intrusive<StringVal>(buffer.GetString());
|
||||
}
|
||||
|
|
|
@ -248,9 +248,12 @@ public:
|
|||
* first match on any record field name in the resulting output. See the
|
||||
* to_json() BiF for context.
|
||||
*
|
||||
* @param interval_as_double If true, interval values will be written as
|
||||
* doubles instead of the broken-out version with units.
|
||||
*
|
||||
* @return JSON data representing the Val.
|
||||
*/
|
||||
StringValPtr ToJSON(bool only_loggable = false, RE_Matcher* re = nullptr);
|
||||
StringValPtr ToJSON(bool only_loggable = false, RE_Matcher* re = nullptr, bool interval_as_double = false);
|
||||
|
||||
template<typename T>
|
||||
T As() {
|
||||
|
|
|
@ -5103,14 +5103,18 @@ function anonymize_addr%(a: addr, cl: IPAddrAnonymizationClass%): addr
|
|||
## rendered name. The default pattern strips a leading
|
||||
## underscore.
|
||||
##
|
||||
## interval_as_double: If T, interval values will be logged as doubles
|
||||
## instead of the broken-out version with units as strings.
|
||||
##
|
||||
## returns: a JSON formatted string.
|
||||
##
|
||||
## .. zeek:see:: fmt cat cat_sep string_cat print_raw from_json
|
||||
function to_json%(val: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/%): string
|
||||
function to_json%(val: any, only_loggable: bool &default=F, field_escape_pattern: pattern &default=/^_/, interval_as_double: bool &default=F%): string
|
||||
%{
|
||||
return val->ToJSON(only_loggable, field_escape_pattern);
|
||||
return val->ToJSON(only_loggable, field_escape_pattern, interval_as_double);
|
||||
%}
|
||||
|
||||
|
||||
## A function to convert a JSON string into Zeek values of a given type.
|
||||
##
|
||||
## Implicit conversion from JSON to Zeek types is implemented for:
|
||||
|
|
|
@ -19,3 +19,7 @@ s, T
|
|||
re, T
|
||||
su, T
|
||||
se, T
|
||||
|
||||
Valid conversion of IntervalOnly: 1
|
||||
|
||||
it, T
|
||||
|
|
|
@ -30,6 +30,10 @@ type Foo: record {
|
|||
tbl: table[addr, port] of string;
|
||||
};
|
||||
|
||||
type IntervalOnly: record {
|
||||
it: interval;
|
||||
};
|
||||
|
||||
event zeek_init()
|
||||
{
|
||||
|
||||
|
@ -55,7 +59,7 @@ event zeek_init()
|
|||
local f_json = to_json(f);
|
||||
|
||||
local f2 = from_json(f_json, Foo);
|
||||
print fmt("Valid conversion of Foo: %d", f2$valid);
|
||||
print fmt("Valid conversion of Foo: %d", f2$valid);
|
||||
print "";
|
||||
|
||||
local f2_v : Foo = f2$v;
|
||||
|
@ -81,4 +85,18 @@ event zeek_init()
|
|||
|
||||
# TODO: direct comparisons of tables isn't allowed. This will have to wait.
|
||||
# print f$tbl == f2_v$tbl;
|
||||
|
||||
local io: IntervalOnly;
|
||||
io$it = double_to_interval(2*24*3600 + 2*3600 + 2*60 + 2*1.0 + 2*0.1 + 2*0.0001);
|
||||
|
||||
# Test round-trip conversion of intervals as doubles.
|
||||
local io_json = to_json(io, F, /^_/, T);
|
||||
local io2 = from_json(io_json, IntervalOnly);
|
||||
|
||||
print "";
|
||||
print fmt("Valid conversion of IntervalOnly: %d", f2$valid);
|
||||
print "";
|
||||
|
||||
local io2_v : IntervalOnly = io2$v;
|
||||
print "it", io$it == io2_v$it;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue