Make json_event_formatter a gen_event_formatter

Make json_event_formatter a generic event formatter by inheriting from
gen_event_formatter and implementing its methods.

Most of the actual work is still done by resolve_format (previously
resolve_tokens, to avoid confusion with sinsp formatter, as it behaves
slightly differently).

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
Mark Stemm
2021-08-25 17:02:53 -07:00
committed by poiana
parent 943a37fcf7
commit de4b2fa831
2 changed files with 129 additions and 32 deletions

View File

@@ -1511,31 +1511,53 @@ std::list<gen_event_filter_factory::filter_fieldclass_info> json_event_filter_fa
return ret; return ret;
} }
json_event_formatter::json_event_formatter(json_event_filter_factory &json_factory, std::string &format): json_event_formatter::json_event_formatter(std::shared_ptr<gen_event_filter_factory> json_factory)
m_format(format), : m_output_format(OF_NORMAL), m_json_factory(json_factory)
m_json_factory(json_factory)
{ {
parse_format();
} }
json_event_formatter::~json_event_formatter() json_event_formatter::~json_event_formatter()
{ {
} }
std::string json_event_formatter::tostring(json_event *ev) void json_event_formatter::set_format(output_format of, const std::string &format)
{ {
m_output_format = of;
m_format = format;
parse_format();
}
bool json_event_formatter::tostring_withformat(gen_event *gevt, std::string &output, gen_event_formatter::output_format of)
{
json_event *ev = static_cast<json_event *>(gevt);
std::string ret; std::string ret;
std::list<std::pair<std::string, std::string>> resolved; if(of == OF_JSON)
resolve_tokens(ev, resolved);
for(auto &res : resolved)
{ {
ret += res.second; ret = tojson(ev);
return true;
} }
else
{
std::list<std::pair<std::string, std::string>> resolved;
return ret; resolve_format(ev, resolved);
output = "";
for(auto &res : resolved)
{
output += res.second;
}
return true;
}
}
bool json_event_formatter::tostring(gen_event *gevt, std::string &output)
{
return tostring_withformat(gevt, output, m_output_format);
} }
std::string json_event_formatter::tojson(json_event *ev) std::string json_event_formatter::tojson(json_event *ev)
@@ -1545,7 +1567,7 @@ std::string json_event_formatter::tojson(json_event *ev)
std::list<std::pair<std::string, std::string>> resolved; std::list<std::pair<std::string, std::string>> resolved;
resolve_tokens(ev, resolved); resolve_format(ev, resolved);
for(auto &res : resolved) for(auto &res : resolved)
{ {
@@ -1560,12 +1582,13 @@ std::string json_event_formatter::tojson(json_event *ev)
return ret.dump(); return ret.dump();
} }
std::map<std::string, std::string> json_event_formatter::tomap(json_event *ev) bool json_event_formatter::get_field_values(gen_event *gevt, std::map<std::string, std::string> &fields)
{ {
std::map<std::string, std::string> ret; json_event *ev = static_cast<json_event *>(gevt);
std::list<std::pair<std::string, std::string>> res; std::list<std::pair<std::string, std::string>> res;
resolve_tokens(ev, res); resolve_format(ev, res);
for(auto &r : res) for(auto &r : res)
{ {
@@ -1576,11 +1599,11 @@ std::map<std::string, std::string> json_event_formatter::tomap(json_event *ev)
{ {
r.second = "<NA>"; r.second = "<NA>";
} }
ret.insert(r); fields.insert(r);
} }
} }
return ret; return true;
} }
void json_event_formatter::parse_format() void json_event_formatter::parse_format()
@@ -1602,7 +1625,7 @@ void json_event_formatter::parse_format()
{ {
// Skip the % // Skip the %
tformat.erase(0, 1); tformat.erase(0, 1);
json_event_filter_check *chk = (json_event_filter_check *)m_json_factory.new_filtercheck(tformat.c_str()); json_event_filter_check *chk = (json_event_filter_check *)m_json_factory->new_filtercheck(tformat.c_str());
if(!chk) if(!chk)
{ {
@@ -1638,7 +1661,7 @@ void json_event_formatter::parse_format()
} }
} }
void json_event_formatter::resolve_tokens(json_event *ev, std::list<std::pair<std::string, std::string>> &resolved) void json_event_formatter::resolve_format(json_event *ev, std::list<std::pair<std::string, std::string>> &resolved)
{ {
for(auto tok : m_tokens) for(auto tok : m_tokens)
{ {
@@ -1678,3 +1701,43 @@ void json_event_formatter::resolve_tokens(json_event *ev, std::list<std::pair<st
} }
} }
} }
gen_event_formatter::output_format json_event_formatter::get_output_format()
{
return m_output_format;
}
json_event_formatter_factory::json_event_formatter_factory(std::shared_ptr<gen_event_filter_factory> json_factory)
: m_output_format(gen_event_formatter::OF_NORMAL), m_json_factory(json_factory)
{
}
json_event_formatter_factory::~json_event_formatter_factory()
{
}
void json_event_formatter_factory::set_output_format(gen_event_formatter::output_format of)
{
m_formatters.clear();
m_output_format = of;
}
std::shared_ptr<gen_event_formatter> json_event_formatter_factory::create_formatter(const std::string &format)
{
auto it = m_formatters.find(format);
if (it != m_formatters.end())
{
return it->second;
}
std::shared_ptr<gen_event_formatter> ret;
ret.reset(new json_event_formatter(m_json_factory));
ret->set_format(m_output_format, format);
m_formatters[format] = ret;
return ret;
}

