diff --git a/scripts/base/frameworks/logging/main.bro b/scripts/base/frameworks/logging/main.bro index cc0d341605..79c9884f9d 100644 --- a/scripts/base/frameworks/logging/main.bro +++ b/scripts/base/frameworks/logging/main.bro @@ -96,6 +96,12 @@ export { ## file name. Generally, filenames are expected to given ## without any extensions; writers will add appropiate ## extensions automatically. + ## + ## If this path is found to conflict with another filter's + ## for the same writer type, it is automatically corrected + ## by appending "-N", where N is the smallest integer greater + ## or equal to 2 that allows the corrected path name to not + ## conflict with another filter's. path: string &optional; ## A function returning the output path for recording entries @@ -115,7 +121,10 @@ export { ## rec: An instance of the streams's ``columns`` type with its ## fields set to the values to be logged. ## - ## Returns: The path to be used for the filter. + ## Returns: The path to be used for the filter, which will be subject + ## to the same automatic correction rules as the *path* + ## field of :bro:type:`Log::Filter` in the case of conflicts + ## with other filters trying to use the same writer/path pair. path_func: function(id: ID, path: string, rec: any): string &optional; ## Subset of column names to record. If not given, all diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 3499d55f74..b1b289a478 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -758,22 +758,43 @@ bool Manager::Write(EnumVal* id, RecordVal* columns) #endif } + Stream::WriterPathPair wpp(filter->writer->AsEnum(), path); + // See if we already have a writer for this path. - Stream::WriterMap::iterator w = - stream->writers.find(Stream::WriterPathPair(filter->writer->AsEnum(), path)); + Stream::WriterMap::iterator w = stream->writers.find(wpp); + + if ( w != stream->writers.end() && + w->second->instantiating_filter != filter->name ) + { + // Auto-correct path due to conflict with another filter over the + // same writer/path pair + string instantiator = w->second->instantiating_filter; + string new_path; + unsigned int i = 2; + + do { + char num[32]; + snprintf(num, sizeof(num), "-%u", i++); + new_path = path + num; + wpp.second = new_path; + w = stream->writers.find(wpp); + } while ( w != stream->writers.end()); + + Unref(filter->path_val); + filter->path_val = new StringVal(new_path.c_str()); + + reporter->Warning("Write using filter '%s' on path '%s' changed to" + " use new path '%s' to avoid conflict with filter '%s'", + filter->name.c_str(), path.c_str(), new_path.c_str(), + instantiator.c_str()); + + path = filter->path = filter->path_val->AsString()->CheckString(); + } WriterFrontend* writer = 0; if ( w != stream->writers.end() ) { - if ( w->second->instantiating_filter != filter->name ) - { - reporter->Warning("Skipping write to filter '%s' on path '%s'" - " because filter '%s' has already instantiated the same" - " writer type for that path", filter->name.c_str(), - filter->path.c_str(), w->second->instantiating_filter.c_str()); - continue; - } // We know this writer already. writer = w->second->writer; } diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-2-2.log b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-2-2.log new file mode 100644 index 0000000000..1e41aca795 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-2-2.log @@ -0,0 +1,23 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http-2-2 +#start 2011-03-18-19-06-08 +#fields status_code +#types count +304 +304 +304 +304 +304 +304 +304 +304 +304 +304 +304 +304 +304 +304 +#end 2011-03-18-19-06-13 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-2.log b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-2.log new file mode 100644 index 0000000000..4d3622c7a0 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-2.log @@ -0,0 +1,23 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http-2 +#start 2011-03-18-19-06-08 +#fields host +#types string +bits.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +meta.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +upload.wikimedia.org +#end 2011-03-18-19-06-13 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-3.log b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-3.log new file mode 100644 index 0000000000..727a6c02fa --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/http-3.log @@ -0,0 +1,23 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path http-3 +#start 2011-03-18-19-06-08 +#fields uri +#types string +/skins-1.5/monobook/main.css +/wikipedia/commons/6/63/Wikipedia-logo.png +/wikipedia/commons/thumb/b/bb/Wikipedia_wordmark.svg/174px-Wikipedia_wordmark.svg.png +/wikipedia/commons/b/bd/Bookshelf-40x201_6.png +/wikipedia/commons/thumb/8/8a/Wikinews-logo.png/35px-Wikinews-logo.png +/wikipedia/commons/4/4a/Wiktionary-logo-en-35px.png +/wikipedia/commons/thumb/f/fa/Wikiquote-logo.svg/35px-Wikiquote-logo.svg.png +/images/wikimedia-button.png +/wikipedia/commons/thumb/f/fa/Wikibooks-logo.svg/35px-Wikibooks-logo.svg.png +/wikipedia/commons/thumb/d/df/Wikispecies-logo.svg/35px-Wikispecies-logo.svg.png +/wikipedia/commons/thumb/4/4c/Wikisource-logo.svg/35px-Wikisource-logo.svg.png +/wikipedia/commons/thumb/4/4a/Commons-logo.svg/35px-Commons-logo.svg.png +/wikipedia/commons/thumb/9/91/Wikiversity-logo.svg/35px-Wikiversity-logo.svg.png +/wikipedia/commons/thumb/7/75/Wikimedia_Community_Logo.svg/35px-Wikimedia_Community_Logo.svg.png +#end 2011-03-18-19-06-13 diff --git a/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/reporter.log b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/reporter.log index 7a4225d718..3514ca5134 100755 --- a/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/reporter.log +++ b/testing/btest/Baseline/scripts.base.frameworks.logging.writer-path-conflict/reporter.log @@ -6,18 +6,7 @@ #start 2011-03-18-19-06-08 #fields ts level message location #types time enum string string -1300475168.843894 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475168.975800 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475168.976327 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475168.979160 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.012666 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.012730 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.014860 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.022665 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.036294 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.036798 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.039923 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.074793 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.074938 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) -1300475169.075065 Reporter::WARNING Skipping write to filter 'host-only' on path 'http' because filter 'default' has already instantiated the same writer type for that path (empty) +1300475168.843894 Reporter::WARNING Write using filter 'host-only' on path 'http' changed to use new path 'http-2' to avoid conflict with filter 'default' (empty) +1300475168.843894 Reporter::WARNING Write using filter 'uri-only' on path 'http' changed to use new path 'http-3' to avoid conflict with filter 'default' (empty) +1300475168.843894 Reporter::WARNING Write using filter 'status-only' on path 'http-2' changed to use new path 'http-2-2' to avoid conflict with filter 'host-only' (empty) #end 2011-03-18-19-06-13 diff --git a/testing/btest/scripts/base/frameworks/logging/writer-path-conflict.bro b/testing/btest/scripts/base/frameworks/logging/writer-path-conflict.bro index be6c0e9e9e..908fb43c72 100644 --- a/testing/btest/scripts/base/frameworks/logging/writer-path-conflict.bro +++ b/testing/btest/scripts/base/frameworks/logging/writer-path-conflict.bro @@ -1,6 +1,9 @@ # @TEST-EXEC: bro -C -r $TRACES/wikipedia.trace %INPUT # @TEST-EXEC: btest-diff reporter.log # @TEST-EXEC: btest-diff http.log +# @TEST-EXEC: btest-diff http-2.log +# @TEST-EXEC: btest-diff http-3.log +# @TEST-EXEC: btest-diff http-2-2.log @load base/protocols/http @@ -8,7 +11,14 @@ event bro_init() { # Both the default filter for the http stream and this new one will # attempt to have the same writer write to path "http", which will - # be reported as a warning and the write skipped. + # be reported as a warning and the path auto-corrected to "http-2" local filter: Log::Filter = [$name="host-only", $include=set("host")]; + # Same deal here, but should be auto-corrected to "http-3". + local filter2: Log::Filter = [$name="uri-only", $include=set("uri")]; + # Conflict between auto-correct paths needs to be corrected, too, this + # time it will be "http-2-2". + local filter3: Log::Filter = [$path="http-2", $name="status-only", $include=set("status_code")]; Log::add_filter(HTTP::LOG, filter); + Log::add_filter(HTTP::LOG, filter2); + Log::add_filter(HTTP::LOG, filter3); }