Adding a few options to the ASCII writer.

module LogAscii;

export {
	# Output everything to stdout rather than into files. This is primarily
	# for testing purposes.
	const output_to_stdout = F &redef;

	# The separator between fields.
	const separator = "\t" &redef;

	# True to include a header line with column names.
	const include_header = T &redef;
}
This commit is contained in:
Robin Sommer 2011-03-08 21:43:52 -08:00
parent 26eab74ecc
commit c6d20dbfdf
9 changed files with 101 additions and 19 deletions

View file

@ -3,11 +3,8 @@ List of the things not implemented yet:
- Not sure if the logging does the right thing with &optional and - Not sure if the logging does the right thing with &optional and
&default values. Needs testing. &default values. Needs testing.
- Check the new event-value code. - Check the new event-value code.
- The Ascii writer doesn't escape the delimiter if it appears
- Configure Ascii Writer: within a field's value. Seems we need to do that.
- "redef LogAscii::output_to_stdout = T"
- "redef LogAscii::separator = '\t'"
- "redef LogAscii::headers = T"
Notes about remote logging: Notes about remote logging:

View file

@ -278,6 +278,7 @@ type entropy_test_result: record {
@load bro.bif.bro @load bro.bif.bro
@load logging # sic! Not logging.bif. @load logging # sic! Not logging.bif.
@load logging-ascii
global bro_alarm_file: file &redef; global bro_alarm_file: file &redef;
global alarm_hook: function(msg: string): bool &redef; global alarm_hook: function(msg: string): bool &redef;

15
policy/logging-ascii.bro Normal file
View file

@ -0,0 +1,15 @@
module LogAscii;
export {
# Output everything to stdout rather than into files. This is primarily
# for testing purposes.
const output_to_stdout = F &redef;
# The separator between fields.
const separator = "\t" &redef;
# True to include a header line with column names.
const include_header = T &redef;
}

View file

@ -3,7 +3,9 @@
// //
// Note than classes derived from LogWriter must be fully thread-safe and not // Note than classes derived from LogWriter must be fully thread-safe and not
// use any non-safe Bro functionality (which is almost all ...). In // use any non-safe Bro functionality (which is almost all ...). In
// particular, do not use fmt() but LogWriter::Fmt()!. // particular, do not use fmt() but LogWriter::Fmt()!. The one exception is
// the constructor: that is guaranteed to be executed inside the main thread
// and it can thus access in particular global script variables.
#ifndef LOGWRITER_H #ifndef LOGWRITER_H
#define LOGWRITER_H #define LOGWRITER_H

View file

@ -3,20 +3,30 @@
#include <errno.h> #include <errno.h>
#include "LogWriterAscii.h" #include "LogWriterAscii.h"
#include "NetVar.h"
LogWriterAscii::LogWriterAscii() LogWriterAscii::LogWriterAscii()
{ {
file = 0; file = 0;
output_to_stdout = BifConst::LogAscii::output_to_stdout;
include_header = BifConst::LogAscii::include_header;
separator = strdup(BifConst::LogAscii::separator->CheckString());
} }
LogWriterAscii::~LogWriterAscii() LogWriterAscii::~LogWriterAscii()
{ {
if ( file ) if ( file )
fclose(file); fclose(file);
free(separator);
} }
bool LogWriterAscii::DoInit(string path, int num_fields, const LogField* const * fields) bool LogWriterAscii::DoInit(string path, int num_fields, const LogField* const * fields)
{ {
if ( output_to_stdout )
path = "/dev/stdout";
fname = IsSpecial(path) ? path : path + ".log"; fname = IsSpecial(path) ? path : path + ".log";
if ( ! (file = fopen(fname.c_str(), "w")) ) if ( ! (file = fopen(fname.c_str(), "w")) )
@ -25,6 +35,8 @@ bool LogWriterAscii::DoInit(string path, int num_fields, const LogField* const *
return false; return false;
} }
if ( include_header )
{
if ( fputs("# ", file) == EOF ) if ( fputs("# ", file) == EOF )
goto write_error; goto write_error;
@ -34,12 +46,13 @@ bool LogWriterAscii::DoInit(string path, int num_fields, const LogField* const *
if ( fputs(field->name.c_str(), file) == EOF ) if ( fputs(field->name.c_str(), file) == EOF )
goto write_error; goto write_error;
if ( fputc('\t', file) == EOF ) if ( fputs(separator, file) == EOF )
goto write_error; goto write_error;
} }
if ( fputc('\n', file) == EOF ) if ( fputc('\n', file) == EOF )
goto write_error; goto write_error;
}
return true; return true;
@ -65,7 +78,7 @@ bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, Log
for ( int i = 0; i < num_fields; i++ ) for ( int i = 0; i < num_fields; i++ )
{ {
if ( i > 0 ) if ( i > 0 )
desc.Add("\t"); desc.Add(separator);
LogVal* val = vals[i]; LogVal* val = vals[i];
const LogField* field = fields[i]; const LogField* field = fields[i];
@ -135,7 +148,7 @@ bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, Log
bool LogWriterAscii::DoRotate(string rotated_path, string postprocessor, double open, double close, bool terminating) bool LogWriterAscii::DoRotate(string rotated_path, string postprocessor, double open, double close, bool terminating)
{ {
if ( ! IsSpecial(Path()) ) if ( IsSpecial(Path()) )
// Don't rotate special files. // Don't rotate special files.
return true; return true;

View file

@ -27,6 +27,11 @@ private:
FILE* file; FILE* file;
string fname; string fname;
// Options from the script-level
bool output_to_stdout;
bool include_header;
char* separator;
}; };
#endif #endif

View file

@ -11,7 +11,7 @@ type Stream: record;
type RotationInfo: record; type RotationInfo: record;
type RotationControl: record; type RotationControl: record;
const Log::rotation_control : RotationControl; 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
%{ %{
@ -60,3 +60,12 @@ function Log::__flush%(id: Log::ID%): bool
bool result = log_mgr->Flush(id->AsEnumVal()); bool result = log_mgr->Flush(id->AsEnumVal());
return new Val(result, TYPE_BOOL); return new Val(result, TYPE_BOOL);
%} %}
# Options for the ASCII writer.
module LogAscii;
const output_to_stdout: bool;
const separator: string;
const include_header: bool;

View file

@ -0,0 +1,5 @@
1299649281.43936|1.2.3.4|1234|2.3.4.5|80|success|unknown
1299649281.43936|1.2.3.4|1234|2.3.4.5|80|failure|US
1299649281.43936|1.2.3.4|1234|2.3.4.5|80|failure|UK
1299649281.43936|1.2.3.4|1234|2.3.4.5|80|success|BR
1299649281.43936|1.2.3.4|1234|2.3.4.5|80|failure|MX

View file

@ -0,0 +1,35 @@
#
# @TEST-EXEC: bro %INPUT >output
# @TEST-EXEC: btest-diff output
redef LogAscii::output_to_stdout = T;
redef LogAscii::separator = "|";
redef LogAscii::include_header = F;
module SSH;
export {
redef enum Log::ID += { SSH };
type Log: record {
t: time;
id: conn_id; # Will be rolled out into individual columns.
status: string &optional;
country: string &default="unknown";
};
}
event bro_init()
{
Log::create_stream(SSH, [$columns=Log]);
local cid = [$orig_h=1.2.3.4, $orig_p=1234/tcp, $resp_h=2.3.4.5, $resp_p=80/tcp];
Log::write(SSH, [$t=network_time(), $id=cid, $status="success"]);
Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="US"]);
Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="UK"]);
Log::write(SSH, [$t=network_time(), $id=cid, $status="success", $country="BR"]);
Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="MX"]);
}