View File

@@ -406,22 +406,34 @@ private:
std::list<json_event_filter_check::check_info> m_info; std::list<json_event_filter_check::check_info> m_info;
}; };
// Unlike the other classes, this does not inherit from a shared class class json_event_formatter : public gen_event_formatter
// that's used both by json events and sinsp events. It might be
// worthwhile, but it would require a lot of additional work to pull
// up functionality into the generic filtercheck class.
class json_event_formatter
{ {
public: public:
json_event_formatter(json_event_filter_factory &factory, std::string &format); json_event_formatter(std::shared_ptr<gen_event_filter_factory> factory);
virtual ~json_event_formatter(); virtual ~json_event_formatter();
std::string tostring(json_event *ev); void set_format(output_format of, const std::string &format) override;
std::string tojson(json_event *ev); bool tostring(gen_event *evt, std::string &output) override;
std::map<std::string, std::string> tomap(json_event *ev); bool tostring_withformat(gen_event *evt, std::string &output, gen_event_formatter::output_format of) override;
bool get_field_values(gen_event *evt, std::map<std::string, std::string> &fields) override;
output_format get_output_format() override;
void resolve_tokens(json_event *ev, std::list<std::pair<std::string, std::string>> &resolved); std::string tojson(json_event *ev);
// Split the format string into a list of tuples, broken at
// output fields, where each tuple is either a block of text
// from the original format string, or a field value/pair from
// the original format string.
//
// For example, given a format string "some output
// (%proc.name)", this will fill in resolved with 3 tuples:
// - ["", "some output ("]
// - ["proc.name", "nginx"]
// - ["", ")"]
//
// This can be used either to return a resolved output string
// or a map of field name/value pairs.
void resolve_format(json_event *ev, std::list<std::pair<std::string, std::string>> &resolved);
private: private:
void parse_format(); void parse_format();
@@ -441,6 +453,8 @@ private:
std::shared_ptr<json_event_filter_check> check; std::shared_ptr<json_event_filter_check> check;
}; };
gen_event_formatter::output_format m_output_format;
// The original format string // The original format string
std::string m_format; std::string m_format;
@@ -449,5 +463,25 @@ private:
std::list<fmt_token> m_tokens; std::list<fmt_token> m_tokens;
// All the filterchecks required to resolve tokens in the format string // All the filterchecks required to resolve tokens in the format string
json_event_filter_factory &m_json_factory; std::shared_ptr<gen_event_filter_factory> m_json_factory;
};
class json_event_formatter_factory : public gen_event_formatter_factory
{
public:
json_event_formatter_factory(std::shared_ptr<gen_event_filter_factory> factory);
virtual ~json_event_formatter_factory();
void set_output_format(gen_event_formatter::output_format of) override;
std::shared_ptr<gen_event_formatter> create_formatter(const std::string &format) override;
protected:
// Maps from output string to formatter
std::map<std::string, std::shared_ptr<gen_event_formatter>> m_formatters;
gen_event_formatter::output_format m_output_format;
// All the filterchecks required to resolve tokens in the format string
std::shared_ptr<gen_event_filter_factory> m_json_factory;
}; };