From b69ecff3ee58d38f0fb2fd5457b4531498d27b36 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Wed, 9 Mar 2011 16:52:46 -0800 Subject: [PATCH] More options for the ASCII writer. # The prefix for the header line if included. const header_prefix = "# " &redef; # The string to use for empty string fields. const empty_field = "" &redef; # The string to use for an unset optional field. const unset_field = "-" &redef; --- policy/logging-ascii.bro | 14 ++++++- src/LogWriterAscii.cc | 27 +++++++++++-- src/LogWriterAscii.h | 10 +++++ src/logging.bif | 5 ++- .../btest/Baseline/logging.ascii-empty/output | 6 +++ testing/btest/logging/ascii-empty.bro | 38 +++++++++++++++++++ testing/btest/logging/ascii-escape.bro | 3 +- 7 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/logging.ascii-empty/output create mode 100644 testing/btest/logging/ascii-empty.bro diff --git a/policy/logging-ascii.bro b/policy/logging-ascii.bro index 0cabeae940..151d29de99 100644 --- a/policy/logging-ascii.bro +++ b/policy/logging-ascii.bro @@ -6,10 +6,20 @@ export { # for testing purposes. const output_to_stdout = F &redef; + # True to include a header line with column names. + const include_header = T &redef; + + # The prefix for the header line if included. + const header_prefix = "# " &redef; + # The separator between fields. const separator = "\t" &redef; - # True to include a header line with column names. - const include_header = T &redef; + # The string to use for empty string fields. + const empty_field = "" &redef; + + # The string to use for an unset optional field. + const unset_field = "-" &redef; } + diff --git a/src/LogWriterAscii.cc b/src/LogWriterAscii.cc index 050616efd4..71bd0cf2e0 100644 --- a/src/LogWriterAscii.cc +++ b/src/LogWriterAscii.cc @@ -15,6 +15,18 @@ LogWriterAscii::LogWriterAscii() separator_len = BifConst::LogAscii::separator->Len(); separator = new char[separator_len]; memcpy(separator, BifConst::LogAscii::separator->Bytes(), separator_len); + + empty_field_len = BifConst::LogAscii::empty_field->Len(); + empty_field = new char[empty_field_len]; + memcpy(empty_field, BifConst::LogAscii::empty_field->Bytes(), empty_field_len); + + unset_field_len = BifConst::LogAscii::unset_field->Len(); + unset_field = new char[unset_field_len]; + memcpy(unset_field, BifConst::LogAscii::unset_field->Bytes(), unset_field_len); + + header_prefix_len = BifConst::LogAscii::header_prefix->Len(); + header_prefix = new char[header_prefix_len]; + memcpy(header_prefix, BifConst::LogAscii::header_prefix->Bytes(), header_prefix_len); } LogWriterAscii::~LogWriterAscii() @@ -23,6 +35,9 @@ LogWriterAscii::~LogWriterAscii() fclose(file); delete [] separator; + delete [] empty_field; + delete [] unset_field; + delete [] header_prefix; } bool LogWriterAscii::DoInit(string path, int num_fields, const LogField* const * fields) @@ -40,7 +55,7 @@ bool LogWriterAscii::DoInit(string path, int num_fields, const LogField* const * if ( include_header ) { - if ( fputs("# ", file) == EOF ) + if ( fwrite(header_prefix, header_prefix_len, 1, file) != 1 ) goto write_error; for ( int i = 0; i < num_fields; i++ ) @@ -89,7 +104,7 @@ bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, Log if ( ! val->present ) { - desc.Add("-"); // TODO: Probably want to get rid of the "-". + desc.AddN(unset_field, unset_field_len); continue; } @@ -127,8 +142,14 @@ bool LogWriterAscii::DoWrite(int num_fields, const LogField* const * fields, Log break; case TYPE_STRING: - desc.AddN(val->val.string_val->data(), val->val.string_val->size()); + { + int size = val->val.string_val->size(); + if ( size ) + desc.AddN(val->val.string_val->data(), val->val.string_val->size()); + else + desc.AddN(empty_field, empty_field_len); break; + } default: Error(Fmt("unsupported field format %d for %s", field->type, field->name.c_str())); diff --git a/src/LogWriterAscii.h b/src/LogWriterAscii.h index 04968e1a8b..384be65f19 100644 --- a/src/LogWriterAscii.h +++ b/src/LogWriterAscii.h @@ -31,8 +31,18 @@ private: // Options from the script-level bool output_to_stdout; bool include_header; + char* separator; int separator_len; + + char* empty_field; + int empty_field_len; + + char* unset_field; + int unset_field_len; + + char* header_prefix; + int header_prefix_len; }; #endif diff --git a/src/logging.bif b/src/logging.bif index 2095264910..2eb8eea35b 100644 --- a/src/logging.bif +++ b/src/logging.bif @@ -66,6 +66,9 @@ function Log::__flush%(id: Log::ID%): bool module LogAscii; const output_to_stdout: bool; -const separator: string; const include_header: bool; +const header_prefix: string; +const separator: string; +const empty_field: string; +const unset_field: string; diff --git a/testing/btest/Baseline/logging.ascii-empty/output b/testing/btest/Baseline/logging.ascii-empty/output new file mode 100644 index 0000000000..1a7ada05ae --- /dev/null +++ b/testing/btest/Baseline/logging.ascii-empty/output @@ -0,0 +1,6 @@ +PREFIX<>t|id.orig_h|id.orig_p|id.resp_h|id.resp_p|status|country|b| +1299718338.37017|1.2.3.4|1234|2.3.4.5|80|success|unknown|NOT-SET +1299718338.37017|1.2.3.4|1234|2.3.4.5|80|NOT-SET|US|NOT-SET +1299718338.37017|1.2.3.4|1234|2.3.4.5|80|failure|UK|NOT-SET +1299718338.37017|1.2.3.4|1234|2.3.4.5|80|NOT-SET|BR|NOT-SET +1299718338.37017|1.2.3.4|1234|2.3.4.5|80|failure|EMPTY|T diff --git a/testing/btest/logging/ascii-empty.bro b/testing/btest/logging/ascii-empty.bro new file mode 100644 index 0000000000..62022107f0 --- /dev/null +++ b/testing/btest/logging/ascii-empty.bro @@ -0,0 +1,38 @@ +# +# @TEST-EXEC: bro %INPUT >output +# @TEST-EXEC: btest-diff output + +redef LogAscii::output_to_stdout = T; +redef LogAscii::separator = "|"; +redef LogAscii::empty_field = "EMPTY"; +redef LogAscii::unset_field = "NOT-SET"; +redef LogAscii::header_prefix = "PREFIX<>"; + +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"; + b: bool &optional; + }; +} + +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, $country="US"]); + Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="UK"]); + Log::write(SSH, [$t=network_time(), $id=cid, $country="BR"]); + Log::write(SSH, [$t=network_time(), $id=cid, $b=T, $status="failure", $country=""]); + +} + diff --git a/testing/btest/logging/ascii-escape.bro b/testing/btest/logging/ascii-escape.bro index 1789c1bb63..f5c50c60bd 100644 --- a/testing/btest/logging/ascii-escape.bro +++ b/testing/btest/logging/ascii-escape.bro @@ -27,7 +27,6 @@ event bro_init() Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="US"]); Log::write(SSH, [$t=network_time(), $id=cid, $status="fa||ure", $country="UK"]); Log::write(SSH, [$t=network_time(), $id=cid, $status="su||ess", $country="BR"]); - Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="MX"]); - + Log::write(SSH, [$t=network_time(), $id=cid, $status="failure", $country="MX"]); }