Tornado.logに自分のアプリケーションのログを出す方法

# 結論：
自分のアプリケーションのハンドラで app_log() を使う

## tornado.log.app_log の import 
自分のアプリケーションのハンドラで tornado.log.app_log を import します。[こんな](https://github.com/UedaTakeyuki/rhizosphere/blob/master/sample_handlers/sample_client_device_pair.py#L8)かんじです

```python:
from tornado.log import app_log
```

Tornado の[ドキュメント](https://www.tornadoweb.org/en/stable/log.html)には、

```text:
Tornado uses three logger streams:
・ tornado.access:
・ tornado.application:
・ tornado.general:
```
とあるのですが、その tornado.application をどうやって使ったらいいのかの記載を見つけられません
そこで、tornado の[ソースコード](https://www.tornadoweb.org/en/stable/_modules/tornado/log.html)みると

```python:
# Logger objects for internal tornado use
access_log = logging.getLogger("tornado.access")
app_log = logging.getLogger("tornado.application")
gen_log = logging.getLogger("tornado.general")
```
と、***app_log*** が***普通にLogerとして用意されてる***のでこれを import します。まさに***これがわからなくて３時間もハマってしまいました*** ^^;;;

##
あとは[こんなふう](https://github.com/UedaTakeyuki/rhizosphere/blob/master/sample_handlers/sample_client_device_pair.py#L54)に、ログをいれると

```python:
    def auth_confirm(self, id, token):
        app_log.info("auth_confirm:")
        app_log.info("id =  %s", id)
        app_log.info("token = %s", token)
        return True
```

こんなふうにtornado のログ・ファイルに混ぜて出力してくれます

```text:
ueda@scw-app1:~/rhizosphere$ cat /var/log/rhizosphere 
[D 181027 10:31:01 selector_events:53] Using selector: EpollSelector
[I 181027 10:31:02 web:2106] 101 GET /device (123.218.210.70) 3.08ms
[I 181027 10:31:02 sample_client_device_pair:60] open:
[I 181027 10:31:02 sample_client_device_pair:54] auth_confirm:
[I 181027 10:31:02 sample_client_device_pair:55] id =  0000000009f479d8
[I 181027 10:31:02 sample_client_device_pair:56] token = True
[I 181027 10:31:02 sample_client_device_pair:69] register id =  0000000009f479d8
[I 181027 10:31:02 sample_client_device_pair:77] on_message: message =  {"command": "register", "id": "0000000009f479d8"}
```

関係ないですが、ここで定義してる auth_confirm って、名前に反して全然 confirm してないですね ^^;;;

# 参考： tornado 自身のログをファイル出力にする方法
ちなみに、あたりまえなのですが tornado 自身のログ出力が有効になっていなければいくら app_log() を使っても、そもそもそれが出力される先がありません。Nginx や Apache なんかとちがって、tornado はデフォルトではログを出力しないので、こちらも設定する必要があります 

それにつきましては @fukkyy様が[こちら](https://qiita.com/fukkyy/items/9561ec2441f6a5f45624)ですでに投稿されてますように、実行時に ***log_file_prefix*** オプションで出力先ファイルのパスを指定しさえすれば、そちらに出力されます。ログレベルの指定も logging オプションで可能です

とはいえ、これらのオプションを指定する手段を用意してあげないと指定ができないので、tornado.option を使います

### tornado.options.options の import
__main__ で [こんなかんじ](https://github.com/UedaTakeyuki/rhizosphere/blob/master/main.py#L6)で tornado.options.options を import します

```python:
from tornado.options import define, options
```
単に log をファイルに出力するだけで良くて、自分でコマンドライン（及び設定ファイル）オプションを追加しないのであれば、parse_config_file はデフォルトで define 済なので ***define は import しなくてもいい***です


```python:
from tornado.options import options
```

### main に option の parse を用意
tornado.options は ものすごく便利で、これで define したオプションは実行時に[こんなふうに](https://github.com/UedaTakeyuki/rhizosphere/blob/master/main.py#L53) ***parse_command_line*** でコマンドラインから受け取ることも、

```python:
options.parse_command_line()
```

[こんなふうに](https://github.com/UedaTakeyuki/rhizosphere/blob/master/main.py#L55)***parse_config_file***で設定ファイルから受け取ることも、

```python:
if options.config_file:
    options.parse_config_file(options.config_file)
```

２つとも用意しておいて両方から受け取ることもできます。これだけのためにでもサーバに関係ないアプリでも tornado.option 使いたいぐらいです

### 実行時にコマンドラインか設定ファイルで parse_config_file を指定
あとは@fukkyy様が[こちら](https://qiita.com/fukkyy/items/9561ec2441f6a5f45624)に投稿されてますようにコマンドラインで指定するか、[このように](https://github.com/UedaTakeyuki/rhizosphere/blob/master/config.py#L10) 設定ファイルで指定するかして、log_file_prefile を指定します

# 経緯
掲題の件、どうするんだろうと思ってまず教科書をみてみたのですが、tornado の教科書って [2012年](https://www.safaribooksonline.com/library/view/introduction-to-tornado/9781449312787/)の本しかなくて、その頃はそもそも tornado.log がまだありません

なので、[ドキュメント](https://www.tornadoweb.org/en/stable/log.html)を見るんですが、tornado.application とか、ちゃんと application のログを出す feature を用意してくれてるみたいなんですけど、どうやって使うのか、フレームワークがわかる記載を見つけられない

で、tornado.log application tutorial とかで検索するも、なぜか tornado.log とは別に logging でログ出してる tutorial ばっかり見つかり

諦めて普段はまず読まない（それが悪いんですが ^^;;;）tornado [ソースコード](https://github.com/tornadoweb/tornado/search?p=3&q=log&unscoped_q=log)を log で検索して眺めてみると、なんか普通に内部で logging 使ってるだけだな、app_logすればログでるのかな？、って見当がついてきたので試してみたら正解でした

# 注意
当たり前ですけど tornado 自身のログって tornado のアプリケーションの中でないと 有効じゃないので、たとえば [こんなふうに tornado の外](https://github.com/UedaTakeyuki/rhizosphere/blob/master/main.py#L12) で app_log してみても黙って無視されるだけで、エラーにもなりません。
思慮深い諸兄諸姉には蛇足でしかない注意喚起かもしれませんが、軽率な私はやってしまい、しばらく悩みました...

# 結び
本稿は[こちら](https://takeyukiueda.qrunch.io/entries/4hjpS11ZDy1BPdIe)でカジュアルに発表させていただきました発表を加筆修正してこちらに投稿させていただきました次第です
経緯に書きましたとおり、tornado が用意するオブジェクトをつかってアプリケーションログを出力する tutorial や sample code が意外と見つけられなかったため、同じように悩まれている方の参考になればと思い投稿させていただきましたのですが、私の誤認識、誤解、誤記などございましたらご奇譚のないご指摘をいただければ幸いです