Express のデフォルト ログ コンポーネント Morgan のメソッド

亚连
リリース: 2018-05-26 15:17:43
オリジナル
1589 人が閲覧しました

Morgan は Express のデフォルトのログ記録ミドルウェアです。この記事では主に Express のデフォルトのログ記録コンポーネント Morgan の方法を紹介します。

章の概要

morgan は、express のデフォルトのログ記録ミドルウェアであり、express を使用せずに、node.js のログ記録コンポーネントとして単独で使用することもできます。この記事は浅いものから深いものまで、主に次の内容を含みます:

  1. morgan の使用例の紹介

  2. ログをローカル ファイルに保存する方法

  3. Core API の使用手順と例

  4. 高度な使用法: 1. ログのセグメント化 2. データベースへのログの書き込み

  5. ソースコード分析: morgan のログ形式とプリコンパイル

開始例

まず、プロジェクトを初期化します。

npm install express morgan
ログイン後にコピー

次に、basic.js に次のコードを追加します。

var express = require('express');
var app = express();
var morgan = require('morgan');

app.use(morgan('short'));
app.use(function(req, res, next){
 res.send('ok');
});

app.listen(3000);
ログイン後にコピー

node basic.js プログラムを実行し、ブラウザで http://127.0.0.1:3000 にアクセスします。 印刷ログは次のとおりです

➜ 2016.12.11-advanced-morgan git:(master) ✗ ノード Basic .js
::ffff:127.0.0.1 - GET / HTTP/1.1 304 - - 3.019 ms
::ffff:127.0.0.1 - GET /favicon.ico HTTP/1.1 200 2 - 0.984 ms

ログをローカルに出力ファイル

morgan は、ランディング ログの効果を実現するために使用できるストリーム設定項目をサポートしています。コードは次のとおりです。

var express = require('express');
var app = express();
var morgan = require('morgan');
var fs = require('fs');
var path = require('path');
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), {flags: 'a'});
app.use(morgan('short', {stream: accessLogStream}));
app.use(function(req, res, next){
 res.send('ok');
});
app.listen(3000);
ログイン後にコピー

コア API

使用する API はほとんどありません。最も頻繁に使用される API は、高速ログ ミドルウェアを返す morgan() です。


morgan(format, options)
ログイン後にコピー

パラメータの説明は次のとおりです:


format: Morgan は、各フォーマットに対応する名前 (combined、short など) を定義しています。デフォルトは、default です。 。さまざまな形式の違いについては、こちらをご覧ください。ログ形式をカスタマイズする方法を説明します。

  1. オプション: ストリーム (一般的に使用される)、スキップ、および即時を含むオプションの構成項目。

  2. stream: ログ出力ストリーム構成。デフォルトは process.stdout です。

  3. スキップ: ログをスキップするかどうか、その使用方法については、こちらをご覧ください。

  4. immediate: ブール値、デフォルトは false です。 true の場合、リクエストを受信するとすぐにログが記録されます。false の場合、リクエストが返された後にログが記録されます。


  5. カスタマイズされたログフォーマット

まず、morgan の 2 つの概念、フォーマットとトークンを理解します。非常に単純です:


format: ログ形式。これは基本的に、:method :url :status :res[content-length] - :response-time ms などのログ形式を表す文字列です。

  1. トークン: 上記の :method や :url などの形式のコンポーネントは、いわゆるトークンです。

  2. フォーマットとトークンの違いを理解したら、morgan でのログフォーマットのカスタマイズに関する主要な API を見てみましょう。

morgan.format(name, format); // 自定义日志格式
morgan.token(name, fn); // 自定义token
ログイン後にコピー

フォーマットのカスタマイズ

は、まず、morgan.format() を通じて、joke という名前のログフォーマットを定義し、それから、morgan('joke') を通じてそれを呼び出します。

var express = require('express');
var app = express();
var morgan = require('morgan');
morgan.format('joke', '[joke] :method :url :status');
app.use(morgan('joke'));
app.use(function(req, res, next){
 res.send('ok');
});
app.listen(3000);
ログイン後にコピー

実行結果を見てみましょう

➜ 2016.12.11-advanced-morgan git:(master) ✗ node morgan.format.js

[joke] GET / 304

[joke] GET /favicon .ico 200


カスタムトークン

コードは次のとおりで、morgan.token() を通じてトークンをカスタマイズし、カスタマイズされたトークンをカスタマイズされた形式に追加します。

var express = require('express');
var app = express();
var morgan = require('morgan');
// 自定义token
morgan.token('from', function(req, res){
 return req.query.from || '-';
});
// 自定义format,其中包含自定义的token
morgan.format('joke', '[joke] :method :url :status :from');

// 使用自定义的format
app.use(morgan('joke'));
app.use(function(req, res, next){
 res.send('ok');
});
app.listen(3000);
ログイン後にコピー

