Express4のログ出力(morgan)について

##はじめに
expressにはmorganというログのライブラリーが用意されています。
https://github.com/expressjs/morgan
そのライブラリを使用することで簡単にログ出力できます。
ここでは、ログの基礎的な出力方法と、カスタマイズしたログをファイルに保存する方法について記述します。

##準備
まずmorganをインストールします。
`npm install morgan --save`

app.jsを以下のように記述します。

```javascript:app.js
//モジュール
var express = require('express');
var logger = require('morgan')

//アプリケーション作成
var app = express();

app.use(logger("short"));

app.get('/',function (req, res){
	res.writeHead(200, { "Content-Type": "text/plain" });
	res.end("Hello, world!");
});

//サーバー起動
var server = app.listen(process.env.PORT || 3000, function(){
	console.log('PORT: %d', server.address().port);
});
```
以上のアプリを実行し、http://localhost:3000/ にアクセスすると以下のようなログが出力されます。
`::1 - GET / HTTP/1.1 200 - - 1.173 ms`
`::1 - GET /favicon.ico HTTP/1.1 404 150 - 4.974 ms`

ここまで、ログの基礎的な出力方法について説明しました。

##カスタマイズしたログをファイルに保存する方法
カスタマイズしたログをファイルに保存する方法について記述します。
まず、以下のようにログの保存場所を指定します。

```javascript
var path = require('path');
// ・・・・・・・・・・・・・・
var logDirectory = path.join(__dirname, './log');
```
上記で指定したディレクトリが存在するか確認し、存在しなかったらディレクトリを作成します。

```javascript
//指定したディレクトリの存在確認
var fs = require('fs-extra');
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);
```
RotatingFileStreamを作成します。

```javascript
var accessLogStream = rfs('access.log', {
	size:'10MB',//ファイルが10MBを超えるとローテートします
	interval: '10d',
	compress: 'gzip',
  	path: logDirectory
});
```

パラメータの意味は以下の通りです。
path: 存在する場合、指定したファイルにログが追加されます。
size: ファイル容量の上限を設定します。(B:バイト、K:キロバイト、M:メガバイト、G:ギガバイト)
interval:ローテートする期間を設定します。(s:秒、m:分、h:時間、d:日)
compress:圧縮する形式

ログのフォーマットをトークンを使用して指定します。

```javascript
//ログのフォーマット
var preformat = ':date[clf] - :method :url - :response-time ms'
```

あらかじめ定義されているトークンの例は以下の通りです。
:date[format]　UTCにおける現在日時
:method リクエストのHTTPメソッド
:response-time[digits]　応答時間(ミリ秒)
:url リクエストのURL
:status ステータス　など

次のようにカスタムトークンを作成することも出来ます。

```javascript
logger.token('custom_token', function getId (req) {
	var return_log = "first:"+req.body["first"] + "\t second:" + req.body["second"];
	return return_log;
})
```
カスタムのトークンを使用してログのフォーマットを作成するには次のようにします。

```javascript
var preformat = ':date[clf] - :type - :method :url :custom_token - :response-time ms'
```
ロガーのセットアップをします。ここの第一引数でログのフォーマットを指定します。
カスタムのログだけでなく、あらかじめ定義されているログフォーマットもあります。
あらかじめ定義されているログのフォーマットは以下の通りです。
combined ･･･標準Apache combined ログ出力
:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
common･･･標準Apache combined ログ出力
:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
dev･･･開発用レスポンズステータスによって色づけされた出力
:method :url :status :response-time ms - :res[content-length]
short･･･短い出力

##完成形
完成形は以下のようになります。

```javascript:app.js
//モジュール
var express = require('express');
var logger = require('morgan');
var path = require('path');
var fs = require('fs-extra');

//アプリケーション作成
var app = express();

app.use(logger("short"));

app.get('/',function (req, res){
	res.writeHead(200, { "Content-Type": "text/plain" });
	res.end("Hello, world!");
});

//ログの保存場所
var logDirectory = path.join(__dirname, './log');

//指定したディレクトリが存在するか？
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);

//ファイルストリームを作成
var accessLogStream = rfs('access.log', {
	size:'10MB',
	interval: '10d',
	compress: 'gzip',
  path: logDirectory
});

//カスタムトークン
logger.token('custom_token', function getId (req) {
	var return_log = "first:"+req.body["first"] + "\t second:" + req.body["second"];
	return return_log;
})

//ログのフォーマット
var preFormat = ':date[clf] - :type - :method :url :custom_token - :response-time ms'

//ロガーのセットアップ
app.use(logger(preFormat,{
	stream: accessLogStream
}));

//サーバー起動
var server = app.listen(process.env.PORT || 3000, function(){
	console.log('PORT: %d', server.address().port);
});
```
あまりまとまっておりません。