mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Merge branch 'topic/corelight/ascii-gzip' of https://github.com/corelight/bro
* 'topic/corelight/ascii-gzip' of https://github.com/corelight/bro: Add gzip log writing to the ascii writer.
This commit is contained in:
commit
4d06ee85ce
9 changed files with 222 additions and 9 deletions
|
@ -24,6 +24,8 @@ Ascii::Ascii(WriterFrontend* frontend) : WriterBackend(frontend)
|
|||
tsv = false;
|
||||
use_json = false;
|
||||
formatter = 0;
|
||||
gzip_level = 0;
|
||||
gzfile = nullptr;
|
||||
|
||||
InitConfigOptions();
|
||||
init_options = InitFilterOptions();
|
||||
|
@ -34,6 +36,7 @@ void Ascii::InitConfigOptions()
|
|||
output_to_stdout = BifConst::LogAscii::output_to_stdout;
|
||||
include_meta = BifConst::LogAscii::include_meta;
|
||||
use_json = BifConst::LogAscii::use_json;
|
||||
gzip_level = BifConst::LogAscii::gzip_level;
|
||||
|
||||
separator.assign(
|
||||
(const char*) BifConst::LogAscii::separator->Bytes(),
|
||||
|
@ -89,6 +92,16 @@ bool Ascii::InitFilterOptions()
|
|||
}
|
||||
}
|
||||
|
||||
else if ( strcmp(i->first, "gzip_level" ) == 0 )
|
||||
{
|
||||
gzip_level = atoi(i->second);
|
||||
|
||||
if ( gzip_level < 0 || gzip_level > 9 )
|
||||
{
|
||||
Error("invalid value for 'gzip_level', must be a number between 0 and 9.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( strcmp(i->first, "use_json") == 0 )
|
||||
{
|
||||
if ( strcmp(i->second, "T") == 0 )
|
||||
|
@ -192,7 +205,7 @@ bool Ascii::WriteHeaderField(const string& key, const string& val)
|
|||
{
|
||||
string str = meta_prefix + key + separator + val + "\n";
|
||||
|
||||
return safe_write(fd, str.c_str(), str.length());
|
||||
return InternalWrite(fd, str.c_str(), str.length());
|
||||
}
|
||||
|
||||
void Ascii::CloseFile(double t)
|
||||
|
@ -203,8 +216,9 @@ void Ascii::CloseFile(double t)
|
|||
if ( include_meta && ! tsv )
|
||||
WriteHeaderField("close", Timestamp(0));
|
||||
|
||||
safe_close(fd);
|
||||
InternalClose(fd);
|
||||
fd = 0;
|
||||
gzfile = nullptr;
|
||||
}
|
||||
|
||||
bool Ascii::DoInit(const WriterInfo& info, int num_fields, const Field* const * fields)
|
||||
|
@ -219,7 +233,8 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const Field* const *
|
|||
if ( output_to_stdout )
|
||||
path = "/dev/stdout";
|
||||
|
||||
fname = IsSpecial(path) ? path : path + "." + LogExt();
|
||||
fname = IsSpecial(path) ? path : path + "." + LogExt() +
|
||||
(gzip_level > 0 ? ".gz" : "");
|
||||
|
||||
fd = open(fname.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
||||
|
||||
|
@ -231,6 +246,31 @@ bool Ascii::DoInit(const WriterInfo& info, int num_fields, const Field* const *
|
|||
return false;
|
||||
}
|
||||
|
||||
if ( gzip_level > 0 )
|
||||
{
|
||||
if ( gzip_level < 0 || gzip_level > 9 )
|
||||
{
|
||||
Error("invalid value for 'gzip_level', must be a number between 0 and 9.");
|
||||
return false;
|
||||
}
|
||||
|
||||
char mode[4];
|
||||
snprintf(mode, sizeof(mode), "wb%d", gzip_level);
|
||||
errno = 0; // errno will only be set under certain circumstances by gzdopen.
|
||||
gzfile = gzdopen(fd, mode);
|
||||
|
||||
if ( gzfile == nullptr )
|
||||
{
|
||||
Error(Fmt("cannot gzip %s: %s", fname.c_str(),
|
||||
Strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gzfile = nullptr;
|
||||
}
|
||||
|
||||
if ( ! WriteHeader(path) )
|
||||
{
|
||||
Error(Fmt("error writing to %s: %s", fname.c_str(), Strerror(errno)));
|
||||
|
@ -264,7 +304,7 @@ bool Ascii::WriteHeader(const string& path)
|
|||
{
|
||||
// A single TSV-style line is all we need.
|
||||
string str = names + "\n";
|
||||
if ( ! safe_write(fd, str.c_str(), str.length()) )
|
||||
if ( ! InternalWrite(fd, str.c_str(), str.length()) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -275,7 +315,7 @@ bool Ascii::WriteHeader(const string& path)
|
|||
+ get_escaped_string(separator, false)
|
||||
+ "\n";
|
||||
|
||||
if ( ! safe_write(fd, str.c_str(), str.length()) )
|
||||
if ( ! InternalWrite(fd, str.c_str(), str.length()) )
|
||||
return false;
|
||||
|
||||
if ( ! (WriteHeaderField("set_separator", get_escaped_string(set_separator, false)) &&
|
||||
|
@ -337,14 +377,14 @@ bool Ascii::DoWrite(int num_fields, const Field* const * fields,
|
|||
char hex[4] = {'\\', 'x', '0', '0'};
|
||||
bytetohex(bytes[0], hex + 2);
|
||||
|
||||
if ( ! safe_write(fd, hex, 4) )
|
||||
if ( ! InternalWrite(fd, hex, 4) )
|
||||
goto write_error;
|
||||
|
||||
++bytes;
|
||||
--len;
|
||||
}
|
||||
|
||||
if ( ! safe_write(fd, bytes, len) )
|
||||
if ( ! InternalWrite(fd, bytes, len) )
|
||||
goto write_error;
|
||||
|
||||
if ( ! IsBuf() )
|
||||
|
@ -368,7 +408,8 @@ bool Ascii::DoRotate(const char* rotated_path, double open, double close, bool t
|
|||
|
||||
CloseFile(close);
|
||||
|
||||
string nname = string(rotated_path) + "." + LogExt();
|
||||
string nname = string(rotated_path) + "." + LogExt() +
|
||||
(gzip_level > 0 ? ".gz" : "");
|
||||
|
||||
if ( rename(fname.c_str(), nname.c_str()) != 0 )
|
||||
{
|
||||
|
@ -434,4 +475,58 @@ string Ascii::Timestamp(double t)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
bool Ascii::InternalWrite(int fd, const char* data, int len)
|
||||
{
|
||||
if ( ! gzfile )
|
||||
return safe_write(fd, data, len);
|
||||
|
||||
while ( len > 0 )
|
||||
{
|
||||
int n = gzwrite(gzfile, data, len);
|
||||
|
||||
if ( n <= 0 )
|
||||
{
|
||||
const char* err = gzerror(gzfile, &n);
|
||||
Error(Fmt("Ascii::InternalWrite error: %s\n", err));
|
||||
return false;
|
||||
}
|
||||
|
||||
data += n;
|
||||
len -= n;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Ascii::InternalClose(int fd)
|
||||
{
|
||||
if ( ! gzfile )
|
||||
{
|
||||
safe_close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
int res = gzclose(gzfile);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue