mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 15:48:19 +00:00
Implement leftover log rotation/archival for supervised nodes
This helps prevent a node from being killed/crashing in the middle of writing a log, restarting, and eventually clobbering that log file that never underwent the rotation/archival process. The old `archive-log` and `post-terminate` scripts as used by ZeekControl previously implemented this behavior, but the new logic is entirely in the ASCII writer. It uses ".shadow" log files stored alongside the real log to help detect such scenarios and rotate them correctly upon the next startup of the Zeek process.
This commit is contained in:
parent
a46e24091a
commit
11949ce37a
11 changed files with 523 additions and 17 deletions
|
@ -1170,6 +1170,11 @@ WriterFrontend* Manager::CreateWriter(zeek::EnumVal* id, zeek::EnumVal* writer,
|
|||
winfo->interval = f->interval;
|
||||
winfo->postprocessor = f->postprocessor;
|
||||
|
||||
if ( f->postprocessor )
|
||||
{
|
||||
delete [] winfo->info->post_proc_func;
|
||||
winfo->info->post_proc_func = copy_string(f->postprocessor->Name());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -1180,6 +1185,18 @@ WriterFrontend* Manager::CreateWriter(zeek::EnumVal* id, zeek::EnumVal* writer,
|
|||
const auto& id = zeek::detail::global_scope()->Find("Log::default_rotation_interval");
|
||||
assert(id);
|
||||
winfo->interval = id->GetVal()->AsInterval();
|
||||
|
||||
if ( winfo->info->post_proc_func &&
|
||||
strlen(winfo->info->post_proc_func) )
|
||||
{
|
||||
auto func = zeek::id::find_func(winfo->info->post_proc_func);
|
||||
|
||||
if ( func )
|
||||
winfo->postprocessor = func.get();
|
||||
else
|
||||
reporter->Warning("failed log postprocessor function lookup: %s\n",
|
||||
winfo->info->post_proc_func);
|
||||
}
|
||||
}
|
||||
|
||||
stream->writers.insert(
|
||||
|
@ -1466,23 +1483,32 @@ void Manager::InstallRotationTimer(WriterInfo* winfo)
|
|||
}
|
||||
}
|
||||
|
||||
std::string Manager::FormatRotationTime(time_t t)
|
||||
{
|
||||
struct tm tm;
|
||||
char buf[128];
|
||||
const char* const date_fmt = "%y-%m-%d_%H.%M.%S";
|
||||
localtime_r(&t, &tm);
|
||||
strftime(buf, sizeof(buf), date_fmt, &tm);
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string Manager::FormatRotationPath(std::string_view path, time_t t)
|
||||
{
|
||||
auto rot_str = FormatRotationTime(t);
|
||||
return fmt("%.*s-%s",
|
||||
static_cast<int>(path.size()), path.data(), rot_str.data());
|
||||
}
|
||||
|
||||
void Manager::Rotate(WriterInfo* winfo)
|
||||
{
|
||||
DBG_LOG(DBG_LOGGING, "Rotating %s at %.6f",
|
||||
winfo->writer->Name(), network_time);
|
||||
|
||||
// Build a temporary path for the writer to move the file to.
|
||||
struct tm tm;
|
||||
char buf[128];
|
||||
const char* const date_fmt = "%y-%m-%d_%H.%M.%S";
|
||||
time_t teatime = (time_t)winfo->open_time;
|
||||
|
||||
localtime_r(&teatime, &tm);
|
||||
strftime(buf, sizeof(buf), date_fmt, &tm);
|
||||
|
||||
// Trigger the rotation.
|
||||
const char* tmp = fmt("%s-%s", winfo->writer->Info().path, buf);
|
||||
winfo->writer->Rotate(tmp, winfo->open_time, network_time, terminating);
|
||||
auto tmp = FormatRotationPath(winfo->writer->Info().path,
|
||||
(time_t)winfo->open_time);
|
||||
winfo->writer->Rotate(tmp.data(), winfo->open_time, network_time, terminating);
|
||||
|
||||
++rotations_pending;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue