[mod_accesslog] %{ratio}n logs compression ratio (fixes #2133)

mod_deflate and mod_compress now provide data for mod_accesslog
"%{ratio}n%%" log format to log compression ratio

Implementation detail: compression ratio is stored in con->environment
since lighttpd does not currently have concept of module notes, which is
from where %{VARNAME}n originates.  In the future, this might change in
lighttpd, so be sure to use %{ratio}n%% and not %{...}e for this info.

x-ref:
  "accesslog support "%n" (compress ratio)"
  https://redmine.lighttpd.net/issues/2133
This commit is contained in:
Glenn Strauss 2016-10-19 06:01:10 -04:00
parent b11d059843
commit 72a5ff1f21
3 changed files with 52 additions and 12 deletions

View File

@ -57,7 +57,8 @@ typedef struct {
FORMAT_BYTES_OUT,
FORMAT_KEEPALIVE_COUNT,
FORMAT_RESPONSE_HEADER
FORMAT_RESPONSE_HEADER,
FORMAT_NOTE
} type;
} format_mapping;
@ -90,7 +91,7 @@ static const format_mapping fmap[] =
{ 'H', FORMAT_REQUEST_PROTOCOL },
{ 'k', FORMAT_KEEPALIVE_COUNT },
{ 'm', FORMAT_REQUEST_METHOD },
{ 'n', FORMAT_UNSUPPORTED }, /* we have no notes */
{ 'n', FORMAT_NOTE },
{ 'p', FORMAT_SERVER_PORT },
{ 'P', FORMAT_UNSUPPORTED }, /* we are only one process */
{ 'q', FORMAT_QUERY_STRING },
@ -942,6 +943,7 @@ REQUESTDONE_FUNC(log_access_write) {
}
break;
case FORMAT_ENV:
case FORMAT_NOTE:
if (NULL != (ds = (data_string *)array_get_element(con->environment, f->string->ptr))) {
accesslog_append_escaped(b, ds->value);
} else {

View File

@ -434,6 +434,20 @@ static int deflate_file_to_buffer_bzip2(server *srv, connection *con, plugin_dat
}
#endif
static void mod_compress_note_ratio(server *srv, connection *con, off_t in, off_t out) {
/* store compression ratio in con->environment
* for possible logging by mod_accesslog
* (late in response handling, so not seen by most other modules) */
/*(should be called only at end of successful response compression)*/
char ratio[LI_ITOSTRING_LENGTH];
if (0 == in) return;
li_itostrn(ratio, sizeof(ratio), out * 100 / in);
array_set_key_value(con->environment,
CONST_STR_LEN("ratio"),
ratio, strlen(ratio));
UNUSED(srv);
}
static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, buffer *fn, stat_cache_entry *sce, int type) {
int ifd, ofd;
int ret;
@ -442,6 +456,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
#endif
void *start;
const char *filename = fn->ptr;
stat_cache_entry *sce_ofn;
ssize_t r;
/* overflow */
@ -483,6 +498,17 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
buffer_append_string_buffer(p->ofn, sce->etag);
if (HANDLER_ERROR != stat_cache_get_entry(srv, con, p->ofn, &sce_ofn)) {
if (0 == sce->st.st_size) return -1; /* cache file being created */
/* cache-entry exists */
#if 0
log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
#endif
mod_compress_note_ratio(srv, con, sce->st.st_size, sce_ofn->st.st_size);
buffer_copy_buffer(con->physical.path, p->ofn);
return 0;
}
if (-1 == mkdir_for_file(p->ofn->ptr)) {
log_error_write(srv, __FILE__, __LINE__, "sb", "couldn't create directory for file", p->ofn);
return -1;
@ -490,13 +516,7 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
if (-1 == (ofd = open(p->ofn->ptr, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))) {
if (errno == EEXIST) {
/* cache-entry exists */
#if 0
log_error_write(srv, __FILE__, __LINE__, "bs", p->ofn, "compress-cache hit");
#endif
buffer_copy_buffer(con->physical.path, p->ofn);
return 0;
return -1; /* cache file being created */
}
log_error_write(srv, __FILE__, __LINE__, "sbss", "creating cachefile", p->ofn, "failed", strerror(errno));
@ -612,6 +632,8 @@ static int deflate_file_to_file(server *srv, connection *con, plugin_data *p, bu
}
buffer_copy_buffer(con->physical.path, p->ofn);
mod_compress_note_ratio(srv, con, sce->st.st_size,
(off_t)buffer_string_length(p->b));
return 0;
}
@ -699,6 +721,8 @@ static int deflate_file_to_buffer(server *srv, connection *con, plugin_data *p,
if (ret != 0) return -1;
mod_compress_note_ratio(srv, con, sce->st.st_size,
(off_t)buffer_string_length(p->b));
chunkqueue_reset(con->write_queue);
chunkqueue_append_buffer(con->write_queue, p->b);

View File

@ -647,6 +647,20 @@ static int mod_deflate_stream_flush(server *srv, connection *con, handler_ctx *h
}
}
static void mod_deflate_note_ratio(server *srv, connection *con, handler_ctx *hctx) {
/* store compression ratio in con->environment
* for possible logging by mod_accesslog
* (late in response handling, so not seen by most other modules) */
/*(should be called only at end of successful response compression)*/
char ratio[LI_ITOSTRING_LENGTH];
if (0 == hctx->bytes_in) return;
li_itostrn(ratio, sizeof(ratio), hctx->bytes_out * 100 / hctx->bytes_in);
array_set_key_value(con->environment,
CONST_STR_LEN("ratio"),
ratio, strlen(ratio));
UNUSED(srv);
}
static int mod_deflate_stream_end(server *srv, handler_ctx *hctx) {
switch(hctx->compression_type) {
#ifdef USE_ZLIB
@ -679,9 +693,6 @@ static void deflate_compress_cleanup(server *srv, connection *con, handler_ctx *
}
#endif
/* future: might store ((double)hctx->bytes_out / hctx->bytes_in)
* in con->environment, for possible logging by mod_accesslog */
handler_ctx_free(hctx);
}
@ -1190,6 +1201,9 @@ CONNECTION_FUNC(mod_deflate_handle_response_start) {
rc = deflate_compress_response(srv, con, hctx);
if (HANDLER_GO_ON != rc) {
if (HANDLER_FINISHED == rc) {
mod_deflate_note_ratio(srv, con, hctx);
}
deflate_compress_cleanup(srv, con, hctx);
if (HANDLER_ERROR == rc) return HANDLER_ERROR;
}