Add a global log policy hook to the logging framework

This addresses the need for a central hook on any log write, which
wasn't previously doable without a lot of effort. The log manager
invokes the new Log::log_stream_policy hook prior to any filter-specific
hooks. Like filter-level hooks, it may veto a log write. Even when
it does, filter-level hooks still get invoked, but cannot "un-veto".

Includes test cases.
This commit is contained in:
Christian Kreibich 2021-06-29 16:42:31 -07:00
parent 50c5968c30
commit 795a7ea98e
10 changed files with 236 additions and 7 deletions

View file

@ -148,6 +148,7 @@ Manager::~Manager()
void Manager::InitPostScript()
{
rotation_format_func = id::find_func("Log::rotation_format_func");
log_stream_policy_hook = id::find_func("Log::log_stream_policy");
}
WriterBackend* Manager::CreateBackend(WriterFrontend* frontend, EnumVal* tag)
@ -722,6 +723,21 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
if ( stream->event )
event_mgr.Enqueue(stream->event, columns);
bool stream_veto = false;
if ( log_stream_policy_hook )
{
auto v = log_stream_policy_hook->Invoke(columns, IntrusivePtr{NewRef{}, id});
if ( v && ! v->AsBool() )
{
// We recod the fact that this hook is vetoing
// the write, but continue on to the filter-
// level hooks to allow them to run anyway.
// They cannot "un-veto".
stream_veto = true;
}
}
// Send to each of our filters.
for ( list<Filter*>::iterator i = stream->filters.begin();
i != stream->filters.end(); ++i )
@ -743,6 +759,9 @@ bool Manager::Write(EnumVal* id, RecordVal* columns_arg)
continue;
}
if ( stream_veto )
continue;
if ( filter->path_func )
{
ValPtr path_arg;