如何正确使用 morgan 和 nginx?
How to properly use morgan with nginx?
- 服务器:Ubuntu18.04
- 节点:9.11.2
- Npm: 6.6.0
- 摩根:1.9.1
- 温斯顿:3.1.0
- Nginx: 1.14.0 (Ubuntu)
我在带有 nginx 的 ubuntu 服务器上有一个 nodejs 应用程序。
安装 winston 和 morgan 用于错误日志,但我的应用程序没有使用 winston,它只在我的 nginx access.log 文件(var/log/nginx/access.log)中注册 http 请求。
它也不会生成我需要的 app.log 文件。
就好像我的应用程序出于某种原因忽略了将 morgan 与 winston 一起使用。
我的app.js
var express = require('express');
var compression = require('compression')
var path = require('path');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var author = require('./routes/author');
var post = require('./routes/post');
var user = require('./routes/user');
var photo = require('./routes/photo');
var winston = require('./lib/config/winston');
var app = express();
app.use(morgan('combined', { stream: winston.stream }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(compression());
var PAGING_COUNT = 10;
var MAX_PAGING_COUNT = 50;
app.use(function(req, res, next) {
var s, c;
if(!req.query) {
s = 0;
c = PAGING_COUNT;
}
else {
var s = parseInt(req.query.s);
var c = parseInt(req.query.c);
if(!s) s = 0;
if(!c) c = PAGING_COUNT;
}
if(c > MAX_PAGING_COUNT) {
var err = new Error('Limit Request');
err.status = 400;
return next(err);
}
req.paging = { start: s, count: c};
next();
});
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization");
res.header("Access-Control-Expose-Headers", "Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization");
res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
next();
});
app.use('/author', author);
app.use('/post', post);
app.use('/user', user);
app.use('/photo', photo);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500).send(err.message);
});
module.exports = app;
我的 winston.js (./lib/config/winston.js)
var winston = require('winston');
var appRoot = require('app-root-path');
// Defino las configuraciones personalizadas para cada transporte (file, console).
var options = {
file: {
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880, // 5MB
maxFiles: 5,
colorize: false,
},
console: {
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
},
};
// Nueva instancia de Winston
var logger = winston.createLogger({
transports: [
new winston.transports.File(options.file),
new winston.transports.Console(options.console)
],
exitOnError: false, // do not exit on handled exceptions
});
// Funcion de flujo que permite a Winston capturar resultados de Morgan
logger.stream = {
write: function(message, encoding) {
// Uso el nivel 'info' para que la salida sea recogida por ambos transportes (file y console)
logger.info(message);
},
};
module.exports = logger;
我的 nginx 服务器配置
server {
listen 80;
listen [::]:80;
#your subdomain
server_name api.mydomain.com;
location /v1/ {
rewrite ^/v1/?(.*) / break;
proxy_buffering off;
#your aplication port
proxy_pass http://localhost:9000;
}
location /start/ {
rewrite ^/start/?(.*) / break;
proxy_buffering off;
#your aplication port
proxy_pass http://localhost:8080;
}
}
server {
server_name storage.mydomain.com;
root /home/ubuntu/app-backend/public/;
index index.html;
location /files {
try_files $uri =404;
}
}
server {
listen 80;
listen [::]:80;
#point to build directory
root /home/ubuntu/app-frontend/build;
index index.html index.htm;
server_name admin.mydomain.com;
location / {
root /home/ubuntu/app-frontend/build;
try_files $uri $uri/ /index.html;
}
}
在我的本地服务器上,我得到以下内容
{"message":"::1 - - [23/Jan/2019:04:36:41 +0000] \"PUT /author/push/012c2cab HTTP/1.1\" 200 17 \"http://localhost:3000/home/page/1\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\"\n","level":"info"}
在我的生产服务器中,我得到以下内容
MY_IP - - [23/Jan/2019:06:35:33 +0000] "PUT /v1/author/push/6a839012 HTTP/1.1" 500 20 "http://admin.mydomain.com/home/page/1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
我的文件:
您没有为 morgan
或 winston
使用流
你必须使用Stream Transport
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'app.log'), { flags: 'a' })
logger.add(new winston.transports.Stream({
stream: accessLogStream
/* other options */
}));
然后使用 accessLogStream
为 morgan
morgan - write logs to a file
app.use(morgan('combined', { stream: accessLogStream }))
- 服务器:Ubuntu18.04
- 节点:9.11.2
- Npm: 6.6.0
- 摩根:1.9.1
- 温斯顿:3.1.0
- Nginx: 1.14.0 (Ubuntu)
我在带有 nginx 的 ubuntu 服务器上有一个 nodejs 应用程序。 安装 winston 和 morgan 用于错误日志,但我的应用程序没有使用 winston,它只在我的 nginx access.log 文件(var/log/nginx/access.log)中注册 http 请求。 它也不会生成我需要的 app.log 文件。 就好像我的应用程序出于某种原因忽略了将 morgan 与 winston 一起使用。
我的app.js
var express = require('express');
var compression = require('compression')
var path = require('path');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var author = require('./routes/author');
var post = require('./routes/post');
var user = require('./routes/user');
var photo = require('./routes/photo');
var winston = require('./lib/config/winston');
var app = express();
app.use(morgan('combined', { stream: winston.stream }));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(compression());
var PAGING_COUNT = 10;
var MAX_PAGING_COUNT = 50;
app.use(function(req, res, next) {
var s, c;
if(!req.query) {
s = 0;
c = PAGING_COUNT;
}
else {
var s = parseInt(req.query.s);
var c = parseInt(req.query.c);
if(!s) s = 0;
if(!c) c = PAGING_COUNT;
}
if(c > MAX_PAGING_COUNT) {
var err = new Error('Limit Request');
err.status = 400;
return next(err);
}
req.paging = { start: s, count: c};
next();
});
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization");
res.header("Access-Control-Expose-Headers", "Origin, X-Requested-With, Content-Type, Accept, api_key, Authorization");
res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
next();
});
app.use('/author', author);
app.use('/post', post);
app.use('/user', user);
app.use('/photo', photo);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500).send(err.message);
});
module.exports = app;
我的 winston.js (./lib/config/winston.js)
var winston = require('winston');
var appRoot = require('app-root-path');
// Defino las configuraciones personalizadas para cada transporte (file, console).
var options = {
file: {
level: 'info',
filename: `${appRoot}/logs/app.log`,
handleExceptions: true,
json: true,
maxsize: 5242880, // 5MB
maxFiles: 5,
colorize: false,
},
console: {
level: 'debug',
handleExceptions: true,
json: false,
colorize: true,
},
};
// Nueva instancia de Winston
var logger = winston.createLogger({
transports: [
new winston.transports.File(options.file),
new winston.transports.Console(options.console)
],
exitOnError: false, // do not exit on handled exceptions
});
// Funcion de flujo que permite a Winston capturar resultados de Morgan
logger.stream = {
write: function(message, encoding) {
// Uso el nivel 'info' para que la salida sea recogida por ambos transportes (file y console)
logger.info(message);
},
};
module.exports = logger;
我的 nginx 服务器配置
server {
listen 80;
listen [::]:80;
#your subdomain
server_name api.mydomain.com;
location /v1/ {
rewrite ^/v1/?(.*) / break;
proxy_buffering off;
#your aplication port
proxy_pass http://localhost:9000;
}
location /start/ {
rewrite ^/start/?(.*) / break;
proxy_buffering off;
#your aplication port
proxy_pass http://localhost:8080;
}
}
server {
server_name storage.mydomain.com;
root /home/ubuntu/app-backend/public/;
index index.html;
location /files {
try_files $uri =404;
}
}
server {
listen 80;
listen [::]:80;
#point to build directory
root /home/ubuntu/app-frontend/build;
index index.html index.htm;
server_name admin.mydomain.com;
location / {
root /home/ubuntu/app-frontend/build;
try_files $uri $uri/ /index.html;
}
}
在我的本地服务器上,我得到以下内容
{"message":"::1 - - [23/Jan/2019:04:36:41 +0000] \"PUT /author/push/012c2cab HTTP/1.1\" 200 17 \"http://localhost:3000/home/page/1\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36\"\n","level":"info"}
在我的生产服务器中,我得到以下内容
MY_IP - - [23/Jan/2019:06:35:33 +0000] "PUT /v1/author/push/6a839012 HTTP/1.1" 500 20 "http://admin.mydomain.com/home/page/1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
我的文件:
您没有为 morgan
或 winston
你必须使用Stream Transport
var accessLogStream = fs.createWriteStream(path.join(__dirname, 'app.log'), { flags: 'a' })
logger.add(new winston.transports.Stream({
stream: accessLogStream
/* other options */
}));
然后使用 accessLogStream
为 morgan
morgan - write logs to a file
app.use(morgan('combined', { stream: accessLogStream }))