Commit d4f00758 by Sxy

feat: 日志

parent b9ec8199
...@@ -4,7 +4,7 @@ import views from 'koa-views' ...@@ -4,7 +4,7 @@ import views from 'koa-views'
import json from 'koa-json' import json from 'koa-json'
import onerror from 'koa-onerror' import onerror from 'koa-onerror'
import bodyparser from 'koa-bodyparser' import bodyparser from 'koa-bodyparser'
import logger from 'koa-logger' // import logger from 'koa-logger'
import parameter from 'koa-parameter' import parameter from 'koa-parameter'
import moment from "moment" import moment from "moment"
...@@ -18,6 +18,9 @@ const logNameSpace = createNamespace('logger') ...@@ -18,6 +18,9 @@ const logNameSpace = createNamespace('logger')
import index from './routes/index' import index from './routes/index'
import test from './routes/test' import test from './routes/test'
import logger from "./utils/logger"
...@@ -30,7 +33,7 @@ app.use(bodyparser({ ...@@ -30,7 +33,7 @@ app.use(bodyparser({
})) }))
app.use(parameter(app)) app.use(parameter(app))
app.use(json()) app.use(json())
app.use(logger()) // app.use(logger())
app.use(require('koa-static')(__dirname + '/public')) app.use(require('koa-static')(__dirname + '/public'))
app.use(views(__dirname + '/views', { app.use(views(__dirname + '/views', {
...@@ -44,8 +47,11 @@ app.use(correlation(logNameSpace)); ...@@ -44,8 +47,11 @@ app.use(correlation(logNameSpace));
app.use(async (ctx, next) => { app.use(async (ctx, next) => {
const start = new Date() const start = new Date()
await next() await next()
const ms = new Date() - start logger.info({
console.log(`${moment().format("YYYY-MM-DD HH:mm:ss")} ${logNameSpace.get("requestId")} ${ctx.method} ${ctx.url} - ${ms}ms`) request: ctx.request,
response: ctx.body,
useTime: new Date() - start
})
}) })
// routes // routes
......
...@@ -25,13 +25,14 @@ class RabbitmqClient { ...@@ -25,13 +25,14 @@ class RabbitmqClient {
this.connnection.on("close", (err) => { this.connnection.on("close", (err) => {
logger.info("[x]Rabbitmq is closed ", err); logger.info("[x]Rabbitmq is closed ", err);
this.connnection = null; this.connnection = null;
process.exit(1)
}); });
process.once('SIGINT', this.connnection.close.bind(this.connnection)); process.once('SIGINT', this.connnection.close.bind(this.connnection));
} }
return this.connnection; return this.connnection;
} catch (err) { } catch (err) {
logger.info("--- MQ 连接 失败 ------"); logger.info("--- MQ 连接 失败 ------");
logger.info(err); logger.error(err);
process.exit(1) process.exit(1)
} }
} }
......
...@@ -36,4 +36,4 @@ ...@@ -36,4 +36,4 @@
"@babel/register": "^7.14.5", "@babel/register": "^7.14.5",
"nodemon": "^1.19.1" "nodemon": "^1.19.1"
} }
} }
\ No newline at end of file
import axios from "axios" import axios from "axios"
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { getNamespace } from 'cls-hooked';
import logger from "../utils/logger"
/** /**
* 请求参数 要求 * 请求参数 要求
* url * url
...@@ -16,8 +20,10 @@ import { v4 as uuidv4 } from 'uuid' ...@@ -16,8 +20,10 @@ import { v4 as uuidv4 } from 'uuid'
* message 成功时返回 null ,失败时返回具体错误消息 * message 成功时返回 null ,失败时返回具体错误消息
*/ */
export async function request(message) { export async function request(message) {
const { url, method = "POST", headers = {}, params = {}, data = {}, timeout = 5 } = message;
const start = new Date()
try { try {
const { url, method = "POST", headers = {}, params = {}, data = {}, timeout = 5 } = message; const logNameSpace = getNamespace('logger');
const response = await axios({ const response = await axios({
method, method,
url, url,
...@@ -26,14 +32,26 @@ export async function request(message) { ...@@ -26,14 +32,26 @@ export async function request(message) {
timeout: timeout * 1000, timeout: timeout * 1000,
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
"X-Request-Id": uuidv4(), "X-Request-Id": (logNameSpace && logNameSpace.get("requestId")) || uuidv4(),
...headers ...headers
} }
}); });
if (response.data.code !== 0) { if (response.data.code !== 0) {
throw new Error(response.data.message) throw new Error(response.data.message)
} }
logger.info({
request: message,
response: response.data,
usedTime: new Date() - start,
requestId: headers["X-Request-Id"]
})
} catch (err) { } catch (err) {
logger.error({
request: message,
response: err.message,
usedTime: new Date() - start,
requestId: headers["X-Request-Id"]
})
throw new Error(err.message); throw new Error(err.message);
} }
} }
\ No newline at end of file
import { createLogger, format, transports } from 'winston'; import { createLogger, format, transports } from 'winston';
import 'winston-daily-rotate-file';
import { getNamespace } from 'cls-hooked'; import { getNamespace } from 'cls-hooked';
const myFormat = format.printf(({ level, message, timestamp }) => { import os from 'os'
const loggerNamespace = getNamespace('logger'); const myFormat = format.printf(({ level, message, timestamp, requestId }) => {
return `[${timestamp}] [${level}] ${loggerNamespace.get('requestId') ? ("[" + loggerNamespace.get('requestId') + "] :") : ''} ${message}`; return `[${timestamp}] [${level}] ${requestId ? ("[" + requestId + "] :") : ''} ${message}`;
}); });
const requestId = format((info) => {
let { message } = info;
const loggerNamespace = getNamespace('logger');
let requestId = loggerNamespace.get('requestId');
if (!requestId && Object.prototype.toString.call(message) === "[object Object]" && message.requestId) {
requestId = message.requestId
}
info.requestId = requestId || '-'
info.message = JSON.stringify(message)
return info
})
import path from "path"
const logger = createLogger({ const logger = createLogger({
level: 'info', level: 'info',
defaultMeta: {
serverName: os.hostname(),
},
format: format.combine( format: format.combine(
format.timestamp(), format.timestamp(),
format.splat(), requestId(),
myFormat, format.json(),
format.json()
), ),
transports: [ transports: [
new transports.Console(), new transports.DailyRotateFile({
new transports.File({ filename: path.join(__dirname, '../', 'logs', `info_%DATE%.log`),
dirname: './logs', datePattern: 'YYYY-MM-DD',
filename: `test.log`, maxSize: '10M',
maxFiles: '30d',
zippedArchive: true,
level: "info"
}),
new transports.DailyRotateFile({
filename: path.join(__dirname, '../', 'logs', `error_%DATE%.log`),
datePattern: 'YYYY-MM-DD',
maxSize: '10M',
maxFiles: '30d',
zippedArchive: true,
level: "error"
}),
new transports.DailyRotateFile({
filename: path.join(__dirname, '../', 'logs', `warn_%DATE%.log`),
datePattern: 'YYYY-MM-DD',
maxSize: '10M',
maxFiles: '30d',
zippedArchive: true,
level: "warn"
}) })
], ],
}); });
if (process.env.NODE_ENV !== 'production') {
logger.add(new transports.Console({
format: format.combine(
format.colorize(
{
//各种日志的颜色
colors: { info: 'blue', error: 'red', warn: "yellow" },
all: true,
}
),
format.simple(),
myFormat,
)
}));
}
export default logger; export default logger;
\ No newline at end of file
...@@ -82,8 +82,6 @@ async function listenCustomerLadderQueue() { ...@@ -82,8 +82,6 @@ async function listenCustomerLadderQueue() {
channel.ack(msg); channel.ack(msg);
} else { } else {
// 重试次数用完还是失败 // 重试次数用完还是失败
logger.error("------ 重试 发送消息 彻底 ERROR ------")
logger.error(msg.content.toString());
channel.ack(msg); channel.ack(msg);
} }
} }
...@@ -165,8 +163,6 @@ async function listenCustomerQueue() { ...@@ -165,8 +163,6 @@ async function listenCustomerQueue() {
await request(content); await request(content);
channel.ack(msg); channel.ack(msg);
} catch (err) { } catch (err) {
logger.error("------ 延时 发送消息 彻底 ERROR ------")
logger.error(msg.content.toString());
channel.ack(msg); channel.ack(msg);
} }
}, },
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment