Skip to main content

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

  1. 打开Inputs配置页面

Dashboard - Inputs

  1. 选择 Input 类型为GELF UDP

select input

点击Launch new input按钮,在弹出框里输入TitleGELF 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里看到有日志了。