

![]() | Start a set with this search |
![]() | Include this search in one of my sets |
![]() | Exclude this search from one of my sets |
![]() | Permalink to these results Paste this link in email or IM: |
| Atom feed for tracking future search results Paste this URL into your reader: |
3 messages in ru.sysoev.nginxRe: configless vhost| From | Sent On | Attachments |
|---|---|---|
| Marcos Neves | Jun 26, 2008 12:26 am | |
| mike | Jun 26, 2008 1:19 am | |
| Igor Sysoev | Jun 26, 2008 1:39 pm | .Other |

![]() | Permalink for this message Paste this link in email or IM: |
![]() | Permalink for this thread Paste this link in email or IM: |
| Atom feed for this thread Paste this URL into your reader: |
| Subject: | Re: configless vhost | Actions... |
|---|---|---|
| From: | Igor Sysoev (is-G...@public.gmane.org) | |
| Date: | Jun 26, 2008 1:39:47 pm | |
| List: | ru.sysoev.nginx | |
| Attachments: | ![]() patch.var_access_log - 6k | |
On Thu, Jun 26, 2008 at 04:26:54AM -0300, Marcos Neves wrote:
I have virtualhost with configuration less feature that works like a charm!
server { server_name _; set $host_without_www $host; if ($host ~* www\.(.*)) { set $host_without_www $1; } root /var/www/$host_without_www/; access_log logs/$host_without_www.log;
unfortunately, access_log don?t parses variables, so a file named $host_without_www.log is created instead.
There?s any way to keep access logs separated by host, without need to configure one by one by hand?
The attached patch allows variables in access_log.
It's a proof-of-concept: for every log operation it opens/creates log, writes, and then closes. It does not keep open frequently used logs.
It does not try to create log if a response status is 404 and there is no root for the request.
-- Igor Sysoev http://sysoev.ru/en/
Index: src/http/modules/ngx_http_log_module.c =================================================================== --- src/http/modules/ngx_http_log_module.c (revision 1389) +++ src/http/modules/ngx_http_log_module.c (working copy) @@ -40,7 +40,14 @@
typedef struct { + ngx_array_t *lengths; + ngx_array_t *values; +} ngx_http_log_script_t; + + +typedef struct { ngx_open_file_t *file; + ngx_http_log_script_t *script; time_t disk_full_time; time_t error_log_time; ngx_array_t *ops; /* array of ngx_http_log_op_t */ @@ -62,6 +69,8 @@
static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log, u_char *buf, size_t len); +static ssize_t ngx_http_log_script_write(ngx_http_request_t *r, + ngx_http_log_script_t *script, u_char *buf, size_t len);
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op); @@ -235,7 +244,7 @@
file = log[l].file;
- if (file->buffer) { + if (file && file->buffer) {
if (len > (size_t) (file->last - file->pos)) {
@@ -289,8 +298,13 @@ ssize_t n; ngx_err_t err;
- n = ngx_write_fd(log->file->fd, buf, len); + if (log->script == NULL) { + n = ngx_write_fd(log->file->fd, buf, len);
+ } else { + n = ngx_http_log_script_write(r, log->script, buf, len); + } + if (n == (ssize_t) len) { return; } @@ -325,6 +339,87 @@ }
+static ssize_t +ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script, + u_char *buf, size_t len) +{ + size_t root; + ssize_t n; + ngx_fd_t fd; + ngx_err_t err; + ngx_str_t name, path; + ngx_uint_t status; + ngx_open_file_info_t of; + ngx_http_core_loc_conf_t *clcf; + + status = r->err_status ? r->err_status : r->headers_out.status; + + if (status == NGX_HTTP_NOT_FOUND) { + + /* test root directory existance */ + + if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { + return -1; + } + + path.data[root] = '\0'; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + ngx_memzero(&of, sizeof(ngx_open_file_info_t)); + + of.valid = clcf->open_file_cache_valid; + of.min_uses = clcf->open_file_cache_min_uses; + of.errors = clcf->open_file_cache_errors; + of.events = clcf->open_file_cache_events; + + if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) + != NGX_OK + || !of.is_dir) + { + /* no root directory: simulate successfull logging */ + + return len; + } + } + + if (ngx_http_script_run(r, &name, script->lengths->elts, 1, + script->values->elts) + == NULL) + { + return -1; + } + + name.data[name.len - 1] = '\0'; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http log \"%s\"", name.data); + + fd = ngx_open_file(name.data, NGX_FILE_RDWR, + NGX_FILE_CREATE_OR_OPEN|NGX_FILE_APPEND, + NGX_FILE_DEFAULT_ACCESS); + + if (fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, + ngx_open_file_n " \"%s\" failed", name.data); + return -1; + } + + n = ngx_write_fd(fd, buf, len); + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + err = ngx_errno; + + ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", name.data); + + ngx_set_errno(err); + } + + return n; +} + + static u_char * ngx_http_log_copy_short(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op) @@ -678,12 +773,13 @@ { ngx_http_log_loc_conf_t *llcf = conf;
- ssize_t buf; - ngx_uint_t i; - ngx_str_t *value, name; - ngx_http_log_t *log; - ngx_http_log_fmt_t *fmt; - ngx_http_log_main_conf_t *lmcf; + ssize_t buf; + ngx_uint_t i, n; + ngx_str_t *value, name; + ngx_http_log_t *log; + ngx_http_log_fmt_t *fmt; + ngx_http_log_main_conf_t *lmcf; + ngx_http_script_compile_t sc;
value = cf->args->elts;
@@ -706,14 +802,41 @@ return NGX_CONF_ERROR; }
- log->file = ngx_conf_open_file(cf->cycle, &value[1]); - if (log->file == NULL) { - return NGX_CONF_ERROR; + ngx_memzero(log, sizeof(ngx_http_log_t)); + + n = ngx_http_script_variables_count(&value[1]); + + if (n == 0) { + log->file = ngx_conf_open_file(cf->cycle, &value[1]); + if (log->file == NULL) { + return NGX_CONF_ERROR; + } + + } else { + if (ngx_conf_full_name(cf->cycle, &value[1], 0) == NGX_ERROR) { + return NGX_CONF_ERROR; + } + + log->script = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_script_t)); + if (log->script == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); + + sc.cf = cf; + sc.source = &value[1]; + sc.lengths = &log->script->lengths; + sc.values = &log->script->values; + sc.variables = n; + sc.complete_lengths = 1; + sc.complete_values = 1; + + if (ngx_http_script_compile(&sc) != NGX_OK) { + return NGX_CONF_ERROR; + } }
- log->disk_full_time = 0; - log->error_log_time = 0; - if (cf->args->nelts >= 3) { name = value[2];
@@ -750,6 +873,12 @@ return NGX_CONF_ERROR; }
+ if (log->script) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "buffered logs can not have variables in name"); + return NGX_CONF_ERROR; + } + name.len = value[3].len - 7; name.data = value[3].data + 7;








.Other