New table Log::rotation_control that enables to control rotation

for individual files, overriding defaults.

The interface isn't the greatest but the best I can come up with right
now.
This commit is contained in:
Robin Sommer 2011-03-08 16:30:53 -08:00
parent eb736a34b3
commit df54cc6e78
5 changed files with 92 additions and 35 deletions

View file

@ -1,9 +1,25 @@
List of the things not implemented yet:
- Cluster-style remote_print.
- Rotation support.
- Not sure if the logging does the right thing with &optional and
&default values. Needs testing.
- Spawning writers in separate threads (not clear if we want that initially).
- Check the new event-value code.
- Configure Ascii Writer:
- "redef LogAscii::output_to_stdout = T"
- "redef LogAscii::separator = '\t'"
- "redef LogAscii::headers = T"
- Extended filter manipualtion interface on the script level:
- Disalbe stream altogether.
- Change individual options of an existing filter.
Notes about remote logging:
- The receiver must create the stream locally via
Log::create_stream() in order to receive data for it. If not
created, anything sent will be ignored.
- However, the receiver does not need to create filter locally.
Filter processing is done and the sender side, and as long as
stream exists at the receiver, it will record whatever it gets.

View file

@ -3,13 +3,6 @@ module Log;
# Log::ID and Log::Writer are defined in bro.init due to circular dependencies.
export {
# Information passed to a rotation callback function.
type RotationInfo: record {
path: string; # Original path value.
open: time; # Time when opened.
close: time; # Time when closed.
};
# If true, local logging is by default enabled for all filters.
const enable_local_logging = T &redef;
@ -19,20 +12,6 @@ export {
# The default writer to use.
const default_writer = Log::WRITER_ASCII &redef;
# Default rotation interval; zero disables rotation.
const default_rotation_interval = 0secs &redef;
# Default naming suffix format.
const default_rotation_date_format = "%y-%m-%d_%H.%M.%S" &redef;
# Default postprocessor for writers outputting into files.
const default_rotation_postprocessor = "" &redef;
# Default function to construct the name of the rotated file.
# The default implementation includes
# default_rotation_date_format into the file name.
global default_rotation_path_func: function(info: RotationInfo) : string &redef;
# A stream defining the logging.
type Stream: record {
# A record type defining the log's columns.
@ -81,6 +60,39 @@ export {
writer: Writer &default=Log::default_writer;
};
### Log rotation support.
# Information passed to a rotation callback function.
type RotationInfo: record {
writer: Writer; # The writer.
path: string; # Original path value.
open: time; # Time when opened.
close: time; # Time when closed.
};
# Default rotation interval; zero disables rotation.
const default_rotation_interval = 0secs &redef;
# Default naming suffix format.
const default_rotation_date_format = "%y-%m-%d_%H.%M.%S" &redef;
# Default postprocessor for writers outputting into files.
const default_rotation_postprocessor = "" &redef;
# Default function to construct the name of the rotated file.
# The default implementation includes
# default_rotation_date_format into the file name.
global default_rotation_path_func: function(info: RotationInfo) : string &redef;
type RotationControl: record {
interv: interval &default=default_rotation_interval;
date_fmt: string &default=default_rotation_date_format;
postprocessor: string &default=default_rotation_postprocessor;
};
# Defines rotation parameters per (id, path) tuple.
const rotation_control: table[Writer, string] of Log::RotationControl &default=[] &redef;
global create_stream: function(id: Log::ID, stream: Log::Stream) : bool;
global add_filter: function(id: Log::ID, filter: Log::Filter) : bool;
global remove_filter: function(id: Log::ID, name: string) : bool;
@ -97,7 +109,8 @@ module Log;
function default_rotation_path_func(info: RotationInfo) : string
{
return fmt("%s-%s", info$path, strftime(default_rotation_date_format, info$open));
local date_fmt = rotation_control[info$writer, info$path]$date_fmt;
return fmt("%s-%s", info$path, strftime(date_fmt, info$open));
}
function create_stream(id: Log::ID, stream: Log::Stream) : bool

View file

@ -40,6 +40,7 @@ struct LogMgr::Filter {
};
struct LogMgr::WriterInfo {
EnumVal* type;
double open_time;
Timer* rotation_timer;
LogWriter *writer;
@ -229,6 +230,7 @@ LogMgr::Stream::~Stream()
if ( winfo->rotation_timer )
timer_mgr->Cancel(winfo->rotation_timer);
Unref(winfo->type);
delete winfo->writer;
delete i->second;
}
@ -798,6 +800,7 @@ LogWriter* LogMgr::CreateWriter(EnumVal* id, EnumVal* writer, string path, int n
}
WriterInfo* winfo = new WriterInfo;
winfo->type = writer->Ref()->AsEnumVal();
winfo->writer = writer_obj;
winfo->open_time = network_time;
winfo->rotation_timer = 0;
@ -928,6 +931,22 @@ 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)
{
if ( terminating )
@ -939,7 +958,10 @@ void LogMgr::InstallRotationTimer(WriterInfo* winfo)
winfo->rotation_timer = 0;
}
double rotation_interval = BifConst::Log::default_rotation_interval;
RecordVal* rc = LookupRotationControl(winfo->type, winfo->writer->Path());
int idx = rc->Type()->AsRecordType()->FieldOffset("interv");
double rotation_interval = rc->LookupWithDefault(idx)->AsInterval();
if ( rotation_interval )
{
@ -974,14 +996,19 @@ void LogMgr::Rotate(WriterInfo* winfo)
// Create the RotationInfo record.
RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo);
info->Assign(0, new StringVal(winfo->writer->Path().c_str()));
info->Assign(1, new Val(winfo->open_time, TYPE_TIME));
info->Assign(2, new Val(network_time, TYPE_TIME));
info->Assign(0, winfo->type->Ref());
info->Assign(1, new StringVal(winfo->writer->Path().c_str()));
info->Assign(2, new Val(winfo->open_time, TYPE_TIME));
info->Assign(3, new Val(network_time, TYPE_TIME));
// Call the function building us the new path.
Func* rotation_path_func = internal_func("Log::default_rotation_path_func");
string rotation_postprocessor = BifConst::Log::default_rotation_postprocessor->AsString()->CheckString();
RecordVal* rc = LookupRotationControl(winfo->type, winfo->writer->Path());
int idx = rc->Type()->AsRecordType()->FieldOffset("postprocessor");
string rotation_postprocessor = rc->LookupWithDefault(idx)->AsString()->CheckString();
val_list vl(1);
vl.append(info);

View file

@ -99,6 +99,7 @@ private:
void RemoveDisabledWriters(Stream* stream);
void InstallRotationTimer(WriterInfo* winfo);
void Rotate(WriterInfo* info);
RecordVal* LookupRotationControl(EnumVal* writer, string path);
vector<Stream *> streams; // Indexed by stream enum.
};

View file

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