Plugin: Add hooks for log init and writing.

The two hooks being added are:

void HookLogInit(const std::string& writer, const std::string& instantiating_filter, bool local, bool remote, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields);

which is called when a writer is being instantiated and contains
information about the fields being logged, as well as

bool HookLogWrite(const std::string& writer, const std::string& filter, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields, threading::Value** vals);

which is called for each log line being written by each writer. It
contains all the data being written. The data can be changed in the
function call and lines can be prevented from being written.

This commit also fixes a few small problems with plugin hooks itself,
and extends the tests that were already there, besides introducing tests
for the added functionality.
This commit is contained in:
Johanna Amann 2017-02-27 10:01:14 -08:00
parent 2c2c9c9052
commit 684ea8aa37
16 changed files with 689 additions and 39 deletions

View file

@ -3,6 +3,8 @@
#include <Func.h>
#include <Event.h>
#include <Conn.h>
#include <threading/Formatter.h>
namespace plugin { namespace Demo_Hooks { Plugin plugin; } }
@ -18,6 +20,9 @@ plugin::Configuration Plugin::Configure()
EnableHook(META_HOOK_PRE);
EnableHook(META_HOOK_POST);
EnableHook(HOOK_BRO_OBJ_DTOR);
EnableHook(HOOK_SETUP_ANALYZER_TREE);
EnableHook(HOOK_LOG_INIT);
EnableHook(HOOK_LOG_WRITE);
plugin::Configuration config;
config.name = "Demo::Hooks";
@ -121,3 +126,134 @@ void Plugin::MetaHookPost(HookType hook, const HookArgumentList& args, HookArgum
hook_name(hook), d1.Description(),
d2.Description());
}
void Plugin::HookSetupAnalyzerTree(Connection *conn)
{
ODesc d;
d.SetShort();
conn->Describe(&d);
fprintf(stderr, "%.6f %-15s %s\n", network_time, "| HookSetupAnalyzerTree", d.Description());
}
void Plugin::HookLogInit(const std::string& writer, const std::string& instantiating_filter, bool local, bool remote, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields)
{
ODesc d;
d.Add("{");
for ( int i=0; i < num_fields; i++ )
{
const threading::Field* f = fields[i];
if ( i > 0 )
d.Add(", ");
d.Add(f->name);
d.Add(" (");
d.Add(f->TypeName());
d.Add(")");
}
d.Add("}");
fprintf(stderr, "%.6f %-15s %s %d/%d %s\n", network_time, "| HookLogInit", info.path, local, remote, d.Description());
}
void Plugin::RenderVal(const threading::Value* val, ODesc &d) const
{
if ( ! val->present )
{
d.Add("<uninitialized>");
return;
}
switch ( val->type ) {
case TYPE_BOOL:
d.Add(val->val.int_val ? "T" : "F");
break;
case TYPE_INT:
d.Add(val->val.int_val);
break;
case TYPE_COUNT:
case TYPE_COUNTER:
d.Add(val->val.uint_val);
break;
case TYPE_PORT:
d.Add(val->val.port_val.port);
break;
case TYPE_SUBNET:
d.Add(threading::formatter::Formatter::Render(val->val.subnet_val));
break;
case TYPE_ADDR:
d.Add(threading::formatter::Formatter::Render(val->val.addr_val));
break;
case TYPE_DOUBLE:
d.Add(val->val.double_val, true);
break;
case TYPE_INTERVAL:
case TYPE_TIME:
d.Add(threading::formatter::Formatter::Render(val->val.double_val));
break;
case TYPE_ENUM:
case TYPE_STRING:
case TYPE_FILE:
case TYPE_FUNC:
d.AddN(val->val.string_val.data, val->val.string_val.length);
break;
case TYPE_TABLE:
for ( int j = 0; j < val->val.set_val.size; j++ )
{
if ( j > 0 )
d.Add(",");
RenderVal(val->val.set_val.vals[j], d);
}
break;
case TYPE_VECTOR:
for ( int j = 0; j < val->val.vector_val.size; j++ )
{
if ( j > 0 )
d.Add(",");
RenderVal(val->val.vector_val.vals[j], d);
}
break;
default:
assert(false);
}
}
bool Plugin::HookLogWrite(const std::string& writer, const std::string& filter, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields, threading::Value** vals)
{
ODesc d;
d.Add("[");
for ( int i=0; i < num_fields; i++ )
{
const threading::Field* f = fields[i];
const threading::Value* val = vals[i];
if ( i > 0 )
d.Add(", ");
d.Add(f->name);
d.Add("=");
RenderVal(val, d);
}
d.Add("]");
fprintf(stderr, "%.6f %-15s %s %s\n", network_time, "| HookLogWrite", info.path, d.Description());
return true;
}

View file

@ -10,17 +10,22 @@ namespace Demo_Hooks {
class Plugin : public ::plugin::Plugin
{
protected:
virtual int HookLoadFile(const std::string& file, const std::string& ext);
virtual std::pair<bool, Val*> HookCallFunction(const Func* func, Frame* frame, val_list* args);
virtual bool HookQueueEvent(Event* event);
virtual void HookDrainEvents();
virtual void HookUpdateNetworkTime(double network_time);
virtual void HookBroObjDtor(void* obj);
virtual void MetaHookPre(HookType hook, const HookArgumentList& args);
virtual void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result);
int HookLoadFile(const std::string& file, const std::string& ext) override;
std::pair<bool, Val*> HookCallFunction(const Func* func, Frame* frame, val_list* args) override;
bool HookQueueEvent(Event* event) override;
void HookDrainEvents() override;
void HookUpdateNetworkTime(double network_time) override;
void HookBroObjDtor(void* obj) override;
void HookLogInit(const std::string& writer, const std::string& instantiating_filter, bool local, bool remote, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields) override;
bool HookLogWrite(const std::string& writer, const std::string& filter, const logging::WriterBackend::WriterInfo& info, int num_fields, const threading::Field* const* fields, threading::Value** vals) override;
void HookSetupAnalyzerTree(Connection *conn) override;
void MetaHookPre(HookType hook, const HookArgumentList& args) override;
void MetaHookPost(HookType hook, const HookArgumentList& args, HookArgument result) override;
void RenderVal(const threading::Value* val, ODesc &d) const;
// Overridden from plugin::Plugin.
virtual plugin::Configuration Configure();
plugin::Configuration Configure() override;
};
extern Plugin plugin;