view src/http/modules/ngx_http_log_handler.c @ 102:7e86d028d8f0

nginx-0.0.1-2003-06-06-18:59:20 import
author Igor Sysoev <igor@sysoev.ru>
date Fri, 06 Jun 2003 14:59:20 +0000
parents 7ebc8b7fb816
children 571bcbff82c5
line wrap: on
line source


#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;
}