Maison >interface Web >js tutoriel >Explication détaillée de l'utilisation du composant log Morgan
Cette fois, je vais vous apporter une explication détaillée de l'utilisation du composant log morgan. Quelles sont les précautions lors de l'utilisation du composant log morgan. Voici un cas pratique, jetons un coup d'oeil.
Morgan est le middleware de journalisation par défaut d'Express. Cet article présente principalement la méthode du composant de journalisation par défaut d'Express, Morgan. L'éditeur pense qu'il est plutôt bon. Maintenant, je vais le partager avec vous et le donner comme référence. Venez jeter un œil avec l'éditeur
Morgan est le middleware de journalisation par défaut d'Express, et peut également être séparé d'Express et utilisé en tant que nœud Le composant de journal .js est utilisé seul. Cet article va du superficiel au profond, et le contenu comprend principalement :
Exemples d'introduction à l'utilisation de Morgan
Comment enregistrer les journaux dans des fichiers locaux
Instructions et exemples d'utilisation de l'API principale
Utilisation avancée : 1. Fractionnement des journaux 2. Écrire le journal dans la base de données
Analyse du code source : format du journal de Morgan et précompilation
Tout d'abord, Projet d'initialisation.
npm install express morgan
Ensuite, ajoutez le code suivant dans 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
Exécutez le programme et accédez à http://127.0.0.1:3000 dans le navigateur. Le journal d'impression est le suivant
➜ 2016.12.11-. advanced- morgan git:(master) ✗ node 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 prend en charge l'élément de configuration du flux, qui peut être utilisé pour atteindre l'objectif effet de l'atterrissage du journal. Le code est le suivant :
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 principale
morgan a très peu d'API, et le plus fréquemment utilisé est morgan(). Il renvoie un middleware de journalisation express.
morgan(format, options)
La description du paramètre est la suivante :
format : Facultatif, Morgan a défini plusieurs formats de journaux, chaque format a un nom correspondant, tel que combiné, court, etc., la valeur par défaut est par défaut. Les différences entre les différents formats peuvent être trouvées ici. Ce qui suit explique comment personnaliser le format du journal.
options : facultatives, éléments de configuration, y compris le flux (couramment utilisé), le saut et l'immédiat.
stream : configuration du flux de sortie du journal, la valeur par défaut est process.stdout.
ignorer : si vous souhaitez ignorer la journalisation, veuillez vous référer à ici pour l'utilisation.
immédiat : valeur booléenne, la valeur par défaut est false. Lorsque vrai, le journal sera enregistré dès que la demande est reçue ; si faux, le journal sera enregistré après le retour de la demande.
Format de journal personnalisé
Comprenez d'abord les deux concepts de Morgan : le format et le jeton. Très simple :
format : format du journal, qui est essentiellement une chaîne représentant le format du journal, tel que :method :url :status :res[content-length] - :response-time MS.
Jeton : les composants de format, tels que :method et :url ci-dessus, sont ce qu'on appelle des jetons.
Après avoir compris la différence entre le format et le jeton, vous pouvez jeter un œil aux API clés concernant la personnalisation des formats de journaux dans Morgan.
morgan.format(name, format); // 自定义日志格式 morgan.token(name, fn); // 自定义token
est très simple. Définissez d'abord le format de journal nommé joke via morgan.format(), puis transmettez morgan('joke') Appelez-le.
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);
Jetons un coup d'œil aux résultats en cours d'exécution
➜ 2016.12.11-advanced-morgan git:(master) ✗ node morgan.format.js
[ blague] GET / 304
[blague] GET /favicon.ico 200
Le code est le suivant, personnalisé via Morgan. token(), puis ajoutez le jeton personnalisé au format personnalisé.
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) ✗ node morgan.token.js
[joke] GET /hello?from=app 200 app
[joke] GET /favicon.ico 304 -
[joke] GET /hello?from=pc 200 pc
[joke] 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 }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!