Skip to content

Log rotation directly within Nginx configuration file: map instead of if #12

Closed
@f2d

Description

@f2d

With this code in my server blocks (included as a snippet):

if ($time_iso8601 ~ "^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})") {}

access_log /var/log/nginx/$server_log_prefix.access.$year-$month-$day.log;

For some requests (probably something automated, probably invalid, maybe even malformed) nginx ends up with just this filename: ".access.--.log"

Depending on whether it is desired to rotate such logs (or even drop these requests or whatever), following code in http block will always give the date, and without using an "if":

map $time_iso8601 $year {
	default				'date';
	'~^(?<yyyy>\d{4})-'		$yyyy;
}
map $time_iso8601 $month {
	default				'not';
	'~^\d{4}-(?<mm>\d{2})-'		$mm;
}
map $time_iso8601 $day {
	default				'found';
	'~^\d{4}-\d{2}-(?<dd>\d{2})'	$dd;
}

Just a tip which I found no better place to tell.
Tested on nginx/1.10.3.

Docs say, the lowest required version is the same 0.9.6, and that with at least 1.11.0 it could combine all parts into one $date variable in one map expression, like this:

map $time_iso8601 $map_date {
	default							'date-not-found';
	'~^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})'	$year-$month-$day;
}

But I didn't test this.

P.S. On second thought, this particular case does not need complex capturing and this works just fine in 0.9.6 and later:

map $time_iso8601 $map_date_now {
	default				'date-not-found';
	'~^(?<ymd>\d{4}-\d{2}-\d{2})'	$ymd;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions