mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00
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:
parent
2c2c9c9052
commit
684ea8aa37
16 changed files with 689 additions and 39 deletions
|
@ -712,7 +712,7 @@ void Manager::HookSetupAnalyzerTree(Connection *conn) const
|
|||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(conn);
|
||||
args.push_back(HookArgument(conn));
|
||||
MetaHookPre(HOOK_SETUP_ANALYZER_TREE, args);
|
||||
}
|
||||
|
||||
|
@ -739,7 +739,7 @@ void Manager::HookUpdateNetworkTime(double network_time) const
|
|||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(network_time);
|
||||
args.push_back(HookArgument(network_time));
|
||||
MetaHookPre(HOOK_UPDATE_NETWORK_TIME, args);
|
||||
}
|
||||
|
||||
|
@ -762,7 +762,7 @@ void Manager::HookBroObjDtor(void* obj) const
|
|||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(obj);
|
||||
args.push_back(HookArgument(obj));
|
||||
MetaHookPre(HOOK_BRO_OBJ_DTOR, args);
|
||||
}
|
||||
|
||||
|
@ -779,6 +779,72 @@ void Manager::HookBroObjDtor(void* obj) const
|
|||
MetaHookPost(HOOK_BRO_OBJ_DTOR, args, HookArgument());
|
||||
}
|
||||
|
||||
void Manager::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) const
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(HookArgument(writer));
|
||||
args.push_back(HookArgument(instantiating_filter));
|
||||
args.push_back(HookArgument(local));
|
||||
args.push_back(HookArgument(remote));
|
||||
args.push_back(HookArgument(&info));
|
||||
args.push_back(HookArgument(num_fields));
|
||||
args.push_back(HookArgument(std::make_pair(num_fields, fields)));
|
||||
MetaHookPre(HOOK_LOG_INIT, args);
|
||||
}
|
||||
|
||||
hook_list* l = hooks[HOOK_LOG_INIT];
|
||||
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
p->HookLogInit(writer, instantiating_filter, local, remote, info, num_fields, fields);
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_LOG_INIT, args, HookArgument());
|
||||
}
|
||||
|
||||
bool Manager::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) const
|
||||
{
|
||||
HookArgumentList args;
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_PRE) )
|
||||
{
|
||||
args.push_back(HookArgument(writer));
|
||||
args.push_back(HookArgument(filter));
|
||||
args.push_back(HookArgument(&info));
|
||||
args.push_back(HookArgument(num_fields));
|
||||
args.push_back(HookArgument(std::make_pair(num_fields, fields)));
|
||||
args.push_back(HookArgument(vals));
|
||||
MetaHookPre(HOOK_LOG_WRITE, args);
|
||||
}
|
||||
|
||||
hook_list* l = hooks[HOOK_LOG_WRITE];
|
||||
|
||||
bool result = true;
|
||||
|
||||
if ( l )
|
||||
for ( hook_list::iterator i = l->begin(); i != l->end(); ++i )
|
||||
{
|
||||
Plugin* p = (*i).second;
|
||||
|
||||
if ( ! p->HookLogWrite(writer, filter, info, num_fields, fields, vals) )
|
||||
{
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( HavePluginForHook(META_HOOK_POST) )
|
||||
MetaHookPost(HOOK_LOG_WRITE, args, HookArgument(result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Manager::MetaHookPre(HookType hook, const HookArgumentList& args) const
|
||||
{
|
||||
hook_list* l = hooks[HOOK_CALL_FUNCTION];
|
||||
|
|
|
@ -291,6 +291,61 @@ public:
|
|||
*/
|
||||
void HookBroObjDtor(void* obj) const;
|
||||
|
||||
/**
|
||||
* Hook into log initialization. This method will be called when a
|
||||
* logging writer is created. A writer represents a single logging
|
||||
* filter. The method is called in the main thread, on the node that
|
||||
* causes a log line to be written. It will _not_ be called on the logger
|
||||
* node. The function will be called each for every instantiated writer.
|
||||
*
|
||||
* @param writer The name of the writer being insantiated.
|
||||
*
|
||||
* @param instantiating_filter Name of the filter causing the
|
||||
* writer instantiation.
|
||||
*
|
||||
* @param local True if the filter is logging locally (writer
|
||||
* thread will be located in same process).
|
||||
*
|
||||
* @param remote True if filter is logging remotely (writer thread
|
||||
* will be located in different thread, typically
|
||||
* in manager or logger node).
|
||||
*
|
||||
* @param info WriterBackend::WriterInfo with information about the writer.
|
||||
*
|
||||
* @param num_fields number of fields in the record being written.
|
||||
*
|
||||
* @param fields threading::Field description of the fields being logged.
|
||||
*/
|
||||
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) const;
|
||||
|
||||
/**
|
||||
* Hook into log writing. This method will be called for each log line
|
||||
* being written by each writer. Each writer represents a single logging
|
||||
* filter. The method is called in the main thread, on the node that
|
||||
* causes a log line to be written. It will _not_ be called on the logger
|
||||
* node. The function will be called each for every instantiated writer.
|
||||
* This function allows plugins to modify or skip logging of information.
|
||||
* Note - once a log line is skipped (by returning false), it will not passed
|
||||
* on to hooks that have not yet been called.
|
||||
*
|
||||
* @param writer The name of the writer.
|
||||
*
|
||||
* @param filter Name of the filter being written to.
|
||||
*
|
||||
* @param info WriterBackend::WriterInfo with information about the writer.
|
||||
*
|
||||
* @param num_fields number of fields in the record being written.
|
||||
*
|
||||
* @param fields threading::Field description of the fields being logged.
|
||||
*
|
||||
* @param vals threading::Values containing the values being written. Values
|
||||
* can be modified in the Hook.
|
||||
*
|
||||
* @return true if log line should be written, false if log line should be
|
||||
* skipped and not passed on to the writer.
|
||||
*/
|
||||
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) const;
|
||||
|
||||
/**
|
||||
* Internal method that registers a freshly instantiated plugin with
|
||||
* the manager.
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
|
||||
#include "../Desc.h"
|
||||
#include "../Event.h"
|
||||
#include "../Conn.h"
|
||||
#include "threading/SerialTypes.h"
|
||||
|
||||
using namespace plugin;
|
||||
|
||||
|
@ -24,6 +26,8 @@ const char* plugin::hook_name(HookType h)
|
|||
"UpdateNetworkTime",
|
||||
"BroObjDtor",
|
||||
"SetupAnalyzerTree",
|
||||
"LogInit",
|
||||
"LogWrite",
|
||||
// MetaHooks
|
||||
"MetaHookPre",
|
||||
"MetaHookPost",
|
||||
|
@ -84,6 +88,11 @@ void HookArgument::Describe(ODesc* d) const
|
|||
d->Add("<null>");
|
||||
break;
|
||||
|
||||
case CONN:
|
||||
if ( arg.conn )
|
||||
arg.conn->Describe(d);
|
||||
break;
|
||||
|
||||
case FUNC_RESULT:
|
||||
if ( func_result.first )
|
||||
{
|
||||
|
@ -145,6 +154,50 @@ void HookArgument::Describe(ODesc* d) const
|
|||
case VOIDP:
|
||||
d->Add("<void ptr>");
|
||||
break;
|
||||
|
||||
case WRITER_INFO:
|
||||
d->Add(arg.winfo->path);
|
||||
d->Add("(");
|
||||
d->Add(arg.winfo->network_time);
|
||||
d->Add(",");
|
||||
d->Add(arg.winfo->rotation_interval);
|
||||
d->Add(",");
|
||||
d->Add(arg.winfo->rotation_base);
|
||||
if ( arg.winfo->config.size() > 0 )
|
||||
{
|
||||
bool first = true;
|
||||
d->Add("config: {");
|
||||
for ( auto& v: arg.winfo->config )
|
||||
{
|
||||
if ( ! first )
|
||||
d->Add(", ");
|
||||
|
||||
d->Add(v.first);
|
||||
d->Add(": ");
|
||||
d->Add(v.second);
|
||||
first = false;
|
||||
}
|
||||
d->Add("}");
|
||||
}
|
||||
d->Add(")");
|
||||
break;
|
||||
|
||||
case THREAD_FIELDS:
|
||||
d->Add("{");
|
||||
for ( int i=0; i < tfields.first; i++ )
|
||||
{
|
||||
const threading::Field* f = tfields.second[i];
|
||||
|
||||
if ( i > 0 )
|
||||
d->Add(", ");
|
||||
|
||||
d->Add(f->name);
|
||||
d->Add(" (");
|
||||
d->Add(f->TypeName());
|
||||
d->Add(")");
|
||||
}
|
||||
d->Add("}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,6 +372,15 @@ void Plugin::HookBroObjDtor(void* obj)
|
|||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Plugin::MetaHookPre(HookType hook, const HookArgumentList& args)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -11,16 +11,21 @@
|
|||
#include "analyzer/Component.h"
|
||||
#include "file_analysis/Component.h"
|
||||
#include "iosource/Component.h"
|
||||
#include "logging/WriterBackend.h"
|
||||
|
||||
// We allow to override this externally for testing purposes.
|
||||
#ifndef BRO_PLUGIN_API_VERSION
|
||||
#define BRO_PLUGIN_API_VERSION 4
|
||||
#define BRO_PLUGIN_API_VERSION 5
|
||||
#endif
|
||||
|
||||
class ODesc;
|
||||
class Func;
|
||||
class Event;
|
||||
|
||||
namespace threading {
|
||||
struct Field;
|
||||
}
|
||||
|
||||
namespace plugin {
|
||||
|
||||
class Manager;
|
||||
|
@ -39,7 +44,9 @@ enum HookType {
|
|||
HOOK_DRAIN_EVENTS, //< Activates Plugin::HookDrainEvents()
|
||||
HOOK_UPDATE_NETWORK_TIME, //< Activates Plugin::HookUpdateNetworkTime.
|
||||
HOOK_BRO_OBJ_DTOR, //< Activates Plugin::HookBroObjDtor.
|
||||
HOOK_SETUP_ANALYZER_TREE, //< Activates Plugin::HookSetupAnalyzerTree
|
||||
HOOK_SETUP_ANALYZER_TREE, //< Activates Plugin::HookAddToAnalyzerTree
|
||||
HOOK_LOG_INIT, //< Activates Plugin::HookLogInit
|
||||
HOOK_LOG_WRITE, //< Activates Plugin::HookLogWrite
|
||||
|
||||
// Meta hooks.
|
||||
META_HOOK_PRE, //< Activates Plugin::MetaHookPre().
|
||||
|
@ -158,7 +165,8 @@ public:
|
|||
* Type of the argument.
|
||||
*/
|
||||
enum Type {
|
||||
BOOL, DOUBLE, EVENT, FRAME, FUNC, FUNC_RESULT, INT, STRING, VAL, VAL_LIST, VOID, VOIDP
|
||||
BOOL, DOUBLE, EVENT, FRAME, FUNC, FUNC_RESULT, INT, STRING, VAL, VAL_LIST, VOID, VOIDP,
|
||||
WRITER_INFO, CONN, THREAD_FIELDS
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -169,57 +177,72 @@ public:
|
|||
/**
|
||||
* Constructor with a boolean argument.
|
||||
*/
|
||||
HookArgument(bool a) { type = BOOL; arg.bool_ = a; }
|
||||
explicit HookArgument(bool a) { type = BOOL; arg.bool_ = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a double argument.
|
||||
*/
|
||||
HookArgument(double a) { type = DOUBLE; arg.double_ = a; }
|
||||
explicit HookArgument(double a) { type = DOUBLE; arg.double_ = a; }
|
||||
|
||||
/**
|
||||
* Constructor with an event argument.
|
||||
*/
|
||||
HookArgument(const Event* a) { type = EVENT; arg.event = a; }
|
||||
explicit HookArgument(const Event* a) { type = EVENT; arg.event = a; }
|
||||
|
||||
/**
|
||||
* Constructor with an connection argument.
|
||||
*/
|
||||
explicit HookArgument(const Connection* c) { type = CONN; arg.conn = c; }
|
||||
|
||||
/**
|
||||
* Constructor with a function argument.
|
||||
*/
|
||||
HookArgument(const Func* a) { type = FUNC; arg.func = a; }
|
||||
explicit HookArgument(const Func* a) { type = FUNC; arg.func = a; }
|
||||
|
||||
/**
|
||||
* Constructor with an integer argument.
|
||||
*/
|
||||
HookArgument(int a) { type = INT; arg.int_ = a; }
|
||||
explicit HookArgument(int a) { type = INT; arg.int_ = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a string argument.
|
||||
*/
|
||||
HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
||||
explicit HookArgument(const std::string& a) { type = STRING; arg_string = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a Bro value argument.
|
||||
*/
|
||||
HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
||||
explicit HookArgument(const Val* a) { type = VAL; arg.val = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a list of Bro values argument.
|
||||
*/
|
||||
HookArgument(const val_list* a) { type = VAL_LIST; arg.vals = a; }
|
||||
explicit HookArgument(const val_list* a) { type = VAL_LIST; arg.vals = a; }
|
||||
|
||||
/**
|
||||
* Constructor with a void pointer argument.
|
||||
*/
|
||||
HookArgument(void* p) { type = VOIDP; arg.voidp = p; }
|
||||
explicit HookArgument(void* p) { type = VOIDP; arg.voidp = p; }
|
||||
|
||||
/**
|
||||
* Constructor with a function result argument.
|
||||
*/
|
||||
HookArgument(std::pair<bool, Val*> fresult) { type = FUNC_RESULT; func_result = fresult; }
|
||||
explicit HookArgument(std::pair<bool, Val*> fresult) { type = FUNC_RESULT; func_result = fresult; }
|
||||
|
||||
/**
|
||||
* Constructor with a Frame argument.
|
||||
*/
|
||||
HookArgument(Frame* f) { type = FRAME; arg.frame = f; }
|
||||
explicit HookArgument(Frame* f) { type = FRAME; arg.frame = f; }
|
||||
|
||||
/**
|
||||
* Constructor with a WriterInfo argument.
|
||||
*/
|
||||
explicit HookArgument(const logging::WriterBackend::WriterInfo* i) { type = WRITER_INFO; arg.winfo = i; }
|
||||
|
||||
/**
|
||||
* Constructor with a threading field argument.
|
||||
*/
|
||||
explicit HookArgument(const std::pair<int, const threading::Field* const*> fpair) { type = THREAD_FIELDS; tfields = fpair; }
|
||||
|
||||
/**
|
||||
* Returns the value for a boolen argument. The argument's type must
|
||||
|
@ -239,6 +262,12 @@ public:
|
|||
*/
|
||||
const Event* AsEvent() const { assert(type == EVENT); return arg.event; }
|
||||
|
||||
/**
|
||||
* Returns the value for an connection argument. The argument's type must
|
||||
* match accordingly.
|
||||
*/
|
||||
const Connection* AsConnection() const { assert(type == CONN); return arg.conn; }
|
||||
|
||||
/**
|
||||
* Returns the value for a function argument. The argument's type must
|
||||
* match accordingly.
|
||||
|
@ -275,6 +304,18 @@ public:
|
|||
*/
|
||||
const Frame* AsFrame() const { assert(type == FRAME); return arg.frame; }
|
||||
|
||||
/**
|
||||
* Returns the value for a logging WriterInfo argument. The argument's type must
|
||||
* match accordingly.
|
||||
*/
|
||||
const logging::WriterBackend::WriterInfo* AsWriterInfo() const { assert(type == WRITER_INFO); return arg.winfo; }
|
||||
|
||||
/**
|
||||
* Returns the value for a threading fields argument. The argument's type must
|
||||
* match accordingly.
|
||||
*/
|
||||
const std::pair<int, const threading::Field* const*> AsThreadFields() const { assert(type == THREAD_FIELDS); return tfields; }
|
||||
|
||||
/**
|
||||
* Returns the value for a list of Bro values argument. The argument's type must
|
||||
* match accordingly.
|
||||
|
@ -305,16 +346,19 @@ private:
|
|||
bool bool_;
|
||||
double double_;
|
||||
const Event* event;
|
||||
const Connection* conn;
|
||||
const Func* func;
|
||||
const Frame* frame;
|
||||
int int_;
|
||||
const Val* val;
|
||||
const val_list* vals;
|
||||
const void* voidp;
|
||||
const logging::WriterBackend::WriterInfo* winfo;
|
||||
} arg;
|
||||
|
||||
// Outside union because these have dtors.
|
||||
std::pair<bool, Val*> func_result;
|
||||
std::pair<int, const threading::Field* const*> tfields;
|
||||
std::string arg_string;
|
||||
};
|
||||
|
||||
|
@ -663,6 +707,61 @@ protected:
|
|||
*/
|
||||
virtual void HookBroObjDtor(void* obj);
|
||||
|
||||
/**
|
||||
* Hook into log initialization. This method will be called when a
|
||||
* logging writer is created. A writer represents a single logging
|
||||
* filter. The method is called in the main thread, on the node that
|
||||
* causes a log line to be written. It will _not_ be called on the logger
|
||||
* node. The function will be called each for every instantiated writer.
|
||||
*
|
||||
* @param writer The name of the writer being insantiated.
|
||||
*
|
||||
* @param instantiating_filter Name of the filter causing the
|
||||
* writer instantiation.
|
||||
*
|
||||
* @param local True if the filter is logging locally (writer
|
||||
* thread will be located in same process).
|
||||
*
|
||||
* @param remote True if filter is logging remotely (writer thread
|
||||
* will be located in different thread, typically
|
||||
* in manager or logger node).
|
||||
*
|
||||
* @param info WriterBackend::WriterInfo with information about the writer.
|
||||
*
|
||||
* @param num_fields number of fields in the record being written.
|
||||
*
|
||||
* @param fields threading::Field description of the fields being logged.
|
||||
*/
|
||||
virtual 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);
|
||||
|
||||
/**
|
||||
* Hook into log writing. This method will be called for each log line
|
||||
* being written by each writer. Each writer represents a single logging
|
||||
* filter. The method is called in the main thread, on the node that
|
||||
* causes a log line to be written. It will _not_ be called on the logger
|
||||
* node. The function will be called each for every instantiated writer.
|
||||
* This function allows plugins to modify or skip logging of information.
|
||||
* Note - once a log line is skipped (by returning false), it will not passed
|
||||
* on to hooks that have not yet been called.
|
||||
*
|
||||
* @param writer The name of the writer.
|
||||
*
|
||||
* @param filter Name of the filter being written to.
|
||||
*
|
||||
* @param info WriterBackend::WriterInfo with information about the writer.
|
||||
*
|
||||
* @param num_fields number of fields in the record being written.
|
||||
*
|
||||
* @param fields threading::Field description of the fields being logged.
|
||||
*
|
||||
* @param vals threading::Values containing the values being written. Values
|
||||
* can be modified in the Hook.
|
||||
*
|
||||
* @return true if log line should be written, false if log line should be
|
||||
* skipped and not passed on to the writer.
|
||||
*/
|
||||
virtual 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);
|
||||
|
||||
// Meta hooks.
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue