Remove Log::rotation_control (addresses #572).

Log rotation is now controlled directly through Filter records.

Also addressed a TODO in the default_path_func regarding the
LogMgr::AddFilter function generating internal filter path
suggestions/fallbacks.  Now, if the user doesn't explicitly set a filter
path, the filter's path will be the result of the first call to
default_path_func (happens during the first write to the log).  And in
that case the path suggestion argument to the path_func is an empty
string.
This commit is contained in:
Jon Siwek 2011-09-08 14:46:17 -05:00
parent d8c716ae17
commit fe38c22d2b
11 changed files with 73 additions and 291 deletions

View file

@ -49,8 +49,6 @@ export {
## Variable IDs that are to be ignored by the update process. ## Variable IDs that are to be ignored by the update process.
const ignore_ids: set[string] = { const ignore_ids: set[string] = {
# FIXME: Bro crashes if it tries to send this ID.
"Log::rotation_control",
}; };
## Event for requesting the value of an ID (a variable). ## Event for requesting the value of an ID (a variable).

View file

@ -32,8 +32,10 @@ export {
## to derive a name. ## to derive a name.
## ##
## id: The log stream. ## id: The log stream.
## path: A suggested path value, which may be either the filter's ``path`` ## path: A suggested path value, which may be either the filter's
## if defined or a fall-back generated internally. ## ``path`` if defined, else a previous result from the function.
## If no ``path`` is defined for the filter, then the first call
## to the function will contain an empty string.
## rec: An instance of the streams's ``columns`` type with its ## rec: An instance of the streams's ``columns`` type with its
## fields set to the values to logged. ## fields set to the values to logged.
## ##
@ -65,20 +67,6 @@ export {
## table are initialized by each writer type. ## table are initialized by each writer type.
const default_rotation_postprocessors: table[Writer] of function(info: RotationInfo) : bool &redef; const default_rotation_postprocessors: table[Writer] of function(info: RotationInfo) : bool &redef;
## Type for controlling file rotation.
type RotationControl: record {
## Rotation interval.
interv: interval &default=default_rotation_interval;
## Callback function to trigger for rotated files. If not set, the default
## comes out of default_rotation_postprocessors.
postprocessor: function(info: RotationInfo) : bool &optional;
};
## Specifies rotation parameters per ``(id, path)`` tuple.
## If a pair is not found in this table, default values defined in
## ``RotationControl`` are used.
const rotation_control: table[Writer, string] of RotationControl &default=[] &redef;
## Filter customizing logging. ## Filter customizing logging.
type Filter: record { type Filter: record {
## Descriptive name to reference this filter. ## Descriptive name to reference this filter.
@ -114,8 +102,10 @@ export {
## connection ... ## connection ...
## ##
## id: The log stream. ## id: The log stream.
## path: A suggested path value, which may be either the filter's ``path`` ## path: A suggested path value, which may be either the filter's
## if defined or a fall-back generated internally. ## ``path`` if defined, else a previous result from the function.
## If no ``path`` is defined for the filter, then the first call
## to the function will contain an empty string.
## rec: An instance of the streams's ``columns`` type with its ## rec: An instance of the streams's ``columns`` type with its
## fields set to the values to logged. ## fields set to the values to logged.
## ##
@ -136,10 +126,12 @@ export {
## If true, entries are passed on to remote peers. ## If true, entries are passed on to remote peers.
log_remote: bool &default=enable_remote_logging; log_remote: bool &default=enable_remote_logging;
## If set, the rotation control value is automatically added to ## Rotation interval.
## :bro:id:`Log::rotation_control` for the filter's (writer, path) interv: interval &default=default_rotation_interval;
## when adding the filter to a stream via :bro:id:`Log::add_filter`
rotation: RotationControl &optional; ## Callback function to trigger for rotated files. If not set,
## the default comes out of default_rotation_postprocessors.
postprocessor: function(info: RotationInfo) : bool &optional;
}; };
## Sentinel value for indicating that a filter was not found when looked up. ## Sentinel value for indicating that a filter was not found when looked up.
@ -182,10 +174,9 @@ function default_path_func(id: ID, path: string, rec: any) : string
local parts = split1(id_str, /::/); local parts = split1(id_str, /::/);
if ( |parts| == 2 ) if ( |parts| == 2 )
{ {
# TODO: the core shouldn't be suggesting paths anymore. Only # The suggested path value is a previous result of this function
# statically defined paths should be sent into here. This # or a filter path explicitly set by the user, so continue using it
# is only to cope with the core generated paths. if ( path != "" )
if ( to_lower(parts[2]) != path )
return path; return path;
# Example: Notice::LOG -> "notice" # Example: Notice::LOG -> "notice"

View file

@ -215,18 +215,6 @@ function log_mailing_postprocessor(info: Log::RotationInfo): bool
return T; return T;
} }
# This extra export section here is just because this redefinition should
# be documented as part of the "public API" of this script, but the redef
# needs to occur after the postprocessor function implementation.
export {
## By default, an ASCII version of the the alarm log is emailed daily to any
## configured :bro:id:`Notice::mail_dest` if not operating on trace files.
redef Log::rotation_control += {
[Log::WRITER_ASCII, "alarm-mail"] =
[$interv=24hrs, $postprocessor=log_mailing_postprocessor]
};
}
event bro_init() &priority=5 event bro_init() &priority=5
{ {
Log::create_stream(Notice::LOG, [$columns=Info, $ev=log_notice]); Log::create_stream(Notice::LOG, [$columns=Info, $ev=log_notice]);
@ -237,9 +225,9 @@ event bro_init() &priority=5
# Make sure that this alarm log is also output as text so that it can # Make sure that this alarm log is also output as text so that it can
# be packaged up and emailed later. # be packaged up and emailed later.
if ( ! reading_traces() && mail_dest != "" ) if ( ! reading_traces() && mail_dest != "" )
Log::add_filter(Notice::ALARM_LOG, [$name="alarm-mail", Log::add_filter(Notice::ALARM_LOG,
$path="alarm-mail", [$name="alarm-mail", $path="alarm-mail", $writer=Log::WRITER_ASCII,
$writer=Log::WRITER_ASCII]); $interv=24hrs, $postprocessor=log_mailing_postprocessor]);
} }
# TODO: fix this. # TODO: fix this.

View file

@ -36,6 +36,8 @@ struct LogMgr::Filter {
EnumVal* writer; EnumVal* writer;
bool local; bool local;
bool remote; bool remote;
double interval;
Func* postprocessor;
int num_fields; int num_fields;
LogField** fields; LogField** fields;
@ -52,6 +54,8 @@ struct LogMgr::WriterInfo {
EnumVal* type; EnumVal* type;
double open_time; double open_time;
Timer* rotation_timer; Timer* rotation_timer;
double interval;
Func* postprocessor;
LogWriter* writer; LogWriter* writer;
}; };
@ -382,17 +386,6 @@ bool LogVal::Write(SerializationFormat* fmt) const
LogMgr::Filter::~Filter() LogMgr::Filter::~Filter()
{ {
// If there's a rotation control table entry associated with this
// filter's (writer, path), remove it
TableVal* rc = BifConst::Log::rotation_control->AsTableVal();
ListVal* index = new ListVal(TYPE_ANY);
index->Append(writer->Ref());
index->Append(path_val->Ref());
Unref(rc->Delete(index));
Unref(index);
for ( int i = 0; i < num_fields; ++i ) for ( int i = 0; i < num_fields; ++i )
delete fields[i]; delete fields[i];
@ -743,6 +736,8 @@ bool LogMgr::AddFilter(EnumVal* id, RecordVal* fval)
Val* path_func = fval->LookupWithDefault(rtype->FieldOffset("path_func")); Val* path_func = fval->LookupWithDefault(rtype->FieldOffset("path_func"));
Val* log_local = fval->LookupWithDefault(rtype->FieldOffset("log_local")); Val* log_local = fval->LookupWithDefault(rtype->FieldOffset("log_local"));
Val* log_remote = fval->LookupWithDefault(rtype->FieldOffset("log_remote")); Val* log_remote = fval->LookupWithDefault(rtype->FieldOffset("log_remote"));
Val* interv = fval->LookupWithDefault(rtype->FieldOffset("interv"));
Val* postprocessor = fval->LookupWithDefault(rtype->FieldOffset("postprocessor"));
Filter* filter = new Filter; Filter* filter = new Filter;
filter->name = name->AsString()->CheckString(); filter->name = name->AsString()->CheckString();
@ -752,12 +747,16 @@ bool LogMgr::AddFilter(EnumVal* id, RecordVal* fval)
filter->writer = writer->Ref()->AsEnumVal(); filter->writer = writer->Ref()->AsEnumVal();
filter->local = log_local->AsBool(); filter->local = log_local->AsBool();
filter->remote = log_remote->AsBool(); filter->remote = log_remote->AsBool();
filter->interval = interv->AsInterval();
filter->postprocessor = postprocessor ? postprocessor->AsFunc() : 0;
Unref(name); Unref(name);
Unref(pred); Unref(pred);
Unref(path_func); Unref(path_func);
Unref(log_local); Unref(log_local);
Unref(log_remote); Unref(log_remote);
Unref(interv);
Unref(postprocessor);
// Build the list of fields that the filter wants included, including // Build the list of fields that the filter wants included, including
// potentially rolling out fields. // potentially rolling out fields.
@ -783,40 +782,14 @@ bool LogMgr::AddFilter(EnumVal* id, RecordVal* fval)
else else
{ {
// If no path is given, use the Stream ID as the default but // If no path is given, it's derived based upon the value returned by
// strip the namespace. // the first call to the filter's path_func (during first write)
const char* s = stream->name.c_str(); filter->path_val = 0;
const char* e = s + strlen(s);
const char* t = strstr(s, "::");
if ( t )
s = t + 2;
string path(s, e);
std::transform(path.begin(), path.end(), path.begin(), ::tolower);
filter->path = path;
filter->path_val = new StringVal(path.c_str());
} }
// Remove any filter with the same name we might already have. // Remove any filter with the same name we might already have.
RemoveFilter(id, filter->name); RemoveFilter(id, filter->name);
// Install the rotation support, if given
Val* rot_val = fval->Lookup(rtype->FieldOffset("rotation"));
if ( rot_val )
{
TableVal* rc = BifConst::Log::rotation_control->AsTableVal();
ListVal* index = new ListVal(TYPE_ANY);
index->Append(filter->writer->Ref());
index->Append(filter->path_val->Ref());
rc->Assign(index, rot_val->Ref());
Unref(index);
}
// Add the new one. // Add the new one.
stream->filters.push_back(filter); stream->filters.push_back(filter);
@ -927,7 +900,12 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
{ {
val_list vl(3); val_list vl(3);
vl.append(id->Ref()); vl.append(id->Ref());
vl.append(filter->path_val->Ref()); Val* path_arg;
if ( filter->path_val )
path_arg = filter->path_val;
else
path_arg = new StringVal("");
vl.append(path_arg->Ref());
vl.append(columns->Ref()); vl.append(columns->Ref());
Val* v = filter->path_func->Call(&vl); Val* v = filter->path_func->Call(&vl);
@ -938,6 +916,13 @@ bool LogMgr::Write(EnumVal* id, RecordVal* columns)
return false; return false;
} }
if ( ! filter->path_val )
{
Unref(path_arg);
filter->path = v->AsString()->CheckString();
filter->path_val = v->Ref();
}
path = v->AsString()->CheckString(); path = v->AsString()->CheckString();
Unref(v); Unref(v);
@ -1264,6 +1249,24 @@ LogWriter* LogMgr::CreateWriter(EnumVal* id, EnumVal* writer, string path,
winfo->writer = writer_obj; winfo->writer = writer_obj;
winfo->open_time = network_time; winfo->open_time = network_time;
winfo->rotation_timer = 0; winfo->rotation_timer = 0;
winfo->interval = 0;
winfo->postprocessor = 0;
// search for a corresponding filter for the writer/path pair and use its
// rotation settings
list<Filter*>::const_iterator it;
for ( it = stream->filters.begin(); it != stream->filters.end(); ++it )
{
Filter* f = *it;
if ( f->writer->AsEnum() == writer->AsEnum() &&
f->path == winfo->writer->Path() )
{
winfo->interval = f->interval;
winfo->postprocessor = f->postprocessor;
break;
}
}
InstallRotationTimer(winfo); InstallRotationTimer(winfo);
stream->writers.insert( stream->writers.insert(
@ -1441,22 +1444,6 @@ void RotationTimer::Dispatch(double t, int is_expire)
} }
} }
RecordVal* LogMgr::LookupRotationControl(EnumVal* writer, string path)
{
TableVal* rc = BifConst::Log::rotation_control->AsTableVal();
ListVal* index = new ListVal(TYPE_ANY);
index->Append(writer->Ref());
index->Append(new StringVal(path.c_str()));
Val* r = rc->Lookup(index);
assert(r);
Unref(index);
return r->AsRecordVal();
}
void LogMgr::InstallRotationTimer(WriterInfo* winfo) void LogMgr::InstallRotationTimer(WriterInfo* winfo)
{ {
if ( terminating ) if ( terminating )
@ -1468,13 +1455,7 @@ void LogMgr::InstallRotationTimer(WriterInfo* winfo)
winfo->rotation_timer = 0; winfo->rotation_timer = 0;
} }
RecordVal* rc = double rotation_interval = winfo->interval;
LookupRotationControl(winfo->type, winfo->writer->Path());
assert(rc);
int idx = rc->Type()->AsRecordType()->FieldOffset("interv");
double rotation_interval = rc->LookupWithDefault(idx)->AsInterval();
if ( rotation_interval ) if ( rotation_interval )
{ {
@ -1535,11 +1516,6 @@ bool LogMgr::FinishedRotation(LogWriter* writer, string new_name, string old_nam
if ( ! winfo ) if ( ! winfo )
return true; return true;
RecordVal* rc =
LookupRotationControl(winfo->type, winfo->writer->Path());
assert(rc);
// Create the RotationInfo record. // Create the RotationInfo record.
RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo); RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo);
info->Assign(0, winfo->type->Ref()); info->Assign(0, winfo->type->Ref());
@ -1549,15 +1525,12 @@ bool LogMgr::FinishedRotation(LogWriter* writer, string new_name, string old_nam
info->Assign(4, new Val(close, TYPE_TIME)); info->Assign(4, new Val(close, TYPE_TIME));
info->Assign(5, new Val(terminating, TYPE_BOOL)); info->Assign(5, new Val(terminating, TYPE_BOOL));
int idx = rc->Type()->AsRecordType()->FieldOffset("postprocessor"); Func* func = winfo->postprocessor;
assert(idx >= 0);
Val* func = rc->Lookup(idx);
if ( ! func ) if ( ! func )
{ {
ID* id = global_scope()->Lookup("Log::__default_rotation_postprocessor"); ID* id = global_scope()->Lookup("Log::__default_rotation_postprocessor");
assert(id); assert(id);
func = id->ID_Val(); func = id->ID_Val()->AsFunc();
} }
assert(func); assert(func);
@ -1565,7 +1538,10 @@ bool LogMgr::FinishedRotation(LogWriter* writer, string new_name, string old_nam
// Call the postprocessor function. // Call the postprocessor function.
val_list vl(1); val_list vl(1);
vl.append(info); vl.append(info);
Val* v = func->AsFunc()->Call(&vl); ODesc d;
func->Describe(&d);
fprintf(stderr, "%s\n", d.Description());
Val* v = func->Call(&vl);
int result = v->AsBool(); int result = v->AsBool();
Unref(v); Unref(v);
return result; return result;

View file

@ -129,7 +129,6 @@ private:
void RemoveDisabledWriters(Stream* stream); void RemoveDisabledWriters(Stream* stream);
void InstallRotationTimer(WriterInfo* winfo); void InstallRotationTimer(WriterInfo* winfo);
void Rotate(WriterInfo* info); void Rotate(WriterInfo* info);
RecordVal* LookupRotationControl(EnumVal* writer, string path);
Filter* FindFilter(EnumVal* id, StringVal* filter); Filter* FindFilter(EnumVal* id, StringVal* filter);
WriterInfo* FindWriter(LogWriter* writer); WriterInfo* FindWriter(LogWriter* writer);

View file

@ -10,9 +10,6 @@ module Log;
type Filter: record; type Filter: record;
type Stream: record; type Stream: record;
type RotationInfo: record; type RotationInfo: record;
type RotationControl: record;
const Log::rotation_control: RotationControl;
function Log::__create_stream%(id: Log::ID, stream: Log::Stream%) : bool function Log::__create_stream%(id: Log::ID, stream: Log::Stream%) : bool
%{ %{

View file

@ -1,10 +0,0 @@
{
[WRITER_ASCII, test2] = [interv=30.0 mins, postprocessor=Test::custom_rotate
{
print custom rotate, Test::info;
return (T);
}]
}
{
}

View file

@ -1,83 +0,0 @@
1st test.2011-03-07-03-00-05.log test 11-03-07_03.00.05 11-03-07_04.00.05 0
1st test.2011-03-07-04-00-05.log test 11-03-07_04.00.05 11-03-07_05.00.05 0
1st test.2011-03-07-05-00-05.log test 11-03-07_05.00.05 11-03-07_06.00.05 0
1st test.2011-03-07-06-00-05.log test 11-03-07_06.00.05 11-03-07_07.00.05 0
1st test.2011-03-07-07-00-05.log test 11-03-07_07.00.05 11-03-07_08.00.05 0
1st test.2011-03-07-08-00-05.log test 11-03-07_08.00.05 11-03-07_09.00.05 0
1st test.2011-03-07-09-00-05.log test 11-03-07_09.00.05 11-03-07_10.00.05 0
1st test.2011-03-07-10-00-05.log test 11-03-07_10.00.05 11-03-07_11.00.05 0
1st test.2011-03-07-11-00-05.log test 11-03-07_11.00.05 11-03-07_12.00.05 0
1st test.2011-03-07-12-00-05.log test 11-03-07_12.00.05 11-03-07_12.59.55 1
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_03.00.05.log, path=test2, open=1299466805.0, close=1299470395.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_03.59.55.log, path=test2, open=1299470395.0, close=1299470405.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_04.00.05.log, path=test2, open=1299470405.0, close=1299473995.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_04.59.55.log, path=test2, open=1299473995.0, close=1299474005.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_05.00.05.log, path=test2, open=1299474005.0, close=1299477595.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_05.59.55.log, path=test2, open=1299477595.0, close=1299477605.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_06.00.05.log, path=test2, open=1299477605.0, close=1299481195.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_06.59.55.log, path=test2, open=1299481195.0, close=1299481205.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_07.00.05.log, path=test2, open=1299481205.0, close=1299484795.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_07.59.55.log, path=test2, open=1299484795.0, close=1299484805.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_08.00.05.log, path=test2, open=1299484805.0, close=1299488395.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_08.59.55.log, path=test2, open=1299488395.0, close=1299488405.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_09.00.05.log, path=test2, open=1299488405.0, close=1299491995.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_09.59.55.log, path=test2, open=1299491995.0, close=1299492005.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_10.00.05.log, path=test2, open=1299492005.0, close=1299495595.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_10.59.55.log, path=test2, open=1299495595.0, close=1299495605.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_11.00.05.log, path=test2, open=1299495605.0, close=1299499195.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_11.59.55.log, path=test2, open=1299499195.0, close=1299499205.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_12.00.05.log, path=test2, open=1299499205.0, close=1299502795.0, terminating=F]
custom rotate, [writer=WRITER_ASCII, fname=test2-11-03-07_12.59.55.log, path=test2, open=1299502795.0, close=1299502795.0, terminating=T]
# t id.orig_h id.orig_p id.resp_h id.resp_p
1299466805.000000 10.0.0.1 20 10.0.0.2 1024
1299470395.000000 10.0.0.2 20 10.0.0.3 0
1299470405.000000 10.0.0.1 20 10.0.0.2 1025
1299473995.000000 10.0.0.2 20 10.0.0.3 1
1299474005.000000 10.0.0.1 20 10.0.0.2 1026
1299477595.000000 10.0.0.2 20 10.0.0.3 2
1299477605.000000 10.0.0.1 20 10.0.0.2 1027
1299481195.000000 10.0.0.2 20 10.0.0.3 3
1299481205.000000 10.0.0.1 20 10.0.0.2 1028
1299484795.000000 10.0.0.2 20 10.0.0.3 4
1299484805.000000 10.0.0.1 20 10.0.0.2 1029
1299488395.000000 10.0.0.2 20 10.0.0.3 5
1299488405.000000 10.0.0.1 20 10.0.0.2 1030
1299491995.000000 10.0.0.2 20 10.0.0.3 6
1299492005.000000 10.0.0.1 20 10.0.0.2 1031
1299495595.000000 10.0.0.2 20 10.0.0.3 7
1299495605.000000 10.0.0.1 20 10.0.0.2 1032
1299499195.000000 10.0.0.2 20 10.0.0.3 8
1299499205.000000 10.0.0.1 20 10.0.0.2 1033
1299502795.000000 10.0.0.2 20 10.0.0.3 9
> test.2011-03-07-03-00-05.log
> test.2011-03-07-04-00-05.log
> test.2011-03-07-05-00-05.log
> test.2011-03-07-06-00-05.log
> test.2011-03-07-07-00-05.log
> test.2011-03-07-08-00-05.log
> test.2011-03-07-09-00-05.log
> test.2011-03-07-10-00-05.log
> test.2011-03-07-11-00-05.log
> test.2011-03-07-12-00-05.log
> test.log
> test2-11-03-07_03.00.05.log
> test2-11-03-07_03.59.55.log
> test2-11-03-07_04.00.05.log
> test2-11-03-07_04.59.55.log
> test2-11-03-07_05.00.05.log
> test2-11-03-07_05.59.55.log
> test2-11-03-07_06.00.05.log
> test2-11-03-07_06.59.55.log
> test2-11-03-07_07.00.05.log
> test2-11-03-07_07.59.55.log
> test2-11-03-07_08.00.05.log
> test2-11-03-07_08.59.55.log
> test2-11-03-07_09.00.05.log
> test2-11-03-07_09.59.55.log
> test2-11-03-07_10.00.05.log
> test2-11-03-07_10.59.55.log
> test2-11-03-07_11.00.05.log
> test2-11-03-07_11.59.55.log
> test2-11-03-07_12.00.05.log
> test2-11-03-07_12.59.55.log
> test2.log

View file

@ -1,30 +0,0 @@
# @TEST-EXEC: bro -b %INPUT >out
# @TEST-EXEC: btest-diff out
module Test;
export {
redef enum Log::ID += { Test };
type Info: record {
t: time;
id: conn_id;
} &log;
}
function custom_rotate(info: Log::RotationInfo) : bool
{
print "custom rotate", info;
return T;
}
event bro_init()
{
Log::create_stream(Test, [$columns=Info]);
Log::add_filter(Test, [$name="2nd", $path="test2",
$rotation=[$interv=30mins, $postprocessor=custom_rotate]]);
print Log::rotation_control;
Log::remove_filter(Test, "2nd");
# The RotationControl should be removed now
print Log::rotation_control;
}

View file

@ -26,15 +26,10 @@ function custom_rotate(info: Log::RotationInfo) : bool
return T; return T;
} }
redef Log::rotation_control += {
[Log::WRITER_ASCII, "test2"] = [$interv=30mins, $postprocessor=custom_rotate]
};
event bro_init() event bro_init()
{ {
Log::create_stream(Test::LOG, [$columns=Log]); Log::create_stream(Test::LOG, [$columns=Log]);
Log::add_filter(Test::LOG, [$name="2nd", $path="test2"]); Log::add_filter(Test::LOG, [$name="2nd", $path="test2", $interv=30mins, $postprocessor=custom_rotate]);
} }
event new_connection(c: connection) event new_connection(c: connection)

View file

@ -1,39 +0,0 @@
#
# @TEST-EXEC: bro -b -r %DIR/rotation.trace %INPUT 2>&1 | egrep "test|test2" | sort >out
# @TEST-EXEC: for i in `ls test*.log | sort`; do printf '> %s\n' $i; cat $i; done | sort | uniq >>out
# @TEST-EXEC: btest-diff out
module Test;
export {
# Create a new ID for our log stream
redef enum Log::ID += { Test };
# Define a record with all the columns the log file can have.
# (I'm using a subset of fields from ssh-ext for demonstration.)
type Log: record {
t: time;
id: conn_id; # Will be rolled out into individual columns.
} &log;
}
redef Log::default_rotation_interval = 1hr;
redef Log::default_rotation_postprocessor_cmd = "echo 1st";
function custom_rotate(info: Log::RotationInfo) : bool
{
print "custom rotate", info;
return T;
}
event bro_init()
{
Log::create_stream(Test, [$columns=Log]);
Log::add_filter(Test, [$name="2nd", $path="test2",
$rotation=[$interv=30mins, $postprocessor=custom_rotate]]);
}
event new_connection(c: connection)
{
Log::write(Test, [$t=network_time(), $id=c$id]);
}