mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
282 lines
8.8 KiB
C++
282 lines
8.8 KiB
C++
// See the file "COPYING" in the main distribution directory for copyright.
|
|
|
|
#pragma once
|
|
|
|
#include "zeek/logging/Types.h"
|
|
#include "zeek/logging/WriterBackend.h"
|
|
|
|
namespace zeek::logging {
|
|
|
|
class Manager;
|
|
|
|
|
|
namespace detail {
|
|
|
|
/**
|
|
* Implements a buffer accumulating log records in \a WriterFrontend instance
|
|
* before passing them to \a WriterBackend instances.
|
|
*
|
|
* \see WriterFrontend::Write
|
|
*/
|
|
class WriteBuffer {
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
explicit WriteBuffer(size_t buffer_size) : buffer_size(buffer_size) {}
|
|
|
|
/**
|
|
* Push a record to the buffer.
|
|
*
|
|
* @param record The records vals.
|
|
*/
|
|
void WriteRecord(LogRecord&& record) { records.emplace_back(std::move(record)); }
|
|
|
|
/**
|
|
* Moves the records out of the buffer and resets it.
|
|
*
|
|
* @return The currently buffered log records.
|
|
*/
|
|
std::vector<LogRecord> TakeRecords() && {
|
|
auto tmp = std::move(records);
|
|
|
|
// Re-initialize the buffer.
|
|
records.clear();
|
|
records.reserve(buffer_size);
|
|
|
|
return tmp;
|
|
}
|
|
|
|
/**
|
|
* @return The size of the buffer.
|
|
*/
|
|
size_t Size() const { return records.size(); }
|
|
|
|
/**
|
|
* @return True if buffer is empty.
|
|
*/
|
|
size_t Empty() const { return records.empty(); }
|
|
|
|
/**
|
|
* @return True if size equals or exceeds configured buffer size.
|
|
*/
|
|
bool Full() const { return records.size() >= buffer_size; }
|
|
|
|
private:
|
|
size_t buffer_size;
|
|
std::vector<LogRecord> records;
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
/**
|
|
* Bridge class between the logging::Manager and backend writer threads. The
|
|
* Manager instantiates one \a WriterFrontend for each open logging filter.
|
|
* Each frontend in turns instantiates a WriterBackend-derived class
|
|
* internally that's specific to the particular output format. That backend
|
|
* runs in a new thread, and it receives messages from the frontend that
|
|
* correspond to method called by the manager.
|
|
*
|
|
*/
|
|
class WriterFrontend {
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* stream: The logging stream.
|
|
*
|
|
* writer: The backend writer type, with the value corresponding to the
|
|
* script-level \c Log::Writer enum (e.g., \a WRITER_ASCII). The
|
|
* frontend will internally instantiate a WriterBackend of the
|
|
* corresponding type.
|
|
*
|
|
* info: The meta information struct for the writer.
|
|
*
|
|
* local: If true, the writer will instantiate a local backend.
|
|
*
|
|
* remote: If true, the writer will forward logs to remote
|
|
* clients.
|
|
*
|
|
* Frontends must only be instantiated by the main thread.
|
|
*/
|
|
WriterFrontend(const WriterBackend::WriterInfo& info, EnumVal* stream, EnumVal* writer, bool local, bool remote);
|
|
|
|
/**
|
|
* Destructor.
|
|
*
|
|
* Frontends must only be destroyed by the main thread.
|
|
*/
|
|
virtual ~WriterFrontend();
|
|
|
|
/**
|
|
* Stops all output to this writer. Calling this methods disables all
|
|
* message forwarding to the backend and will eventually remove the
|
|
* backend thread.
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void Stop();
|
|
|
|
/**
|
|
* Initializes the writer.
|
|
*
|
|
* This method generates a message to the backend writer and triggers
|
|
* the corresponding message there. If the backend method fails, it
|
|
* sends a message back that will asynchronously call Disable().
|
|
*
|
|
* See WriterBackend::Init() for arguments. The method takes
|
|
* ownership of \a fields.
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void Init(int num_fields, const threading::Field* const* fields);
|
|
|
|
/**
|
|
* Write out a record.
|
|
*
|
|
* This method generates a message to the backend writer and triggers
|
|
* the corresponding message there. If the backend method fails, it
|
|
* sends a message back that will asynchronously call Disable().
|
|
*
|
|
* As an optimization, if buffering is enabled (which is the default)
|
|
* this method may buffer several writes and send them over to the
|
|
* backend in bulk with a single message. An explicit bulk write of
|
|
* all currently buffered data can be triggered with
|
|
* FlushWriteBuffer(). The backend writer triggers this with a
|
|
* message at every heartbeat.
|
|
*
|
|
* If the frontend has remote logging enabled, the record is also
|
|
* published to interested peers.
|
|
*
|
|
* @param rec Representation of the log record. Callee takes ownership.
|
|
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void Write(detail::LogRecord&& rec);
|
|
|
|
/**
|
|
* Sets the buffering state.
|
|
*
|
|
* This method generates a message to the backend writer and triggers
|
|
* the corresponding message there. If the backend method fails, it
|
|
* sends a message back that will asynchronously call Disable().
|
|
*
|
|
* See WriterBackend::SetBuf() for arguments.
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void SetBuf(bool enabled);
|
|
|
|
/**
|
|
* Flushes the output.
|
|
*
|
|
* This method generates a message to the backend writer and triggers
|
|
* the corresponding message there. In addition, it also triggers
|
|
* FlushWriteBuffer(). If the backend method fails, it sends a
|
|
* message back that will asynchronously call Disable().
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*
|
|
* @param network_time The network time when the flush was triggered.
|
|
*/
|
|
void Flush(double network_time);
|
|
|
|
/**
|
|
* Triggers log rotation.
|
|
*
|
|
* This method generates a message to the backend writer and triggers
|
|
* the corresponding message there. If the backend method fails, it
|
|
* sends a message back that will asynchronously call Disable().
|
|
*
|
|
* See WriterBackend::Rotate() for arguments.
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void Rotate(const char* rotated_path, double open, double close, bool terminating);
|
|
|
|
/**
|
|
* Explicitly triggers a transfer of all potentially buffered Write()
|
|
* operations over to the backend.
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void FlushWriteBuffer();
|
|
|
|
/**
|
|
* Disables the writer frontend. From now on, all method calls that
|
|
* would normally send message over to the backend, turn into no-ops.
|
|
* Note though that it does not stop the backend itself, use Stop()
|
|
* to do that as well (this method is primarily for use as callback
|
|
* when the backend wants to disable the frontend).
|
|
*
|
|
* Disabled frontend will eventually be discarded by the
|
|
* logging::Manager.
|
|
*
|
|
* This method must only be called from the main thread.
|
|
*/
|
|
void SetDisable() { disabled = true; }
|
|
|
|
/**
|
|
* Returns true if the writer frontend has been disabled with SetDisable().
|
|
*/
|
|
bool Disabled() { return disabled; }
|
|
|
|
/**
|
|
* Returns the additional writer information as passed into the constructor.
|
|
*/
|
|
const WriterBackend::WriterInfo& Info() const { return *info; }
|
|
|
|
/**
|
|
* Returns the number of log fields as passed into the constructor.
|
|
*/
|
|
[[deprecated("Remove in v8.1: Use GetFields() instead")]]
|
|
int NumFields() const {
|
|
return num_fields;
|
|
}
|
|
|
|
/**
|
|
* Returns a descriptive name for the writer, including the type of
|
|
* the backend and the path used.
|
|
*
|
|
* This method is safe to call from any thread.
|
|
*/
|
|
const char* Name() const { return name; }
|
|
|
|
/**
|
|
* Returns the name of the filter for which this frontend was instantiated.
|
|
*/
|
|
const std::string& GetFilterName() const { return info->filter_name; }
|
|
|
|
/**
|
|
* Returns the log fields as passed into the constructor.
|
|
*/
|
|
[[deprecated("Remove in v8.1: Use GetFields() instead")]]
|
|
const threading::Field* const* Fields() const {
|
|
return fields;
|
|
}
|
|
|
|
/**
|
|
* Returns the log fields once Init() was called on the frontend.
|
|
*/
|
|
const std::vector<threading::Field>& GetFields() const { return header.fields; }
|
|
|
|
protected:
|
|
friend class Manager;
|
|
|
|
WriterBackend* backend; // The backend we have instantiated.
|
|
bool disabled; // True if disabled.
|
|
bool initialized; // True if initialized.
|
|
bool buf; // True if buffering is enabled (default).
|
|
bool local; // True if logging locally.
|
|
bool remote; // True if logging remotely.
|
|
|
|
const char* name; // Descriptive name of the
|
|
WriterBackend::WriterInfo* info; // The writer information.
|
|
int num_fields; // Remove in v8.1.
|
|
const threading::Field* const* fields; // Remove in v8.1.
|
|
|
|
detail::LogWriteHeader header; // Collected information about the WriterFrontend.
|
|
detail::WriteBuffer write_buffer; // Buffer for bulk writes.
|
|
};
|
|
|
|
} // namespace zeek::logging
|