diff --git a/src/logging/CMakeLists.txt b/src/logging/CMakeLists.txt index 7690998520..d064fb278a 100644 --- a/src/logging/CMakeLists.txt +++ b/src/logging/CMakeLists.txt @@ -5,6 +5,7 @@ zeek_add_subdir_library( Manager.cc WriterBackend.cc WriterFrontend.cc + Types.cc BIFS logging.bif) diff --git a/src/logging/Types.cc b/src/logging/Types.cc new file mode 100644 index 0000000000..9fab8baf05 --- /dev/null +++ b/src/logging/Types.cc @@ -0,0 +1,48 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +#include "zeek/logging/Types.h" + +#include "zeek/Desc.h" +#include "zeek/Type.h" +#include "zeek/Val.h" + +namespace zeek::logging::detail { + +LogWriteHeader::LogWriteHeader() = default; + +LogWriteHeader::LogWriteHeader(EnumValPtr arg_stream_id, EnumValPtr arg_writer_id, std::string arg_filter_name, + std::string arg_path) + : stream_id(std::move(arg_stream_id)), + writer_id(std::move(arg_writer_id)), + filter_name(std::move(arg_filter_name)), + path(std::move(arg_path)) { + stream_name = obj_desc_short(stream_id.get()); + writer_name = obj_desc_short(writer_id.get()); +} + +LogWriteHeader& LogWriteHeader::operator=(const LogWriteHeader& other) = default; + +LogWriteHeader::~LogWriteHeader() = default; + +bool LogWriteHeader::PopulateEnumVals() { + static const auto& stream_id_type = zeek::id::find_type("Log::ID"); + static const auto& writer_id_type = zeek::id::find_type("Log::Writer"); + + if ( stream_name.empty() || writer_name.empty() ) + return false; + + auto sid = stream_id_type->Lookup(stream_name); + if ( sid < 0 ) + return false; + + auto wid = writer_id_type->Lookup(writer_name); + if ( wid < 0 ) + return false; + + stream_id = stream_id_type->GetEnumVal(sid); + writer_id = writer_id_type->GetEnumVal(wid); + + return true; +} + +} // namespace zeek::logging::detail diff --git a/src/logging/Types.h b/src/logging/Types.h new file mode 100644 index 0000000000..06d83897a8 --- /dev/null +++ b/src/logging/Types.h @@ -0,0 +1,99 @@ +// See the file "COPYING" in the main distribution directory for copyright. + +// Header for types shared between cluster and logging components. +// +// Currently these are in detail, but over time may move into the +// public namespace once established. + +#pragma once + +#include +#include + +#include "zeek/IntrusivePtr.h" +#include "zeek/threading/SerialTypes.h" + +namespace zeek { +class EnumVal; +using EnumValPtr = IntrusivePtr; + +namespace logging::detail { + +/** + * A single log record. + * + * This is what a Zeek record value passed into Log::write() + * is converted into before passed to a local log writer or + * send via the cluster to a remote node. + */ +using LogRecord = std::vector; + +/** + * A struct holding all necessary information that relates to + * log writes for a given path. These values are constant over + * the lifetime of a \a WriterFrontend. + * + * Note that the constructor, destructor and assignment operator are + * defaulted in Types.cc. This is to avoid a Val.h include here. + */ +struct LogWriteHeader { + /** + * Default constructor. + */ + LogWriteHeader(); + + /** + * Constructor that populates stream_name and writer_name. + * + * @param stream_id Enum value representing the stream. + * @param writer_id Enum value representing the writer. + * @param filter_name The filter name of the writer frontend. + * @param path The path of the writer frontend. + */ + LogWriteHeader(EnumValPtr stream_id, EnumValPtr writer_id, std::string filter_name, std::string path); + + /** + * Assignment operator. + */ + LogWriteHeader& operator=(const LogWriteHeader& other); + + /** + * Destructor. + */ + ~LogWriteHeader(); + + /** + * Helper to populate stream_id and writer_id after the + * stream_name and writer_name members were set. + * + * @return true if matching enum values were, else false. + */ + bool PopulateEnumVals(); + + EnumValPtr stream_id; // The enum identifying the stream. + std::string stream_name; // The name of the stream, e.g. Conn::LOG + EnumValPtr writer_id; // The enum identifying the writer. Mostly for backwards compat with broker. + std::string writer_name; // The name of the writer, e.g. WRITER_ASCII. + std::string filter_name; // The name of the filter. + std::string path; // The path as configured or produced by the filter's path_func. + std::vector fields; // The schema describing a log record. +}; + +/** + * A batch of log records including their header. + * + * This is the object created when unserialzing a log-write + * from another cluster node. + * + * This layout currently implies that during de-serialization + * data is copied into LogRecord / threading::Value structures. + * If the need for zero-copy approaches arises, might need a + * different approach to free the underlying buffer (capnproto). + */ +struct LogWriteBatch { + LogWriteHeader header; + std::vector records; +}; + +} // namespace logging::detail +} // namespace zeek