xilore-log4js 1.0.0
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/README.md +181 -0
- package/dist/appender/xil-log-print-appender.d.ts +8 -0
- package/dist/appender/xil-log-print-appender.d.ts.map +1 -0
- package/dist/appender/xil-log-print-appender.js +18 -0
- package/dist/appender/xil-log-print-appender.js.map +1 -0
- package/dist/appender/xil-log-upload-appender.d.ts +14 -0
- package/dist/appender/xil-log-upload-appender.d.ts.map +1 -0
- package/dist/appender/xil-log-upload-appender.js +94 -0
- package/dist/appender/xil-log-upload-appender.js.map +1 -0
- package/dist/appender/xil-log-write-appender.d.ts +22 -0
- package/dist/appender/xil-log-write-appender.d.ts.map +1 -0
- package/dist/appender/xil-log-write-appender.js +106 -0
- package/dist/appender/xil-log-write-appender.js.map +1 -0
- package/dist/config/xil-log-config-loader.d.ts +7 -0
- package/dist/config/xil-log-config-loader.d.ts.map +1 -0
- package/dist/config/xil-log-config-loader.js +127 -0
- package/dist/config/xil-log-config-loader.js.map +1 -0
- package/dist/config/xil-log-config.d.ts +21 -0
- package/dist/config/xil-log-config.d.ts.map +1 -0
- package/dist/config/xil-log-config.js +2 -0
- package/dist/config/xil-log-config.js.map +1 -0
- package/dist/config/xil-log-properties-config.d.ts +26 -0
- package/dist/config/xil-log-properties-config.d.ts.map +1 -0
- package/dist/config/xil-log-properties-config.js +143 -0
- package/dist/config/xil-log-properties-config.js.map +1 -0
- package/dist/entity/xil-log-entity.d.ts +17 -0
- package/dist/entity/xil-log-entity.d.ts.map +1 -0
- package/dist/entity/xil-log-entity.js +2 -0
- package/dist/entity/xil-log-entity.js.map +1 -0
- package/dist/entity/xil-log-exclude-item.d.ts +12 -0
- package/dist/entity/xil-log-exclude-item.d.ts.map +1 -0
- package/dist/entity/xil-log-exclude-item.js +13 -0
- package/dist/entity/xil-log-exclude-item.js.map +1 -0
- package/dist/entity/xil-log-level-switch.d.ts +10 -0
- package/dist/entity/xil-log-level-switch.d.ts.map +1 -0
- package/dist/entity/xil-log-level-switch.js +4 -0
- package/dist/entity/xil-log-level-switch.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/ansi.d.ts +13 -0
- package/dist/utils/ansi.d.ts.map +1 -0
- package/dist/utils/ansi.js +50 -0
- package/dist/utils/ansi.js.map +1 -0
- package/dist/utils/container-id.d.ts +7 -0
- package/dist/utils/container-id.d.ts.map +1 -0
- package/dist/utils/container-id.js +37 -0
- package/dist/utils/container-id.js.map +1 -0
- package/dist/utils/date-format.d.ts +5 -0
- package/dist/utils/date-format.d.ts.map +1 -0
- package/dist/utils/date-format.js +33 -0
- package/dist/utils/date-format.js.map +1 -0
- package/dist/utils/format.d.ts +20 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +188 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/parse-detail.d.ts +6 -0
- package/dist/utils/parse-detail.d.ts.map +1 -0
- package/dist/utils/parse-detail.js +15 -0
- package/dist/utils/parse-detail.js.map +1 -0
- package/dist/utils/xil-log-ansi.d.ts +13 -0
- package/dist/utils/xil-log-ansi.d.ts.map +1 -0
- package/dist/utils/xil-log-ansi.js +50 -0
- package/dist/utils/xil-log-ansi.js.map +1 -0
- package/dist/utils/xil-log-container-id.d.ts +7 -0
- package/dist/utils/xil-log-container-id.d.ts.map +1 -0
- package/dist/utils/xil-log-container-id.js +37 -0
- package/dist/utils/xil-log-container-id.js.map +1 -0
- package/dist/utils/xil-log-date-format.d.ts +5 -0
- package/dist/utils/xil-log-date-format.d.ts.map +1 -0
- package/dist/utils/xil-log-date-format.js +33 -0
- package/dist/utils/xil-log-date-format.js.map +1 -0
- package/dist/utils/xil-log-format.d.ts +20 -0
- package/dist/utils/xil-log-format.d.ts.map +1 -0
- package/dist/utils/xil-log-format.js +187 -0
- package/dist/utils/xil-log-format.js.map +1 -0
- package/dist/utils/xil-log-parse-detail.d.ts +6 -0
- package/dist/utils/xil-log-parse-detail.d.ts.map +1 -0
- package/dist/utils/xil-log-parse-detail.js +15 -0
- package/dist/utils/xil-log-parse-detail.js.map +1 -0
- package/dist/xil-log-level.d.ts +7 -0
- package/dist/xil-log-level.d.ts.map +1 -0
- package/dist/xil-log-level.js +15 -0
- package/dist/xil-log-level.js.map +1 -0
- package/dist/xil-log-runner.d.ts +19 -0
- package/dist/xil-log-runner.d.ts.map +1 -0
- package/dist/xil-log-runner.js +125 -0
- package/dist/xil-log-runner.js.map +1 -0
- package/dist/xil-logger.d.ts +34 -0
- package/dist/xil-logger.d.ts.map +1 -0
- package/dist/xil-logger.js +79 -0
- package/dist/xil-logger.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Xilore Log4js
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://nodejs.org/)
|
|
5
|
+
|
|
6
|
+
轻量级 TypeScript/Node 日志库,参考 [xilore-log4j](https://git.kiiiv.com/Luminous/xilore-log4j) 设计,提供**控制台 / 按日滚动文件 / 远程上传**三种输出,支持 JSON/YAML 配置与按包/类排除。
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 特性
|
|
11
|
+
|
|
12
|
+
- **门面 API**:`getLogger(name)` 或 `getLogger(MyClass)`,支持 `trace` / `debug` / `info` / `warn` / `error`
|
|
13
|
+
- **三种输出**:控制台(Print)、按日滚动写文件(Write)、远程上传(Upload),各级别可单独开关
|
|
14
|
+
- **多格式配置**:支持 `xilore.json`、`xilore.yml` / `xilore.yaml`(需安装可选依赖 `js-yaml`),环境变量 `log.*` 可覆盖
|
|
15
|
+
- **包/类排除**:按名称模式排除日志,可限定生效级别
|
|
16
|
+
- **控制台彩色**:基于 ANSI 的级别着色,可通过配置或 `NO_COLOR` 关闭
|
|
17
|
+
- **容器标识**:自动解析 Docker/cgroup 或环境变量 `CONTAINER_ID`、`HOSTNAME`
|
|
18
|
+
- **宽度压缩**:超长 logger 名可缩写显示
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 环境要求
|
|
23
|
+
|
|
24
|
+
- **Node.js 16+**
|
|
25
|
+
- **TypeScript 5.x**(仅构建时)
|
|
26
|
+
- 可选:**js-yaml**(用于 YAML 配置)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 安装
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install xilore-log4js
|
|
34
|
+
# 若使用 YAML 配置
|
|
35
|
+
npm install js-yaml
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 快速开始
|
|
41
|
+
|
|
42
|
+
### 1. 使用 getLogger(推荐)
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { getLogger } from 'xilore-log4js';
|
|
46
|
+
|
|
47
|
+
const log = getLogger('my-app');
|
|
48
|
+
log.info('Hello xilore-log4js');
|
|
49
|
+
log.warn('Warning', new Error('demo'));
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. 按类名获取 Logger
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { getLogger } from 'xilore-log4js';
|
|
56
|
+
|
|
57
|
+
class App {
|
|
58
|
+
private static log = getLogger(App);
|
|
59
|
+
run() {
|
|
60
|
+
App.log.info('running');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 3. 配置文件
|
|
66
|
+
|
|
67
|
+
将配置放在**项目根目录**(与 `package.json` 同级),任选其一:
|
|
68
|
+
|
|
69
|
+
| 文件 | 说明 |
|
|
70
|
+
|-----------------|-------------------------|
|
|
71
|
+
| `xilore.json` | JSON,始终可加载 |
|
|
72
|
+
| `xilore.yml` / `xilore.yaml` | 需安装 `js-yaml` 时使用 |
|
|
73
|
+
|
|
74
|
+
加载优先级:**xilore.json → xilore.yml**,环境变量中键以 `log.` 开头的会覆盖已加载配置。
|
|
75
|
+
|
|
76
|
+
#### xilore.json 示例
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"log": {
|
|
81
|
+
"path": ".",
|
|
82
|
+
"file_prefix": "app",
|
|
83
|
+
"date_format": "yyyy-MM-dd HH:mm:ss.SSS",
|
|
84
|
+
"detail": {
|
|
85
|
+
"trace": { "print": true, "write": false, "upload": false },
|
|
86
|
+
"debug": { "print": true, "write": false, "upload": false },
|
|
87
|
+
"info": { "print": true, "write": false, "upload": false },
|
|
88
|
+
"warn": { "print": true, "write": true, "upload": false },
|
|
89
|
+
"error": { "print": true, "write": true, "upload": true }
|
|
90
|
+
},
|
|
91
|
+
"upload": { "host": "", "token": "" },
|
|
92
|
+
"charset": "UTF-8",
|
|
93
|
+
"app_name": "my-app",
|
|
94
|
+
"color": true,
|
|
95
|
+
"compress_width": true,
|
|
96
|
+
"exclude": [
|
|
97
|
+
{ "pattern": "com.third.party", "levels": ["debug", "info"] },
|
|
98
|
+
"org.noise"
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
#### xilore.yml 示例
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
log:
|
|
108
|
+
path: .
|
|
109
|
+
file_prefix: app
|
|
110
|
+
date_format: "yyyy-MM-dd HH:mm:ss.SSS"
|
|
111
|
+
detail:
|
|
112
|
+
trace: { print: true, write: false, upload: false }
|
|
113
|
+
debug: { print: true, write: false, upload: false }
|
|
114
|
+
info: { print: true, write: false, upload: false }
|
|
115
|
+
warn: { print: true, write: true, upload: false }
|
|
116
|
+
error: { print: true, write: true, upload: true }
|
|
117
|
+
upload: { host: "", token: "" }
|
|
118
|
+
charset: UTF-8
|
|
119
|
+
app_name: my-app
|
|
120
|
+
color: true
|
|
121
|
+
compress_width: true
|
|
122
|
+
exclude:
|
|
123
|
+
- pattern: com.third.party
|
|
124
|
+
levels: [debug, info]
|
|
125
|
+
- org.noise
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## 配置项摘要
|
|
131
|
+
|
|
132
|
+
| 配置键 | 说明 | 默认值 |
|
|
133
|
+
|--------|------|--------|
|
|
134
|
+
| `path` | 日志文件目录 | `.` |
|
|
135
|
+
| `file_prefix` | 日志文件名前缀(文件为 `path/file_prefix+yyyy-MM-dd.log`) | `app` |
|
|
136
|
+
| `date_format` | 日期格式 | `yyyy-MM-dd HH:mm:ss.SSS` |
|
|
137
|
+
| `detail.{level}.print` / `.write` / `.upload` | 该级别是否输出到控制台/写文件/上传 | 未配置时仅 print |
|
|
138
|
+
| `upload.host` / `upload.token` | 上传服务地址与 token,host 为空则不上传 | 空 |
|
|
139
|
+
| `charset` | 字符集 | `UTF-8` |
|
|
140
|
+
| `app_name` | 应用名,日志中显示为 `[appName]` | 空 |
|
|
141
|
+
| `color` | 控制台是否彩色 | `true` |
|
|
142
|
+
| `compress_width` | 是否压缩 logger 名宽度 | `true` |
|
|
143
|
+
| `exclude` | 不输出日志的包或类排除项,可配 `levels` 限定级别 | 空 |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## API
|
|
148
|
+
|
|
149
|
+
- `getLogger(name: string): XilLogger`
|
|
150
|
+
- `getLogger(ctor: Function | { name?: string }): XilLogger`
|
|
151
|
+
- `shutdownIfPresent(): void` — 关闭 runner,等待未完成任务
|
|
152
|
+
- `setConfig(config: XilLogConfig | null): void` — 注入配置(测试或程序化配置)
|
|
153
|
+
|
|
154
|
+
`XilLogger` 方法:`trace`, `debug`, `info`, `warn`, `error`,每个支持 `(message: string)` 或 `(message: string, err?: unknown)`。
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 开发与测试
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm install
|
|
162
|
+
npm run test # 运行测试
|
|
163
|
+
npm run test:watch # 监听模式
|
|
164
|
+
npm run build # 编译
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## 构建与发布
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm run build
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
发布前会自动执行 `npm run test && npm run build`(`prepublishOnly`)。
|
|
174
|
+
|
|
175
|
+
**堆栈显示为 .ts 源文件**:运行编译后的代码时使用 `node --enable-source-maps dist/xxx.js`,或安装可选依赖 `source-map-support`,日志中的错误堆栈会显示 TypeScript 源文件(如 `demo.ts:8:32`)而非编译后的 `.js`。
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 许可证
|
|
180
|
+
|
|
181
|
+
[MIT License](https://opensource.org/licenses/MIT)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { XilLogEntity } from '../entity/xil-log-entity.js';
|
|
2
|
+
import type { XilLogConfig } from '../config/xil-log-config.js';
|
|
3
|
+
export declare class XilLogPrintAppender {
|
|
4
|
+
private readonly useColor;
|
|
5
|
+
constructor(config: XilLogConfig | null);
|
|
6
|
+
append(entity: XilLogEntity | null): void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=xil-log-print-appender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-print-appender.d.ts","sourceRoot":"","sources":["../../src/appender/xil-log-print-appender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;gBAEvB,MAAM,EAAE,YAAY,GAAG,IAAI;IAKvC,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;CAS1C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { colorize, isColorDisabledByEnv } from '../utils/xil-log-ansi.js';
|
|
2
|
+
const COLOR_DISABLED_BY_ENV = isColorDisabledByEnv();
|
|
3
|
+
export class XilLogPrintAppender {
|
|
4
|
+
constructor(config) {
|
|
5
|
+
this.useColor =
|
|
6
|
+
!COLOR_DISABLED_BY_ENV && (config == null || config.isColorEnabled());
|
|
7
|
+
}
|
|
8
|
+
append(entity) {
|
|
9
|
+
if (entity == null) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const line = this.useColor
|
|
13
|
+
? colorize(entity.level, entity.basicLog)
|
|
14
|
+
: entity.basicLog;
|
|
15
|
+
process.stdout.write(line + '\n');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=xil-log-print-appender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-print-appender.js","sourceRoot":"","sources":["../../src/appender/xil-log-print-appender.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,qBAAqB,GAAG,oBAAoB,EAAE,CAAC;AAErD,MAAM,OAAO,mBAAmB;IAG9B,YAAY,MAA2B;QACrC,IAAI,CAAC,QAAQ;YACX,CAAC,qBAAqB,IAAI,CAAC,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,CAAC,MAA2B;QAChC,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ;YACxB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC;YACzC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QACpB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { XilLogEntity } from '../entity/xil-log-entity.js';
|
|
2
|
+
import type { XilLogConfig } from '../config/xil-log-config.js';
|
|
3
|
+
export declare class XilLogUploadAppender {
|
|
4
|
+
private readonly uploadHost;
|
|
5
|
+
private readonly uploadToken;
|
|
6
|
+
private readonly queue;
|
|
7
|
+
private running;
|
|
8
|
+
constructor(config: XilLogConfig);
|
|
9
|
+
private drainLoop;
|
|
10
|
+
append(entity: XilLogEntity | null): void;
|
|
11
|
+
private doUpload;
|
|
12
|
+
shutdown(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=xil-log-upload-appender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-upload-appender.d.ts","sourceRoot":"","sources":["../../src/appender/xil-log-upload-appender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,6BAA6B,CAAC;AAgC9D,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;IACjD,OAAO,CAAC,OAAO,CAAQ;gBAEX,MAAM,EAAE,YAAY;IAMhC,OAAO,CAAC,SAAS;IAejB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;YAO3B,QAAQ;IA+BhB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { request as httpsRequest } from 'node:https';
|
|
2
|
+
import { request as httpRequest } from 'node:http';
|
|
3
|
+
function escapeJson(s) {
|
|
4
|
+
if (s == null) {
|
|
5
|
+
return '';
|
|
6
|
+
}
|
|
7
|
+
return s
|
|
8
|
+
.replace(/\\/g, '\\\\')
|
|
9
|
+
.replace(/"/g, '\\"')
|
|
10
|
+
.replace(/\n/g, '\\n')
|
|
11
|
+
.replace(/\r/g, '\\r')
|
|
12
|
+
.replace(/\t/g, '\\t');
|
|
13
|
+
}
|
|
14
|
+
function toJson(entity) {
|
|
15
|
+
const parts = [
|
|
16
|
+
`"level":"${escapeJson(entity.level)}"`,
|
|
17
|
+
`"message":"${escapeJson(entity.message)}"`,
|
|
18
|
+
`"timestamp":${entity.timestamp}`,
|
|
19
|
+
`"timestampIso":"${escapeJson(entity.timestampIso)}"`,
|
|
20
|
+
`"threadName":"${escapeJson(entity.threadName)}"`,
|
|
21
|
+
`"loggerName":"${escapeJson(entity.loggerName)}"`,
|
|
22
|
+
`"appName":"${escapeJson(entity.appName)}"`,
|
|
23
|
+
`"containerId":"${escapeJson(entity.containerId ?? '')}"`,
|
|
24
|
+
`"basicLog":"${escapeJson(entity.basicLog)}"`,
|
|
25
|
+
];
|
|
26
|
+
if (entity.throwableStackTrace?.trim()) {
|
|
27
|
+
parts.push(`"throwableStackTrace":"${escapeJson(entity.throwableStackTrace)}"`);
|
|
28
|
+
}
|
|
29
|
+
return '{' + parts.join(',') + '}';
|
|
30
|
+
}
|
|
31
|
+
export class XilLogUploadAppender {
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.queue = [];
|
|
34
|
+
this.running = true;
|
|
35
|
+
this.uploadHost = config.getUploadHost()?.trim() ?? '';
|
|
36
|
+
this.uploadToken = config.getUploadToken()?.trim() ?? '';
|
|
37
|
+
this.drainLoop();
|
|
38
|
+
}
|
|
39
|
+
drainLoop() {
|
|
40
|
+
const run = async () => {
|
|
41
|
+
const entity = this.queue.shift();
|
|
42
|
+
if (entity) {
|
|
43
|
+
await this.doUpload(entity);
|
|
44
|
+
setImmediate(run);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (this.running) {
|
|
48
|
+
setImmediate(run);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
setImmediate(run);
|
|
52
|
+
}
|
|
53
|
+
append(entity) {
|
|
54
|
+
if (entity == null || !this.uploadHost) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.queue.push(entity);
|
|
58
|
+
}
|
|
59
|
+
async doUpload(entity) {
|
|
60
|
+
const path = this.uploadHost.endsWith('/')
|
|
61
|
+
? this.uploadHost + 'receive'
|
|
62
|
+
: this.uploadHost + '/receive';
|
|
63
|
+
const urlStr = this.uploadToken ? `${path}?token=${encodeURIComponent(this.uploadToken)}` : path;
|
|
64
|
+
try {
|
|
65
|
+
const url = new URL(urlStr);
|
|
66
|
+
const request = url.protocol === 'https:' ? httpsRequest : httpRequest;
|
|
67
|
+
const body = toJson(entity);
|
|
68
|
+
await new Promise((resolve, reject) => {
|
|
69
|
+
const req = request(url, {
|
|
70
|
+
method: 'PUT',
|
|
71
|
+
headers: { 'Content-Type': 'application/json; charset=UTF-8', 'Content-Length': Buffer.byteLength(body, 'utf8') },
|
|
72
|
+
}, (res) => {
|
|
73
|
+
res.on('data', () => { });
|
|
74
|
+
res.on('end', () => resolve());
|
|
75
|
+
res.on('error', reject);
|
|
76
|
+
});
|
|
77
|
+
req.on('error', reject);
|
|
78
|
+
req.write(body, 'utf8');
|
|
79
|
+
req.end();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// ignore
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async shutdown() {
|
|
87
|
+
this.running = false;
|
|
88
|
+
const deadline = Date.now() + 5000;
|
|
89
|
+
while (this.queue.length > 0 && Date.now() < deadline) {
|
|
90
|
+
await new Promise((r) => setImmediate(r));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=xil-log-upload-appender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-upload-appender.js","sourceRoot":"","sources":["../../src/appender/xil-log-upload-appender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { XilLogEntity } from '../entity/xil-log-entity.js';
|
|
2
|
+
import type { XilLogConfig } from '../config/xil-log-config.js';
|
|
3
|
+
export declare class XilLogWriteAppender {
|
|
4
|
+
private readonly path;
|
|
5
|
+
private readonly filePrefix;
|
|
6
|
+
private readonly charset;
|
|
7
|
+
private readonly flushInterval;
|
|
8
|
+
private currentDate;
|
|
9
|
+
private currentWriter;
|
|
10
|
+
private writtenSinceFlush;
|
|
11
|
+
private readonly queue;
|
|
12
|
+
private running;
|
|
13
|
+
private readonly lock;
|
|
14
|
+
constructor(config: XilLogConfig);
|
|
15
|
+
private drainLoop;
|
|
16
|
+
append(entity: XilLogEntity | null): void;
|
|
17
|
+
private doAppend;
|
|
18
|
+
private writerForToday;
|
|
19
|
+
private closeCurrent;
|
|
20
|
+
shutdown(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=xil-log-write-appender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-write-appender.d.ts","sourceRoot":"","sources":["../../src/appender/xil-log-write-appender.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAKhE,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;gBAE5B,MAAM,EAAE,YAAY;IAQhC,OAAO,CAAC,SAAS;IAmBjB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI;IAOzC,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,cAAc;IAuBtB,OAAO,CAAC,YAAY;IAYd,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAQhC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createWriteStream, mkdirSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const LINE_SEP = '\n';
|
|
4
|
+
const SHUTDOWN_AWAIT_MS = 10000;
|
|
5
|
+
export class XilLogWriteAppender {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.currentDate = '';
|
|
8
|
+
this.currentWriter = null;
|
|
9
|
+
this.writtenSinceFlush = 0;
|
|
10
|
+
this.queue = [];
|
|
11
|
+
this.running = true;
|
|
12
|
+
this.lock = { current: '' };
|
|
13
|
+
this.path = config.getPath();
|
|
14
|
+
this.filePrefix = config.getFilePrefix();
|
|
15
|
+
this.charset = (config.getCharset() || 'utf8');
|
|
16
|
+
this.flushInterval = Math.max(1, config.getWriteFlushInterval());
|
|
17
|
+
this.drainLoop();
|
|
18
|
+
}
|
|
19
|
+
drainLoop() {
|
|
20
|
+
const run = () => {
|
|
21
|
+
const task = this.queue.shift();
|
|
22
|
+
if (task) {
|
|
23
|
+
try {
|
|
24
|
+
task();
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// ignore
|
|
28
|
+
}
|
|
29
|
+
setImmediate(run);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (this.running) {
|
|
33
|
+
setImmediate(run);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
setImmediate(run);
|
|
37
|
+
}
|
|
38
|
+
append(entity) {
|
|
39
|
+
if (entity == null) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.queue.push(() => this.doAppend(entity));
|
|
43
|
+
}
|
|
44
|
+
doAppend(entity) {
|
|
45
|
+
try {
|
|
46
|
+
const w = this.writerForToday();
|
|
47
|
+
if (w) {
|
|
48
|
+
w.write(entity.basicLog + LINE_SEP, this.charset);
|
|
49
|
+
this.writtenSinceFlush++;
|
|
50
|
+
if (this.writtenSinceFlush >= this.flushInterval) {
|
|
51
|
+
this.writtenSinceFlush = 0;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// ignore
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
writerForToday() {
|
|
60
|
+
const today = new Date().toISOString().slice(0, 10); // yyyy-MM-dd
|
|
61
|
+
const lock = this.lock;
|
|
62
|
+
synchronized(lock, () => {
|
|
63
|
+
if (today !== this.currentDate) {
|
|
64
|
+
this.closeCurrent();
|
|
65
|
+
this.currentDate = today;
|
|
66
|
+
this.writtenSinceFlush = 0;
|
|
67
|
+
const dir = this.path;
|
|
68
|
+
if (!existsSync(dir)) {
|
|
69
|
+
mkdirSync(dir, { recursive: true });
|
|
70
|
+
}
|
|
71
|
+
const fileName = this.filePrefix + this.currentDate + '.log';
|
|
72
|
+
const filePath = join(dir, fileName);
|
|
73
|
+
this.currentWriter = createWriteStream(filePath, {
|
|
74
|
+
flags: 'a',
|
|
75
|
+
encoding: this.charset,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return this.currentWriter;
|
|
80
|
+
}
|
|
81
|
+
closeCurrent() {
|
|
82
|
+
if (this.currentWriter) {
|
|
83
|
+
try {
|
|
84
|
+
this.currentWriter.end();
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// ignore
|
|
88
|
+
}
|
|
89
|
+
this.currentWriter = null;
|
|
90
|
+
}
|
|
91
|
+
this.writtenSinceFlush = 0;
|
|
92
|
+
}
|
|
93
|
+
async shutdown() {
|
|
94
|
+
this.running = false;
|
|
95
|
+
const deadline = Date.now() + SHUTDOWN_AWAIT_MS;
|
|
96
|
+
while (this.queue.length > 0 && Date.now() < deadline) {
|
|
97
|
+
await new Promise((r) => setImmediate(r));
|
|
98
|
+
}
|
|
99
|
+
synchronized(this.lock, () => this.closeCurrent());
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function synchronized(_lock, fn) {
|
|
103
|
+
// 单线程 Node 下简化:仅保证同一 lock 串行
|
|
104
|
+
return fn();
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=xil-log-write-appender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-write-appender.js","sourceRoot":"","sources":["../../src/appender/xil-log-write-appender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { XilLogConfig } from './xil-log-config.js';
|
|
2
|
+
/**
|
|
3
|
+
* 按优先级加载配置:json → yaml → 环境变量覆盖。
|
|
4
|
+
* 搜索路径:process.cwd(),以及逐级向上查找 xilore.json / xilore.yml。
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadConfig(searchDir?: string): XilLogConfig;
|
|
7
|
+
//# sourceMappingURL=xil-log-config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-config-loader.d.ts","sourceRoot":"","sources":["../../src/config/xil-log-config-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAkHxD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAQ3D"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { XilLogPropertiesConfig } from './xil-log-properties-config.js';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const PREFIX = 'log.';
|
|
7
|
+
function normalizeKey(key) {
|
|
8
|
+
let k = key;
|
|
9
|
+
if (k.startsWith(PREFIX)) {
|
|
10
|
+
k = k.slice(PREFIX.length);
|
|
11
|
+
}
|
|
12
|
+
if (k.startsWith('xilore.log.')) {
|
|
13
|
+
k = k.slice('xilore.log.'.length);
|
|
14
|
+
}
|
|
15
|
+
return k;
|
|
16
|
+
}
|
|
17
|
+
function flattenInto(target, source, prefix) {
|
|
18
|
+
if (source == null || typeof source !== 'object') {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const [k, v] of Object.entries(source)) {
|
|
22
|
+
const segment = k.trim().toLowerCase();
|
|
23
|
+
const key = prefix + segment;
|
|
24
|
+
if (v != null && typeof v === 'object') {
|
|
25
|
+
if (Array.isArray(v)) {
|
|
26
|
+
v.forEach((item, i) => {
|
|
27
|
+
if (item != null && typeof item === 'object' && !Array.isArray(item)) {
|
|
28
|
+
flattenInto(target, item, `${key}.${i}.`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
target.set(normalizeKey(`${key}.${i}`), String(item).trim());
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
else if (!(v instanceof Date)) {
|
|
36
|
+
flattenInto(target, v, key + '.');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (v != null) {
|
|
40
|
+
target.set(normalizeKey(key), String(v).trim());
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function loadFromJson(map, cwd) {
|
|
45
|
+
for (const name of ['xilore.json']) {
|
|
46
|
+
const p = join(cwd, name);
|
|
47
|
+
if (!existsSync(p)) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const content = readFileSync(p, 'utf8');
|
|
52
|
+
const data = JSON.parse(content);
|
|
53
|
+
const log = data?.log;
|
|
54
|
+
if (log && typeof log === 'object') {
|
|
55
|
+
flattenInto(map, log, '');
|
|
56
|
+
}
|
|
57
|
+
else if (data && typeof data === 'object') {
|
|
58
|
+
flattenInto(map, data, '');
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// ignore
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
function loadFromYaml(map, cwd) {
|
|
69
|
+
let yaml = null;
|
|
70
|
+
try {
|
|
71
|
+
yaml = require('js-yaml');
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (!yaml?.load) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
for (const name of ['xilore.yml', 'xilore.yaml']) {
|
|
80
|
+
const p = join(cwd, name);
|
|
81
|
+
if (!existsSync(p)) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const content = readFileSync(p, 'utf8');
|
|
86
|
+
const data = yaml.load(content);
|
|
87
|
+
const log = data?.log;
|
|
88
|
+
if (log && typeof log === 'object') {
|
|
89
|
+
flattenInto(map, log, '');
|
|
90
|
+
}
|
|
91
|
+
else if (data && typeof data === 'object') {
|
|
92
|
+
flattenInto(map, data, '');
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// ignore
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
function loadFromEnv(map) {
|
|
103
|
+
for (const [k, v] of Object.entries(process.env)) {
|
|
104
|
+
if (v == null) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const key = k.trim().toLowerCase();
|
|
108
|
+
if (!key.startsWith(PREFIX)) {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
map.set(normalizeKey(key), v.trim());
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 按优先级加载配置:json → yaml → 环境变量覆盖。
|
|
116
|
+
* 搜索路径:process.cwd(),以及逐级向上查找 xilore.json / xilore.yml。
|
|
117
|
+
*/
|
|
118
|
+
export function loadConfig(searchDir) {
|
|
119
|
+
const map = new Map();
|
|
120
|
+
const cwd = searchDir ?? process.cwd();
|
|
121
|
+
if (!loadFromJson(map, cwd)) {
|
|
122
|
+
loadFromYaml(map, cwd);
|
|
123
|
+
}
|
|
124
|
+
loadFromEnv(map);
|
|
125
|
+
return new XilLogPropertiesConfig(map);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=xil-log-config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-config-loader.js","sourceRoot":"","sources":["../../src/config/xil-log-config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { XilLogLevel } from '../xil-log-level.js';
|
|
2
|
+
import type { XilLogExcludeItem } from '../entity/xil-log-exclude-item.js';
|
|
3
|
+
/**
|
|
4
|
+
* 配置接口:组件通过此接口获取配置值。
|
|
5
|
+
*/
|
|
6
|
+
export interface XilLogConfig {
|
|
7
|
+
getPath(): string;
|
|
8
|
+
getFilePrefix(): string;
|
|
9
|
+
getWriteFlushInterval(): number;
|
|
10
|
+
getDateFormat(): string;
|
|
11
|
+
getDetail(level: XilLogLevel): string;
|
|
12
|
+
getUploadHost(): string;
|
|
13
|
+
getUploadToken(): string;
|
|
14
|
+
getCharset(): string;
|
|
15
|
+
getContainerId(): string;
|
|
16
|
+
getAppName(): string;
|
|
17
|
+
isColorEnabled(): boolean;
|
|
18
|
+
isCompressWidth(): boolean;
|
|
19
|
+
getLogExclude(): readonly XilLogExcludeItem[];
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=xil-log-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-config.d.ts","sourceRoot":"","sources":["../../src/config/xil-log-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,IAAI,MAAM,CAAC;IAClB,aAAa,IAAI,MAAM,CAAC;IACxB,qBAAqB,IAAI,MAAM,CAAC;IAChC,aAAa,IAAI,MAAM,CAAC;IACxB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAAC;IACtC,aAAa,IAAI,MAAM,CAAC;IACxB,cAAc,IAAI,MAAM,CAAC;IACzB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,OAAO,CAAC;IAC1B,eAAe,IAAI,OAAO,CAAC;IAC3B,aAAa,IAAI,SAAS,iBAAiB,EAAE,CAAC;CAC/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xil-log-config.js","sourceRoot":"","sources":["../../src/config/xil-log-config.ts"],"names":[],"mappings":""}
|