mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 08:38:20 +00:00
Reformat the world
This commit is contained in:
parent
194cb24547
commit
b2f171ec69
714 changed files with 35149 additions and 35203 deletions
|
@ -1,11 +1,13 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/logging/Component.h"
|
||||
#include "zeek/logging/Manager.h"
|
||||
|
||||
#include "zeek/Desc.h"
|
||||
#include "zeek/logging/Manager.h"
|
||||
#include "zeek/util.h"
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
Component::Component(const std::string& name, factory_callback arg_factory)
|
||||
: plugin::Component(plugin::component::WRITER, name)
|
||||
|
@ -19,9 +21,7 @@ void Component::Initialize()
|
|||
log_mgr->RegisterComponent(this, "WRITER_");
|
||||
}
|
||||
|
||||
Component::~Component()
|
||||
{
|
||||
}
|
||||
Component::~Component() { }
|
||||
|
||||
void Component::DoDescribe(ODesc* d) const
|
||||
{
|
||||
|
@ -29,4 +29,4 @@ void Component::DoDescribe(ODesc* d) const
|
|||
d->Add(CanonicalName());
|
||||
}
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
#include "zeek/plugin/Component.h"
|
||||
#include "zeek/plugin/TaggedComponent.h"
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
class WriterFrontend;
|
||||
class WriterBackend;
|
||||
|
@ -14,8 +15,8 @@ class WriterBackend;
|
|||
/**
|
||||
* Component description for plugins providing log writers.
|
||||
*/
|
||||
class Component : public plugin::Component,
|
||||
public plugin::TaggedComponent<logging::Tag> {
|
||||
class Component : public plugin::Component, public plugin::TaggedComponent<logging::Tag>
|
||||
{
|
||||
public:
|
||||
typedef WriterBackend* (*factory_callback)(WriterFrontend* frontend);
|
||||
|
||||
|
@ -48,16 +49,16 @@ public:
|
|||
/**
|
||||
* Returns the writer's factory function.
|
||||
*/
|
||||
factory_callback Factory() const { return factory; }
|
||||
factory_callback Factory() const { return factory; }
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Overriden from plugin::Component.
|
||||
*/
|
||||
* Overriden from plugin::Component.
|
||||
*/
|
||||
void DoDescribe(ODesc* d) const override;
|
||||
|
||||
private:
|
||||
factory_callback factory;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,21 +6,28 @@
|
|||
|
||||
#include <string_view>
|
||||
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/Tag.h"
|
||||
#include "zeek/EventHandler.h"
|
||||
#include "zeek/plugin/ComponentManager.h"
|
||||
|
||||
#include "zeek/Tag.h"
|
||||
#include "zeek/Val.h"
|
||||
#include "zeek/logging/Component.h"
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
#include "zeek/plugin/ComponentManager.h"
|
||||
|
||||
namespace broker { struct endpoint_info; }
|
||||
namespace broker
|
||||
{
|
||||
struct endpoint_info;
|
||||
}
|
||||
|
||||
namespace zeek {
|
||||
namespace zeek
|
||||
{
|
||||
|
||||
namespace detail { class SerializationFormat; }
|
||||
namespace detail
|
||||
{
|
||||
class SerializationFormat;
|
||||
}
|
||||
|
||||
namespace logging {
|
||||
namespace logging
|
||||
{
|
||||
|
||||
class WriterFrontend;
|
||||
class RotationFinishedMessage;
|
||||
|
@ -29,9 +36,9 @@ class RotationTimer;
|
|||
/**
|
||||
* Singleton class for managing log streams.
|
||||
*/
|
||||
class Manager : public plugin::ComponentManager<Tag, Component> {
|
||||
class Manager : public plugin::ComponentManager<Tag, Component>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
|
@ -55,10 +62,8 @@ public:
|
|||
* @param rotation_info The fields of a Log::RotationFmtInfo record
|
||||
* to create and pass to Log::rotation_format_func.
|
||||
*/
|
||||
std::string FormatRotationPath(EnumValPtr writer,
|
||||
std::string_view path, double open,
|
||||
double close, bool terminating,
|
||||
FuncPtr postprocesor);
|
||||
std::string FormatRotationPath(EnumValPtr writer, std::string_view path, double open,
|
||||
double close, bool terminating, FuncPtr postprocesor);
|
||||
|
||||
/**
|
||||
* Creates a new log stream.
|
||||
|
@ -189,8 +194,8 @@ public:
|
|||
* @param vals An array of log values to write, of size num_fields.
|
||||
* The method takes ownership of the array.
|
||||
*/
|
||||
bool WriteFromRemote(EnumVal* stream, EnumVal* writer, const std::string& path,
|
||||
int num_fields, threading::Value** vals);
|
||||
bool WriteFromRemote(EnumVal* stream, EnumVal* writer, const std::string& path, int num_fields,
|
||||
threading::Value** vals);
|
||||
|
||||
/**
|
||||
* Announces all instantiated writers to a given Broker peer.
|
||||
|
@ -264,9 +269,9 @@ protected:
|
|||
|
||||
// Takes ownership of fields and info.
|
||||
WriterFrontend* CreateWriter(EnumVal* id, EnumVal* writer, WriterBackend::WriterInfo* info,
|
||||
int num_fields, const threading::Field* const* fields,
|
||||
bool local, bool remote, bool from_remote,
|
||||
const std::string& instantiating_filter="");
|
||||
int num_fields, const threading::Field* const* fields, bool local,
|
||||
bool remote, bool from_remote,
|
||||
const std::string& instantiating_filter = "");
|
||||
|
||||
// Signals that a file has been rotated.
|
||||
bool FinishedRotation(WriterFrontend* writer, const char* new_name, const char* old_name,
|
||||
|
@ -280,12 +285,10 @@ private:
|
|||
struct Stream;
|
||||
struct WriterInfo;
|
||||
|
||||
bool TraverseRecord(Stream* stream, Filter* filter, RecordType* rt,
|
||||
TableVal* include, TableVal* exclude,
|
||||
const std::string& path, const std::list<int>& indices);
|
||||
bool TraverseRecord(Stream* stream, Filter* filter, RecordType* rt, TableVal* include,
|
||||
TableVal* exclude, const std::string& path, const std::list<int>& indices);
|
||||
|
||||
threading::Value** RecordToFilterVals(Stream* stream, Filter* filter,
|
||||
RecordVal* columns);
|
||||
threading::Value** RecordToFilterVals(Stream* stream, Filter* filter, RecordVal* columns);
|
||||
|
||||
threading::Value* ValToLogVal(Val* val, Type* ty = nullptr);
|
||||
Stream* FindStream(EnumVal* id);
|
||||
|
@ -296,14 +299,14 @@ private:
|
|||
bool CompareFields(const Filter* filter, const WriterFrontend* writer);
|
||||
bool CheckFilterWriterConflict(const WriterInfo* winfo, const Filter* filter);
|
||||
|
||||
std::vector<Stream *> streams; // Indexed by stream enum.
|
||||
int rotations_pending; // Number of rotations not yet finished.
|
||||
std::vector<Stream*> streams; // Indexed by stream enum.
|
||||
int rotations_pending; // Number of rotations not yet finished.
|
||||
FuncPtr rotation_format_func;
|
||||
FuncPtr log_stream_policy_hook;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace logging;
|
||||
} // namespace logging;
|
||||
|
||||
extern logging::Manager* log_mgr;
|
||||
|
||||
} // namespace zeek
|
||||
} // namespace zeek
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/logging/Tag.h"
|
||||
|
||||
#include "zeek/logging/Manager.h"
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
const Tag Tag::Error;
|
||||
|
||||
Tag::Tag(type_t type, subtype_t subtype)
|
||||
: zeek::Tag(log_mgr->GetTagType(), type, subtype)
|
||||
{
|
||||
}
|
||||
Tag::Tag(type_t type, subtype_t subtype) : zeek::Tag(log_mgr->GetTagType(), type, subtype) { }
|
||||
|
||||
Tag& Tag::operator=(const Tag& other)
|
||||
{
|
||||
|
@ -29,8 +28,6 @@ const EnumValPtr& Tag::AsVal() const
|
|||
return zeek::Tag::AsVal(log_mgr->GetTagType());
|
||||
}
|
||||
|
||||
Tag::Tag(EnumValPtr val)
|
||||
: zeek::Tag(std::move(val))
|
||||
{ }
|
||||
Tag::Tag(EnumValPtr val) : zeek::Tag(std::move(val)) { }
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
|
@ -2,21 +2,24 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
#include "zeek/Tag.h"
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
namespace zeek {
|
||||
namespace zeek
|
||||
{
|
||||
|
||||
class EnumVal;
|
||||
|
||||
namespace plugin {
|
||||
namespace plugin
|
||||
{
|
||||
|
||||
template <class T> class TaggedComponent;
|
||||
template <class T, class C> class ComponentManager;
|
||||
|
||||
} // namespace plugin
|
||||
} // namespace plugin
|
||||
|
||||
namespace logging {
|
||||
namespace logging
|
||||
{
|
||||
|
||||
class Manager;
|
||||
class Component;
|
||||
|
@ -26,29 +29,30 @@ class Component;
|
|||
*
|
||||
* The script-layer analogue is Log::Writer.
|
||||
*/
|
||||
class Tag : public zeek::Tag {
|
||||
class Tag : public zeek::Tag
|
||||
{
|
||||
public:
|
||||
/*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Tag(const Tag& other) : zeek::Tag(other) {}
|
||||
Tag(const Tag& other) : zeek::Tag(other) { }
|
||||
|
||||
/**
|
||||
* Default constructor. This initializes the tag with an error value
|
||||
* that will make \c operator \c bool return false.
|
||||
*/
|
||||
Tag() : zeek::Tag() {}
|
||||
Tag() : zeek::Tag() { }
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~Tag() {}
|
||||
~Tag() { }
|
||||
|
||||
/**
|
||||
* Returns false if the tag represents an error value rather than a
|
||||
* legal writer type.
|
||||
*/
|
||||
explicit operator bool() const { return *this != Error; }
|
||||
explicit operator bool() const { return *this != Error; }
|
||||
|
||||
/**
|
||||
* Assignment operator.
|
||||
|
@ -63,26 +67,17 @@ public:
|
|||
/**
|
||||
* Compares two tags for equality.
|
||||
*/
|
||||
bool operator==(const Tag& other) const
|
||||
{
|
||||
return zeek::Tag::operator==(other);
|
||||
}
|
||||
bool operator==(const Tag& other) const { return zeek::Tag::operator==(other); }
|
||||
|
||||
/**
|
||||
* Compares two tags for inequality.
|
||||
*/
|
||||
bool operator!=(const Tag& other) const
|
||||
{
|
||||
return zeek::Tag::operator!=(other);
|
||||
}
|
||||
bool operator!=(const Tag& other) const { return zeek::Tag::operator!=(other); }
|
||||
|
||||
/**
|
||||
* Compares two tags for less-than relationship.
|
||||
*/
|
||||
bool operator<(const Tag& other) const
|
||||
{
|
||||
return zeek::Tag::operator<(other);
|
||||
}
|
||||
bool operator<(const Tag& other) const { return zeek::Tag::operator<(other); }
|
||||
|
||||
/**
|
||||
* Returns the \c Log::Writer enum that corresponds to this tag.
|
||||
|
@ -116,7 +111,7 @@ protected:
|
|||
* @param val An enum value of script type \c Log::Writer.
|
||||
*/
|
||||
explicit Tag(EnumValPtr val);
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace logging
|
||||
} // namespace zeek
|
||||
} // namespace logging
|
||||
} // namespace zeek
|
||||
|
|
|
@ -4,64 +4,80 @@
|
|||
|
||||
#include <broker/data.hh>
|
||||
|
||||
#include "zeek/util.h"
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
#include "zeek/logging/Manager.h"
|
||||
#include "zeek/logging/WriterFrontend.h"
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
#include "zeek/util.h"
|
||||
|
||||
// Messages sent from backend to frontend (i.e., "OutputMessages").
|
||||
|
||||
using zeek::threading::Value;
|
||||
using zeek::threading::Field;
|
||||
using zeek::threading::Value;
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
class RotationFinishedMessage final : public threading::OutputMessage<WriterFrontend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
RotationFinishedMessage(WriterFrontend* writer, const char* new_name, const char* old_name,
|
||||
double open, double close, bool success, bool terminating)
|
||||
double open, double close, bool success, bool terminating)
|
||||
: threading::OutputMessage<WriterFrontend>("RotationFinished", writer),
|
||||
new_name(util::copy_string(new_name)), old_name(util::copy_string(old_name)), open(open),
|
||||
close(close), success(success), terminating(terminating) { }
|
||||
new_name(util::copy_string(new_name)), old_name(util::copy_string(old_name)), open(open),
|
||||
close(close), success(success), terminating(terminating)
|
||||
{
|
||||
}
|
||||
|
||||
~RotationFinishedMessage() override
|
||||
{
|
||||
delete [] new_name;
|
||||
delete [] old_name;
|
||||
delete[] new_name;
|
||||
delete[] old_name;
|
||||
}
|
||||
|
||||
bool Process() override
|
||||
{
|
||||
return log_mgr->FinishedRotation(Object(), new_name, old_name, open, close, success, terminating);
|
||||
return log_mgr->FinishedRotation(Object(), new_name, old_name, open, close, success,
|
||||
terminating);
|
||||
}
|
||||
|
||||
private:
|
||||
const char* new_name;
|
||||
const char* old_name;
|
||||
double open;
|
||||
double close;
|
||||
const char* new_name;
|
||||
const char* old_name;
|
||||
double open;
|
||||
double close;
|
||||
bool success;
|
||||
bool terminating;
|
||||
};
|
||||
bool terminating;
|
||||
};
|
||||
|
||||
class FlushWriteBufferMessage final : public threading::OutputMessage<WriterFrontend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
FlushWriteBufferMessage(WriterFrontend* writer)
|
||||
: threading::OutputMessage<WriterFrontend>("FlushWriteBuffer", writer) {}
|
||||
: threading::OutputMessage<WriterFrontend>("FlushWriteBuffer", writer)
|
||||
{
|
||||
}
|
||||
|
||||
bool Process() override { Object()->FlushWriteBuffer(); return true; }
|
||||
};
|
||||
bool Process() override
|
||||
{
|
||||
Object()->FlushWriteBuffer();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class DisableMessage final : public threading::OutputMessage<WriterFrontend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
DisableMessage(WriterFrontend* writer)
|
||||
: threading::OutputMessage<WriterFrontend>("Disable", writer) {}
|
||||
: threading::OutputMessage<WriterFrontend>("Disable", writer)
|
||||
{
|
||||
}
|
||||
|
||||
bool Process() override { Object()->SetDisable(); return true; }
|
||||
};
|
||||
bool Process() override
|
||||
{
|
||||
Object()->SetDisable();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
// Backend methods.
|
||||
|
||||
|
@ -78,7 +94,8 @@ broker::data WriterBackend::WriterInfo::ToBroker() const
|
|||
|
||||
auto bppf = post_proc_func ? post_proc_func : "";
|
||||
|
||||
return broker::vector({path, rotation_base, rotation_interval, network_time, std::move(t), bppf});
|
||||
return broker::vector(
|
||||
{path, rotation_base, rotation_interval, network_time, std::move(t), bppf});
|
||||
}
|
||||
|
||||
bool WriterBackend::WriterInfo::FromBroker(broker::data d)
|
||||
|
@ -134,10 +151,10 @@ WriterBackend::~WriterBackend()
|
|||
{
|
||||
if ( fields )
|
||||
{
|
||||
for(int i = 0; i < num_fields; ++i)
|
||||
for ( int i = 0; i < num_fields; ++i )
|
||||
delete fields[i];
|
||||
|
||||
delete [] fields;
|
||||
delete[] fields;
|
||||
}
|
||||
|
||||
delete info;
|
||||
|
@ -151,17 +168,18 @@ void WriterBackend::DeleteVals(int num_writes, Value*** vals)
|
|||
for ( int i = 0; i < num_fields; i++ )
|
||||
delete vals[j][i];
|
||||
|
||||
delete [] vals[j];
|
||||
delete[] vals[j];
|
||||
}
|
||||
|
||||
delete [] vals;
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
bool WriterBackend::FinishedRotation(const char* new_name, const char* old_name,
|
||||
double open, double close, bool terminating)
|
||||
bool WriterBackend::FinishedRotation(const char* new_name, const char* old_name, double open,
|
||||
double close, bool terminating)
|
||||
{
|
||||
--rotation_counter;
|
||||
SendOut(new RotationFinishedMessage(frontend, new_name, old_name, open, close, true, terminating));
|
||||
SendOut(
|
||||
new RotationFinishedMessage(frontend, new_name, old_name, open, close, true, terminating));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -204,7 +222,7 @@ bool WriterBackend::Write(int arg_num_fields, int num_writes, Value*** vals)
|
|||
|
||||
#ifdef DEBUG
|
||||
const char* msg = Fmt("Number of fields don't match in WriterBackend::Write() (%d vs. %d)",
|
||||
arg_num_fields, num_fields);
|
||||
arg_num_fields, num_fields);
|
||||
Debug(DBG_LOGGING, msg);
|
||||
#endif
|
||||
|
||||
|
@ -221,8 +239,9 @@ bool WriterBackend::Write(int arg_num_fields, int num_writes, Value*** vals)
|
|||
if ( vals[j][i]->type != fields[i]->type )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
const char* msg = Fmt("Field #%d type doesn't match in WriterBackend::Write() (%d vs. %d)",
|
||||
i, vals[j][i]->type, fields[i]->type);
|
||||
const char* msg =
|
||||
Fmt("Field #%d type doesn't match in WriterBackend::Write() (%d vs. %d)", i,
|
||||
vals[j][i]->type, fields[i]->type);
|
||||
Debug(DBG_LOGGING, msg);
|
||||
#endif
|
||||
DisableFrontend();
|
||||
|
@ -273,8 +292,7 @@ bool WriterBackend::SetBuf(bool enabled)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool WriterBackend::Rotate(const char* rotated_path, double open,
|
||||
double close, bool terminating)
|
||||
bool WriterBackend::Rotate(const char* rotated_path, double open, double close, bool terminating)
|
||||
{
|
||||
if ( Failed() )
|
||||
return true;
|
||||
|
@ -292,7 +310,8 @@ bool WriterBackend::Rotate(const char* rotated_path, double open,
|
|||
InternalError(Fmt("writer %s did not call FinishedRotation() in DoRotation()", Name()));
|
||||
|
||||
if ( rotation_counter < 0 )
|
||||
InternalError(Fmt("writer %s called FinishedRotation() more than once in DoRotation()", Name()));
|
||||
InternalError(
|
||||
Fmt("writer %s called FinishedRotation() more than once in DoRotation()", Name()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -328,4 +347,4 @@ bool WriterBackend::OnHeartbeat(double network_time, double current_time)
|
|||
return DoHeartbeat(network_time, current_time);
|
||||
}
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
|
@ -4,12 +4,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "zeek/threading/MsgThread.h"
|
||||
#include "zeek/logging/Component.h"
|
||||
#include "zeek/threading/MsgThread.h"
|
||||
|
||||
namespace broker { class data; }
|
||||
namespace broker
|
||||
{
|
||||
class data;
|
||||
}
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
class WriterFrontend;
|
||||
|
||||
|
@ -23,7 +27,7 @@ class WriterFrontend;
|
|||
* thread (the constructor and destructor are the exceptions.)
|
||||
*/
|
||||
class WriterBackend : public threading::MsgThread
|
||||
{
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -90,33 +94,34 @@ public:
|
|||
*/
|
||||
config_map config;
|
||||
|
||||
WriterInfo() : path(nullptr), rotation_interval(0.0), rotation_base(0.0),
|
||||
network_time(0.0)
|
||||
WriterInfo() : path(nullptr), rotation_interval(0.0), rotation_base(0.0), network_time(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
WriterInfo(const WriterInfo& other)
|
||||
{
|
||||
path = other.path ? util::copy_string(other.path) : nullptr;
|
||||
post_proc_func = other.post_proc_func ? util::copy_string(other.post_proc_func) : nullptr;
|
||||
post_proc_func =
|
||||
other.post_proc_func ? util::copy_string(other.post_proc_func) : nullptr;
|
||||
rotation_interval = other.rotation_interval;
|
||||
rotation_base = other.rotation_base;
|
||||
network_time = other.network_time;
|
||||
|
||||
for ( config_map::const_iterator i = other.config.begin(); i != other.config.end(); i++ )
|
||||
config.insert(std::make_pair(util::copy_string(i->first),
|
||||
util::copy_string(i->second)));
|
||||
for ( config_map::const_iterator i = other.config.begin(); i != other.config.end();
|
||||
i++ )
|
||||
config.insert(
|
||||
std::make_pair(util::copy_string(i->first), util::copy_string(i->second)));
|
||||
}
|
||||
|
||||
~WriterInfo()
|
||||
{
|
||||
delete [] path;
|
||||
delete [] post_proc_func;
|
||||
delete[] path;
|
||||
delete[] post_proc_func;
|
||||
|
||||
for ( config_map::iterator i = config.begin(); i != config.end(); i++ )
|
||||
{
|
||||
delete [] i->first;
|
||||
delete [] i->second;
|
||||
delete[] i->first;
|
||||
delete[] i->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +130,7 @@ public:
|
|||
broker::data ToBroker() const;
|
||||
bool FromBroker(broker::data d);
|
||||
|
||||
private:
|
||||
private:
|
||||
const WriterInfo& operator=(const WriterInfo& other); // Disable.
|
||||
};
|
||||
|
||||
|
@ -200,24 +205,24 @@ public:
|
|||
/**
|
||||
* Returns the additional writer information passed into the constructor.
|
||||
*/
|
||||
const WriterInfo& Info() const { return *info; }
|
||||
const WriterInfo& Info() const { return *info; }
|
||||
|
||||
/**
|
||||
* Returns the number of log fields as passed into the constructor.
|
||||
*/
|
||||
int NumFields() const { return num_fields; }
|
||||
int NumFields() const { return num_fields; }
|
||||
|
||||
/**
|
||||
* Returns the log fields as passed into the constructor.
|
||||
*/
|
||||
const threading::Field* const * Fields() const { return fields; }
|
||||
const threading::Field* const* Fields() const { return fields; }
|
||||
|
||||
/**
|
||||
* Returns the current buffering state.
|
||||
*
|
||||
* @return True if buffering is enabled.
|
||||
*/
|
||||
bool IsBuf() { return buffering; }
|
||||
bool IsBuf() { return buffering; }
|
||||
|
||||
/**
|
||||
* Signals that a file has been successfully rotated and any
|
||||
|
@ -240,8 +245,8 @@ public:
|
|||
* @param terminating: True if the original rotation request occured
|
||||
* due to the main Bro process shutting down.
|
||||
*/
|
||||
bool FinishedRotation(const char* new_name, const char* old_name,
|
||||
double open, double close, bool terminating);
|
||||
bool FinishedRotation(const char* new_name, const char* old_name, double open, double close,
|
||||
bool terminating);
|
||||
|
||||
/**
|
||||
* Signals that a file rotation request has been processed, but no
|
||||
|
@ -276,7 +281,7 @@ protected:
|
|||
* implementation should also call Error() to indicate what happened.
|
||||
*/
|
||||
virtual bool DoInit(const WriterInfo& info, int num_fields,
|
||||
const threading::Field* const* fields) = 0;
|
||||
const threading::Field* const* fields) = 0;
|
||||
|
||||
/**
|
||||
* Writer-specific output method implementing recording of fone log
|
||||
|
@ -288,8 +293,8 @@ protected:
|
|||
* disabled and eventually deleted. When returning false, an
|
||||
* implementation should also call Error() to indicate what happened.
|
||||
*/
|
||||
virtual bool DoWrite(int num_fields, const threading::Field* const* fields,
|
||||
threading::Value** vals) = 0;
|
||||
virtual bool DoWrite(int num_fields, const threading::Field* const* fields,
|
||||
threading::Value** vals) = 0;
|
||||
|
||||
/**
|
||||
* Writer-specific method implementing a change of fthe buffering
|
||||
|
@ -362,7 +367,7 @@ protected:
|
|||
* reached a regularly scheduled time for rotation).
|
||||
*/
|
||||
virtual bool DoRotate(const char* rotated_path, double open, double close,
|
||||
bool terminating) = 0;
|
||||
bool terminating) = 0;
|
||||
|
||||
/**
|
||||
* Writer-specific method called just before the threading system is
|
||||
|
@ -390,12 +395,12 @@ private:
|
|||
// this class, it's running in a different thread!
|
||||
WriterFrontend* frontend;
|
||||
|
||||
const WriterInfo* info; // Meta information.
|
||||
int num_fields; // Number of log fields.
|
||||
const threading::Field* const* fields; // Log fields.
|
||||
bool buffering; // True if buffering is enabled.
|
||||
const WriterInfo* info; // Meta information.
|
||||
int num_fields; // Number of log fields.
|
||||
const threading::Field* const* fields; // Log fields.
|
||||
bool buffering; // True if buffering is enabled.
|
||||
|
||||
int rotation_counter; // Tracks FinishedRotation() calls.
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
|
@ -1,44 +1,47 @@
|
|||
#include "zeek/logging/WriterFrontend.h"
|
||||
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
#include "zeek/broker/Manager.h"
|
||||
#include "zeek/logging/Manager.h"
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
|
||||
using zeek::threading::Value;
|
||||
using zeek::threading::Field;
|
||||
using zeek::threading::Value;
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
// Messages sent from frontend to backend (i.e., "InputMessages").
|
||||
|
||||
class InitMessage final : public threading::InputMessage<WriterBackend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
InitMessage(WriterBackend* backend, const int num_fields, const Field* const* fields)
|
||||
: threading::InputMessage<WriterBackend>("Init", backend),
|
||||
num_fields(num_fields), fields(fields)
|
||||
{}
|
||||
: threading::InputMessage<WriterBackend>("Init", backend), num_fields(num_fields),
|
||||
fields(fields)
|
||||
{
|
||||
}
|
||||
|
||||
bool Process() override { return Object()->Init(num_fields, fields); }
|
||||
|
||||
private:
|
||||
const int num_fields;
|
||||
const Field * const* fields;
|
||||
};
|
||||
const Field* const* fields;
|
||||
};
|
||||
|
||||
class RotateMessage final : public threading::InputMessage<WriterBackend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
RotateMessage(WriterBackend* backend, WriterFrontend* frontend, const char* rotated_path, const double open,
|
||||
const double close, const bool terminating)
|
||||
: threading::InputMessage<WriterBackend>("Rotate", backend),
|
||||
frontend(frontend),
|
||||
rotated_path(util::copy_string(rotated_path)), open(open),
|
||||
close(close), terminating(terminating) { }
|
||||
RotateMessage(WriterBackend* backend, WriterFrontend* frontend, const char* rotated_path,
|
||||
const double open, const double close, const bool terminating)
|
||||
: threading::InputMessage<WriterBackend>("Rotate", backend), frontend(frontend),
|
||||
rotated_path(util::copy_string(rotated_path)), open(open), close(close),
|
||||
terminating(terminating)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~RotateMessage() { delete [] rotated_path; }
|
||||
virtual ~RotateMessage() { delete[] rotated_path; }
|
||||
|
||||
bool Process() override { return Object()->Rotate(rotated_path, open, close, terminating); }
|
||||
|
||||
|
@ -48,47 +51,52 @@ private:
|
|||
const double open;
|
||||
const double close;
|
||||
const bool terminating;
|
||||
};
|
||||
};
|
||||
|
||||
class WriteMessage final : public threading::InputMessage<WriterBackend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
WriteMessage(WriterBackend* backend, int num_fields, int num_writes, Value*** vals)
|
||||
: threading::InputMessage<WriterBackend>("Write", backend),
|
||||
num_fields(num_fields), num_writes(num_writes), vals(vals) {}
|
||||
: threading::InputMessage<WriterBackend>("Write", backend), num_fields(num_fields),
|
||||
num_writes(num_writes), vals(vals)
|
||||
{
|
||||
}
|
||||
|
||||
bool Process() override { return Object()->Write(num_fields, num_writes, vals); }
|
||||
|
||||
private:
|
||||
int num_fields;
|
||||
int num_writes;
|
||||
Value ***vals;
|
||||
};
|
||||
Value*** vals;
|
||||
};
|
||||
|
||||
class SetBufMessage final : public threading::InputMessage<WriterBackend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
SetBufMessage(WriterBackend* backend, const bool enabled)
|
||||
: threading::InputMessage<WriterBackend>("SetBuf", backend),
|
||||
enabled(enabled) { }
|
||||
: threading::InputMessage<WriterBackend>("SetBuf", backend), enabled(enabled)
|
||||
{
|
||||
}
|
||||
|
||||
bool Process() override { return Object()->SetBuf(enabled); }
|
||||
|
||||
private:
|
||||
const bool enabled;
|
||||
};
|
||||
};
|
||||
|
||||
class FlushMessage final : public threading::InputMessage<WriterBackend>
|
||||
{
|
||||
{
|
||||
public:
|
||||
FlushMessage(WriterBackend* backend, double network_time)
|
||||
: threading::InputMessage<WriterBackend>("Flush", backend),
|
||||
network_time(network_time) {}
|
||||
: threading::InputMessage<WriterBackend>("Flush", backend), network_time(network_time)
|
||||
{
|
||||
}
|
||||
|
||||
bool Process() override { return Object()->Flush(network_time); }
|
||||
|
||||
private:
|
||||
double network_time;
|
||||
};
|
||||
};
|
||||
|
||||
// Frontend methods.
|
||||
|
||||
|
@ -131,12 +139,12 @@ WriterFrontend::~WriterFrontend()
|
|||
for ( auto i = 0; i < num_fields; ++i )
|
||||
delete fields[i];
|
||||
|
||||
delete [] fields;
|
||||
delete[] fields;
|
||||
|
||||
Unref(stream);
|
||||
Unref(writer);
|
||||
delete info;
|
||||
delete [] name;
|
||||
delete[] name;
|
||||
}
|
||||
|
||||
void WriterFrontend::Stop()
|
||||
|
@ -151,7 +159,7 @@ void WriterFrontend::Stop()
|
|||
}
|
||||
}
|
||||
|
||||
void WriterFrontend::Init(int arg_num_fields, const Field* const * arg_fields)
|
||||
void WriterFrontend::Init(int arg_num_fields, const Field* const* arg_fields)
|
||||
{
|
||||
if ( disabled )
|
||||
return;
|
||||
|
@ -176,13 +184,8 @@ void WriterFrontend::Init(int arg_num_fields, const Field* const * arg_fields)
|
|||
|
||||
if ( remote )
|
||||
{
|
||||
broker_mgr->PublishLogCreate(stream,
|
||||
writer,
|
||||
*info,
|
||||
arg_num_fields,
|
||||
arg_fields);
|
||||
broker_mgr->PublishLogCreate(stream, writer, *info, arg_num_fields, arg_fields);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void WriterFrontend::Write(int arg_num_fields, Value** vals)
|
||||
|
@ -203,11 +206,7 @@ void WriterFrontend::Write(int arg_num_fields, Value** vals)
|
|||
|
||||
if ( remote )
|
||||
{
|
||||
broker_mgr->PublishLogWrite(stream,
|
||||
writer,
|
||||
info->path,
|
||||
num_fields,
|
||||
vals);
|
||||
broker_mgr->PublishLogWrite(stream, writer, info->path, num_fields, vals);
|
||||
}
|
||||
|
||||
if ( ! backend )
|
||||
|
@ -228,7 +227,6 @@ void WriterFrontend::Write(int arg_num_fields, Value** vals)
|
|||
if ( write_buffer_pos >= WRITER_BUFFER_SIZE || ! buf || run_state::terminating )
|
||||
// Buffer full (or no bufferin desired or termiating).
|
||||
FlushWriteBuffer();
|
||||
|
||||
}
|
||||
|
||||
void WriterFrontend::FlushWriteBuffer()
|
||||
|
@ -291,7 +289,7 @@ void WriterFrontend::DeleteVals(int num_fields, Value** vals)
|
|||
for ( int i = 0; i < num_fields; i++ )
|
||||
delete vals[i];
|
||||
|
||||
delete [] vals;
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
|
||||
namespace zeek::logging {
|
||||
namespace zeek::logging
|
||||
{
|
||||
|
||||
class Manager;
|
||||
|
||||
|
@ -17,7 +18,8 @@ class Manager;
|
|||
* correspond to method called by the manager.
|
||||
*
|
||||
*/
|
||||
class WriterFrontend {
|
||||
class WriterFrontend
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -38,8 +40,8 @@ public:
|
|||
*
|
||||
* Frontends must only be instantiated by the main thread.
|
||||
*/
|
||||
WriterFrontend(const WriterBackend::WriterInfo& info, EnumVal* stream,
|
||||
EnumVal* writer, bool local, bool remote);
|
||||
WriterFrontend(const WriterBackend::WriterInfo& info, EnumVal* stream, EnumVal* writer,
|
||||
bool local, bool remote);
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
|
@ -69,7 +71,7 @@ public:
|
|||
*
|
||||
* This method must only be called from the main thread.
|
||||
*/
|
||||
void Init(int num_fields, const threading::Field* const* fields);
|
||||
void Init(int num_fields, const threading::Field* const* fields);
|
||||
|
||||
/**
|
||||
* Write out a record.
|
||||
|
@ -153,22 +155,22 @@ public:
|
|||
*
|
||||
* This method must only be called from the main thread.
|
||||
*/
|
||||
void SetDisable() { disabled = true; }
|
||||
void SetDisable() { disabled = true; }
|
||||
|
||||
/**
|
||||
* Returns true if the writer frontend has been disabled with SetDisable().
|
||||
*/
|
||||
bool Disabled() { return disabled; }
|
||||
bool Disabled() { return disabled; }
|
||||
|
||||
/**
|
||||
* Returns the additional writer information as passed into the constructor.
|
||||
*/
|
||||
const WriterBackend::WriterInfo& Info() const { return *info; }
|
||||
const WriterBackend::WriterInfo& Info() const { return *info; }
|
||||
|
||||
/**
|
||||
* Returns the number of log fields as passed into the constructor.
|
||||
*/
|
||||
int NumFields() const { return num_fields; }
|
||||
int NumFields() const { return num_fields; }
|
||||
|
||||
/**
|
||||
* Returns a descriptive name for the writer, including the type of
|
||||
|
@ -176,12 +178,12 @@ public:
|
|||
*
|
||||
* This method is safe to call from any thread.
|
||||
*/
|
||||
const char* Name() const { return name; }
|
||||
const char* Name() const { return name; }
|
||||
|
||||
/**
|
||||
* Returns the log fields as passed into the constructor.
|
||||
*/
|
||||
const threading::Field* const * Fields() const { return fields; }
|
||||
const threading::Field* const* Fields() const { return fields; }
|
||||
|
||||
protected:
|
||||
friend class Manager;
|
||||
|
@ -191,22 +193,22 @@ protected:
|
|||
EnumVal* stream;
|
||||
EnumVal* writer;
|
||||
|
||||
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 loggin remotely.
|
||||
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 loggin remotely.
|
||||
|
||||
const char* name; // Descriptive name of the
|
||||
WriterBackend::WriterInfo* info; // The writer information.
|
||||
int num_fields; // The number of log fields.
|
||||
const threading::Field* const* fields; // The log fields.
|
||||
const char* name; // Descriptive name of the
|
||||
WriterBackend::WriterInfo* info; // The writer information.
|
||||
int num_fields; // The number of log fields.
|
||||
const threading::Field* const* fields; // The log fields.
|
||||
|
||||
// Buffer for bulk writes.
|
||||
static const int WRITER_BUFFER_SIZE = 1000;
|
||||
int write_buffer_pos; // Position of next write in buffer.
|
||||
threading::Value*** write_buffer; // Buffer of size WRITER_BUFFER_SIZE.
|
||||
};
|
||||
int write_buffer_pos; // Position of next write in buffer.
|
||||
threading::Value*** write_buffer; // Buffer of size WRITER_BUFFER_SIZE.
|
||||
};
|
||||
|
||||
} // namespace zeek::logging
|
||||
} // namespace zeek::logging
|
||||
|
|
|
@ -2,41 +2,41 @@
|
|||
|
||||
#include "zeek/logging/writers/ascii/Ascii.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <ctime>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "zeek/Func.h"
|
||||
#include "zeek/RunState.h"
|
||||
#include "zeek/logging/Manager.h"
|
||||
#include "zeek/logging/writers/ascii/ascii.bif.h"
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
|
||||
#include "zeek/logging/writers/ascii/ascii.bif.h"
|
||||
|
||||
using namespace std;
|
||||
using zeek::threading::Value;
|
||||
using zeek::threading::Field;
|
||||
using zeek::threading::Value;
|
||||
|
||||
static constexpr auto shadow_file_prefix = ".shadow.";
|
||||
|
||||
namespace zeek::logging::writer::detail {
|
||||
namespace zeek::logging::writer::detail
|
||||
{
|
||||
|
||||
/**
|
||||
* Information about an leftover log file: that is, one that a previous
|
||||
* process was in the middle of writing, but never completed a rotation
|
||||
* for whatever reason (prematurely crashed/killed).
|
||||
*/
|
||||
struct LeftoverLog {
|
||||
struct LeftoverLog
|
||||
{
|
||||
/*
|
||||
* Name of leftover log, relative to working dir.
|
||||
*/
|
||||
|
@ -85,15 +85,13 @@ struct LeftoverLog {
|
|||
* Return the "path" (logging framework parlance) of the log without the
|
||||
* file extension. E.g. the "path" of "conn.log" is just "conn".
|
||||
*/
|
||||
std::string Path() const
|
||||
{ return filename.substr(0, filename.size() - extension.size()); }
|
||||
std::string Path() const { return filename.substr(0, filename.size() - extension.size()); }
|
||||
|
||||
/**
|
||||
* Deletes the shadow file and returns whether it succeeded.
|
||||
*/
|
||||
bool DeleteShadow() const
|
||||
{ return unlink(shadow_filename.data()) == 0; }
|
||||
};
|
||||
bool DeleteShadow() const { return unlink(shadow_filename.data()) == 0; }
|
||||
};
|
||||
|
||||
static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
||||
{
|
||||
|
@ -107,8 +105,8 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
|
||||
if ( ! sf_stream )
|
||||
{
|
||||
rval.error = util::fmt("Failed to open %s: %s",
|
||||
rval.shadow_filename.data(), strerror(errno));
|
||||
rval.error =
|
||||
util::fmt("Failed to open %s: %s", rval.shadow_filename.data(), strerror(errno));
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -116,8 +114,8 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
|
||||
if ( res == -1 )
|
||||
{
|
||||
rval.error = util::fmt("Failed to fseek(SEEK_END) on %s: %s",
|
||||
rval.shadow_filename.data(), strerror(errno));
|
||||
rval.error = util::fmt("Failed to fseek(SEEK_END) on %s: %s", rval.shadow_filename.data(),
|
||||
strerror(errno));
|
||||
fclose(sf_stream);
|
||||
return rval;
|
||||
}
|
||||
|
@ -126,8 +124,8 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
|
||||
if ( sf_len == -1 )
|
||||
{
|
||||
rval.error = util::fmt("Failed to ftell() on %s: %s",
|
||||
rval.shadow_filename.data(), strerror(errno));
|
||||
rval.error =
|
||||
util::fmt("Failed to ftell() on %s: %s", rval.shadow_filename.data(), strerror(errno));
|
||||
fclose(sf_stream);
|
||||
return rval;
|
||||
}
|
||||
|
@ -136,8 +134,8 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
|
||||
if ( res == -1 )
|
||||
{
|
||||
rval.error = util::fmt("Failed to fseek(SEEK_SET) on %s: %s",
|
||||
rval.shadow_filename.data(), strerror(errno));
|
||||
rval.error = util::fmt("Failed to fseek(SEEK_SET) on %s: %s", rval.shadow_filename.data(),
|
||||
strerror(errno));
|
||||
fclose(sf_stream);
|
||||
return rval;
|
||||
}
|
||||
|
@ -158,8 +156,8 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
if ( sf_lines.size() < 2 )
|
||||
{
|
||||
rval.error = util::fmt("Found leftover log, '%s', but the associated shadow "
|
||||
" file, '%s', required to process it is invalid",
|
||||
rval.filename.data(), rval.shadow_filename.data());
|
||||
" file, '%s', required to process it is invalid",
|
||||
rval.filename.data(), rval.shadow_filename.data());
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -171,8 +169,8 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
// Use shadow file's modification time as creation time.
|
||||
if ( stat(rval.shadow_filename.data(), &st) != 0 )
|
||||
{
|
||||
rval.error = util::fmt("Failed to stat %s: %s",
|
||||
rval.shadow_filename.data(), strerror(errno));
|
||||
rval.error =
|
||||
util::fmt("Failed to stat %s: %s", rval.shadow_filename.data(), strerror(errno));
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -181,8 +179,7 @@ static std::optional<LeftoverLog> parse_shadow_log(const std::string& fname)
|
|||
// Use log file's modification time for closing time.
|
||||
if ( stat(rval.filename.data(), &st) != 0 )
|
||||
{
|
||||
rval.error = util::fmt("Failed to stat %s: %s",
|
||||
rval.filename.data(), strerror(errno));
|
||||
rval.error = util::fmt("Failed to stat %s: %s", rval.filename.data(), strerror(errno));
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -216,48 +213,30 @@ void Ascii::InitConfigOptions()
|
|||
enable_utf_8 = BifConst::LogAscii::enable_utf_8;
|
||||
gzip_level = BifConst::LogAscii::gzip_level;
|
||||
|
||||
separator.assign(
|
||||
(const char*) BifConst::LogAscii::separator->Bytes(),
|
||||
BifConst::LogAscii::separator->Len()
|
||||
);
|
||||
separator.assign((const char*)BifConst::LogAscii::separator->Bytes(),
|
||||
BifConst::LogAscii::separator->Len());
|
||||
|
||||
set_separator.assign(
|
||||
(const char*) BifConst::LogAscii::set_separator->Bytes(),
|
||||
BifConst::LogAscii::set_separator->Len()
|
||||
);
|
||||
set_separator.assign((const char*)BifConst::LogAscii::set_separator->Bytes(),
|
||||
BifConst::LogAscii::set_separator->Len());
|
||||
|
||||
empty_field.assign(
|
||||
(const char*) BifConst::LogAscii::empty_field->Bytes(),
|
||||
BifConst::LogAscii::empty_field->Len()
|
||||
);
|
||||
empty_field.assign((const char*)BifConst::LogAscii::empty_field->Bytes(),
|
||||
BifConst::LogAscii::empty_field->Len());
|
||||
|
||||
unset_field.assign(
|
||||
(const char*) BifConst::LogAscii::unset_field->Bytes(),
|
||||
BifConst::LogAscii::unset_field->Len()
|
||||
);
|
||||
unset_field.assign((const char*)BifConst::LogAscii::unset_field->Bytes(),
|
||||
BifConst::LogAscii::unset_field->Len());
|
||||
|
||||
meta_prefix.assign(
|
||||
(const char*) BifConst::LogAscii::meta_prefix->Bytes(),
|
||||
BifConst::LogAscii::meta_prefix->Len()
|
||||
);
|
||||
meta_prefix.assign((const char*)BifConst::LogAscii::meta_prefix->Bytes(),
|
||||
BifConst::LogAscii::meta_prefix->Len());
|
||||
|
||||
ODesc tsfmt;
|
||||
BifConst::LogAscii::json_timestamps->Describe(&tsfmt);
|
||||
json_timestamps.assign(
|
||||
(const char*) tsfmt.Bytes(),
|
||||
tsfmt.Len()
|
||||
);
|
||||
json_timestamps.assign((const char*)tsfmt.Bytes(), tsfmt.Len());
|
||||
|
||||
gzip_file_extension.assign(
|
||||
(const char*) BifConst::LogAscii::gzip_file_extension->Bytes(),
|
||||
BifConst::LogAscii::gzip_file_extension->Len()
|
||||
);
|
||||
|
||||
logdir.assign(
|
||||
(const char*) BifConst::LogAscii::logdir->Bytes(),
|
||||
BifConst::LogAscii::logdir->Len()
|
||||
);
|
||||
gzip_file_extension.assign((const char*)BifConst::LogAscii::gzip_file_extension->Bytes(),
|
||||
BifConst::LogAscii::gzip_file_extension->Len());
|
||||
|
||||
logdir.assign((const char*)BifConst::LogAscii::logdir->Bytes(),
|
||||
BifConst::LogAscii::logdir->Len());
|
||||
}
|
||||
|
||||
bool Ascii::InitFilterOptions()
|
||||
|
@ -265,8 +244,8 @@ bool Ascii::InitFilterOptions()
|
|||
const WriterInfo& info = Info();
|
||||
|
||||
// Set per-filter configuration options.
|
||||
for ( WriterInfo::config_map::const_iterator i = info.config.begin();
|
||||
i != info.config.end(); ++i )
|
||||
for ( WriterInfo::config_map::const_iterator i = info.config.begin(); i != info.config.end();
|
||||
++i )
|
||||
{
|
||||
if ( strcmp(i->first, "tsv") == 0 )
|
||||
{
|
||||
|
@ -281,7 +260,7 @@ bool Ascii::InitFilterOptions()
|
|||
}
|
||||
}
|
||||
|
||||
else if ( strcmp(i->first, "gzip_level" ) == 0 )
|
||||
else if ( strcmp(i->first, "gzip_level") == 0 )
|
||||
{
|
||||
gzip_level = atoi(i->second);
|
||||
|
||||
|
@ -312,7 +291,8 @@ bool Ascii::InitFilterOptions()
|
|||
enable_utf_8 = false;
|
||||
else
|
||||
{
|
||||
Error("invalid value for 'enable_utf_8', must be a string and either \"T\" or \"F\"");
|
||||
Error(
|
||||
"invalid value for 'enable_utf_8', must be a string and either \"T\" or \"F\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -325,7 +305,8 @@ bool Ascii::InitFilterOptions()
|
|||
output_to_stdout = false;
|
||||
else
|
||||
{
|
||||
Error("invalid value for 'output_to_stdout', must be a string and either \"T\" or \"F\"");
|
||||
Error("invalid value for 'output_to_stdout', must be a string and either \"T\" or "
|
||||
"\"F\"");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +377,8 @@ bool Ascii::InitFormatter()
|
|||
// Use the default "Bro logs" format.
|
||||
desc.EnableEscaping();
|
||||
desc.AddEscapeSequence(separator);
|
||||
threading::formatter::Ascii::SeparatorInfo sep_info(separator, set_separator, unset_field, empty_field);
|
||||
threading::formatter::Ascii::SeparatorInfo sep_info(separator, set_separator, unset_field,
|
||||
empty_field);
|
||||
formatter = new threading::formatter::Ascii(this, sep_info);
|
||||
}
|
||||
|
||||
|
@ -433,7 +415,7 @@ void Ascii::CloseFile(double t)
|
|||
gzfile = nullptr;
|
||||
}
|
||||
|
||||
bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Field* const * fields)
|
||||
bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Field* const* fields)
|
||||
{
|
||||
assert(! fd);
|
||||
|
||||
|
@ -472,7 +454,8 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel
|
|||
|
||||
fname += ext;
|
||||
|
||||
bool use_shadow = BifConst::LogAscii::enable_leftover_log_rotation && Info().rotation_interval > 0;
|
||||
bool use_shadow =
|
||||
BifConst::LogAscii::enable_leftover_log_rotation && Info().rotation_interval > 0;
|
||||
|
||||
if ( use_shadow )
|
||||
{
|
||||
|
@ -500,9 +483,8 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel
|
|||
|
||||
if ( rename(tmp_sfname.data(), sfname.data()) == -1 )
|
||||
{
|
||||
Error(Fmt("Unable to rename %s to %s: %s",
|
||||
tmp_sfname.data(), sfname.data(),
|
||||
Strerror(errno)));
|
||||
Error(Fmt("Unable to rename %s to %s: %s", tmp_sfname.data(), sfname.data(),
|
||||
Strerror(errno)));
|
||||
|
||||
unlink(tmp_sfname.data());
|
||||
|
||||
|
@ -515,8 +497,7 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel
|
|||
|
||||
if ( fd < 0 )
|
||||
{
|
||||
Error(Fmt("cannot open %s: %s", fname.c_str(),
|
||||
Strerror(errno)));
|
||||
Error(Fmt("cannot open %s: %s", fname.c_str(), Strerror(errno)));
|
||||
fd = 0;
|
||||
return false;
|
||||
}
|
||||
|
@ -536,8 +517,7 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const threading::Fiel
|
|||
|
||||
if ( gzfile == nullptr )
|
||||
{
|
||||
Error(Fmt("cannot gzip %s: %s", fname.c_str(),
|
||||
Strerror(errno)));
|
||||
Error(Fmt("cannot gzip %s: %s", fname.c_str(), Strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -585,10 +565,8 @@ bool Ascii::WriteHeader(const string& path)
|
|||
return true;
|
||||
}
|
||||
|
||||
string str = meta_prefix
|
||||
+ "separator " // Always use space as separator here.
|
||||
+ util::get_escaped_string(separator, false)
|
||||
+ "\n";
|
||||
string str = meta_prefix + "separator " // Always use space as separator here.
|
||||
+ util::get_escaped_string(separator, false) + "\n";
|
||||
|
||||
if ( ! InternalWrite(fd, str.c_str(), str.length()) )
|
||||
return false;
|
||||
|
@ -600,8 +578,7 @@ bool Ascii::WriteHeader(const string& path)
|
|||
WriteHeaderField("open", Timestamp(0))) )
|
||||
return false;
|
||||
|
||||
if ( ! (WriteHeaderField("fields", names) &&
|
||||
WriteHeaderField("types", types)) )
|
||||
if ( ! (WriteHeaderField("fields", names) && WriteHeaderField("types", types)) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -630,8 +607,7 @@ bool Ascii::DoFinish(double network_time)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Ascii::DoWrite(int num_fields, const threading::Field* const * fields,
|
||||
threading::Value** vals)
|
||||
bool Ascii::DoWrite(int num_fields, const threading::Field* const* fields, threading::Value** vals)
|
||||
{
|
||||
if ( ! fd )
|
||||
DoInit(Info(), NumFields(), Fields());
|
||||
|
@ -662,7 +638,7 @@ bool Ascii::DoWrite(int num_fields, const threading::Field* const * fields,
|
|||
if ( ! InternalWrite(fd, bytes, len) )
|
||||
goto write_error;
|
||||
|
||||
if ( ! IsBuf() )
|
||||
if ( ! IsBuf() )
|
||||
fsync(fd);
|
||||
|
||||
return true;
|
||||
|
@ -695,13 +671,13 @@ bool Ascii::DoRotate(const char* rotated_path, double open, double close, bool t
|
|||
{
|
||||
char buf[256];
|
||||
util::zeek_strerror_r(errno, buf, sizeof(buf));
|
||||
Error(Fmt("failed to rename %s to %s: %s", fname.c_str(),
|
||||
nname.c_str(), buf));
|
||||
Error(Fmt("failed to rename %s to %s: %s", fname.c_str(), nname.c_str(), buf));
|
||||
FinishedRotation();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool use_shadow = BifConst::LogAscii::enable_leftover_log_rotation && Info().rotation_interval > 0;
|
||||
bool use_shadow =
|
||||
BifConst::LogAscii::enable_leftover_log_rotation && Info().rotation_interval > 0;
|
||||
|
||||
if ( use_shadow )
|
||||
{
|
||||
|
@ -755,8 +731,8 @@ static std::vector<LeftoverLog> find_leftover_logs()
|
|||
cwd[1] = '\0';
|
||||
}
|
||||
|
||||
reporter->Error("failed to open directory '%s' in search of leftover logs: %s",
|
||||
cwd, strerror(errno));
|
||||
reporter->Error("failed to open directory '%s' in search of leftover logs: %s", cwd,
|
||||
strerror(errno));
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -774,8 +750,8 @@ static std::vector<LeftoverLog> find_leftover_logs()
|
|||
if ( ll->error.empty() )
|
||||
rval.emplace_back(std::move(*ll));
|
||||
else
|
||||
reporter->Error("failed to process leftover log '%s': %s",
|
||||
log_name.data(), ll->error.data());
|
||||
reporter->Error("failed to process leftover log '%s': %s", log_name.data(),
|
||||
ll->error.data());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -833,8 +809,8 @@ void Ascii::RotateLeftoverLogs()
|
|||
ll.filename.data(), ll.post_proc_func.data());
|
||||
}
|
||||
|
||||
auto rotation_path = log_mgr->FormatRotationPath(
|
||||
writer_val, ll.Path(), ll.open_time, ll.close_time, false, ppf);
|
||||
auto rotation_path = log_mgr->FormatRotationPath(writer_val, ll.Path(), ll.open_time,
|
||||
ll.close_time, false, ppf);
|
||||
|
||||
rotation_path += ll.extension;
|
||||
|
||||
|
@ -853,19 +829,19 @@ void Ascii::RotateLeftoverLogs()
|
|||
|
||||
if ( ! ll.DeleteShadow() )
|
||||
// Unusual failure to report, but not strictly fatal.
|
||||
reporter->Warning("Failed to unlink %s: %s",
|
||||
ll.shadow_filename.data(), strerror(errno));
|
||||
reporter->Warning("Failed to unlink %s: %s", ll.shadow_filename.data(),
|
||||
strerror(errno));
|
||||
|
||||
try
|
||||
{
|
||||
ppf->Invoke(std::move(rot_info));
|
||||
reporter->Info("Rotated/postprocessed leftover log '%s' -> '%s' ",
|
||||
ll.filename.data(), rotation_path.data());
|
||||
reporter->Info("Rotated/postprocessed leftover log '%s' -> '%s' ", ll.filename.data(),
|
||||
rotation_path.data());
|
||||
}
|
||||
catch ( InterpreterException& e )
|
||||
{
|
||||
reporter->Warning("Postprocess function '%s' failed for leftover log '%s'",
|
||||
ppf->Name(), ll.filename.data());
|
||||
reporter->Warning("Postprocess function '%s' failed for leftover log '%s'", ppf->Name(),
|
||||
ll.filename.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -940,23 +916,24 @@ bool Ascii::InternalClose(int fd)
|
|||
if ( res == Z_OK )
|
||||
return true;
|
||||
|
||||
switch ( res ) {
|
||||
case Z_STREAM_ERROR:
|
||||
Error("Ascii::InternalClose gzclose error: invalid file stream");
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
Error("Ascii::InternalClose gzclose error: "
|
||||
"no compression progress possible during buffer flush");
|
||||
break;
|
||||
case Z_ERRNO:
|
||||
Error(Fmt("Ascii::InternalClose gzclose error: %s\n", Strerror(errno)));
|
||||
break;
|
||||
default:
|
||||
Error("Ascii::InternalClose invalid gzclose result");
|
||||
break;
|
||||
}
|
||||
switch ( res )
|
||||
{
|
||||
case Z_STREAM_ERROR:
|
||||
Error("Ascii::InternalClose gzclose error: invalid file stream");
|
||||
break;
|
||||
case Z_BUF_ERROR:
|
||||
Error("Ascii::InternalClose gzclose error: "
|
||||
"no compression progress possible during buffer flush");
|
||||
break;
|
||||
case Z_ERRNO:
|
||||
Error(Fmt("Ascii::InternalClose gzclose error: %s\n", Strerror(errno)));
|
||||
break;
|
||||
default:
|
||||
Error("Ascii::InternalClose invalid gzclose result");
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace zeek::logging::writer::detail
|
||||
} // namespace zeek::logging::writer::detail
|
||||
|
|
|
@ -6,33 +6,36 @@
|
|||
|
||||
#include <zlib.h>
|
||||
|
||||
#include "zeek/Desc.h"
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
#include "zeek/threading/formatters/Ascii.h"
|
||||
#include "zeek/threading/formatters/JSON.h"
|
||||
#include "zeek/Desc.h"
|
||||
|
||||
namespace zeek::plugin::detail::Zeek_AsciiWriter { class Plugin; }
|
||||
namespace zeek::plugin::detail::Zeek_AsciiWriter
|
||||
{
|
||||
class Plugin;
|
||||
}
|
||||
|
||||
namespace zeek::logging::writer::detail {
|
||||
namespace zeek::logging::writer::detail
|
||||
{
|
||||
|
||||
class Ascii : public WriterBackend {
|
||||
class Ascii : public WriterBackend
|
||||
{
|
||||
public:
|
||||
explicit Ascii(WriterFrontend* frontend);
|
||||
~Ascii() override;
|
||||
|
||||
static std::string LogExt();
|
||||
|
||||
static WriterBackend* Instantiate(WriterFrontend* frontend)
|
||||
{ return new Ascii(frontend); }
|
||||
static WriterBackend* Instantiate(WriterFrontend* frontend) { return new Ascii(frontend); }
|
||||
|
||||
protected:
|
||||
bool DoInit(const WriterInfo& info, int num_fields,
|
||||
const threading::Field* const* fields) override;
|
||||
bool DoWrite(int num_fields, const threading::Field* const* fields,
|
||||
threading::Value** vals) override;
|
||||
threading::Value** vals) override;
|
||||
bool DoSetBuf(bool enabled) override;
|
||||
bool DoRotate(const char* rotated_path, double open,
|
||||
double close, bool terminating) override;
|
||||
bool DoRotate(const char* rotated_path, double open, double close, bool terminating) override;
|
||||
bool DoFlush(double network_time) override;
|
||||
bool DoFinish(double network_time) override;
|
||||
bool DoHeartbeat(double network_time, double current_time) override;
|
||||
|
@ -42,7 +45,7 @@ private:
|
|||
|
||||
static void RotateLeftoverLogs();
|
||||
|
||||
bool IsSpecial(const std::string &path) { return path.find("/dev/") == 0; }
|
||||
bool IsSpecial(const std::string& path) { return path.find("/dev/") == 0; }
|
||||
bool WriteHeader(const std::string& path);
|
||||
bool WriteHeaderField(const std::string& key, const std::string& value);
|
||||
void CloseFile(double t);
|
||||
|
@ -76,9 +79,9 @@ private:
|
|||
bool enable_utf_8;
|
||||
std::string json_timestamps;
|
||||
std::string logdir;
|
||||
|
||||
|
||||
threading::Formatter* formatter;
|
||||
bool init_options;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace zeek::logging::writer::detail
|
||||
} // namespace zeek::logging::writer::detail
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
// See the file in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/plugin/Plugin.h"
|
||||
|
||||
#include "zeek/logging/writers/ascii/Ascii.h"
|
||||
|
||||
namespace zeek::plugin::detail::Zeek_AsciiWriter {
|
||||
namespace zeek::plugin::detail::Zeek_AsciiWriter
|
||||
{
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
class Plugin : public zeek::plugin::Plugin
|
||||
{
|
||||
public:
|
||||
zeek::plugin::Configuration Configure() override
|
||||
{
|
||||
AddComponent(new zeek::logging::Component("Ascii", zeek::logging::writer::detail::Ascii::Instantiate));
|
||||
AddComponent(new zeek::logging::Component(
|
||||
"Ascii", zeek::logging::writer::detail::Ascii::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::AsciiWriter";
|
||||
config.description = "ASCII log writer";
|
||||
return config;
|
||||
}
|
||||
|
||||
protected:
|
||||
void InitPostScript() override
|
||||
{
|
||||
zeek::logging::writer::detail::Ascii::RotateLeftoverLogs();
|
||||
}
|
||||
void InitPostScript() override { zeek::logging::writer::detail::Ascii::RotateLeftoverLogs(); }
|
||||
|
||||
} plugin;
|
||||
} plugin;
|
||||
|
||||
} // namespace zeek::plugin::detail::Zeek_AsciiWriter
|
||||
} // namespace zeek::plugin::detail::Zeek_AsciiWriter
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
#include "zeek/logging/writers/none/none.bif.h"
|
||||
|
||||
namespace zeek::logging::writer::detail {
|
||||
namespace zeek::logging::writer::detail
|
||||
{
|
||||
|
||||
bool None::DoInit(const WriterInfo& info, int num_fields,
|
||||
const threading::Field* const * fields)
|
||||
bool None::DoInit(const WriterInfo& info, int num_fields, const threading::Field* const* fields)
|
||||
{
|
||||
if ( BifConst::LogNone::debug )
|
||||
{
|
||||
|
@ -19,21 +19,22 @@ bool None::DoInit(const WriterInfo& info, int num_fields,
|
|||
|
||||
// Output the config sorted by keys.
|
||||
|
||||
std::vector<std::pair<std::string, std::string> > keys;
|
||||
std::vector<std::pair<std::string, std::string>> keys;
|
||||
|
||||
for ( WriterInfo::config_map::const_iterator i = info.config.begin(); i != info.config.end(); i++ )
|
||||
for ( WriterInfo::config_map::const_iterator i = info.config.begin();
|
||||
i != info.config.end(); i++ )
|
||||
keys.push_back(std::make_pair(i->first, i->second));
|
||||
|
||||
std::sort(keys.begin(), keys.end());
|
||||
|
||||
for ( std::vector<std::pair<std::string, std::string> >::const_iterator i = keys.begin(); i != keys.end(); i++ )
|
||||
for ( std::vector<std::pair<std::string, std::string>>::const_iterator i = keys.begin();
|
||||
i != keys.end(); i++ )
|
||||
std::cout << " config[" << (*i).first << "] = " << (*i).second << std::endl;
|
||||
|
||||
for ( int i = 0; i < num_fields; i++ )
|
||||
{
|
||||
const threading::Field* field = fields[i];
|
||||
std::cout << " field " << field->name << ": "
|
||||
<< type_name(field->type) << std::endl;
|
||||
std::cout << " field " << field->name << ": " << type_name(field->type) << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
@ -44,7 +45,7 @@ bool None::DoInit(const WriterInfo& info, int num_fields,
|
|||
|
||||
bool None::DoRotate(const char* rotated_path, double open, double close, bool terminating)
|
||||
{
|
||||
if ( ! FinishedRotation("/dev/null", Info().path, open, close, terminating))
|
||||
if ( ! FinishedRotation("/dev/null", Info().path, open, close, terminating) )
|
||||
{
|
||||
Error(Fmt("error rotating %s", Info().path));
|
||||
return false;
|
||||
|
@ -53,4 +54,4 @@ bool None::DoRotate(const char* rotated_path, double open, double close, bool te
|
|||
return true;
|
||||
}
|
||||
|
||||
} // namespace zeek::logging::writer::detail
|
||||
} // namespace zeek::logging::writer::detail
|
||||
|
|
|
@ -6,27 +6,30 @@
|
|||
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
|
||||
namespace zeek::logging::writer::detail {
|
||||
namespace zeek::logging::writer::detail
|
||||
{
|
||||
|
||||
class None : public WriterBackend {
|
||||
class None : public WriterBackend
|
||||
{
|
||||
public:
|
||||
explicit None(WriterFrontend* frontend) : WriterBackend(frontend) {}
|
||||
~None() override {};
|
||||
explicit None(WriterFrontend* frontend) : WriterBackend(frontend) { }
|
||||
~None() override{};
|
||||
|
||||
static WriterBackend* Instantiate(WriterFrontend* frontend)
|
||||
{ return new None(frontend); }
|
||||
static WriterBackend* Instantiate(WriterFrontend* frontend) { return new None(frontend); }
|
||||
|
||||
protected:
|
||||
bool DoInit(const WriterInfo& info, int num_fields,
|
||||
const threading::Field* const * fields) override;
|
||||
const threading::Field* const* fields) override;
|
||||
bool DoWrite(int num_fields, const threading::Field* const* fields,
|
||||
threading::Value** vals) override { return true; }
|
||||
threading::Value** vals) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool DoSetBuf(bool enabled) override { return true; }
|
||||
bool DoRotate(const char* rotated_path, double open,
|
||||
double close, bool terminating) override;
|
||||
bool DoRotate(const char* rotated_path, double open, double close, bool terminating) override;
|
||||
bool DoFlush(double network_time) override { return true; }
|
||||
bool DoFinish(double network_time) override { return true; }
|
||||
bool DoHeartbeat(double network_time, double current_time) override { return true; }
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace zeek::logging::writer::detail
|
||||
} // namespace zeek::logging::writer::detail
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
// See the file in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/plugin/Plugin.h"
|
||||
|
||||
#include "zeek/logging/writers/none/None.h"
|
||||
|
||||
namespace zeek::plugin::detail::Zeek_NoneWriter {
|
||||
namespace zeek::plugin::detail::Zeek_NoneWriter
|
||||
{
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
class Plugin : public zeek::plugin::Plugin
|
||||
{
|
||||
public:
|
||||
zeek::plugin::Configuration Configure() override
|
||||
{
|
||||
AddComponent(new zeek::logging::Component("None", zeek::logging::writer::detail::None::Instantiate));
|
||||
AddComponent(
|
||||
new zeek::logging::Component("None", zeek::logging::writer::detail::None::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::NoneWriter";
|
||||
config.description = "None log writer (primarily for debugging)";
|
||||
return config;
|
||||
}
|
||||
} plugin;
|
||||
} plugin;
|
||||
|
||||
} // namespace zeek::plugin::detail::Zeek_NoneWriter
|
||||
} // namespace zeek::plugin::detail::Zeek_NoneWriter
|
||||
|
|
|
@ -1,21 +1,25 @@
|
|||
// See the file in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/plugin/Plugin.h"
|
||||
|
||||
#include "zeek/logging/writers/sqlite/SQLite.h"
|
||||
|
||||
namespace zeek::plugin::detail::Zeek_SQLiteWriter {
|
||||
namespace zeek::plugin::detail::Zeek_SQLiteWriter
|
||||
{
|
||||
|
||||
class Plugin : public zeek::plugin::Plugin {
|
||||
class Plugin : public zeek::plugin::Plugin
|
||||
{
|
||||
public:
|
||||
zeek::plugin::Configuration Configure() override
|
||||
{
|
||||
AddComponent(new zeek::logging::Component("SQLite", zeek::logging::writer::detail::SQLite::Instantiate));
|
||||
AddComponent(new zeek::logging::Component(
|
||||
"SQLite", zeek::logging::writer::detail::SQLite::Instantiate));
|
||||
|
||||
zeek::plugin::Configuration config;
|
||||
config.name = "Zeek::SQLiteWriter";
|
||||
config.description = "SQLite log writer";
|
||||
return config;
|
||||
}
|
||||
} plugin;
|
||||
} plugin;
|
||||
|
||||
} // namespace zeek::plugin::detail::Zeek_SQLiteWriter
|
||||
} // namespace zeek::plugin::detail::Zeek_SQLiteWriter
|
||||
|
|
|
@ -1,42 +1,36 @@
|
|||
// See the file "COPYING" in the main distribution directory for copyright.
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
#include "zeek/logging/writers/sqlite/SQLite.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
|
||||
#include "zeek/logging/writers/sqlite/sqlite.bif.h"
|
||||
#include "zeek/threading/SerialTypes.h"
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
using namespace std;
|
||||
using zeek::threading::Value;
|
||||
using zeek::threading::Field;
|
||||
using zeek::threading::Value;
|
||||
|
||||
namespace zeek::logging::writer::detail {
|
||||
namespace zeek::logging::writer::detail
|
||||
{
|
||||
|
||||
SQLite::SQLite(WriterFrontend* frontend)
|
||||
: WriterBackend(frontend),
|
||||
fields(), num_fields(), db(), st()
|
||||
: WriterBackend(frontend), fields(), num_fields(), db(), st()
|
||||
{
|
||||
set_separator.assign(
|
||||
(const char*) BifConst::LogSQLite::set_separator->Bytes(),
|
||||
BifConst::LogSQLite::set_separator->Len()
|
||||
);
|
||||
set_separator.assign((const char*)BifConst::LogSQLite::set_separator->Bytes(),
|
||||
BifConst::LogSQLite::set_separator->Len());
|
||||
|
||||
unset_field.assign(
|
||||
(const char*) BifConst::LogSQLite::unset_field->Bytes(),
|
||||
BifConst::LogSQLite::unset_field->Len()
|
||||
);
|
||||
unset_field.assign((const char*)BifConst::LogSQLite::unset_field->Bytes(),
|
||||
BifConst::LogSQLite::unset_field->Len());
|
||||
|
||||
empty_field.assign(
|
||||
(const char*) BifConst::LogSQLite::empty_field->Bytes(),
|
||||
BifConst::LogSQLite::empty_field->Len()
|
||||
);
|
||||
empty_field.assign((const char*)BifConst::LogSQLite::empty_field->Bytes(),
|
||||
BifConst::LogSQLite::empty_field->Len());
|
||||
|
||||
threading::formatter::Ascii::SeparatorInfo sep_info(string(), set_separator, unset_field, empty_field);
|
||||
threading::formatter::Ascii::SeparatorInfo sep_info(string(), set_separator, unset_field,
|
||||
empty_field);
|
||||
io = new threading::formatter::Ascii(this, sep_info);
|
||||
}
|
||||
|
||||
|
@ -54,50 +48,54 @@ SQLite::~SQLite()
|
|||
delete io;
|
||||
}
|
||||
|
||||
string SQLite::GetTableType(int arg_type, int arg_subtype) {
|
||||
string SQLite::GetTableType(int arg_type, int arg_subtype)
|
||||
{
|
||||
string type;
|
||||
|
||||
switch ( arg_type ) {
|
||||
case TYPE_BOOL:
|
||||
type = "boolean";
|
||||
break;
|
||||
switch ( arg_type )
|
||||
{
|
||||
case TYPE_BOOL:
|
||||
type = "boolean";
|
||||
break;
|
||||
|
||||
case TYPE_INT:
|
||||
case TYPE_COUNT:
|
||||
case TYPE_PORT: // note that we do not save the protocol at the moment. Just like in the case of the ascii-writer
|
||||
type = "integer";
|
||||
break;
|
||||
case TYPE_INT:
|
||||
case TYPE_COUNT:
|
||||
case TYPE_PORT: // note that we do not save the protocol at the moment. Just like in the
|
||||
// case of the ascii-writer
|
||||
type = "integer";
|
||||
break;
|
||||
|
||||
case TYPE_SUBNET:
|
||||
case TYPE_ADDR:
|
||||
type = "text"; // sqlite3 does not have a type for internet addresses
|
||||
break;
|
||||
case TYPE_SUBNET:
|
||||
case TYPE_ADDR:
|
||||
type = "text"; // sqlite3 does not have a type for internet addresses
|
||||
break;
|
||||
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
case TYPE_DOUBLE:
|
||||
type = "double precision";
|
||||
break;
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
case TYPE_DOUBLE:
|
||||
type = "double precision";
|
||||
break;
|
||||
|
||||
case TYPE_ENUM:
|
||||
case TYPE_STRING:
|
||||
case TYPE_FILE:
|
||||
case TYPE_FUNC:
|
||||
type = "text";
|
||||
break;
|
||||
case TYPE_ENUM:
|
||||
case TYPE_STRING:
|
||||
case TYPE_FILE:
|
||||
case TYPE_FUNC:
|
||||
type = "text";
|
||||
break;
|
||||
|
||||
case TYPE_TABLE:
|
||||
case TYPE_VECTOR:
|
||||
type = "text"; // dirty - but sqlite does not directly support arrays. so - we just roll it into a ","-separated string.
|
||||
break;
|
||||
case TYPE_TABLE:
|
||||
case TYPE_VECTOR:
|
||||
type = "text"; // dirty - but sqlite does not directly support arrays. so - we just roll
|
||||
// it into a ","-separated string.
|
||||
break;
|
||||
|
||||
default:
|
||||
Error(Fmt("unsupported field format %d ", arg_type));
|
||||
return ""; // not the cleanest way to abort. But sqlite will complain on create table...
|
||||
}
|
||||
default:
|
||||
Error(Fmt("unsupported field format %d ", arg_type));
|
||||
return ""; // not the cleanest way to abort. But sqlite will complain on create table...
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
// returns true true in case of error
|
||||
bool SQLite::checkError(int code)
|
||||
|
@ -111,12 +109,12 @@ bool SQLite::checkError(int code)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SQLite::DoInit(const WriterInfo& info, int arg_num_fields,
|
||||
const Field* const * arg_fields)
|
||||
bool SQLite::DoInit(const WriterInfo& info, int arg_num_fields, const Field* const* arg_fields)
|
||||
{
|
||||
if ( sqlite3_threadsafe() == 0 )
|
||||
{
|
||||
Error("SQLite reports that it is not threadsafe. Zeek needs a threadsafe version of SQLite. Aborting");
|
||||
Error("SQLite reports that it is not threadsafe. Zeek needs a threadsafe version of "
|
||||
"SQLite. Aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -136,24 +134,20 @@ bool SQLite::DoInit(const WriterInfo& info, int arg_num_fields,
|
|||
WriterInfo::config_map::const_iterator it = info.config.find("tablename");
|
||||
if ( it == info.config.end() )
|
||||
{
|
||||
MsgThread::Info(Fmt("tablename configuration option not found. Defaulting to path %s", info.path));
|
||||
MsgThread::Info(
|
||||
Fmt("tablename configuration option not found. Defaulting to path %s", info.path));
|
||||
tablename = info.path;
|
||||
}
|
||||
else
|
||||
tablename = it->second;
|
||||
|
||||
if ( checkError(sqlite3_open_v2(
|
||||
fullpath.c_str(),
|
||||
&db,
|
||||
SQLITE_OPEN_READWRITE |
|
||||
SQLITE_OPEN_CREATE |
|
||||
SQLITE_OPEN_NOMUTEX
|
||||
,
|
||||
NULL)) )
|
||||
fullpath.c_str(), &db,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL)) )
|
||||
return false;
|
||||
|
||||
string create = "CREATE TABLE IF NOT EXISTS " + tablename + " (\n";
|
||||
//"id SERIAL UNIQUE NOT NULL"; // SQLite has rowids, we do not need a counter here.
|
||||
//"id SERIAL UNIQUE NOT NULL"; // SQLite has rowids, we do not need a counter here.
|
||||
|
||||
for ( unsigned int i = 0; i < num_fields; ++i )
|
||||
{
|
||||
|
@ -190,7 +184,7 @@ bool SQLite::DoInit(const WriterInfo& info, int arg_num_fields,
|
|||
|
||||
create += "\n);";
|
||||
|
||||
char *errorMsg = 0;
|
||||
char* errorMsg = 0;
|
||||
int res = sqlite3_exec(db, create.c_str(), NULL, NULL, &errorMsg);
|
||||
if ( res != SQLITE_OK )
|
||||
{
|
||||
|
@ -233,7 +227,7 @@ bool SQLite::DoInit(const WriterInfo& info, int arg_num_fields,
|
|||
|
||||
insert = names + insert;
|
||||
|
||||
if ( checkError(sqlite3_prepare_v2(db, insert.c_str(), insert.size()+1, &st, NULL)) )
|
||||
if ( checkError(sqlite3_prepare_v2(db, insert.c_str(), insert.size() + 1, &st, NULL)) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -244,103 +238,107 @@ int SQLite::AddParams(Value* val, int pos)
|
|||
if ( ! val->present )
|
||||
return sqlite3_bind_null(st, pos);
|
||||
|
||||
switch ( val->type ) {
|
||||
case TYPE_BOOL:
|
||||
return sqlite3_bind_int(st, pos, val->val.int_val != 0 ? 1 : 0 );
|
||||
|
||||
case TYPE_INT:
|
||||
return sqlite3_bind_int(st, pos, val->val.int_val);
|
||||
|
||||
case TYPE_COUNT:
|
||||
return sqlite3_bind_int(st, pos, val->val.uint_val);
|
||||
|
||||
case TYPE_PORT:
|
||||
return sqlite3_bind_int(st, pos, val->val.port_val.port);
|
||||
|
||||
case TYPE_SUBNET:
|
||||
switch ( val->type )
|
||||
{
|
||||
string out = io->Render(val->val.subnet_val);
|
||||
return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT);
|
||||
}
|
||||
case TYPE_BOOL:
|
||||
return sqlite3_bind_int(st, pos, val->val.int_val != 0 ? 1 : 0);
|
||||
|
||||
case TYPE_ADDR:
|
||||
{
|
||||
string out = io->Render(val->val.addr_val);
|
||||
return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT);
|
||||
}
|
||||
case TYPE_INT:
|
||||
return sqlite3_bind_int(st, pos, val->val.int_val);
|
||||
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
case TYPE_DOUBLE:
|
||||
return sqlite3_bind_double(st, pos, val->val.double_val);
|
||||
case TYPE_COUNT:
|
||||
return sqlite3_bind_int(st, pos, val->val.uint_val);
|
||||
|
||||
case TYPE_ENUM:
|
||||
case TYPE_STRING:
|
||||
case TYPE_FILE:
|
||||
case TYPE_FUNC:
|
||||
{
|
||||
if ( ! val->val.string_val.length || val->val.string_val.length == 0 )
|
||||
return sqlite3_bind_null(st, pos);
|
||||
case TYPE_PORT:
|
||||
return sqlite3_bind_int(st, pos, val->val.port_val.port);
|
||||
|
||||
return sqlite3_bind_text(st, pos, val->val.string_val.data, val->val.string_val.length, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
{
|
||||
ODesc desc;
|
||||
desc.Clear();
|
||||
desc.EnableEscaping();
|
||||
desc.AddEscapeSequence(set_separator);
|
||||
|
||||
if ( ! val->val.set_val.size )
|
||||
desc.Add(empty_field);
|
||||
else
|
||||
for ( bro_int_t j = 0; j < val->val.set_val.size; j++ )
|
||||
case TYPE_SUBNET:
|
||||
{
|
||||
if ( j > 0 )
|
||||
desc.AddRaw(set_separator);
|
||||
|
||||
io->Describe(&desc, val->val.set_val.vals[j], fields[pos-1]->name);
|
||||
string out = io->Render(val->val.subnet_val);
|
||||
return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
desc.RemoveEscapeSequence(set_separator);
|
||||
return sqlite3_bind_text(st, pos, (const char*) desc.Bytes(), desc.Len(), SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
case TYPE_VECTOR:
|
||||
{
|
||||
ODesc desc;
|
||||
desc.Clear();
|
||||
desc.EnableEscaping();
|
||||
desc.AddEscapeSequence(set_separator);
|
||||
|
||||
if ( ! val->val.vector_val.size )
|
||||
desc.Add(empty_field);
|
||||
else
|
||||
for ( bro_int_t j = 0; j < val->val.vector_val.size; j++ )
|
||||
case TYPE_ADDR:
|
||||
{
|
||||
if ( j > 0 )
|
||||
desc.AddRaw(set_separator);
|
||||
|
||||
io->Describe(&desc, val->val.vector_val.vals[j], fields[pos-1]->name);
|
||||
string out = io->Render(val->val.addr_val);
|
||||
return sqlite3_bind_text(st, pos, out.data(), out.size(), SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
desc.RemoveEscapeSequence(set_separator);
|
||||
return sqlite3_bind_text(st, pos, (const char*) desc.Bytes(), desc.Len(), SQLITE_TRANSIENT);
|
||||
case TYPE_TIME:
|
||||
case TYPE_INTERVAL:
|
||||
case TYPE_DOUBLE:
|
||||
return sqlite3_bind_double(st, pos, val->val.double_val);
|
||||
|
||||
case TYPE_ENUM:
|
||||
case TYPE_STRING:
|
||||
case TYPE_FILE:
|
||||
case TYPE_FUNC:
|
||||
{
|
||||
if ( ! val->val.string_val.length || val->val.string_val.length == 0 )
|
||||
return sqlite3_bind_null(st, pos);
|
||||
|
||||
return sqlite3_bind_text(st, pos, val->val.string_val.data,
|
||||
val->val.string_val.length, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
case TYPE_TABLE:
|
||||
{
|
||||
ODesc desc;
|
||||
desc.Clear();
|
||||
desc.EnableEscaping();
|
||||
desc.AddEscapeSequence(set_separator);
|
||||
|
||||
if ( ! val->val.set_val.size )
|
||||
desc.Add(empty_field);
|
||||
else
|
||||
for ( bro_int_t j = 0; j < val->val.set_val.size; j++ )
|
||||
{
|
||||
if ( j > 0 )
|
||||
desc.AddRaw(set_separator);
|
||||
|
||||
io->Describe(&desc, val->val.set_val.vals[j], fields[pos - 1]->name);
|
||||
}
|
||||
|
||||
desc.RemoveEscapeSequence(set_separator);
|
||||
return sqlite3_bind_text(st, pos, (const char*)desc.Bytes(), desc.Len(),
|
||||
SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
case TYPE_VECTOR:
|
||||
{
|
||||
ODesc desc;
|
||||
desc.Clear();
|
||||
desc.EnableEscaping();
|
||||
desc.AddEscapeSequence(set_separator);
|
||||
|
||||
if ( ! val->val.vector_val.size )
|
||||
desc.Add(empty_field);
|
||||
else
|
||||
for ( bro_int_t j = 0; j < val->val.vector_val.size; j++ )
|
||||
{
|
||||
if ( j > 0 )
|
||||
desc.AddRaw(set_separator);
|
||||
|
||||
io->Describe(&desc, val->val.vector_val.vals[j], fields[pos - 1]->name);
|
||||
}
|
||||
|
||||
desc.RemoveEscapeSequence(set_separator);
|
||||
return sqlite3_bind_text(st, pos, (const char*)desc.Bytes(), desc.Len(),
|
||||
SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
default:
|
||||
Error(Fmt("unsupported field format %d", val->type));
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
Error(Fmt("unsupported field format %d", val->type));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool SQLite::DoWrite(int num_fields, const Field* const * fields, Value** vals)
|
||||
bool SQLite::DoWrite(int num_fields, const Field* const* fields, Value** vals)
|
||||
{
|
||||
// bind parameters
|
||||
for ( int i = 0; i < num_fields; i++ )
|
||||
{
|
||||
if ( checkError(AddParams(vals[i], i+1)) )
|
||||
if ( checkError(AddParams(vals[i], i + 1)) )
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -360,13 +358,13 @@ bool SQLite::DoWrite(int num_fields, const Field* const * fields, Value** vals)
|
|||
|
||||
bool SQLite::DoRotate(const char* rotated_path, double open, double close, bool terminating)
|
||||
{
|
||||
if ( ! FinishedRotation("/dev/null", Info().path, open, close, terminating))
|
||||
if ( ! FinishedRotation("/dev/null", Info().path, open, close, terminating) )
|
||||
{
|
||||
Error(Fmt("error rotating %s", Info().path));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace zeek::logging::writer::detail
|
||||
} // namespace zeek::logging::writer::detail
|
||||
|
|
|
@ -4,31 +4,30 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
#include "zeek/threading/formatters/Ascii.h"
|
||||
#include "zeek/3rdparty/sqlite3.h"
|
||||
#include "zeek/Desc.h"
|
||||
#include "zeek/logging/WriterBackend.h"
|
||||
#include "zeek/threading/formatters/Ascii.h"
|
||||
#include "zeek/zeek-config.h"
|
||||
|
||||
namespace zeek::logging::writer::detail {
|
||||
namespace zeek::logging::writer::detail
|
||||
{
|
||||
|
||||
class SQLite : public WriterBackend {
|
||||
class SQLite : public WriterBackend
|
||||
{
|
||||
public:
|
||||
explicit SQLite(WriterFrontend* frontend);
|
||||
~SQLite() override;
|
||||
|
||||
static WriterBackend* Instantiate(WriterFrontend* frontend)
|
||||
{ return new SQLite(frontend); }
|
||||
static WriterBackend* Instantiate(WriterFrontend* frontend) { return new SQLite(frontend); }
|
||||
|
||||
protected:
|
||||
bool DoInit(const WriterInfo& info, int arg_num_fields,
|
||||
const threading::Field* const* arg_fields) override;
|
||||
const threading::Field* const* arg_fields) override;
|
||||
bool DoWrite(int num_fields, const threading::Field* const* fields,
|
||||
threading::Value** vals) override;
|
||||
threading::Value** vals) override;
|
||||
bool DoSetBuf(bool enabled) override { return true; }
|
||||
bool DoRotate(const char* rotated_path, double open,
|
||||
double close, bool terminating) override;
|
||||
bool DoRotate(const char* rotated_path, double open, double close, bool terminating) override;
|
||||
bool DoFlush(double network_time) override { return true; }
|
||||
bool DoFinish(double network_time) override { return true; }
|
||||
bool DoHeartbeat(double network_time, double current_time) override { return true; }
|
||||
|
@ -39,17 +38,17 @@ private:
|
|||
int AddParams(threading::Value* val, int pos);
|
||||
std::string GetTableType(int, int);
|
||||
|
||||
const threading::Field* const * fields; // raw mapping
|
||||
const threading::Field* const* fields; // raw mapping
|
||||
unsigned int num_fields;
|
||||
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *st;
|
||||
sqlite3* db;
|
||||
sqlite3_stmt* st;
|
||||
|
||||
std::string set_separator;
|
||||
std::string unset_field;
|
||||
std::string empty_field;
|
||||
|
||||
threading::formatter::Ascii* io;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace zeek::logging::writer::detail
|
||||
} // namespace zeek::logging::writer::detail
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue