@rife/logger 0.0.5-beta.5 → 0.0.5-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -98,7 +98,7 @@ function createLogger(options) {
98
98
  if (config.writeToConsole) {
99
99
  transports.push(new winston_1.default.transports.Console());
100
100
  }
101
- const { combine, timestamp, colorize, errors, metadata, splat, json } = winston_1.default.format;
101
+ const { combine, timestamp, colorize, errors, metadata, splat } = winston_1.default.format;
102
102
  const timeFormat = isProd() ? 'YYYY-MM-DD HH:mm:ss.SSS' : 'HH:mm:ss.SSS';
103
103
  let format = [
104
104
  errors({ stack: true }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rife/logger",
3
- "version": "0.0.5-beta.5",
3
+ "version": "0.0.5-beta.7",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./src/index.ts",
@@ -15,7 +15,7 @@
15
15
  "safe-stable-stringify": "^2.4.3",
16
16
  "winston": "^3.9.0",
17
17
  "winston-daily-rotate-file": "^4.7.1",
18
- "@rife/config": "0.0.5-beta.5"
18
+ "@rife/config": "0.0.5-beta.7"
19
19
  },
20
20
  "scripts": {
21
21
  "dev": "infra dev",
package/src/index.ts CHANGED
@@ -1,194 +1,194 @@
1
- import path from 'path';
2
- import { AsyncLocalStorage } from 'async_hooks';
3
-
4
- import chalk from 'chalk';
5
- import { customAlphabet } from 'nanoid';
6
- import winston from 'winston';
7
- import JSONStringify from 'safe-stable-stringify';
8
- import 'winston-daily-rotate-file';
9
-
10
- export type { winston };
11
-
12
- const als = new AsyncLocalStorage<{ traceId: string } & any>();
13
-
14
- const isDev = () => process.env.NODE_ENV === 'development';
15
- const isProd = () => !isDev();
16
-
17
- // https://github.com/CyberAP/nanoid-dictionary/blob/master/src/nolookalikes.js
18
- export const getNewTraceId = customAlphabet('346789ABCDEFGHJKLMNPQRTUVWXYabcdefghijkmnpqrtwxyz', 5);
19
-
20
- export function runInTrace<T>(fn: (...args: any[]) => T): T {
21
- return als.run({ traceId: getNewTraceId() }, fn);
22
- }
23
-
24
- export function getTraceId() {
25
- return als.getStore()?.traceId;
26
- }
27
-
28
- const levelColor = {
29
- info: chalk.green,
30
- error: chalk.redBright,
31
- warn: chalk.yellow,
32
- };
33
-
34
- const levelSymbolMap = {
35
- info: 'INF',
36
- warn: 'WRN',
37
- error: 'ERR',
38
- };
39
-
40
- // 设置traceId
41
- // https://www.npmjs.com/package/cls-rtracer
42
- const tracerFormat = (options: { writeToFile: boolean; format: { time: boolean } }) =>
43
- winston.format.printf(info => {
44
- let traceId = getTraceId();
45
- const color = (message: string, chalk: chalk.Chalk) => (options.writeToFile ? message : chalk(message));
46
- const levelit = (text: string) => {
47
- switch (info.level) {
48
- case 'info': {
49
- return color(text, levelColor.info);
50
- }
51
- case 'warn': {
52
- return color(text, levelColor.warn);
53
- }
54
- case 'error': {
55
- return color(text, levelColor.error);
56
- }
57
- }
58
- return text;
59
- };
60
- const levelSymbol = levelSymbolMap[info.level as keyof typeof levelSymbolMap];
61
- const level = levelSymbol ? levelit(` [${levelSymbol}]`) : '';
62
- const service = info.metadata.service ? levelit(` [${info.metadata.service}]`) : '';
63
- const timestamp = options.format.time ? color(info.timestamp, chalk.gray) : '';
64
- const trace = traceId ? color(` [${traceId}]`, chalk.gray) : '';
65
- let message = info.message || '';
66
- if (typeof info?.message !== 'string') {
67
- try {
68
- if (isDev()) {
69
- message = '\n' + JSONStringify(info?.message, undefined, 4);
70
- } else {
71
- message = JSONStringify(info?.message, undefined, 0);
72
- }
73
- } catch (e) {
74
- message = 'fail to stringify json';
75
- }
76
- }
77
- message = ' ' + message;
78
- const stack = info.metadata.stack ? color('\n' + info.metadata.stack + '\n', chalk.gray) : '';
79
- return `${timestamp}${trace}${level}${service}${message}${stack}`;
80
- });
81
-
82
- export namespace Logger {
83
- export interface Options {
84
- /**
85
- * 输出日志到console
86
- * 默认:development环境下输出,production环境下不输出
87
- */
88
- writeToConsole?: boolean;
89
-
90
- /**
91
- * 输出日志到文件
92
- * 默认:development环境下输出,production环境下不输出
93
- */
94
- writeToFile?: boolean;
95
-
96
- /**
97
- * 输出日志的文件目录
98
- * 默认:./logs/
99
- */
100
- dirname?: string;
101
-
102
- /**
103
- * 输出日志的文件名
104
- * 默认:server
105
- */
106
- filename?: string;
107
-
108
- /**
109
- * 日志输出格式
110
- */
111
- format?: {
112
- /**
113
- * 显示时间
114
- * 默认:true
115
- */
116
- time?: boolean;
117
-
118
- /**
119
- * 显示traceId
120
- * 默认:true
121
- */
122
- traceId?: boolean;
123
- };
124
- }
125
- }
126
-
127
- export interface Logger {
128
- info: winston.LeveledLogMethod;
129
- warn: winston.LeveledLogMethod;
130
- error: winston.LeveledLogMethod;
131
- setMetaData: (data: any) => void;
132
- }
133
-
134
- export function createLogger(options?: Logger.Options) {
135
- let transports: winston.transport[] = [];
136
- let config = {
137
- writeToConsole: options?.writeToConsole ?? isDev(),
138
- writeToFile: options?.writeToFile ?? isProd(),
139
- dirname: options?.dirname || path.join(process.cwd(), './logs/'),
140
- filename: options?.filename || 'server',
141
- format: {
142
- time: options?.format?.time ?? true,
143
- },
144
- };
145
- if (config.writeToFile) {
146
- transports.push(
147
- new winston.transports.DailyRotateFile({
148
- // https://www.npmjs.com/package/winston-daily-rotate-file
149
- filename: config.filename,
150
- dirname: config.dirname,
151
- datePattern: 'YYYY-MM-DD',
152
- maxFiles: '30d',
153
- extension: '.log',
154
- }),
155
- );
156
- }
157
-
158
- if (config.writeToConsole) {
159
- transports.push(new winston.transports.Console());
160
- }
161
-
162
- const { combine, timestamp, colorize, errors, metadata, splat, json } = winston.format;
163
- const timeFormat = isProd() ? 'YYYY-MM-DD HH:mm:ss.SSS' : 'HH:mm:ss.SSS';
164
- let format: winston.Logform.Format[] = [
165
- errors({ stack: true }),
166
- metadata(),
167
- timestamp({ format: timeFormat }),
168
- splat(), // https://github.com/winstonjs/logform/blob/master/splat.js
169
- tracerFormat(config),
170
- ];
171
- if (!config.writeToFile) {
172
- format.push(colorize());
173
- }
174
- const instance = winston.createLogger({
175
- format: combine(...format),
176
- transports,
177
- });
178
-
179
- const setMetaData = (data: any) => {
180
- instance.defaultMeta = {
181
- ...instance.defaultMeta,
182
- ...data,
183
- };
184
- };
185
-
186
- const logger: Logger = {
187
- info: instance.info.bind(instance),
188
- warn: instance.warn.bind(instance),
189
- error: instance.error.bind(instance),
190
- setMetaData,
191
- };
192
-
193
- return { logger };
194
- }
1
+ import path from 'path';
2
+ import { AsyncLocalStorage } from 'async_hooks';
3
+
4
+ import chalk from 'chalk';
5
+ import { customAlphabet } from 'nanoid';
6
+ import winston from 'winston';
7
+ import JSONStringify from 'safe-stable-stringify';
8
+ import 'winston-daily-rotate-file';
9
+
10
+ export type { winston };
11
+
12
+ const als = new AsyncLocalStorage<{ traceId: string } & any>();
13
+
14
+ const isDev = () => process.env.NODE_ENV === 'development';
15
+ const isProd = () => !isDev();
16
+
17
+ // https://github.com/CyberAP/nanoid-dictionary/blob/master/src/nolookalikes.js
18
+ export const getNewTraceId = customAlphabet('346789ABCDEFGHJKLMNPQRTUVWXYabcdefghijkmnpqrtwxyz', 5);
19
+
20
+ export function runInTrace<T>(fn: (...args: any[]) => T): T {
21
+ return als.run({ traceId: getNewTraceId() }, fn);
22
+ }
23
+
24
+ export function getTraceId() {
25
+ return als.getStore()?.traceId;
26
+ }
27
+
28
+ const levelColor = {
29
+ info: chalk.green,
30
+ error: chalk.redBright,
31
+ warn: chalk.yellow,
32
+ };
33
+
34
+ const levelSymbolMap = {
35
+ info: 'INF',
36
+ warn: 'WRN',
37
+ error: 'ERR',
38
+ };
39
+
40
+ // 设置traceId
41
+ // https://www.npmjs.com/package/cls-rtracer
42
+ const tracerFormat = (options: { writeToFile: boolean; format: { time: boolean } }) =>
43
+ winston.format.printf(info => {
44
+ let traceId = getTraceId();
45
+ const color = (message: string, chalk: chalk.Chalk) => (options.writeToFile ? message : chalk(message));
46
+ const levelit = (text: string) => {
47
+ switch (info.level) {
48
+ case 'info': {
49
+ return color(text, levelColor.info);
50
+ }
51
+ case 'warn': {
52
+ return color(text, levelColor.warn);
53
+ }
54
+ case 'error': {
55
+ return color(text, levelColor.error);
56
+ }
57
+ }
58
+ return text;
59
+ };
60
+ const levelSymbol = levelSymbolMap[info.level as keyof typeof levelSymbolMap];
61
+ const level = levelSymbol ? levelit(` [${levelSymbol}]`) : '';
62
+ const service = info.metadata.service ? levelit(` [${info.metadata.service}]`) : '';
63
+ const timestamp = options.format.time ? color(info.timestamp, chalk.gray) : '';
64
+ const trace = traceId ? color(` [${traceId}]`, chalk.gray) : '';
65
+ let message = info.message || '';
66
+ if (typeof info?.message !== 'string') {
67
+ try {
68
+ if (isDev()) {
69
+ message = '\n' + JSONStringify(info?.message, undefined, 4);
70
+ } else {
71
+ message = JSONStringify(info?.message, undefined, 0);
72
+ }
73
+ } catch (e) {
74
+ message = 'fail to stringify json';
75
+ }
76
+ }
77
+ message = ' ' + message;
78
+ const stack = info.metadata.stack ? color('\n' + info.metadata.stack + '\n', chalk.gray) : '';
79
+ return `${timestamp}${trace}${level}${service}${message}${stack}`;
80
+ });
81
+
82
+ export namespace Logger {
83
+ export interface Options {
84
+ /**
85
+ * 输出日志到console
86
+ * 默认:development环境下输出,production环境下不输出
87
+ */
88
+ writeToConsole?: boolean;
89
+
90
+ /**
91
+ * 输出日志到文件
92
+ * 默认:development环境下输出,production环境下不输出
93
+ */
94
+ writeToFile?: boolean;
95
+
96
+ /**
97
+ * 输出日志的文件目录
98
+ * 默认:./logs/
99
+ */
100
+ dirname?: string;
101
+
102
+ /**
103
+ * 输出日志的文件名
104
+ * 默认:server
105
+ */
106
+ filename?: string;
107
+
108
+ /**
109
+ * 日志输出格式
110
+ */
111
+ format?: {
112
+ /**
113
+ * 显示时间
114
+ * 默认:true
115
+ */
116
+ time?: boolean;
117
+
118
+ /**
119
+ * 显示traceId
120
+ * 默认:true
121
+ */
122
+ traceId?: boolean;
123
+ };
124
+ }
125
+ }
126
+
127
+ export interface Logger {
128
+ info: winston.LeveledLogMethod;
129
+ warn: winston.LeveledLogMethod;
130
+ error: winston.LeveledLogMethod;
131
+ setMetaData: (data: any) => void;
132
+ }
133
+
134
+ export function createLogger(options?: Logger.Options) {
135
+ let transports: winston.transport[] = [];
136
+ let config = {
137
+ writeToConsole: options?.writeToConsole ?? isDev(),
138
+ writeToFile: options?.writeToFile ?? isProd(),
139
+ dirname: options?.dirname || path.join(process.cwd(), './logs/'),
140
+ filename: options?.filename || 'server',
141
+ format: {
142
+ time: options?.format?.time ?? true,
143
+ },
144
+ };
145
+ if (config.writeToFile) {
146
+ transports.push(
147
+ new winston.transports.DailyRotateFile({
148
+ // https://www.npmjs.com/package/winston-daily-rotate-file
149
+ filename: config.filename,
150
+ dirname: config.dirname,
151
+ datePattern: 'YYYY-MM-DD',
152
+ maxFiles: '30d',
153
+ extension: '.log',
154
+ }),
155
+ );
156
+ }
157
+
158
+ if (config.writeToConsole) {
159
+ transports.push(new winston.transports.Console());
160
+ }
161
+
162
+ const { combine, timestamp, colorize, errors, metadata, splat } = winston.format;
163
+ const timeFormat = isProd() ? 'YYYY-MM-DD HH:mm:ss.SSS' : 'HH:mm:ss.SSS';
164
+ let format: winston.Logform.Format[] = [
165
+ errors({ stack: true }),
166
+ metadata(),
167
+ timestamp({ format: timeFormat }),
168
+ splat(), // https://github.com/winstonjs/logform/blob/master/splat.js
169
+ tracerFormat(config),
170
+ ];
171
+ if (!config.writeToFile) {
172
+ format.push(colorize());
173
+ }
174
+ const instance = winston.createLogger({
175
+ format: combine(...format),
176
+ transports,
177
+ });
178
+
179
+ const setMetaData = (data: any) => {
180
+ instance.defaultMeta = {
181
+ ...instance.defaultMeta,
182
+ ...data,
183
+ };
184
+ };
185
+
186
+ const logger: Logger = {
187
+ info: instance.info.bind(instance),
188
+ warn: instance.warn.bind(instance),
189
+ error: instance.error.bind(instance),
190
+ setMetaData,
191
+ };
192
+
193
+ return { logger };
194
+ }
package/src/test.ts CHANGED
@@ -1,25 +1,25 @@
1
- process.env.NODE_ENV = 'development';
2
- // process.env.NODE_ENV = 'production';
3
-
4
- import { createLogger } from '.';
5
-
6
- const { logger } = createLogger({ writeToFile: false, writeToConsole: true, format: { time: false } });
7
-
8
- const deep = { a: { b: { c: { g: { e: { f: 1 } } } } } };
9
- logger.info('1 %s', { a: 1 });
10
- logger.info('2 %j', deep);
11
- logger.info('3 \n%j', deep);
12
- logger.info('4 %s %s', 1, 2);
13
- logger.info('5 %o', deep);
14
- logger.info(deep);
15
- logger.warn('execed');
16
- logger.error(new Error('not found'));
17
-
18
- // import { format } from 'logform';
19
-
20
- // const jsonFormat = format.json({ space: 2 });
21
- // const info = jsonFormat.transform({
22
- // level: 'info',
23
- // message: 'my message',
24
- // });
25
- // console.log(info);
1
+ process.env.NODE_ENV = 'development';
2
+ // process.env.NODE_ENV = 'production';
3
+
4
+ import { createLogger } from '.';
5
+
6
+ const { logger } = createLogger({ writeToFile: false, writeToConsole: true, format: { time: false } });
7
+
8
+ const deep = { a: { b: { c: { g: { e: { f: 1 } } } } } };
9
+ logger.info('1 %s', { a: 1 });
10
+ logger.info('2 %j', deep);
11
+ logger.info('3 \n%j', deep);
12
+ logger.info('4 %s %s', 1, 2);
13
+ logger.info('5 %o', deep);
14
+ logger.info(deep);
15
+ logger.warn('execed');
16
+ logger.error(new Error('not found'));
17
+
18
+ // import { format } from 'logform';
19
+
20
+ // const jsonFormat = format.json({ space: 2 });
21
+ // const info = jsonFormat.transform({
22
+ // level: 'info',
23
+ // message: 'my message',
24
+ // });
25
+ // console.log(info);
package/tsconfig.json CHANGED
@@ -1,12 +1,12 @@
1
- {
2
- "extends": "@rife/config/tsconfig.json", // 继承 packages 目录下通用配置
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "declaration": true,
6
- "baseUrl": ".",
7
- "paths": {
8
- "@/*": ["./src/*"]
9
- }
10
- },
11
- "include": ["./src/**/*"]
12
- }
1
+ {
2
+ "extends": "@rife/config/tsconfig.json", // 继承 packages 目录下通用配置
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "declaration": true,
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ "@/*": ["./src/*"]
9
+ }
10
+ },
11
+ "include": ["./src/**/*"]
12
+ }