Change reporter messages to more reliably print to stderr.

Moved this functionality to be internal instead of in the script-layer
event handlers.  The issue with the later is that bad things can happen
between the time a reporter event handler is dispatched and the time it
is executed, and if bro crashes in that time, the message may never be
seen/logged.

Addressed #930 (and revisits #836).
This commit is contained in:
Jon Siwek 2013-01-18 12:46:00 -06:00
parent 2823744ea5
commit fdd11428c1
11 changed files with 90 additions and 64 deletions

View file

@ -27,6 +27,13 @@ Reporter::Reporter()
via_events = false;
in_error_handler = 0;
// Always use stderr at startup/init before scripts have been fully parsed.
// Messages may otherwise be missed if an error occurs that prevents events
// from ever being dispatched.
info_to_stderr = true;
warnings_to_stderr = true;
errors_to_stderr = true;
openlog("bro", 0, LOG_LOCAL5);
}
@ -35,11 +42,19 @@ Reporter::~Reporter()
closelog();
}
void Reporter::InitOptions()
{
info_to_stderr = internal_const_val("Reporter::info_to_stderr")->AsBool();
warnings_to_stderr = internal_const_val("Reporter::warnings_to_stderr")->AsBool();
errors_to_stderr = internal_const_val("Reporter::errors_to_stderr")->AsBool();
}
void Reporter::Info(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
DoLog("", reporter_info, stderr, 0, 0, true, true, 0, fmt, ap);
FILE* out = info_to_stderr ? stderr : 0;
DoLog("", reporter_info, out, 0, 0, true, true, 0, fmt, ap);
va_end(ap);
}
@ -47,7 +62,8 @@ void Reporter::Warning(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
DoLog("warning", reporter_warning, stderr, 0, 0, true, true, 0, fmt, ap);
FILE* out = warnings_to_stderr ? stderr : 0;
DoLog("warning", reporter_warning, out, 0, 0, true, true, 0, fmt, ap);
va_end(ap);
}
@ -56,7 +72,8 @@ void Reporter::Error(const char* fmt, ...)
++errors;
va_list ap;
va_start(ap, fmt);
DoLog("error", reporter_error, stderr, 0, 0, true, true, 0, fmt, ap);
FILE* out = errors_to_stderr ? stderr : 0;
DoLog("error", reporter_error, out, 0, 0, true, true, 0, fmt, ap);
va_end(ap);
}
@ -98,7 +115,9 @@ void Reporter::ExprRuntimeError(const Expr* expr, const char* fmt, ...)
PushLocation(expr->GetLocationInfo());
va_list ap;
va_start(ap, fmt);
DoLog("expression error", reporter_error, stderr, 0, 0, true, true, d.Description(), fmt, ap);
FILE* out = errors_to_stderr ? stderr : 0;
DoLog("expression error", reporter_error, out, 0, 0, true, true,
d.Description(), fmt, ap);
va_end(ap);
PopLocation();
throw InterpreterException();
@ -122,7 +141,9 @@ void Reporter::InternalWarning(const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
DoLog("internal warning", reporter_warning, stderr, 0, 0, true, true, 0, fmt, ap);
FILE* out = warnings_to_stderr ? stderr : 0;
DoLog("internal warning", reporter_warning, out, 0, 0, true, true, 0, fmt,
ap);
va_end(ap);
}
@ -189,7 +210,9 @@ void Reporter::Weird(const IPAddr& orig, const IPAddr& resp, const char* name)
WeirdFlowHelper(orig, resp, "%s", name);
}
void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Connection* conn, val_list* addl, bool location, bool time, const char* postfix, const char* fmt, va_list ap)
void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out,
Connection* conn, val_list* addl, bool location, bool time,
const char* postfix, const char* fmt, va_list ap)
{
static char tmp[512];
@ -298,7 +321,7 @@ void Reporter::DoLog(const char* prefix, EventHandlerPtr event, FILE* out, Conne
mgr.QueueEvent(event, vl);
}
else
if ( out )
{
string s = "";