Lots of infracstructure for the new logging framework.

This pretty much follows the proposal on the projects page.

It includes:

    - A new LogMgr, maintaining the set of writers.

    - The abstract LogWriter API.

    - An initial implementation in the form of LogWriterAscii
      producing tab-separated columns.

Note that things are only partially working right now, things are
subject to change, and it's all not much tested at all. That's why I'm
creating separate branch for now.

Example:

     bro -B logging test-logging && cat debug.log
    1298063168.409852/1298063168.410368 [logging] Created new logging stream 'SSH::LOG_SSH'
    1298063168.409852/1298063168.410547 [logging] Created new filter 'default' for stream 'SSH::LOG_SSH'
    1298063168.409852/1298063168.410564 [logging]    writer    : Ascii
    1298063168.409852/1298063168.410574 [logging]    path      : ssh_log_ssh
    1298063168.409852/1298063168.410584 [logging]    path_func : not set
    1298063168.409852/1298063168.410594 [logging]    event     : not set
    1298063168.409852/1298063168.410604 [logging]    pred      : not set
    1298063168.409852/1298063168.410614 [logging]    field          t: time
    1298063168.409852/1298063168.410625 [logging]    field  id.orig_h: addr
    1298063168.409852/1298063168.410635 [logging]    field  id.orig_p: port
    1298063168.409852/1298063168.410645 [logging]    field  id.resp_h: addr
    1298063168.409852/1298063168.410655 [logging]    field  id.resp_p: port
    1298063168.409852/1298063168.410665 [logging]    field     status: string
    1298063168.409852/1298063168.410675 [logging]    field    country: string
    1298063168.409852/1298063168.410817 [logging] Wrote record to filter 'default' on stream 'SSH::LOG_SSH'
    1298063168.409852/1298063168.410865 [logging] Wrote record to filter 'default' on stream 'SSH::LOG_SSH'
    1298063168.409852/1298063168.410906 [logging] Wrote record to filter 'default' on stream 'SSH::LOG_SSH'
    1298063168.409852/1298063168.410945 [logging] Wrote record to filter 'default' on stream 'SSH::LOG_SSH'
    1298063168.409852/1298063168.411044 [logging] Wrote record to filter 'default' on stream 'SSH::LOG_SSH

> cat ssh_log_ssh.log
1298063168.40985        1.2.3.4 66770   2.3.4.5 65616   success unknown
1298063168.40985        1.2.3.4 66770   2.3.4.5 65616   failure US
1298063168.40985        1.2.3.4 66770   2.3.4.5 65616   failure UK
1298063168.40985        1.2.3.4 66770   2.3.4.5 65616   success BR
1298063168.40985        1.2.3.4 66770   2.3.4.5 65616   failure MX
This commit is contained in:
Robin Sommer 2011-02-18 13:03:46 -08:00
parent 9d407d882c
commit 68062e87f1
18 changed files with 1121 additions and 218 deletions

129
src/LogWriterAscii.cc Normal file
View file

@ -0,0 +1,129 @@
#include <string>
#include <errno.h>
#include "LogWriterAscii.h"
LogWriterAscii::LogWriterAscii()
{
fname = 0;
file = 0;
}
LogWriterAscii::~LogWriterAscii()
{
if ( fname )
free(fname);
if ( file )
fclose(file);
}
bool LogWriterAscii::DoInit(string path, int num_fields, LogField** fields)
{
fname = strdup(Fmt("%s.log", path.c_str()));
if ( ! (file = fopen(fname, "w")) )
{
Error(Fmt("cannot open %s: %s", fname, strerror(errno)));
return false;
}
if ( fputs("# ", file) == EOF )
goto write_error;
for ( int i = 0; i < num_fields; i++ )
{
LogField* field = fields[i];
if ( fputs(field->name.c_str(), file) == EOF )
goto write_error;
if ( fputc('\t', file) == EOF )
goto write_error;
}
if ( fputc('\n', file) == EOF )
goto write_error;
return true;
write_error:
Error(Fmt("error writing to %s: %s", fname, strerror(errno)));
return false;
}
void LogWriterAscii::DoFinish()
{
}
bool LogWriterAscii::DoWrite(int num_fields, LogField** fields, LogVal** vals)
{
ODesc desc(DESC_READABLE);
for ( int i = 0; i < num_fields; i++ )
{
if ( i > 0 )
desc.Add("\t");
LogVal* val = vals[i];
LogField* field = fields[i];
if ( ! val->present )
{
desc.Add("-"); // TODO: Probably want to get rid of the "-".
continue;
}
switch ( field->type ) {
case TYPE_BOOL:
desc.Add(val->val.int_val ? "T" : "F");
break;
case TYPE_INT:
case TYPE_ENUM:
desc.Add(val->val.int_val);
break;
case TYPE_COUNT:
case TYPE_COUNTER:
case TYPE_PORT:
desc.Add(val->val.uint_val);
break;
case TYPE_SUBNET:
desc.Add(dotted_addr(val->val.subnet_val.net));
desc.Add("/");
desc.Add(val->val.subnet_val.width);
break;
case TYPE_NET:
case TYPE_ADDR:
desc.Add(dotted_addr(val->val.addr_val));
break;
case TYPE_DOUBLE:
case TYPE_TIME:
case TYPE_INTERVAL:
desc.Add(val->val.double_val);
break;
case TYPE_STRING:
desc.AddN((const char*)&val->val.string_val.string, val->val.string_val.len);
break;
default:
Error(Fmt("unsupported field format %d for %s", field->type, field->name.c_str()));
return false;
}
}
desc.Add("\n");
if ( fwrite(desc.Bytes(), desc.Len(), 1, file) != 1 )
{
Error(Fmt("error writing to %s: %s", fname, strerror(errno)));
return false;
}
return true;
}