3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

nginx のログでVariableに値が存在しないとき、ダッシュ(-)ではなく空白または任意の文字列を出力する

Posted at

やりたいこと

nginx のログの書式設定には、log_format ディレクティブを使いますします。
その中には Variable が使用できて、ここ に書いてあるような変数を埋め込めます。

で、その変数のうち、以下のようなものはリクエストによっては値が無い可能性があります。

  • httpヘッダー由来のもの $http_name
  • cookie の値を取り出すやつ $cookie_name
  • httpクエリパラメータを取り出すやつ $arg_name

これらをそのまま log_format で指定すると、値が存在しないときは値の代わりに - ダッシュを出力してしまいます。

この挙動を変えたい。具体的には空白を出したい。

やり方

map ディレクティブ を使う

map a $lang { default $http_accept_language; }
map a $argp { default $arg_p; }

log_format dummy 'lang:$lang\tp:$argp'

とかすると、HTTP ヘッダに Accept-Language が無いときは空白を出してくれます。query に p が与えられなかったら、空白が出ます。

そうなる理由

map の説明を見るとわかるのですが、map string $lang {} は、string(上の例の場合は固定の a という文字列) から $lang という新たな変数を作るのだけど、その際に {} 内の処理をする、という動きをするようです。

で、そこに default $baz と書いておくと、string にかかわらず、$baz の値を使うようになる。値が無いので、空白文字列が入ると。

値が無いときに - を入れるのは、ロギング時の仕様で、変数の値を評価するときの仕様というわけでは無さそうです。

この、変数を評価する仕組みが場所によって異なる(というか、log_format の指定が他と異なる?)のを利用して、例えば通常は使えない - を名前に含むような cookie の値を出力するときの hack などにも使われるようです(というか、そこから inspire した)。

発展。値が無いときに任意の文字を使う

ログに変数の値が存在しないとき、- ではなく空白を出すことはできましたが、「任意の文字列」を出せるようにしてみましょう。

    map $http_x_forwarded_for $xff {
        default $http_x_forwarded_for;
        "" "=";
    }

こうです。
$http_x_forwarded_for から $xff を作りますが、""(空文字列)と一致したときは = を使い、一致しなかったとき(つまり、値があるときですね)は $http_x_forwarded_for の値を使う、という意味です。

任意の文字に変えるのはあんまりニーズ無さそうですが、なんか応用ができるかもしれません。

他の方法を知りたい

もっとスマートな方法は無いのですかね...

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?