$time_iso8601 is not set for invalid HTTP?

Maxim Dounin mdounin at mdounin.ru
Mon Dec 1 12:53:32 UTC 2014


Hello!

On Sat, Nov 29, 2014 at 03:48:24PM -0500, igorb wrote:

> I use the if trick to get timestamped log names:
> 
> if ($time_iso8601 ~ "^(\d{4})-(\d{2})") {
> 	set $year $1;
> 	set $month $2;
> }
> 
> access_log .../access-$year-$month.log combined;
> 
> However, with nginx/1.4.6 (Ubuntu) I see that for invalid HTTP requests
> $year and $month are not set. For example, with the above config after
> issuing from a shell:
> 
> ~> printf foo | nc host 80
> 
> I see in the error log for nginx:
> 
> 2014/11/29 21:28:57 [warn] 8#0: *18 using uninitialized "year" variable
> while logging request, client: 172.17.42.1, server: localhost, request:
> "foo"
> 2014/11/29 21:28:57 [warn] 8#0: *18 using uninitialized "month" variable
> while logging request, client: 172.17.42.1, server: localhost, request:
> "foo"
> 
> That leads for the log file named .access--.log
> 
> Is it because $time_iso8601 is only set for valid request? If so, is this
> just a bug or a feature?

The rewrite module directives are not executed unless an 
actual request handling happens, so this is expected result.  Use 
map instead:

    map $time_iso8601 $year_and_month {
        "~^(?<temp>\d{4}-\d{2})"  $temp;
    }

Or, better, avoid using such "timestamped log names" at all as 
this approach implies unneeded overhead on opening/closing files 
for each request.  It is much more efficient to use normal log 
rotation instead, see here:

http://nginx.org/en/docs/control.html#logs

Most OSes have newsyslog/logrotate utilities readily available to 
do this and trivial to configure.

-- 
Maxim Dounin
http://nginx.org/



More information about the nginx mailing list