mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00
Consistent error handling.
This commit is contained in:
parent
cf148c8a25
commit
ac936feb95
5 changed files with 92 additions and 40 deletions
14
TODO.logging
14
TODO.logging
|
@ -1,21 +1,17 @@
|
||||||
List of the things not implemented yet:
|
List of the things not implemented yet:
|
||||||
|
|
||||||
- Cluster-style remote_print
|
- Cluster-style remote_print.
|
||||||
- Rotation support
|
- Rotation support.
|
||||||
- Spawning writers in separate threads (not clear if we want that initially).
|
|
||||||
- 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.
|
||||||
- Seems we could do some of the filter-related type checks
|
|
||||||
currently done dynamically at startup via a TraversalCallback.
|
|
||||||
- LogMgs' error handling
|
|
||||||
- Put script function/constants into namespace.
|
- Put script function/constants into namespace.
|
||||||
|
- Some typchecks are still missing.
|
||||||
- Cleanup code.
|
- Cleanup code.
|
||||||
|
- Spawning writers in separate threads (not clear if we want that initially).
|
||||||
There's probably more missing.
|
|
||||||
|
|
||||||
Questions:
|
Questions:
|
||||||
|
|
||||||
* Is giving the record column twice to create_stream too
|
* Is giving the record column twice to create_stream() too
|
||||||
redundant? (once directly, and once via the event)::
|
redundant? (once directly, and once via the event)::
|
||||||
|
|
||||||
global ssh_log: event(rec: Log);
|
global ssh_log: event(rec: Log);
|
||||||
|
|
|
@ -89,6 +89,28 @@ LogMgr::Stream* LogMgr::FindStream(EnumVal* stream_id)
|
||||||
return streams[idx];
|
return streams[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogMgr::RemoveDisabledWriters(Stream* stream)
|
||||||
|
{
|
||||||
|
for ( list<Filter*>::iterator i = stream->filters.begin(); i != stream->filters.end(); ++i )
|
||||||
|
{
|
||||||
|
Filter* filter = (*i);
|
||||||
|
|
||||||
|
list<string> disabled;
|
||||||
|
|
||||||
|
for ( Filter::WriterMap::iterator j = filter->writers.begin(); j != filter->writers.end(); j++ )
|
||||||
|
{
|
||||||
|
if ( j->second->Disabled() )
|
||||||
|
{
|
||||||
|
delete j->second;
|
||||||
|
disabled.push_back(j->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( list<string>::iterator j = disabled.begin(); j != disabled.end(); j++ )
|
||||||
|
filter->writers.erase(*j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool LogMgr::CreateStream(EnumVal* stream_id, RecordType* columns, EventHandlerPtr handler)
|
bool LogMgr::CreateStream(EnumVal* stream_id, RecordType* columns, EventHandlerPtr handler)
|
||||||
{
|
{
|
||||||
// TODO: Should check that the record has only supported types.
|
// TODO: Should check that the record has only supported types.
|
||||||
|
@ -349,6 +371,8 @@ bool LogMgr::RemoveFilter(EnumVal* stream_id, StringVal* filter)
|
||||||
|
|
||||||
bool LogMgr::Write(EnumVal* stream_id, RecordVal* columns)
|
bool LogMgr::Write(EnumVal* stream_id, RecordVal* columns)
|
||||||
{
|
{
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
Stream* stream = FindStream(stream_id);
|
Stream* stream = FindStream(stream_id);
|
||||||
if ( ! stream )
|
if ( ! stream )
|
||||||
return false;
|
return false;
|
||||||
|
@ -440,7 +464,8 @@ bool LogMgr::Write(EnumVal* stream_id, RecordVal* columns)
|
||||||
|
|
||||||
// Alright, can do the write now.
|
// Alright, can do the write now.
|
||||||
LogVal** vals = RecordToFilterVals(filter, columns);
|
LogVal** vals = RecordToFilterVals(filter, columns);
|
||||||
writer->Write(vals);
|
if ( ! writer->Write(vals) )
|
||||||
|
error = true;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DBG_LOG(DBG_LOGGING, "Wrote record to filter '%s' on stream '%s'", filter->name.c_str(), stream->name.c_str());
|
DBG_LOG(DBG_LOGGING, "Wrote record to filter '%s' on stream '%s'", filter->name.c_str(), stream->name.c_str());
|
||||||
|
@ -448,6 +473,10 @@ bool LogMgr::Write(EnumVal* stream_id, RecordVal* columns)
|
||||||
}
|
}
|
||||||
|
|
||||||
Unref(columns);
|
Unref(columns);
|
||||||
|
|
||||||
|
if ( error )
|
||||||
|
RemoveDisabledWriters(stream);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,9 +574,12 @@ bool LogMgr::SetBuf(EnumVal* stream_id, bool enabled)
|
||||||
j->second->SetBuf(enabled);
|
j->second->SetBuf(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RemoveDisabledWriters(stream);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogMgr::Error(LogWriter* writer, const char* msg)
|
void LogMgr::Error(LogWriter* writer, const char* msg)
|
||||||
{
|
{
|
||||||
|
run_time(fmt("error with writer for %s: %s", writer->Path().c_str(), msg));
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ private:
|
||||||
bool TraverseRecord(Filter* filter, RecordType* rt, TableVal* include, TableVal* exclude, string path, list<int> indices);
|
bool TraverseRecord(Filter* filter, RecordType* rt, TableVal* include, TableVal* exclude, string path, list<int> indices);
|
||||||
LogVal** RecordToFilterVals(Filter* filter, RecordVal* columns);
|
LogVal** RecordToFilterVals(Filter* filter, RecordVal* columns);
|
||||||
Stream* FindStream(EnumVal* stream_id);
|
Stream* FindStream(EnumVal* stream_id);
|
||||||
|
void RemoveDisabledWriters(Stream* stream);
|
||||||
|
|
||||||
vector<Stream *> streams; // Indexed by stream enum.
|
vector<Stream *> streams; // Indexed by stream enum.
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,6 +7,7 @@ LogWriter::LogWriter()
|
||||||
buf = 0;
|
buf = 0;
|
||||||
buf_len = 1024;
|
buf_len = 1024;
|
||||||
buffering = true;
|
buffering = true;
|
||||||
|
disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogWriter::~LogWriter()
|
LogWriter::~LogWriter()
|
||||||
|
@ -22,7 +23,13 @@ bool LogWriter::Init(string arg_path, int arg_num_fields, LogField** arg_fields)
|
||||||
path = arg_path;
|
path = arg_path;
|
||||||
num_fields = arg_num_fields;
|
num_fields = arg_num_fields;
|
||||||
fields = arg_fields;
|
fields = arg_fields;
|
||||||
DoInit(arg_path, arg_num_fields, arg_fields);
|
|
||||||
|
if ( ! DoInit(arg_path, arg_num_fields, arg_fields) )
|
||||||
|
{
|
||||||
|
disabled = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,12 +37,11 @@ bool LogWriter::Write(LogVal** vals)
|
||||||
{
|
{
|
||||||
bool result = DoWrite(num_fields, fields, vals);
|
bool result = DoWrite(num_fields, fields, vals);
|
||||||
DeleteVals(vals);
|
DeleteVals(vals);
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogWriter::Finish()
|
if ( ! result )
|
||||||
{
|
disabled = true;
|
||||||
DoFinish();
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LogWriter::SetBuf(bool enabled)
|
bool LogWriter::SetBuf(bool enabled)
|
||||||
|
@ -45,7 +51,18 @@ bool LogWriter::SetBuf(bool enabled)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
buffering = enabled;
|
buffering = enabled;
|
||||||
return DoSetBuf(enabled);
|
if ( ! DoSetBuf(enabled) )
|
||||||
|
{
|
||||||
|
disabled = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogWriter::Finish()
|
||||||
|
{
|
||||||
|
DoFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* LogWriter::Fmt(const char* format, ...)
|
const char* LogWriter::Fmt(const char* format, ...)
|
||||||
|
@ -72,10 +89,9 @@ const char* LogWriter::Fmt(const char* format, ...)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LogWriter::Error(const char *msg)
|
void LogWriter::Error(const char *msg)
|
||||||
{
|
{
|
||||||
run_time(msg);
|
log_mgr->Error(this, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogWriter::DeleteVals(LogVal** vals)
|
void LogWriter::DeleteVals(LogVal** vals)
|
||||||
|
|
|
@ -31,38 +31,38 @@ public:
|
||||||
// occured, in which case the writer must not be used further.
|
// occured, in which case the writer must not be used further.
|
||||||
bool Write(LogVal** vals);
|
bool Write(LogVal** vals);
|
||||||
|
|
||||||
|
// Sets the buffering status for the writer, if the writer supports
|
||||||
|
bool SetBuf(bool enabled);
|
||||||
|
|
||||||
// Finished writing to this logger. Will not be called if an error has
|
// Finished writing to this logger. Will not be called if an error has
|
||||||
// been indicated earlier. After calling this, no more writing must be
|
// been indicated earlier. After calling this, no more writing must be
|
||||||
// performed.
|
// performed.
|
||||||
void Finish();
|
void Finish();
|
||||||
|
|
||||||
// Sets the buffering status for the writer, if the writer supports
|
|
||||||
bool SetBuf(bool enabled);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//// Methods for Writers to override.
|
// Methods for Writers to override. If any of these returs false, it will
|
||||||
|
// be assumed that a fatal error has occured that prevents the writer
|
||||||
|
// from further operation. It will then be disabled and deleted. In that
|
||||||
|
// case, the writer should also report the error via Error(). If a writer
|
||||||
|
// does not specifically implement one of the methods, it must still
|
||||||
|
// always return true.
|
||||||
|
|
||||||
// Called once for initialization of the Writer. Must return false if an
|
// Called once for initialization of the Writer.
|
||||||
// error occured, in which case the writer will be disabled. The error
|
|
||||||
// reason should be reported via Error().
|
|
||||||
virtual bool DoInit(string path, int num_fields, LogField** fields) = 0;
|
virtual bool DoInit(string path, int num_fields, LogField** fields) = 0;
|
||||||
|
|
||||||
// Called once per entry to record. Must return false if an error
|
// Called once per entry to record.
|
||||||
// occured, in which case the writer will be disabled. The error reason
|
|
||||||
// should be reported via Error().
|
|
||||||
virtual bool DoWrite(int num_fields, LogField** fields, LogVal** vals) = 0;
|
virtual bool DoWrite(int num_fields, LogField** fields, LogVal** vals) = 0;
|
||||||
|
|
||||||
// Called when the buffering status for this writer is changed. If
|
// Called when the buffering status for this writer is changed. If
|
||||||
// buffering is disabled, the writer should attempt to write out
|
// buffering is disabled, the writer should attempt to write out
|
||||||
// information as quickly as possible even if that may have an
|
// information as quickly as possible even if doing so may have an
|
||||||
// performance impact. If enabled (which the writer should assume to be
|
// performance impact. If enabled (which is the default), it can buffer
|
||||||
// the default), then it can buffer things up as necessary and write out
|
// things up as necessary and write out in a way optimized for
|
||||||
// in a way optimized for performance. The current buffering state can
|
// performance. The current buffering state can be queried via IsBuf().
|
||||||
// alse be queried via IsBuf().
|
|
||||||
//
|
//
|
||||||
// A writer may ignore buffering if it doesn't fit with its semantics.
|
// A writer may ignore buffering changes if it doesn't fit with its
|
||||||
// Still return true in that case.
|
// semantics.
|
||||||
virtual bool DoSetBuf(bool enabled) = 0;
|
virtual bool DoSetBuf(bool enabled) = 0;
|
||||||
|
|
||||||
// Called when a log output is to be rotated. Most directly, this only
|
// Called when a log output is to be rotated. Most directly, this only
|
||||||
|
@ -83,7 +83,7 @@ protected:
|
||||||
// still call Error(), but return true.
|
// still call Error(), but return true.
|
||||||
//
|
//
|
||||||
// A writer may ignore rotation requests if it doesn't fit with its
|
// A writer may ignore rotation requests if it doesn't fit with its
|
||||||
// semantics. In that case, still return true.
|
// semantics.
|
||||||
virtual bool DoRotate(string rotated_path) = 0;
|
virtual bool DoRotate(string rotated_path) = 0;
|
||||||
|
|
||||||
// Called once on termination. Not called when any of the other methods
|
// Called once on termination. Not called when any of the other methods
|
||||||
|
@ -106,13 +106,20 @@ protected:
|
||||||
const string Path() const { return path; }
|
const string Path() const { return path; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Delete values as passed into Write().
|
friend class LogMgr;
|
||||||
|
|
||||||
|
// When an error occurs, we set this flag. The LogMgr will check it an
|
||||||
|
// remove any disabled writers.
|
||||||
|
bool Disabled() { return disabled; }
|
||||||
|
|
||||||
|
// Deletes the values passed into Write().
|
||||||
void DeleteVals(LogVal** vals);
|
void DeleteVals(LogVal** vals);
|
||||||
|
|
||||||
string path;
|
string path;
|
||||||
int num_fields;
|
int num_fields;
|
||||||
LogField** fields;
|
LogField** fields;
|
||||||
bool buffering;
|
bool buffering;
|
||||||
|
bool disabled;
|
||||||
|
|
||||||
// For Fmt().
|
// For Fmt().
|
||||||
char* buf;
|
char* buf;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue