zeek/scripts/policy/frameworks/management/log.zeek
Christian Kreibich b96a4276eb Management framework: move role variable from logging into framework-wide config
The role isn't just about logging, it can also act as a general indicator to key
in on in role-specific code elsewhere, such as @if.
2022-05-25 13:56:23 -07:00

139 lines
3.7 KiB
Text

##! This module implements logging abilities for controller and agent. It uses
##! Zeek's logging framework and works only for nodes managed by the
##! supervisor. In this setting Zeek's logging framework operates locally, i.e.,
##! this does not involve logger nodes.
@load ./config
module Management::Log;
export {
## The cluster logging stream identifier.
redef enum Log::ID += { LOG };
## A default logging policy hook for the stream.
global log_policy: Log::PolicyHook;
## The controller/agent log supports four different log levels.
type Level: enum {
DEBUG = 10,
INFO = 20,
WARNING = 30,
ERROR = 40,
};
## The record type containing the column fields of the agent/controller log.
type Info: record {
## The time at which a cluster message was generated.
ts: time;
## The name of the node that is creating the log record.
node: string;
## Log level of this message, converted from the above Level enum
level: string;
## The role of the node, translated from Management::Role.
role: string;
## A message indicating information about cluster controller operation.
message: string;
} &log;
## The log level in use for this node. This is the minimum
## log level required to produce output.
global log_level = INFO &redef;
## A debug-level log message writer.
##
## message: the message to log.
##
global debug: function(message: string);
## An info-level log message writer.
##
## message: the message to log.
##
global info: function(message: string);
## A warning-level log message writer.
##
## message: the message to log.
##
global warning: function(message: string);
## An error-level log message writer. (This only logs a message, it does not
## terminate Zeek or have other runtime effects.)
##
## message: the message to log.
##
global error: function(message: string);
}
# Enum translations to strings. This avoids those enums being reported
# with full qualifications in the logs, which is too verbose.
global l2s: table[Level] of string = {
[DEBUG] = "DEBUG",
[INFO] = "INFO",
[WARNING] = "WARNING",
[ERROR] = "ERROR",
};
global r2s: table[Management::Role] of string = {
[Management::AGENT] = "AGENT",
[Management::CONTROLLER] = "CONTROLLER",
[Management::NODE] = "NODE",
};
function debug(message: string)
{
if ( enum_to_int(log_level) > enum_to_int(DEBUG) )
return;
local node = Supervisor::node();
Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[DEBUG],
$role=r2s[Management::role], $message=message]);
}
function info(message: string)
{
if ( enum_to_int(log_level) > enum_to_int(INFO) )
return;
local node = Supervisor::node();
Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[INFO],
$role=r2s[Management::role], $message=message]);
}
function warning(message: string)
{
if ( enum_to_int(log_level) > enum_to_int(WARNING) )
return;
local node = Supervisor::node();
Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[WARNING],
$role=r2s[Management::role], $message=message]);
}
function error(message: string)
{
if ( enum_to_int(log_level) > enum_to_int(ERROR) )
return;
local node = Supervisor::node();
Log::write(LOG, [$ts=network_time(), $node=node$name, $level=l2s[ERROR],
$role=r2s[Management::role], $message=message]);
}
event zeek_init()
{
if ( ! Supervisor::is_supervised() )
return;
local node = Supervisor::node();
# Defining the stream outside of the stream creation call sidesteps
# the coverage.find-bro-logs test, which tries to inventory all logs.
# This log isn't yet ready for that level of scrutiny.
local stream = Log::Stream($columns=Info, $path=fmt("management-%s", node$name),
$policy=log_policy);
Log::create_stream(Management::Log::LOG, stream);
}