mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00

This is based on Gilbert's code but I ended up refactoring it quite a bit. That's why I didn't do a direct merge but started with a new branch and copied things over to adapt. It looks quite a bit different now as I tried to generalize things a bit more to also support the Input Framework. The larger changes code are: - Moved all logging code into subdirectory src/logging/. Code here is in namespace "logging". - Moved all threading code into subdirectory src/threading/. Code here is in namespace "threading". - Introduced a central thread manager that tracks threads and is in charge of termination and (eventually) statistics. - Refactored logging independent threading code into base classes BasicThread and MsgThread. The former encapsulates all the pthread code with simple start/stop methods and provides a single Run() method to override. The latter is derived from BasicThread and adds bi-directional message passing between main and child threads. The hope is that the Input Framework can reuse this part quite directly. - A log writer is now split into a general WriterFrontend (LogEmissary in Gilbert's code) and a type-specific WriterBackend. Specific writers are implemented by deriving from the latter. (The plugin interface is almost unchanged compared to the 2.0 version.). Frontend and backend communicate via MsgThread's message passing. - MsgThread (and thus WriterBackend) has a Heartbeat() method that a thread can override to execute code on a regular basis. It's triggered roughly once a second by the main thread. - Integration into "the rest of Bro". Threads can send messages to the reporter and do debugging output; they are hooked into the I/O loop for sending messages back; and there's a new debugging stream "threading" that logs, well, threading activity. This all seems to work for the most part, but it's not done yet. TODO list: - Not all tests pass yet. In particular, diffs for the external tests seem to indicate some memory problem (no crashes, just an occasional weird character). - Only tested in --enable-debug mode. - Only tested on Linux. - Needs leak check. - Each log write is currently a single inter-thread message. Bring Gilbert's bulk writes back. - Code needs further cleanup. - Document the class API. - Document the internal structure of the logging framework. - Check for robustness: live traffic, aborting, signals, etc. - Add thread statistics to profile.log (most of the code is there). - Customize the OS-visible thread names on platforms that support it.
88 lines
2.1 KiB
C++
88 lines
2.1 KiB
C++
// A logger for (selective) debugging output. Only compiled in if DEBUG is
|
|
// defined.
|
|
|
|
#ifndef debug_logger_h
|
|
#define debug_logger_h
|
|
|
|
#ifdef DEBUG
|
|
|
|
#include <stdio.h>
|
|
|
|
// To add a new debugging stream, add a constant here as well as
|
|
// an entry to DebugLogger::streams in DebugLogger.cc.
|
|
|
|
enum DebugStream {
|
|
DBG_SERIAL, // Serialization
|
|
DBG_RULES, // Signature matching
|
|
DBG_COMM, // Remote communication
|
|
DBG_STATE, // StateAccess logging
|
|
DBG_CHUNKEDIO, // ChunkedIO logging
|
|
DBG_COMPRESSOR, // Connection compressor
|
|
DBG_STRING, // String code
|
|
DBG_NOTIFIERS, // Notifiers (see StateAccess.h)
|
|
DBG_MAINLOOP, // Main IOSource loop
|
|
DBG_DPD, // Dynamic application detection framework
|
|
DBG_TM, // Time-machine packet input via Brocolli
|
|
DBG_LOGGING, // Logging streams
|
|
DBG_THREADING, // Threading system
|
|
|
|
NUM_DBGS // Has to be last
|
|
};
|
|
|
|
#define DBG_LOG(args...) debug_logger.Log(args)
|
|
#define DBG_LOG_VERBOSE(args...) \
|
|
if ( debug_logger.IsVerbose() ) \
|
|
debug_logger.Log(args)
|
|
#define DBG_PUSH(stream) debug_logger.PushIndent(stream)
|
|
#define DBG_POP(stream) debug_logger.PopIndent(stream)
|
|
|
|
class DebugLogger {
|
|
public:
|
|
// Output goes to stderr per default.
|
|
DebugLogger(const char* filename = 0);
|
|
~DebugLogger();
|
|
|
|
void Log(DebugStream stream, const char* fmt, ...);
|
|
|
|
void PushIndent(DebugStream stream)
|
|
{ ++streams[int(stream)].indent; }
|
|
void PopIndent(DebugStream stream)
|
|
{ --streams[int(stream)].indent; }
|
|
|
|
void EnableStream(DebugStream stream)
|
|
{ streams[int(stream)].enabled = true; }
|
|
void DisableStream(DebugStream stream)
|
|
{ streams[int(stream)].enabled = false; }
|
|
|
|
// Takes comma-seperated list of stream prefixes.
|
|
void EnableStreams(const char* streams);
|
|
|
|
bool IsEnabled(DebugStream stream) const
|
|
{ return streams[int(stream)].enabled; }
|
|
|
|
void SetVerbose(bool arg_verbose) { verbose = arg_verbose; }
|
|
bool IsVerbose() const { return verbose; }
|
|
|
|
private:
|
|
FILE* file;
|
|
bool verbose;
|
|
|
|
struct Stream {
|
|
const char* prefix;
|
|
int indent;
|
|
bool enabled;
|
|
};
|
|
|
|
static Stream streams[NUM_DBGS];
|
|
};
|
|
|
|
extern DebugLogger debug_logger;
|
|
|
|
#else
|
|
#define DBG_LOG(args...)
|
|
#define DBG_LOG_VERBOSE(args...)
|
|
#define DBG_PUSH(stream)
|
|
#define DBG_POP(stream)
|
|
#endif
|
|
|
|
#endif
|