Send logs to Graylog with Winston GELF package
Graylog Open 的日志服务,对于小微服务来说简直就是神器,每次登录服务器看日志实在太 low 了,所以集成到 express 服务上,就可以在线直接查日志了。
Graylog 部署
使用 docker-compose 来部署 Graylog,我尝试用官网的 docker-compose 但是起不起来,总是有各种奇怪的问题,后来找到这个配置文件,可以成功部署:
docker-compose.yml
version: '3'
services:
# MongoDB: https://hub.docker.com/_/mongo/
mongo:
image: mongo:5.0.13
networks:
- graylog
# Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/7.10/docker.html
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch-oss:7.10.2
environment:
- http.host=0.0.0.0
- transport.host=localhost
- network.host=0.0.0.0
- 'ES_JAVA_OPTS=-Dlog4j2.formatMsgNoLookups=true -Xms512m -Xmx512m'
deploy:
resources:
limits:
memory: 1g
networks:
- graylog
# Graylog: https://hub.docker.com/r/graylog/graylog/
graylog:
image: graylog/graylog:5.0
environment:
# CHANGE ME (must be at least 16 characters)!
- GRAYLOG_PASSWORD_SECRET=B1wLkcwCoZ102xsRbx3
# Password:
- GRAYLOG_ROOT_PASSWORD_SHA2=xxx
- GRAYLOG_HTTP_EXTERNAL_URI=http://127.0.0.1:9000/
entrypoint: /usr/bin/tini -- wait-for-it elasticsearch:9200 -- /docker-entrypoint.sh
networks:
- graylog
restart: always
depends_on:
- mongo
- elasticsearch
ports:
# Graylog web interface and REST API
- 9000:9000
# Syslog TCP
- 1514:1514
# Syslog UDP
- 1514:1514/udp
# GELF TCP
- 12201:12201
# GELF UDP
- 12201:12201/udp
networks:
graylog:
driver: bridge
其中,
GRAYLOG_PASSWORD_SECRET
的长度必须大于等于 16 位,随便找个password 生成器即可。GRAYLOG_ROOT_PASSWORD_SHA2
是 dashboard 登录密码的 sha2 加密字符串,用生成器里直接生成即可。
启动:
docker compose up -d
配置 Graylog 接收 Winston 的日志
打开 dashboard,本地访问地址是 http://localhost:9000
- 打开
Inputs
配置页面
- 选择 Input 类型为
GELF UDP
点击Launch new input
按钮,在弹出框里输入Title
为GELF UDP
,然后点击确认按钮Launch Input
.
在 express 项目中配置 Winston
安装winston-graylog2
类库,在 Winston 的 transports 中添加:
new WinstonGraylog2({
level: 'info',
graylog: {
servers: [{ host: 'localhost', port: 12201 }],
hostname: 'app',
facility: 'service-logs',
bufferSize: 1400,
},
}) as any,
我的完整 logger 工具代码如下:
logger.ts
import winston from 'winston';
import 'winston-daily-rotate-file';
import WinstonGraylog2 from 'winston-graylog2';
const { combine, timestamp, json } = winston.format;
export const logger = winston.createLogger({
level: 'info',
format: combine(timestamp(), json()),
transports: [
new winston.transports.DailyRotateFile({
level: 'info',
filename: './logs/app-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d',
}),
new winston.transports.DailyRotateFile({
level: 'error',
filename: './logs/app-err-%DATE%.log',
datePattern: 'YYYY-MM-DD',
zippedArchive: true,
maxSize: '20m',
maxFiles: '14d',
}),
new WinstonGraylog2({
level: 'info',
graylog: {
servers: [{ host: 'localhost', port: 12201 }],
hostname: 'app',
facility: 'service-logs',
bufferSize: 1400,
},
}) as any,
],
});
if (process.env.NODE_ENV !== 'production') {
logger.add(
new winston.transports.Console({
format: winston.format.simple(),
})
);
}
启动 express,触发日志打印,回到 dashboard,就可以在Graylog-Dashboard/Search
里看到有日志了。