|
|
|
@ -135,6 +135,8 @@ typedef struct {
|
|
|
|
|
|
|
|
|
|
buffer *access_logbuffer; |
|
|
|
|
buffer *ts_accesslog_str; |
|
|
|
|
buffer *ts_accesslog_fmt_str; |
|
|
|
|
unsigned short append_tz_offset; |
|
|
|
|
|
|
|
|
|
format_fields *parsed_format; |
|
|
|
|
} plugin_config; |
|
|
|
@ -365,6 +367,7 @@ FREE_FUNC(mod_accesslog_free) {
|
|
|
|
|
if (s->log_access_fd != -1) close(s->log_access_fd); |
|
|
|
|
|
|
|
|
|
buffer_free(s->ts_accesslog_str); |
|
|
|
|
buffer_free(s->ts_accesslog_fmt_str); |
|
|
|
|
buffer_free(s->access_logbuffer); |
|
|
|
|
buffer_free(s->format); |
|
|
|
|
buffer_free(s->access_logfile); |
|
|
|
@ -413,6 +416,7 @@ SETDEFAULTS_FUNC(log_access_open) {
|
|
|
|
|
s->format = buffer_init(); |
|
|
|
|
s->access_logbuffer = buffer_init(); |
|
|
|
|
s->ts_accesslog_str = buffer_init(); |
|
|
|
|
s->ts_accesslog_fmt_str = buffer_init(); |
|
|
|
|
s->log_access_fd = -1; |
|
|
|
|
s->last_generated_accesslog_ts = 0; |
|
|
|
|
s->last_generated_accesslog_ts_ptr = &(s->last_generated_accesslog_ts); |
|
|
|
@ -437,6 +441,8 @@ SETDEFAULTS_FUNC(log_access_open) {
|
|
|
|
|
/* parse */ |
|
|
|
|
|
|
|
|
|
if (s->format->used) { |
|
|
|
|
size_t j, count; |
|
|
|
|
|
|
|
|
|
s->parsed_format = calloc(1, sizeof(*(s->parsed_format))); |
|
|
|
|
|
|
|
|
|
if (-1 == accesslog_parse_format(srv, s->parsed_format, s->format)) { |
|
|
|
@ -446,6 +452,29 @@ SETDEFAULTS_FUNC(log_access_open) {
|
|
|
|
|
|
|
|
|
|
return HANDLER_ERROR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* make sure they didn't try to send the timestamp in twice...
|
|
|
|
|
* also, save the format string in a different variable (this |
|
|
|
|
* will save a few conditionals later) |
|
|
|
|
*/ |
|
|
|
|
count = 0; |
|
|
|
|
for (j = 0; j < s->parsed_format->used; j++) { |
|
|
|
|
if (FIELD_FORMAT == s->parsed_format->ptr[j]->type) { |
|
|
|
|
if (FORMAT_TIMESTAMP == s->parsed_format->ptr[j]->field) { |
|
|
|
|
if (!buffer_is_empty(s->parsed_format->ptr[j]->string)) { |
|
|
|
|
buffer_copy_string(s->ts_accesslog_fmt_str, s->parsed_format->ptr[j]->string->ptr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (++count > 1) { |
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb", |
|
|
|
|
"you may not use the timestamp twice in the same access log:", s->format); |
|
|
|
|
|
|
|
|
|
return HANDLER_ERROR; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
|
/* debugging */ |
|
|
|
|
for (j = 0; j < s->parsed_format->used; j++) { |
|
|
|
@ -466,6 +495,16 @@ SETDEFAULTS_FUNC(log_access_open) {
|
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s->append_tz_offset = 0; |
|
|
|
|
if (buffer_is_empty(s->ts_accesslog_fmt_str)) { |
|
|
|
|
#if defined(HAVE_STRUCT_TM_GMTOFF) |
|
|
|
|
BUFFER_COPY_STRING_CONST(s->ts_accesslog_fmt_str, "[%d/%b/%Y:%H:%M:%S "); |
|
|
|
|
s->append_tz_offset = 1; |
|
|
|
|
#else |
|
|
|
|
BUFFER_COPY_STRING_CONST(s->ts_accesslog_fmt_str, "[%d/%b/%Y:%H:%M:%S +0000]"); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s->use_syslog) { |
|
|
|
|
/* ignore the next checks */ |
|
|
|
|
continue; |
|
|
|
@ -539,6 +578,8 @@ static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_d
|
|
|
|
|
PATCH(last_generated_accesslog_ts_ptr); |
|
|
|
|
PATCH(access_logbuffer); |
|
|
|
|
PATCH(ts_accesslog_str); |
|
|
|
|
PATCH(ts_accesslog_fmt_str); |
|
|
|
|
PATCH(append_tz_offset); |
|
|
|
|
PATCH(parsed_format); |
|
|
|
|
PATCH(use_syslog); |
|
|
|
|
|
|
|
|
@ -557,17 +598,17 @@ static int mod_accesslog_patch_connection(server *srv, connection *con, plugin_d
|
|
|
|
|
if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.filename"))) { |
|
|
|
|
PATCH(access_logfile); |
|
|
|
|
PATCH(log_access_fd); |
|
|
|
|
PATCH(last_generated_accesslog_ts_ptr); |
|
|
|
|
PATCH(access_logbuffer); |
|
|
|
|
PATCH(ts_accesslog_str); |
|
|
|
|
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.format"))) { |
|
|
|
|
PATCH(format); |
|
|
|
|
PATCH(parsed_format); |
|
|
|
|
PATCH(last_generated_accesslog_ts_ptr); |
|
|
|
|
PATCH(ts_accesslog_str); |
|
|
|
|
PATCH(ts_accesslog_fmt_str); |
|
|
|
|
PATCH(append_tz_offset); |
|
|
|
|
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("accesslog.use-syslog"))) { |
|
|
|
|
PATCH(use_syslog); |
|
|
|
|
PATCH(last_generated_accesslog_ts_ptr); |
|
|
|
|
PATCH(access_logbuffer); |
|
|
|
|
PATCH(ts_accesslog_str); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -614,34 +655,36 @@ REQUESTDONE_FUNC(log_access_write) {
|
|
|
|
|
#if defined(HAVE_STRUCT_TM_GMTOFF) |
|
|
|
|
# ifdef HAVE_LOCALTIME_R |
|
|
|
|
localtime_r(&(srv->cur_ts), &tm); |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", &tm); |
|
|
|
|
# else |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S ", localtime(&(srv->cur_ts))); |
|
|
|
|
# endif |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm); |
|
|
|
|
# else /* HAVE_LOCALTIME_R */ |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, localtime_r(&(srv->cur_ts))); |
|
|
|
|
# endif /* HAVE_LOCALTIME_R */ |
|
|
|
|
p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; |
|
|
|
|
|
|
|
|
|
buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1); |
|
|
|
|
if (p->conf.append_tz_offset) { |
|
|
|
|
buffer_append_string_len(p->conf.ts_accesslog_str, tm.tm_gmtoff >= 0 ? "+" : "-", 1); |
|
|
|
|
|
|
|
|
|
scd = abs(tm.tm_gmtoff); |
|
|
|
|
hrs = scd / 3600; |
|
|
|
|
min = (scd % 3600) / 60; |
|
|
|
|
scd = abs(tm.tm_gmtoff); |
|
|
|
|
hrs = scd / 3600; |
|
|
|
|
min = (scd % 3600) / 60; |
|
|
|
|
|
|
|
|
|
/* hours */ |
|
|
|
|
if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); |
|
|
|
|
buffer_append_long(p->conf.ts_accesslog_str, hrs); |
|
|
|
|
/* hours */ |
|
|
|
|
if (hrs < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); |
|
|
|
|
buffer_append_long(p->conf.ts_accesslog_str, hrs); |
|
|
|
|
|
|
|
|
|
if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); |
|
|
|
|
buffer_append_long(p->conf.ts_accesslog_str, min); |
|
|
|
|
buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]")); |
|
|
|
|
#else |
|
|
|
|
#ifdef HAVE_GMTIME_R |
|
|
|
|
if (min < 10) buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("0")); |
|
|
|
|
buffer_append_long(p->conf.ts_accesslog_str, min); |
|
|
|
|
buffer_append_string_len(p->conf.ts_accesslog_str, CONST_STR_LEN("]")); |
|
|
|
|
} |
|
|
|
|
#else /* HAVE_STRUCT_TM_GMTOFF */ |
|
|
|
|
# ifdef HAVE_GMTIME_R |
|
|
|
|
gmtime_r(&(srv->cur_ts), &tm); |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S +0000]", &tm); |
|
|
|
|
#else |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, "[%d/%b/%Y:%H:%M:%S +0000]", gmtime(&(srv->cur_ts))); |
|
|
|
|
#endif |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, &tm); |
|
|
|
|
# else /* HAVE_GMTIME_R */ |
|
|
|
|
strftime(p->conf.ts_accesslog_str->ptr, p->conf.ts_accesslog_str->size - 1, p->conf.ts_accesslog_fmt_str->ptr, gmtime(&(srv->cur_ts))); |
|
|
|
|
# endif /* HAVE_GMTIME_R */ |
|
|
|
|
p->conf.ts_accesslog_str->used = strlen(p->conf.ts_accesslog_str->ptr) + 1; |
|
|
|
|
#endif |
|
|
|
|
#endif /* HAVE_STRUCT_TM_GMTOFF */ |
|
|
|
|
|
|
|
|
|
*(p->conf.last_generated_accesslog_ts_ptr) = srv->cur_ts; |
|
|
|
|
newts = 1; |
|
|
|
|