@pippocao/bqlog 2.2.1
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 +185 -0
- package/dist/cjs/bq/category_log.js +55 -0
- package/dist/cjs/bq/def/log_category_base.js +23 -0
- package/dist/cjs/bq/def/log_level.js +23 -0
- package/dist/cjs/bq/def/string_holder.js +17 -0
- package/dist/cjs/bq/impl/log_invoker.js +107 -0
- package/dist/cjs/bq/lib_def.js +18 -0
- package/dist/cjs/bq/log.js +251 -0
- package/dist/cjs/bq/tools/log_decoder.js +63 -0
- package/dist/cjs/bq/utils/env_detector.js +29 -0
- package/dist/cjs/bq/utils/lib_loader.js +107 -0
- package/dist/cjs/bq/utils/lib_loader_core.js +197 -0
- package/dist/cjs/bq/utils/tools.js +163 -0
- package/dist/cjs/index.js +27 -0
- package/dist/cjs/package.json +3 -0
- package/dist/esm/bq/category_log.js +51 -0
- package/dist/esm/bq/def/log_category_base.js +19 -0
- package/dist/esm/bq/def/log_level.js +20 -0
- package/dist/esm/bq/def/string_holder.js +13 -0
- package/dist/esm/bq/impl/log_invoker.js +103 -0
- package/dist/esm/bq/lib_def.js +15 -0
- package/dist/esm/bq/log.js +247 -0
- package/dist/esm/bq/tools/log_decoder.js +59 -0
- package/dist/esm/bq/utils/env_detector.js +26 -0
- package/dist/esm/bq/utils/lib_loader.js +46 -0
- package/dist/esm/bq/utils/lib_loader_core.js +161 -0
- package/dist/esm/bq/utils/tools.js +158 -0
- package/dist/esm/index.js +24 -0
- package/dist/types/bq/category_log.d.ts +27 -0
- package/dist/types/bq/def/log_category_base.d.ts +4 -0
- package/dist/types/bq/def/log_level.d.ts +8 -0
- package/dist/types/bq/def/string_holder.d.ts +3 -0
- package/dist/types/bq/impl/log_invoker.d.ts +27 -0
- package/dist/types/bq/lib_def.d.ts +3 -0
- package/dist/types/bq/log.d.ts +139 -0
- package/dist/types/bq/tools/log_decoder.d.ts +17 -0
- package/dist/types/bq/utils/env_detector.d.ts +2 -0
- package/dist/types/bq/utils/lib_loader.d.ts +1 -0
- package/dist/types/bq/utils/lib_loader_core.d.ts +10 -0
- package/dist/types/bq/utils/tools.d.ts +16 -0
- package/dist/types/index.d.ts +13 -0
- package/package.json +66 -0
- package/prebuilds/darwin-arm64/BqLog.node +0 -0
- package/prebuilds/darwin-x64/BqLog.node +0 -0
- package/prebuilds/dragonfly-x64/BqLog.node +0 -0
- package/prebuilds/freebsd-arm64/BqLog.node +0 -0
- package/prebuilds/freebsd-x64/BqLog.node +0 -0
- package/prebuilds/linux-arm64/BqLog.node +0 -0
- package/prebuilds/linux-ia32/BqLog.node +0 -0
- package/prebuilds/linux-x64/BqLog.node +0 -0
- package/prebuilds/netbsd-arm64/BqLog.node +0 -0
- package/prebuilds/netbsd-x64/BqLog.node +0 -0
- package/prebuilds/openbsd-arm64/BqLog.node +0 -0
- package/prebuilds/openbsd-x64/BqLog.node +0 -0
- package/prebuilds/sunos-x64/BqLog.node +0 -0
- package/prebuilds/win32-arm64/BqLog.node +0 -0
- package/prebuilds/win32-arm64/BqLog.pdb +0 -0
- package/prebuilds/win32-x64/BqLog.node +0 -0
- package/prebuilds/win32-x64/BqLog.pdb +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# @pippocao/bqlog
|
|
2
|
+
|
|
3
|
+
> **The fastest industrial-grade logging engine** for Node.js — powered by a native C++ lock-free ring-buffer core, battle-tested at Tencent across large-scale game engines and backend services.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@pippocao/bqlog)
|
|
6
|
+
[](https://www.apache.org/licenses/LICENSE-2.0)
|
|
7
|
+
|
|
8
|
+
Part of the [BqLog](https://github.com/Tencent/BqLog) project.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 🚀 Why BqLog?
|
|
13
|
+
|
|
14
|
+
- ⚡ **Fastest in class** — lock-free MISO ring-buffer delivers ~80% higher throughput than comparable loggers for UTF-8, and >500% for UTF-16 environments
|
|
15
|
+
- 🏭 **Industrial grade** — production-proven at Tencent, designed for game engines (Unity, Unreal), mobile apps, and high-concurrency server workloads
|
|
16
|
+
- 🔐 **Compressed & Encrypted appender** — `compressed_file` produces the smallest log files with near-zero overhead, and supports **hybrid asymmetric encryption** (RSA + AES) for secure log storage at virtually no performance cost
|
|
17
|
+
- 🔄 **Sync & Async modes** — choose per-log thread model to balance latency vs throughput
|
|
18
|
+
- 🏷️ **Category logging** — attach categories to log entries, filter with category masks
|
|
19
|
+
- 🛡️ **Crash-safe recovery** — memory-mapped buffers survive process crashes; unflushed logs are recovered on restart
|
|
20
|
+
- 🌍 **Cross-platform native binaries** — prebuilt for Windows, macOS, Linux, FreeBSD, OpenBSD, NetBSD, DragonflyBSD, Solaris/OmniOS (x64 & ARM64)
|
|
21
|
+
- 📦 **ESM + CommonJS** — dual module support, works everywhere
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 📥 Installation
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install @pippocao/bqlog
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## ⚡ Quick Start
|
|
34
|
+
|
|
35
|
+
### ESM
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { bq } from "@pippocao/bqlog";
|
|
39
|
+
|
|
40
|
+
const config = `
|
|
41
|
+
appenders_config.console.type=console
|
|
42
|
+
appenders_config.console.levels=[all]
|
|
43
|
+
`;
|
|
44
|
+
const log = bq.log.create_log("my_log", config);
|
|
45
|
+
|
|
46
|
+
log.info("Hello BqLog! int:{}, float:{}", 123, 3.14);
|
|
47
|
+
bq.log.force_flush_all_logs();
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### CommonJS
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
const { bq } = require("@pippocao/bqlog");
|
|
54
|
+
|
|
55
|
+
const log = bq.log.create_log("my_log", `
|
|
56
|
+
appenders_config.console.type=console
|
|
57
|
+
appenders_config.console.levels=[all]
|
|
58
|
+
`);
|
|
59
|
+
log.info("Hello from CJS!");
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 📋 Appender Types
|
|
65
|
+
|
|
66
|
+
| Type | Description |
|
|
67
|
+
|------|-------------|
|
|
68
|
+
| `console` | 🖥️ Output to stdout/stderr |
|
|
69
|
+
| `text_file` | 📄 Plain text log files, human-readable |
|
|
70
|
+
| `compressed_file` | 🔒 **Binary compressed — smallest size, fastest writes, optional RSA+AES encryption.** Decode with the BqLog decoder tool. |
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 🔐 Compressed & Encrypted Appender
|
|
75
|
+
|
|
76
|
+
The `compressed_file` appender is the **recommended choice for production**:
|
|
77
|
+
|
|
78
|
+
- 📉 **Smallest output** — proprietary binary format produces files significantly smaller than plain text or gzip
|
|
79
|
+
- ⚡ **Fastest writes** — compression is integrated into the write path with near-zero overhead
|
|
80
|
+
- 🔑 **Hybrid encryption** — optional RSA + AES encryption protects log content at rest; encryption adds virtually no performance penalty
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const config = `
|
|
84
|
+
appenders_config.SecureFile.type=compressed_file
|
|
85
|
+
appenders_config.SecureFile.time_zone=localtime
|
|
86
|
+
appenders_config.SecureFile.levels=[all]
|
|
87
|
+
appenders_config.SecureFile.file_name=logs/secure
|
|
88
|
+
appenders_config.SecureFile.max_file_size=100000000
|
|
89
|
+
appenders_config.SecureFile.expire_time_days=30
|
|
90
|
+
|
|
91
|
+
# Optional: enable encryption (provide RSA public key)
|
|
92
|
+
# appenders_config.SecureFile.pub_key=your_rsa_public_key_here
|
|
93
|
+
|
|
94
|
+
log.thread_mode=async
|
|
95
|
+
`;
|
|
96
|
+
const log = bq.log.create_log("secure_log", config);
|
|
97
|
+
log.info("This log is compressed and optionally encrypted");
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## ⚙️ Configuration Example
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
const config = `
|
|
106
|
+
appenders_config.ConsoleAppender.type=console
|
|
107
|
+
appenders_config.ConsoleAppender.time_zone=localtime
|
|
108
|
+
appenders_config.ConsoleAppender.levels=[all]
|
|
109
|
+
|
|
110
|
+
appenders_config.FileAppender.type=compressed_file
|
|
111
|
+
appenders_config.FileAppender.time_zone=localtime
|
|
112
|
+
appenders_config.FileAppender.levels=[info,warning,error,fatal]
|
|
113
|
+
appenders_config.FileAppender.file_name=logs/app
|
|
114
|
+
appenders_config.FileAppender.max_file_size=100000000
|
|
115
|
+
appenders_config.FileAppender.expire_time_days=7
|
|
116
|
+
|
|
117
|
+
log.thread_mode=async
|
|
118
|
+
`;
|
|
119
|
+
const log = bq.log.create_log("app", config);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 🏷️ Category Logging
|
|
125
|
+
|
|
126
|
+
Use the [BqLog Category Generator](https://github.com/Tencent/BqLog/tree/main/tools/category_log_generator) tool to generate type-safe category wrappers:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { my_category_log } from "./my_category_log";
|
|
130
|
+
|
|
131
|
+
const log = my_category_log.create_log("cat_log", config);
|
|
132
|
+
log.info(log.cat.ModuleA.SystemA, "categorized message: {}", value);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## 📊 Log Levels
|
|
138
|
+
|
|
139
|
+
| Level | Usage |
|
|
140
|
+
|-------|-------|
|
|
141
|
+
| `verbose` | Fine-grained tracing |
|
|
142
|
+
| `debug` | Debugging information |
|
|
143
|
+
| `info` | General operational messages |
|
|
144
|
+
| `warning` | Potential issues |
|
|
145
|
+
| `error` | Error conditions |
|
|
146
|
+
| `fatal` | Critical failures |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 🌍 Supported Platforms
|
|
151
|
+
|
|
152
|
+
Prebuilt native binaries are included — **no compiler needed** at install time.
|
|
153
|
+
|
|
154
|
+
| OS | Architectures |
|
|
155
|
+
|----|--------------|
|
|
156
|
+
| 🪟 Windows | x64, ARM64 |
|
|
157
|
+
| 🍎 macOS | x64, ARM64 (Universal Binary) |
|
|
158
|
+
| 🐧 Linux | x64, ARM64, x86 (ia32) |
|
|
159
|
+
| 😈 FreeBSD | x64, ARM64 |
|
|
160
|
+
| 🐡 OpenBSD | x64, ARM64 |
|
|
161
|
+
| 🏁 NetBSD | x64, ARM64 |
|
|
162
|
+
| 🐉 DragonflyBSD | x64 |
|
|
163
|
+
| ☀️ Solaris / OmniOS (SunOS) | x64 |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## 📈 Benchmark
|
|
168
|
+
|
|
169
|
+
BqLog consistently outperforms popular logging libraries. See [full benchmark results](https://github.com/Tencent/BqLog#benchmark) in the main repository.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 📚 Documentation
|
|
174
|
+
|
|
175
|
+
Full documentation and examples for all supported languages:
|
|
176
|
+
|
|
177
|
+
**C++ · Java · C# · Python · TypeScript · Unreal Engine · Unity · HarmonyOS**
|
|
178
|
+
|
|
179
|
+
👉 **[github.com/Tencent/BqLog](https://github.com/Tencent/BqLog)**
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 📄 License
|
|
184
|
+
|
|
185
|
+
[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) — free for commercial use.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.category_log = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2025 Tencent.
|
|
6
|
+
* BQLOG is licensed under the Apache License, Version 2.0.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
*/
|
|
15
|
+
const log_1 = require("./log");
|
|
16
|
+
const log_invoker_1 = require("./impl/log_invoker");
|
|
17
|
+
class category_log extends log_1.log {
|
|
18
|
+
constructor(arg) {
|
|
19
|
+
super(arg);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get log categories count
|
|
23
|
+
* @return
|
|
24
|
+
*/
|
|
25
|
+
get_categories_count() {
|
|
26
|
+
return this.categories_name_array_.length;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Get names of all categories
|
|
30
|
+
* @return
|
|
31
|
+
*/
|
|
32
|
+
get_categories_name_array() {
|
|
33
|
+
return this.categories_name_array_;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a category log
|
|
37
|
+
* @param name
|
|
38
|
+
* If the log name is an empty string, bqLog will automatically assign you a unique log name.
|
|
39
|
+
* If the log name already exists, it will return the previously existing log object and overwrite the previous configuration with the new config.
|
|
40
|
+
* @param config
|
|
41
|
+
* Log config string
|
|
42
|
+
* @param categories_count
|
|
43
|
+
* @param categories
|
|
44
|
+
* @returns
|
|
45
|
+
* A log id, if create failed, 0 will be returned
|
|
46
|
+
*/
|
|
47
|
+
static call_api_create_category_log(name, config, categories_count, categories) {
|
|
48
|
+
if (!config || config.length == 0) {
|
|
49
|
+
return 0n;
|
|
50
|
+
}
|
|
51
|
+
let log_handle = log_invoker_1.log_invoker.__api_create_log(name, config, categories_count, categories);
|
|
52
|
+
return log_handle;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.category_log = category_log;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2025 Tencent.
|
|
4
|
+
* BQLOG is licensed under the Apache License, Version 2.0.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.log_category_base = void 0;
|
|
15
|
+
const log_invoker_1 = require("../impl/log_invoker");
|
|
16
|
+
class log_category_base {
|
|
17
|
+
constructor(index) {
|
|
18
|
+
this.index = 0;
|
|
19
|
+
this.index = index;
|
|
20
|
+
log_invoker_1.log_invoker.__api_attach_category_base_inst(this);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.log_category_base = log_category_base;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2025 Tencent.
|
|
4
|
+
* BQLOG is licensed under the Apache License, Version 2.0.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.log_level = void 0;
|
|
15
|
+
var log_level;
|
|
16
|
+
(function (log_level) {
|
|
17
|
+
log_level[log_level["verbose"] = 0] = "verbose";
|
|
18
|
+
log_level[log_level["debug"] = 1] = "debug";
|
|
19
|
+
log_level[log_level["info"] = 2] = "info";
|
|
20
|
+
log_level[log_level["warning"] = 3] = "warning";
|
|
21
|
+
log_level[log_level["error"] = 4] = "error";
|
|
22
|
+
log_level[log_level["fatal"] = 5] = "fatal";
|
|
23
|
+
})(log_level || (exports.log_level = log_level = {}));
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2025 Tencent.
|
|
4
|
+
* BQLOG is licensed under the Apache License, Version 2.0.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.string_holder = void 0;
|
|
15
|
+
class string_holder {
|
|
16
|
+
}
|
|
17
|
+
exports.string_holder = string_holder;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2025 Tencent.
|
|
4
|
+
* BQLOG is licensed under the Apache License, Version 2.0.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.log_invoker = void 0;
|
|
15
|
+
// IMPORTANT: this is a build-alias file generated per build.
|
|
16
|
+
// For ESM build it is a copy of lib_loader.esm.txt,
|
|
17
|
+
// for CJS and OHOS build it is lib_loader.ts.
|
|
18
|
+
const lib_loader_1 = require("../utils/lib_loader");
|
|
19
|
+
function as_bigint(v, def = 0n) {
|
|
20
|
+
return typeof v === "bigint" ? v : def;
|
|
21
|
+
}
|
|
22
|
+
class log_invoker {
|
|
23
|
+
static __api_get_log_version() {
|
|
24
|
+
return (0, lib_loader_1.native_export)("get_log_version")();
|
|
25
|
+
}
|
|
26
|
+
static __api_enable_auto_crash_handler() {
|
|
27
|
+
(0, lib_loader_1.native_export)("enable_auto_crash_handler")();
|
|
28
|
+
}
|
|
29
|
+
static __api_create_log(log_name, config_content, category_count, category_names_array) {
|
|
30
|
+
const id = (0, lib_loader_1.native_export)("create_log")(log_name, config_content, category_count, category_names_array);
|
|
31
|
+
return as_bigint(id);
|
|
32
|
+
}
|
|
33
|
+
static __api_log_reset_config(log_name, config_content) {
|
|
34
|
+
(0, lib_loader_1.native_export)("log_reset_config")(log_name, config_content);
|
|
35
|
+
}
|
|
36
|
+
static __api_attach_log_inst(log_inst) {
|
|
37
|
+
return (0, lib_loader_1.native_export)("attach_log_inst")(log_inst, log_inst['log_id_']);
|
|
38
|
+
}
|
|
39
|
+
static __api_attach_category_base_inst(category_inst) {
|
|
40
|
+
return (0, lib_loader_1.native_export)("attach_category_base_inst")(category_inst, category_inst['index']);
|
|
41
|
+
}
|
|
42
|
+
static __api_set_appender_enable(log_id, appender_name, enable) {
|
|
43
|
+
(0, lib_loader_1.native_export)("set_appender_enable")(log_id, appender_name, !!enable);
|
|
44
|
+
}
|
|
45
|
+
static __api_get_logs_count() {
|
|
46
|
+
return (0, lib_loader_1.native_export)("get_logs_count")();
|
|
47
|
+
}
|
|
48
|
+
static __api_get_log_id_by_index(index) {
|
|
49
|
+
return as_bigint((0, lib_loader_1.native_export)("get_log_id_by_index")(index));
|
|
50
|
+
}
|
|
51
|
+
static __api_get_log_name_by_id(log_id) {
|
|
52
|
+
return (0, lib_loader_1.native_export)("get_log_name_by_id")(log_id);
|
|
53
|
+
}
|
|
54
|
+
static __api_get_log_categories_count(log_id) {
|
|
55
|
+
return (0, lib_loader_1.native_export)("get_log_categories_count")(log_id);
|
|
56
|
+
}
|
|
57
|
+
static __api_get_log_category_name_by_index(log_id, category_index) {
|
|
58
|
+
return (0, lib_loader_1.native_export)("get_log_category_name_by_index")(log_id, category_index);
|
|
59
|
+
}
|
|
60
|
+
static __api_log_device_console(level, content) {
|
|
61
|
+
(0, lib_loader_1.native_export)("log_device_console")(level, content);
|
|
62
|
+
}
|
|
63
|
+
static __api_force_flush(log_id) {
|
|
64
|
+
(0, lib_loader_1.native_export)("force_flush")(log_id);
|
|
65
|
+
}
|
|
66
|
+
static __api_get_file_base_dir(base_dir_type) {
|
|
67
|
+
return (0, lib_loader_1.native_export)("get_file_base_dir")(base_dir_type);
|
|
68
|
+
}
|
|
69
|
+
static __api_log_decoder_create(log_file_path, priv_key) {
|
|
70
|
+
return (0, lib_loader_1.native_export)("log_decoder_create")(log_file_path, priv_key ? priv_key : "");
|
|
71
|
+
}
|
|
72
|
+
static __api_log_decoder_decode(handle, out) {
|
|
73
|
+
const obj = (0, lib_loader_1.native_export)("log_decoder_decode")(handle);
|
|
74
|
+
if (out && typeof out === "object") {
|
|
75
|
+
out.value = obj?.text ?? "";
|
|
76
|
+
}
|
|
77
|
+
return obj?.code ?? 0;
|
|
78
|
+
}
|
|
79
|
+
static __api_attach_decoder_inst(decoder_inst) {
|
|
80
|
+
(0, lib_loader_1.native_export)("attach_decoder_inst")(decoder_inst, decoder_inst['handle_']);
|
|
81
|
+
}
|
|
82
|
+
static __api_log_decode(in_file_path, out_file_path, priv_key) {
|
|
83
|
+
return !!(0, lib_loader_1.native_export)("log_decode")(in_file_path, out_file_path, priv_key ? priv_key : "");
|
|
84
|
+
}
|
|
85
|
+
static __api_take_snapshot_string(log_id, time_zone_config) {
|
|
86
|
+
return (0, lib_loader_1.native_export)("take_snapshot_string")(log_id, time_zone_config ? time_zone_config : "");
|
|
87
|
+
}
|
|
88
|
+
static __api_set_console_callback(callback) {
|
|
89
|
+
if (typeof callback !== "function" && callback !== null) {
|
|
90
|
+
throw new Error("__api_set_console_callback requires a function callback, or pass null ");
|
|
91
|
+
}
|
|
92
|
+
(0, lib_loader_1.native_export)("set_console_callback")(callback);
|
|
93
|
+
}
|
|
94
|
+
static __api_set_console_buffer_enable(enable) {
|
|
95
|
+
(0, lib_loader_1.native_export)("set_console_buffer_enable")(!!enable);
|
|
96
|
+
}
|
|
97
|
+
static __api_reset_base_dir(base_dir_type, dir) {
|
|
98
|
+
(0, lib_loader_1.native_export)("reset_base_dir")(base_dir_type, dir);
|
|
99
|
+
}
|
|
100
|
+
static __api_fetch_and_remove_console_buffer(callback) {
|
|
101
|
+
if (typeof callback !== "function") {
|
|
102
|
+
throw new Error("__api_fetch_and_remove_console_buffer requires a function callback");
|
|
103
|
+
}
|
|
104
|
+
return !!(0, lib_loader_1.native_export)("fetch_and_remove_console_buffer")(callback);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
exports.log_invoker = log_invoker;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (C) 2025 Tencent.
|
|
4
|
+
* BQLOG is licensed under the Apache License, Version 2.0.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.lib_def = void 0;
|
|
15
|
+
exports.lib_def = {
|
|
16
|
+
// native module name; keep as runtime string, not an identifier
|
|
17
|
+
lib_name: "BqLog",
|
|
18
|
+
};
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.log = void 0;
|
|
4
|
+
const log_invoker_1 = require("./impl/log_invoker");
|
|
5
|
+
// IMPORTANT: this is a build-alias file generated per build.
|
|
6
|
+
// For ESM build it is a copy of lib_loader.esm.txt,
|
|
7
|
+
// for CJS and OHOS build it is lib_loader.ts.
|
|
8
|
+
const lib_loader_1 = require("./utils/lib_loader");
|
|
9
|
+
class log {
|
|
10
|
+
static inner_callback(log_id, category_idx, level, text) {
|
|
11
|
+
if (log.callback_) {
|
|
12
|
+
log.callback_(log_id, category_idx, level, text);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get bqLog lib version
|
|
17
|
+
* @return
|
|
18
|
+
*/
|
|
19
|
+
static get_version() {
|
|
20
|
+
return log_invoker_1.log_invoker.__api_get_log_version();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reset the base dir
|
|
24
|
+
* @param base_dir_type
|
|
25
|
+
* @param dir
|
|
26
|
+
*/
|
|
27
|
+
static reset_base_dir(base_dir_type, dir) {
|
|
28
|
+
log_invoker_1.log_invoker.__api_reset_base_dir(base_dir_type, dir);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* If bqLog is asynchronous, a crash in the program may cause the logs in the buffer not to be persisted to disk.
|
|
32
|
+
* If this feature is enabled, bqLog will attempt to perform a forced flush of the logs in the buffer in the event of a crash. However,
|
|
33
|
+
* this functionality does not guarantee success.
|
|
34
|
+
*/
|
|
35
|
+
static enable_auto_crash_handle() {
|
|
36
|
+
log_invoker_1.log_invoker.__api_enable_auto_crash_handler();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* If bqLog is stored in a relative path, the base dir is determined by the value of base_dir_type.
|
|
40
|
+
* This will return the absolute paths corresponding to both scenarios.
|
|
41
|
+
* @param base_dir_type
|
|
42
|
+
* @return
|
|
43
|
+
*/
|
|
44
|
+
static get_file_base_dir(base_dir_type) {
|
|
45
|
+
return log_invoker_1.log_invoker.__api_get_file_base_dir(base_dir_type);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create a log object
|
|
49
|
+
* @param name
|
|
50
|
+
* If the log name is an empty string, bqLog will automatically assign you a unique log name.
|
|
51
|
+
* If the log name already exists, it will return the previously existing log object and overwrite the previous configuration with the new config.
|
|
52
|
+
* @param config
|
|
53
|
+
* Log config string
|
|
54
|
+
* @return
|
|
55
|
+
* A log object, if create failed, the is_valid() method of it will return false
|
|
56
|
+
*/
|
|
57
|
+
static create_log(name, config) {
|
|
58
|
+
if (!config || config.length == 0) {
|
|
59
|
+
return new log(0n);
|
|
60
|
+
}
|
|
61
|
+
let log_id = log_invoker_1.log_invoker.__api_create_log(name, config, 0, null);
|
|
62
|
+
return new log(log_id);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get a log object by it's name
|
|
66
|
+
* @param log_name
|
|
67
|
+
* Name of the log you want to find
|
|
68
|
+
* @return
|
|
69
|
+
* A log object, if the log object with specific name was not found, the is_valid() method of it will return false
|
|
70
|
+
*/
|
|
71
|
+
static get_log_by_name(log_name) {
|
|
72
|
+
if (!log_name || log_name.length == 0) {
|
|
73
|
+
return new log(0n);
|
|
74
|
+
}
|
|
75
|
+
let log_count = log_invoker_1.log_invoker.__api_get_logs_count();
|
|
76
|
+
for (let i = 0; i < log_count; ++i) {
|
|
77
|
+
let id = log_invoker_1.log_invoker.__api_get_log_id_by_index(i);
|
|
78
|
+
let name = log_invoker_1.log_invoker.__api_get_log_name_by_id(id);
|
|
79
|
+
if (log_name == name) {
|
|
80
|
+
return new log(id);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return new log(0n);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Synchronously flush the buffer of all log objects
|
|
87
|
+
* to ensure that all data in the buffer is processed after the call.
|
|
88
|
+
*/
|
|
89
|
+
static force_flush_all_logs() {
|
|
90
|
+
log_invoker_1.log_invoker.__api_force_flush(0n);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Register a callback that will be invoked whenever a console log message is output.
|
|
94
|
+
* This can be used for an external system to monitor console log output.
|
|
95
|
+
* @param callback
|
|
96
|
+
*/
|
|
97
|
+
static register_console_callback(callback) {
|
|
98
|
+
log.callback_ = callback;
|
|
99
|
+
if (null != log.callback_) {
|
|
100
|
+
log_invoker_1.log_invoker.__api_set_console_callback(log.inner_callback);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
log_invoker_1.log_invoker.__api_set_console_callback(null);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Unregister a previously registered console callback.
|
|
108
|
+
* @param callback
|
|
109
|
+
*/
|
|
110
|
+
static unregister_console_callback(callback) {
|
|
111
|
+
if (log.callback_ == callback) {
|
|
112
|
+
log_invoker_1.log_invoker.__api_set_console_callback(null);
|
|
113
|
+
log.callback_ = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Enable or disable the console appender buffer.
|
|
118
|
+
* Since our wrapper may run in both C# and Java virtual machines, and we do not want to directly invoke callbacks from a native thread,
|
|
119
|
+
* we can enable this option. This way, all console outputs will be saved in the buffer until we fetch them.
|
|
120
|
+
* @param enable
|
|
121
|
+
*/
|
|
122
|
+
static set_console_buffer_enable(enable) {
|
|
123
|
+
log_invoker_1.log_invoker.__api_set_console_buffer_enable(enable);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Fetch and remove a log entry from the console appender buffer in a thread-safe manner.
|
|
127
|
+
* If the console appender buffer is not empty, the on_console_callback function will be invoked for this log entry.
|
|
128
|
+
* Please ensure not to output synchronized BQ logs within the callback function.
|
|
129
|
+
* @param on_console_callback
|
|
130
|
+
* A callback function to be invoked for the fetched log entry if the console appender buffer is not empty
|
|
131
|
+
* @return
|
|
132
|
+
* True if the console appender buffer is not empty and a log entry is fetched; otherwise False is returned.
|
|
133
|
+
*/
|
|
134
|
+
static fetch_and_remove_console_buffer(on_console_callback) {
|
|
135
|
+
return log_invoker_1.log_invoker.__api_fetch_and_remove_console_buffer(on_console_callback);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Output to console with log_level.
|
|
139
|
+
* Important: This is not log entry, and can not be caught by console callback which was registered by register_console_callback or fetch_and_remove_console_buffer
|
|
140
|
+
* @param level
|
|
141
|
+
* @param str
|
|
142
|
+
*/
|
|
143
|
+
static console(level, str) {
|
|
144
|
+
log_invoker_1.log_invoker.__api_log_device_console(level, str);
|
|
145
|
+
}
|
|
146
|
+
constructor(arg) {
|
|
147
|
+
this.log_id_ = 0n;
|
|
148
|
+
this.name_ = "";
|
|
149
|
+
this.categories_name_array_ = [];
|
|
150
|
+
if (arg instanceof log) {
|
|
151
|
+
this.name_ = arg.name_;
|
|
152
|
+
this.log_id_ = arg.log_id_;
|
|
153
|
+
let category_count = log_invoker_1.log_invoker.__api_get_log_categories_count(this.log_id_);
|
|
154
|
+
this.categories_name_array_ = [];
|
|
155
|
+
for (let i = 0; i < category_count; ++i) {
|
|
156
|
+
let category_item_name = log_invoker_1.log_invoker.__api_get_log_category_name_by_index(this.log_id_, i);
|
|
157
|
+
if (category_item_name) {
|
|
158
|
+
this.categories_name_array_.push(category_item_name);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (typeof (arg) === 'bigint') {
|
|
163
|
+
this.log_id_ = arg;
|
|
164
|
+
let name = log_invoker_1.log_invoker.__api_get_log_name_by_id(this.log_id_);
|
|
165
|
+
if (!name) {
|
|
166
|
+
this.log_id_ = 0n;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.name_ = name;
|
|
170
|
+
let category_count = log_invoker_1.log_invoker.__api_get_log_categories_count(this.log_id_);
|
|
171
|
+
this.categories_name_array_ = [];
|
|
172
|
+
for (let i = 0; i < category_count; ++i) {
|
|
173
|
+
let category_item_name = log_invoker_1.log_invoker.__api_get_log_category_name_by_index(this.log_id_, i);
|
|
174
|
+
this.categories_name_array_.push(category_item_name);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
log_invoker_1.log_invoker.__api_attach_log_inst(this);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Modify the log configuration, but some fields, such as buffer_size, cannot be modified.
|
|
181
|
+
* @param config
|
|
182
|
+
*/
|
|
183
|
+
reset_config(config) {
|
|
184
|
+
if (!config || config.length == 0) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
log_invoker_1.log_invoker.__api_log_reset_config(this.name_, config);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Temporarily disable or enable a specific Appender.
|
|
191
|
+
* @param appender_name
|
|
192
|
+
* @param enable
|
|
193
|
+
*/
|
|
194
|
+
set_appender_enable(appender_name, enable) {
|
|
195
|
+
log_invoker_1.log_invoker.__api_set_appender_enable(this.log_id_, appender_name, enable);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Synchronously flush the buffer of this log object
|
|
199
|
+
* to ensure that all data in the buffer is processed after the call.
|
|
200
|
+
*/
|
|
201
|
+
force_flush() {
|
|
202
|
+
log_invoker_1.log_invoker.__api_force_flush(this.log_id_);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Get id of this log object
|
|
206
|
+
* @return
|
|
207
|
+
*/
|
|
208
|
+
get_id() {
|
|
209
|
+
return this.log_id_;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Whether a log object is valid
|
|
213
|
+
* @return
|
|
214
|
+
*/
|
|
215
|
+
is_valid() {
|
|
216
|
+
return this.get_id() != 0n;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get the name of a log
|
|
220
|
+
* @return
|
|
221
|
+
*/
|
|
222
|
+
get_name() {
|
|
223
|
+
return this.name_;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Works only when snapshot is configured.
|
|
227
|
+
* It will decode the snapshot buffer to text.
|
|
228
|
+
* @param time_zone_config
|
|
229
|
+
* Use this to specify the time display of log text. such as : "localtime", "gmt", "Z", "UTC", "UTC+8", "UTC-11", "utc+11:30"
|
|
230
|
+
* @return
|
|
231
|
+
* The decoded snapshot buffer
|
|
232
|
+
*/
|
|
233
|
+
take_snapshot(time_zone_config) {
|
|
234
|
+
return log_invoker_1.log_invoker.__api_take_snapshot_string(this.log_id_, time_zone_config);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.log = log;
|
|
238
|
+
log.callback_ = null;
|
|
239
|
+
function defineNativeMethod(proto, name) {
|
|
240
|
+
const fn = (0, lib_loader_1.native_export)(name);
|
|
241
|
+
if (typeof fn !== 'function') {
|
|
242
|
+
throw new Error(`Native method "__bq_napi_${name}" not found or not a function`);
|
|
243
|
+
}
|
|
244
|
+
Object.defineProperty(proto, name, {
|
|
245
|
+
value: fn,
|
|
246
|
+
writable: false,
|
|
247
|
+
enumerable: false,
|
|
248
|
+
configurable: false,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
['verbose', 'debug', 'info', 'warning', 'error', 'fatal'].forEach(n => defineNativeMethod(log.prototype, n));
|