blob: 1ddca32417c81fb262d85363abfd59a4816c7905 [file] [log] [blame]
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
typedef struct {
ngx_file_t file;
} ngx_http_log_conf_t;
static void *ngx_http_log_create_conf(ngx_pool_t *pool);
static char *ngx_http_log_merge_conf(ngx_pool_t *p, void *parent, void *child);
static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_command_t ngx_http_log_commands[] = {
{ngx_string("access_log"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_http_log_set_log,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL},
ngx_null_command
};
ngx_http_module_t ngx_http_log_module_ctx = {
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_http_log_create_conf, /* create location configration */
ngx_http_log_merge_conf /* merge location configration */
};
ngx_module_t ngx_http_log_module = {
NGX_MODULE,
&ngx_http_log_module_ctx, /* module context */
ngx_http_log_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init module */
};
static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
int ngx_http_log_handler(ngx_http_request_t *r)
{
char *line, *p;
size_t len;
ngx_tm_t tm;
ngx_http_log_conf_t *lcf;
ngx_log_debug(r->connection->log, "log handler");
lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
/* 10:%con, 1:%pipe, 22:%date, 2:"%r", 3:%status, 20:%bytes, 2:%user-agent,
7*" ", 2/1: "\r\n" */
#if (WIN32)
len = 10 + 1 + 22 + 2 + 3 + 20 + 2 + 7 + 2;
#else
len = 10 + 1 + 22 + 2 + 3 + 20 + 2 + 7 + 1;
#endif
len += r->connection->addr_text.len;
len += r->request_line.len;
if (r->headers_in.user_agent) {
len += r->headers_in.user_agent->value.len;
}
ngx_test_null(line, ngx_palloc(r->pool, len), NGX_ERROR);
p = line;
ngx_memcpy(p, r->connection->addr_text.data, r->connection->addr_text.len);
p += r->connection->addr_text.len;
*p++ = ' ';
p += ngx_snprintf(p, 21, "%u", r->connection->number);
*p++ = ' ';
if (r->pipeline) {
*p++ = 'p';
} else {
*p++ = '.';
}
*p++ = ' ';
ngx_localtime(&tm);
*p++ = '[';
p += ngx_snprintf(p, 21, "%02d/%s/%d:%02d:%02d:%02d",
tm.ngx_tm_mday, months[tm.ngx_tm_mon - 1],
tm.ngx_tm_year,
tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec);
*p++ = ']';
*p++ = ' ';
*p++ = '"';
ngx_memcpy(p, r->request_line.data, r->request_line.len);
p += r->request_line.len;
*p++ = '"';
*p++ = ' ';
p += ngx_snprintf(p, 4, "%d", r->headers_out.status);
*p++ = ' ';
p += ngx_snprintf(p, 21, OFF_FMT, r->connection->sent);
*p++ = ' ';
*p++ = '"';
if (r->headers_in.user_agent) {
ngx_memcpy(p, r->headers_in.user_agent->value.data,
r->headers_in.user_agent->value.len);
p += r->headers_in.user_agent->value.len;
}
*p++ = '"';
#if (WIN32)
*p++ = CR; *p++ = LF;
#else
*p++ = LF;
#endif
write(lcf->file.fd, line, p - line);
return NGX_OK;
}
static void *ngx_http_log_create_conf(ngx_pool_t *pool)
{
ngx_http_log_conf_t *conf;
ngx_test_null(conf, ngx_pcalloc(pool, sizeof(ngx_http_log_conf_t)),
NGX_CONF_ERROR);
return conf;
}
static char *ngx_http_log_merge_conf(ngx_pool_t *p, void *parent, void *child)
{
ngx_http_log_conf_t *prev = parent;
ngx_http_log_conf_t *conf = child;
/* STUB */
*conf = *prev;
return NGX_CONF_OK;
}
static char *ngx_http_log_set_log(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf)
{
ngx_http_log_conf_t *lcf = conf;
int len;
ngx_err_t err;
ngx_str_t *value;
value = cf->args->elts;
lcf->file.name.len = value[1].len;
lcf->file.name.data = value[1].data;
lcf->file.fd = ngx_open_file(lcf->file.name.data,
NGX_FILE_RDWR,
NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND);
if (lcf->file.fd == NGX_INVALID_FILE) {
err = ngx_errno;
len = ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
ngx_open_file_n " \"%s\" failed (%d: ",
lcf->file.name.data, err);
len += ngx_strerror_r(err, ngx_conf_errstr + len,
sizeof(ngx_conf_errstr) - len - 1);
ngx_conf_errstr[len++] = ')';
ngx_conf_errstr[len++] = '\0';
return ngx_conf_errstr;
}
#if (WIN32)
if (ngx_file_append_mode(lcf->file.fd) == NGX_ERROR) {
err = ngx_errno;
len = ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
ngx_file_append_mode_n " \"%s\" failed (%d: ",
lcf->file.name.data, err);
len += ngx_strerror_r(err, ngx_conf_errstr + len,
sizeof(ngx_conf_errstr) - len - 1);
ngx_conf_errstr[len++] = ')';
ngx_conf_errstr[len++] = '\0';
return ngx_conf_errstr;
}
#endif
return NGX_CONF_OK;
}