Implementing dynamic paths via $path_func.

One change to original plan: the function also receives the standard
$path argument.
This commit is contained in:
Robin Sommer 2011-02-21 17:12:58 -08:00
parent 28216c84a2
commit 434f57f85f
2 changed files with 27 additions and 5 deletions

View file

@ -308,7 +308,7 @@ type log_filter: record {
# extension is given; the writer will add whatever is # extension is given; the writer will add whatever is
# appropiate. # appropiate.
path: string &optional; path: string &optional;
path_func: function(id: Log_ID): string &optional; path_func: function(id: Log_ID, path: string): string &optional;
# A subset of column names to record. If not given, all # A subset of column names to record. If not given, all
# columns are recorded. # columns are recorded.

View file

@ -25,6 +25,7 @@ struct LogMgr::Filter {
Func* pred; Func* pred;
Func* path_func; Func* path_func;
string path; string path;
Val* path_val;
LogWriterDefinition* writer; LogWriterDefinition* writer;
int num_fields; int num_fields;
@ -54,6 +55,8 @@ LogMgr::Filter::~Filter()
for ( WriterMap::iterator i = writers.begin(); i != writers.end(); i++ ) for ( WriterMap::iterator i = writers.begin(); i != writers.end(); i++ )
delete i->second; delete i->second;
Unref(path_val);
} }
LogMgr::Stream::~Stream() LogMgr::Stream::~Stream()
@ -263,7 +266,10 @@ bool LogMgr::AddFilter(EnumVal* stream_id, RecordVal* fval)
Val* path_val = fval->Lookup(rtype->FieldOffset("path")); Val* path_val = fval->Lookup(rtype->FieldOffset("path"));
if ( path_val ) if ( path_val )
{
filter->path = path_val->AsString()->CheckString(); filter->path = path_val->AsString()->CheckString();
filter->path_val = path_val->Ref();
}
else else
{ {
@ -286,6 +292,7 @@ bool LogMgr::AddFilter(EnumVal* stream_id, RecordVal* fval)
} }
filter->path = string(lower); filter->path = string(lower);
filter->path_val = new StringVal(lower);
free(lower); free(lower);
} }
@ -371,7 +378,6 @@ bool LogMgr::Write(EnumVal* stream_id, RecordVal* columns)
for ( list<Filter*>::iterator i = stream->filters.begin(); i != stream->filters.end(); ++i ) for ( list<Filter*>::iterator i = stream->filters.begin(); i != stream->filters.end(); ++i )
{ {
Filter* filter = *i; Filter* filter = *i;
string path = filter->path; string path = filter->path;
if ( filter->pred ) if ( filter->pred )
@ -389,7 +395,23 @@ bool LogMgr::Write(EnumVal* stream_id, RecordVal* columns)
if ( filter->path_func ) if ( filter->path_func )
{ {
// XXX Do dynamic path here. val_list vl(2);
vl.append(stream_id->Ref());
vl.append(filter->path_val->Ref());
Val* v = filter->path_func->Call(&vl);
if ( ! v->Type()->Tag() == TYPE_STRING )
{
run_time("path_func did not return string");
Unref(v);
return false;
}
path = v->AsString()->CheckString();
#ifdef DEBUG
DBG_LOG(DBG_LOGGING, "Path function for filter '%s' on stream '%s' return '%s'", filter->name.c_str(), stream->name.c_str(), path.c_str());
#endif
} }
// See if we already have a writer for this path. // See if we already have a writer for this path.