プログラムを実行し、ブラウザで http://127.0.0.1:3000/hello?from=app と

http://127.0.0.1:3000/hello?from=pc に連続してアクセスします

➜ 2016.12.11-advanced-morgan git:(master) ✗ ノード morgan.token.js [ジョーク] GET /hello?from=app 200 app[ジョーク] GET /favicon.ico 304 -

[ジョーク] GET /hello?from=pc 200 pc

[ジョーク] GET /favicon.ico 304 -



高度な使用


ログ切断

オンラインアプリケーション(すべてのログが実装されている場合) 同じローカルファイル時間の経過とともに非常に大きくなり、パフォーマンスに影響を及ぼし、表示が不便になります。現時点では、ログのセグメント化を使用する必要があります。

file-stream-rotator プラグインを使用すると、ログの分割を簡単に完了できます。 file-stream-rotator に関連する構成コードを除いて、残りは前の例と同様であるため、ここでは詳しく説明しません。


var FileStreamRotator = require('file-stream-rotator')
var express = require('express')
var fs = require('fs')
var morgan = require('morgan')
var path = require('path')

var app = express()
var logDirectory = path.join(__dirname, 'log')

// ensure log directory exists
fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory)

// create a rotating write stream
var accessLogStream = FileStreamRotator.getStream({
 date_format: 'YYYYMMDD',
 filename: path.join(logDirectory, 'access-%DATE%.log'),
 frequency: 'daily',
 verbose: false
})

// setup the logger
app.use(morgan('combined', {stream: accessLogStream}))

app.get('/', function (req, res) {
 res.send('hello, world!')
})
ログイン後にコピー

データベースへのログの書き込み

場合によっては、データベースにアクセス ログを書き込む必要があることがあります。この要件は、リアルタイムのクエリ統計を必要とするログ システムでは一般的です。

在morgan里该如何实现呢?从文档上,并没有看到适合的扩展接口。于是查阅了下morgan的源码,发现实现起来非常简单。

回顾下之前日志写入本地文件的例子,最关键的两行代码如下。通过stream指定日志的输出流。

var accessLogStream = fs.createWriteStream(path.join(__dirname, 'access.log'), {flags: 'a'});
app.use(morgan('short', {stream: accessLogStream}));
ログイン後にコピー

在morgan内部,大致实现是这样的(简化后)。

// opt为配置文件
var stream = opts.stream || process.stdout;
var logString = createLogString(); // 伪代码,根据format、token的定义,生成日志
stream.write(logString);
ログイン後にコピー

于是,可以用比较取巧的方式来实现目的:声明一个带write方法的对象,并作为stream配置传入。

var express = require('express');
var app = express();
var morgan = require('morgan');

// 带write方法的对象
var dbStream = {
 write: function(line){
 saveToDatabase(line); // 伪代码,保存到数据库
 }
};

// 将 dbStream 作为 stream 配置项的值
app.use(morgan('short', {stream: dbStream}));
app.use(function(req, res, next){
 res.send('ok');
});

app.listen(3000);
ログイン後にコピー

深入剖析

morgan的代码非常简洁,从设计上来说,morgan的生命周期包含:

token定义 --> 日志格式定义 -> 日志格式预编译 --> 请求达到/返回 --> 写日志

其中,token定义、日志格式定义前面已经讲到,这里就只讲下 日志格式预编译 的细节。

跟模板引擎预编译一样,日志格式预编译,也是为了提升性能。源码如下,最关键的代码就是compile(fmt)。

 function getFormatFunction (name) {
 // lookup format
 var fmt = morgan[name] || name || morgan.default

 // return compiled format
 return typeof fmt !== 'function'
 ? compile(fmt)
 : fmt
}
ログイン後にコピー

compile()方法的实现细节这里不赘述,着重看下compile(fmt)返回的内容:

var morgan = require('morgan');
var format = morgan['tiny'];
var fn = morgan.compile(format);

console.log(fn.toString());
ログイン後にコピー

运行上面程序,输出内容如下,其中tokens其实就是morgan。

function anonymous(tokens, req, res
/**/) {
 return ""
 + (tokens["method"](req, res, undefined) || "-") + " "
 + (tokens["url"](req, res, undefined) || "-") + " "
 + (tokens["status"](req, res, undefined) || "-") + " "
 + (tokens["res"](req, res, "content-length") || "-") + " - "
 + (tokens["response-time"](req, res, undefined) || "-") + " ms";
}
ログイン後にコピー

看下morgan.token()的定义,就很清晰了

function token (name, fn) {
 morgan[name] = fn
 return this
}
ログイン後にコピー

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

ajax请求之返回数据的顺序问题分析

解决ajax返回验证的时候总是弹出error错误的方法

防止重复发送Ajax请求的解决方案

以上がExpress のデフォルト ログ コンポーネント Morgan のメソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート