mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Switching all use of gmtime and localtime to use reentrant variants.
This was causing occasional problems with the time on processes running lots of threads. The use of gmtime in the json formatter is the likely culprit due to the fact that the json formatter runs in threads. More evidence for this is that the problem only appears to exhibit when logs are being written as JSON.
This commit is contained in:
parent
209c8936d1
commit
40e9724de7
3 changed files with 35 additions and 13 deletions
18
src/bro.bif
18
src/bro.bif
|
@ -145,12 +145,17 @@ static void do_fmt(const char*& fmt, Val* v, ODesc* d)
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t time = time_t(v->InternalDouble());
|
time_t time = time_t(v->InternalDouble());
|
||||||
|
struct tm t;
|
||||||
|
|
||||||
int is_time_fmt = *fmt == 'T';
|
int is_time_fmt = *fmt == 'T';
|
||||||
|
|
||||||
|
if ( ! localtime_r(&time, &t) )
|
||||||
|
s.AddSP("<problem getting time>");
|
||||||
|
|
||||||
if ( ! strftime(out_buf, sizeof(out_buf),
|
if ( ! strftime(out_buf, sizeof(out_buf),
|
||||||
is_time_fmt ?
|
is_time_fmt ?
|
||||||
"%Y-%m-%d-%H:%M" : "%Y-%m-%d-%H:%M:%S",
|
"%Y-%m-%d-%H:%M" : "%Y-%m-%d-%H:%M:%S",
|
||||||
localtime(&time)) )
|
&t) )
|
||||||
s.AddSP("<bad time>");
|
s.AddSP("<bad time>");
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -3140,9 +3145,11 @@ function strftime%(fmt: string, d: time%) : string
|
||||||
%{
|
%{
|
||||||
static char buffer[128];
|
static char buffer[128];
|
||||||
|
|
||||||
time_t t = time_t(d);
|
time_t timeval = time_t(d);
|
||||||
|
struct tm t;
|
||||||
|
|
||||||
if ( strftime(buffer, 128, fmt->CheckString(), localtime(&t)) == 0 )
|
if ( ! localtime_r(&timeval, &t) ||
|
||||||
|
! strftime(buffer, 128, fmt->CheckString(), &t) )
|
||||||
return new StringVal("<strftime error>");
|
return new StringVal("<strftime error>");
|
||||||
|
|
||||||
return new StringVal(buffer);
|
return new StringVal(buffer);
|
||||||
|
@ -3160,9 +3167,10 @@ function strftime%(fmt: string, d: time%) : string
|
||||||
function strptime%(fmt: string, d: string%) : time
|
function strptime%(fmt: string, d: string%) : time
|
||||||
%{
|
%{
|
||||||
const time_t timeval = time_t();
|
const time_t timeval = time_t();
|
||||||
struct tm t = *localtime(&timeval);
|
struct tm t;
|
||||||
|
|
||||||
if ( strptime(d->CheckString(), fmt->CheckString(), &t) == NULL )
|
if ( ! localtime_r(&timeval, &t) ||
|
||||||
|
! strptime(d->CheckString(), fmt->CheckString(), &t) )
|
||||||
{
|
{
|
||||||
reporter->Warning("strptime conversion failed: fmt:%s d:%s", fmt->CheckString(), d->CheckString());
|
reporter->Warning("strptime conversion failed: fmt:%s d:%s", fmt->CheckString(), d->CheckString());
|
||||||
return new Val(0.0, TYPE_TIME);
|
return new Val(0.0, TYPE_TIME);
|
||||||
|
|
|
@ -116,21 +116,28 @@ bool JSON::Describe(ODesc* desc, Value* val, const string& name) const
|
||||||
{
|
{
|
||||||
char buffer[40];
|
char buffer[40];
|
||||||
char buffer2[40];
|
char buffer2[40];
|
||||||
time_t t = time_t(val->val.double_val);
|
time_t the_time = time_t(val->val.double_val);
|
||||||
|
struct tm t;
|
||||||
|
|
||||||
if ( strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", gmtime(&t)) > 0 )
|
desc->AddRaw("\"", 1);
|
||||||
|
|
||||||
|
if ( ! gmtime_r(&the_time, &t) ||
|
||||||
|
! strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%S", &t) )
|
||||||
|
{
|
||||||
|
GetThread()->Error(GetThread()->Fmt("json formatter: failure getting time: (%" PRIu64 ")", val->val.double_val));
|
||||||
|
// This was a failure, doesn't really matter what gets put here
|
||||||
|
// but it should probably stand out...
|
||||||
|
desc->Add("2000-01-01T00:00:00.000000");
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
double integ;
|
double integ;
|
||||||
double frac = modf(val->val.double_val, &integ);
|
double frac = modf(val->val.double_val, &integ);
|
||||||
snprintf(buffer2, sizeof(buffer2), "%s.%06.0fZ", buffer, frac * 1000000);
|
snprintf(buffer2, sizeof(buffer2), "%s.%06.0fZ", buffer, frac * 1000000);
|
||||||
desc->AddRaw("\"", 1);
|
|
||||||
desc->Add(buffer2);
|
desc->Add(buffer2);
|
||||||
desc->AddRaw("\"", 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
desc->AddRaw("\"", 1);
|
||||||
GetThread()->Error(GetThread()->Fmt("strftime error for JSON: %" PRIu64));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ( timestamps == TS_EPOCH )
|
else if ( timestamps == TS_EPOCH )
|
||||||
|
|
|
@ -571,7 +571,14 @@ const char* fmt_access_time(double t)
|
||||||
{
|
{
|
||||||
static char buf[256];
|
static char buf[256];
|
||||||
time_t time = (time_t) t;
|
time_t time = (time_t) t;
|
||||||
strftime(buf, sizeof(buf), "%d/%m-%H:%M", localtime(&time));
|
struct tm ts;
|
||||||
|
|
||||||
|
if ( ! localtime_r(&time, &ts) )
|
||||||
|
{
|
||||||
|
reporter->InternalError("unable to get time");
|
||||||
|
}
|
||||||
|
|
||||||
|
strftime(buf, sizeof(buf), "%d/%m-%H:%M", &ts);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue