Overhauling the internal reporting of messages to the user.

The Logger class is now in charge of reporting all errors, warnings,
informational messages, weirds, and syslogs. All other components
route their messages through the global bro_logger singleton.

The Logger class comes with these reporting methods:

    void Message(const char* fmt, ...);
    void Warning(const char* fmt, ...);
    void Error(const char* fmt, ...);
    void FatalError(const char* fmt, ...); // Terminate Bro.
    void Weird(const char* name);
    [ .. some more Weird() variants ... ]
    void Syslog(const char* fmt, ...);
    void InternalWarning(const char* fmt, ...);
    void InternalError(const char* fmt, ...); // Terminates Bro.

See Logger.h for more information on these.

Generally, the reporting now works as follows:

    - All non-fatal message are reported in one of two ways:

        (1) At startup (i.e., before we start processing packets),
            they are logged to stderr.

        (2) During processing, they turn into events:

            event log_message%(msg: string, location: string%);
            event log_warning%(msg: string, location: string%);
            event log_error%(msg: string, location: string%);

            The script level can then handle them as desired.

            If we don't have an event handler, we fall back to
            reporting on stderr.

    - All fatal errors are logged to stderr and Bro terminates
      immediately.

    - Syslog(msg) directly syslogs, but doesn't do anything else.

The three main types of messages can also be generated on the
scripting layer via new Log::* bifs:

    Log::error(msg: string);
    Log::warning(msg: string);
    Log::message(msg: string);

These pass through the bro_logger as well and thus are handled in the
same way. Their output includes location information.

More changes:

    - Removed the alarm statement and the alarm_hook event.

    - Adapted lots of locations to use the bro_logger, including some
      of the messages that were previously either just written to
      stdout, or even funneled through the alarm mechanism.

    - No distinction anymore between Error() and RunTime(). There's
      now only one class of errors; the line was quite blurred already
      anyway.

    - util.h: all the error()/warn()/message()/run_time()/pinpoint()
      functions are gone. Use the bro_logger instead now.

    - Script errors are formatted a bit differently due to the
      changes. What I've seen so far looks ok to me, but let me know
      if there's something odd.

Notes:

    - The default handlers for the new log_* events are just dummy
      implementations for now since we need to integrate all this into
      the new scripts anyway.

    - I'm not too happy with the names of the Logger class and its
      instance bro_logger. We now have a LogMgr as well, which makes
      this all a bit confusing. But I didn't have a good idea for
      better names so I stuck with them for now.

      Perhaps we should merge Logger and LogMgr?
This commit is contained in:
Robin Sommer 2011-06-24 21:33:05 -07:00
parent ff7b92ffc8
commit 93894eed9b
140 changed files with 2453 additions and 1054 deletions

View file

@ -30,6 +30,7 @@
#include "Net.h"
#include "Serializer.h"
#include "Event.h"
#include "Logger.h"
// Timer which on dispatching rotates the file.
class RotateTimer : public Timer {
@ -93,7 +94,7 @@ static int maximize_num_fds()
#else
struct rlimit rl;
if ( getrlimit(RLIMIT_NOFILE, &rl) < 0 )
internal_error("maximize_num_fds(): getrlimit failed");
bro_logger->InternalError("maximize_num_fds(): getrlimit failed");
if ( rl.rlim_max == RLIM_INFINITY )
{
@ -109,7 +110,7 @@ static int maximize_num_fds()
rl.rlim_cur = rl.rlim_max;
if ( setrlimit(RLIMIT_NOFILE, &rl) < 0 )
internal_error("maximize_num_fds(): setrlimit failed");
bro_logger->InternalError("maximize_num_fds(): setrlimit failed");
return rl.rlim_cur / 2;
#endif
@ -150,7 +151,7 @@ BroFile::BroFile(const char* arg_name, const char* arg_access, BroType* arg_t)
t = arg_t ? arg_t : base_type(TYPE_STRING);
if ( ! Open() )
{
error(fmt("cannot open %s: %s", name, strerror(errno)));
bro_logger->Error(fmt("cannot open %s: %s", name, strerror(errno)));
is_open = 0;
okay_to_manage = 0;
}
@ -272,7 +273,7 @@ FILE* BroFile::File()
FILE* BroFile::BringIntoCache()
{
if ( f )
internal_error("BroFile non-nil non-open file");
bro_logger->InternalError("BroFile non-nil non-open file");
if ( num_files_in_cache >= max_files_in_cache )
PurgeCache();
@ -286,12 +287,12 @@ FILE* BroFile::BringIntoCache()
if ( ! f )
{
run_time("can't open %s", this);
bro_logger->Error("can't open %s", this);
f = fopen("/dev/null", "w");
if ( ! f )
internal_error("out of file descriptors");
bro_logger->InternalError("out of file descriptors");
okay_to_manage = 0;
return f;
@ -301,7 +302,7 @@ FILE* BroFile::BringIntoCache()
UpdateFileSize();
if ( fseek(f, position, SEEK_SET) < 0 )
run_time("reopen seek failed", this);
bro_logger->Error("reopen seek failed", this);
InsertAtBeginning();
@ -314,7 +315,7 @@ FILE* BroFile::Seek(long new_position)
return 0;
if ( fseek(f, new_position, SEEK_SET) < 0 )
run_time("seek failed", this);
bro_logger->Error("seek failed", this);
return f;
}
@ -325,7 +326,7 @@ void BroFile::SetBuf(bool arg_buffered)
return;
if ( setvbuf(f, NULL, arg_buffered ? _IOFBF : _IOLBF, 0) != 0 )
run_time("setvbuf failed", this);
bro_logger->Error("setvbuf failed", this);
buffered = arg_buffered;
}
@ -376,18 +377,18 @@ int BroFile::Close()
void BroFile::Suspend()
{
if ( ! is_in_cache )
internal_error("BroFile::Suspend() called for non-cached file");
bro_logger->InternalError("BroFile::Suspend() called for non-cached file");
if ( ! is_open )
internal_error("BroFile::Suspend() called for non-open file");
bro_logger->InternalError("BroFile::Suspend() called for non-open file");
Unlink();
if ( ! f )
internal_error("BroFile::Suspend() called for nil file");
bro_logger->InternalError("BroFile::Suspend() called for nil file");
if ( (position = ftell(f)) < 0 )
{
run_time("ftell failed", this);
bro_logger->Error("ftell failed", this);
position = 0;
}
@ -398,7 +399,7 @@ void BroFile::Suspend()
void BroFile::PurgeCache()
{
if ( ! tail )
internal_error("BroFile purge of empty cache");
bro_logger->InternalError("BroFile purge of empty cache");
tail->Suspend();
}
@ -418,13 +419,13 @@ void BroFile::Unlink()
Next()->SetPrev(prev);
if ( (head || tail) && ! (head && tail) )
internal_error("BroFile link list botch");
bro_logger->InternalError("BroFile link list botch");
is_in_cache = 0;
prev = next = 0;
if ( --num_files_in_cache < 0 )
internal_error("BroFile underflow of file cache");
bro_logger->InternalError("BroFile underflow of file cache");
}
}
@ -444,7 +445,7 @@ void BroFile::InsertAtBeginning()
}
if ( ++num_files_in_cache > max_files_in_cache )
internal_error("BroFile overflow of file cache");
bro_logger->InternalError("BroFile overflow of file cache");
is_in_cache = 1;
}
@ -455,7 +456,7 @@ void BroFile::MoveToBeginning()
return; // already at the beginning
if ( ! is_in_cache || ! prev )
internal_error("BroFile inconsistency in MoveToBeginning()");
bro_logger->InternalError("BroFile inconsistency in MoveToBeginning()");
Unlink();
InsertAtBeginning();
@ -642,7 +643,7 @@ void BroFile::InitEncrypt(const char* keyfile)
if ( ! key )
{
error(fmt("can't open key file %s: %s", keyfile, strerror(errno)));
bro_logger->Error(fmt("can't open key file %s: %s", keyfile, strerror(errno)));
Close();
return;
}
@ -650,7 +651,7 @@ void BroFile::InitEncrypt(const char* keyfile)
pub_key = PEM_read_PUBKEY(key, 0, 0, 0);
if ( ! pub_key )
{
error(fmt("can't read key from %s: %s", keyfile,
bro_logger->Error(fmt("can't read key from %s: %s", keyfile,
ERR_error_string(ERR_get_error(), 0)));
Close();
return;
@ -672,7 +673,7 @@ void BroFile::InitEncrypt(const char* keyfile)
if ( ! EVP_SealInit(cipher_ctx, cipher_type, &psecret,
(int*) &secret_len, iv, &pub_key, 1) )
{
error(fmt("can't init cipher context for %s: %s", keyfile,
bro_logger->Error(fmt("can't init cipher context for %s: %s", keyfile,
ERR_error_string(ERR_get_error(), 0)));
Close();
return;
@ -685,7 +686,7 @@ void BroFile::InitEncrypt(const char* keyfile)
fwrite(secret, ntohl(secret_len), 1, f) &&
fwrite(iv, iv_len, 1, f)) )
{
error(fmt("can't write header to log file %s: %s",
bro_logger->Error(fmt("can't write header to log file %s: %s",
name, strerror(errno)));
Close();
return;
@ -710,7 +711,7 @@ void BroFile::FinishEncrypt()
if ( outl && ! fwrite(cipher_buffer, outl, 1, f) )
{
run_time(fmt("write error for %s: %s",
bro_logger->Error(fmt("write error for %s: %s",
name, strerror(errno)));
return;
}
@ -742,7 +743,7 @@ int BroFile::Write(const char* data, int len)
if ( ! EVP_SealUpdate(cipher_ctx, cipher_buffer, &outl,
(unsigned char*)data, inl) )
{
run_time(fmt("encryption error for %s: %s",
bro_logger->Error(fmt("encryption error for %s: %s",
name,
ERR_error_string(ERR_get_error(), 0)));
Close();
@ -751,7 +752,7 @@ int BroFile::Write(const char* data, int len)
if ( outl && ! fwrite(cipher_buffer, outl, 1, f) )
{
run_time(fmt("write error for %s: %s",
bro_logger->Error(fmt("write error for %s: %s",
name, strerror(errno)));
Close();
return 0;
@ -799,7 +800,7 @@ void BroFile::UpdateFileSize()
struct stat s;
if ( fstat(fileno(f), &s) < 0 )
{
run_time(fmt("can't stat fd for %s: %s", name, strerror(errno)));
bro_logger->Error(fmt("can't stat fd for %s: %s", name, strerror(errno)));
current_size = 0;
return;
}