Reworking logging's postprocessor logic.

The main change is that the postprocessor commands are no longer run
by the log writers themselves. Instead, the writers send back a
message to the log mgr once they have rotated. The manager then calls
a script level function to do somethign with the rotated file. By
default, it will be renamed to somethingn nice and then a
postprocessor shell command will be run on it if defined.

Pieces going into this:

    - Terminology change: "postprocessor" now refers to a script
    *function*. In addition, there are "postprocessor commands", which
    are shell commands that may be triggered by the function to run on
    a rotated file.

    - The RotationInfo record now comes with all the information that
    was previously provided internally to the C++ function running the
    post-processor command.

    - Changing the default time format to %Y-%m-%d-%H-%M-%S

    - rotation_path_func is gone

    - The default postprocessor function is defined individually by
      each LogWriter in frameworks/logging/plugin/*

    - The interface to postprocessor shell commands remains the same.

Needs a bit more testing ...
This commit is contained in:
Robin Sommer 2011-07-29 17:21:38 -07:00
parent 0e5bc16a60
commit 96a9d488e0
14 changed files with 225 additions and 160 deletions

View file

@ -431,6 +431,25 @@ LogMgr::Stream* LogMgr::FindStream(EnumVal* id)
return streams[idx];
}
LogMgr::WriterInfo* LogMgr::FindWriter(LogWriter* writer)
{
for ( vector<Stream *>::iterator s = streams.begin(); s != streams.end(); ++s )
{
if ( ! *s )
continue;
for ( Stream::WriterMap::iterator i = (*s)->writers.begin(); i != (*s)->writers.end(); i++ )
{
WriterInfo* winfo = i->second;
if ( winfo->writer == writer )
return winfo;
}
}
return 0;
}
void LogMgr::RemoveDisabledWriters(Stream* stream)
{
list<Stream::WriterPathPair> disabled;
@ -1369,6 +1388,8 @@ void LogMgr::InstallRotationTimer(WriterInfo* winfo)
RecordVal* rc =
LookupRotationControl(winfo->type, winfo->writer->Path());
assert(rc);
int idx = rc->Type()->AsRecordType()->FieldOffset("interv");
double rotation_interval = rc->LookupWithDefault(idx)->AsInterval();
@ -1406,34 +1427,63 @@ void LogMgr::Rotate(WriterInfo* winfo)
DBG_LOG(DBG_LOGGING, "Rotating %s at %.6f",
winfo->writer->Path().c_str(), network_time);
// Create the RotationInfo record.
RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo);
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));
// Build a temporary path for the writer to move the file to.
struct tm tm;
char buf[128];
const char* const date_fmt = "%y-%m-%d_%H.%M.%S";
time_t teatime = (time_t)winfo->open_time;
// Call the function building us the new path.
localtime_r(&teatime, &tm);
strftime(buf, sizeof(buf), date_fmt, &tm);
Func* rotation_path_func =
internal_func("Log::default_rotation_path_func");
string tmp = string(fmt("%s-%s", winfo->writer->Path().c_str(), buf));
// Trigger the rotation.
winfo->writer->Rotate(tmp, winfo->open_time, network_time, terminating);
}
bool LogMgr::FinishedRotation(LogWriter* writer, string new_name, string old_name,
double open, double close, bool terminating)
{
DBG_LOG(DBG_LOGGING, "Finished rotating %s at %.6f, new name %s",
writer->Path().c_str(), network_time, new_name.c_str());
WriterInfo* winfo = FindWriter(writer);
assert(winfo);
RecordVal* rc =
LookupRotationControl(winfo->type, winfo->writer->Path());
assert(rc);
// Create the RotationInfo record.
RecordVal* info = new RecordVal(BifType::Record::Log::RotationInfo);
info->Assign(0, winfo->type->Ref());
info->Assign(1, new StringVal(new_name.c_str()));
info->Assign(2, new StringVal(winfo->writer->Path().c_str()));
info->Assign(3, new Val(open, TYPE_TIME));
info->Assign(4, new Val(close, TYPE_TIME));
info->Assign(5, new Val(terminating, TYPE_BOOL));
int idx = rc->Type()->AsRecordType()->FieldOffset("postprocessor");
assert(idx >= 0);
string rotation_postprocessor =
rc->LookupWithDefault(idx)->AsString()->CheckString();
Val* func = rc->Lookup(idx);
if ( ! func )
{
ID* id = global_scope()->Lookup("Log::__default_rotation_postprocessor");
assert(id);
func = id->ID_Val();
}
assert(func);
// Call the postprocessor function.
val_list vl(1);
vl.append(info);
Val* result = rotation_path_func->Call(&vl);
string new_path = result->AsString()->CheckString();
Unref(result);
winfo->writer->Rotate(new_path, rotation_postprocessor,
winfo->open_time, network_time, terminating);
Val* v = func->AsFunc()->Call(&vl);
int result = v->AsBool();
Unref(v);
return result;
}