@tusi-ai/logger 0.0.0-stage → 0.0.1-beta.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 CHANGED
@@ -1,3 +1,43 @@
1
- # Temporary Holding Version
1
+ # @tusi-ai/logger
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > 吐司统一日志上报:`aegisV2` 优先 / 伽利略 HTTP 兜底。plugins / services 共用的通用层。
4
+
5
+ ## 用法
6
+
7
+ ```ts
8
+ import { Logger } from '@tusi-ai/logger';
9
+
10
+ const logger = new Logger({
11
+ env: 'production', // 可选,未传回落 production
12
+ contentPrefix: 'geolocation', // 可选,与内容直接拼接(格式调用方控制)
13
+ appId: 'xxx', // 可选,伽利略 ext.tusi_app_id
14
+ version: '1.0.0', // 可选,伽利略 ext.tusi_app_version
15
+ mode: 'preview', // 可选,伽利略 ext.tusi_mode
16
+ });
17
+
18
+ logger.error('获取定位失败');
19
+ logger.info('环境判定完成');
20
+ ```
21
+
22
+ ## 通道策略
23
+
24
+ | 通道 | 条件 | 行为 |
25
+ |---|---|---|
26
+ | Aegis V2 | `window.aegisV2` 存在(error/info 齐备,每次调用时判定) | 直接 `aegisV2.error/info(msg)`,env/appId/version/mode 忽略 |
27
+ | 伽利略 HTTP | 无 aegisV2 | axios POST `https://galileotelemetry.tencent.com/collect`,TOPIC `SDK-42a0ae29a90bc4f6a218`,异步不阻塞、失败静默、超时 5s |
28
+
29
+ ## 目录结构
30
+
31
+ ```
32
+ src/
33
+ ├── index.ts # Logger 类与通道逻辑
34
+ ├── type/index.ts # LoggerConfig / AegisV2 / LogLevel
35
+ └── config/index.ts # 端点 / TOPIC / 协议常量
36
+ test/
37
+ └── index.spec.ts
38
+ ```
39
+
40
+ ## 硬约束
41
+
42
+ - 唯一运行时依赖:axios(伽利略兜底上报)
43
+ - 模块顶层无副作用(`sideEffects: false` 为诚实声明)
package/dist/index.cjs ADDED
@@ -0,0 +1,124 @@
1
+ 'use strict';
2
+
3
+ var axios = require('axios');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var axios__default = /*#__PURE__*/_interopDefault(axios);
8
+
9
+ var __async = (__this, __arguments, generator) => {
10
+ return new Promise((resolve, reject) => {
11
+ var fulfilled = (value) => {
12
+ try {
13
+ step(generator.next(value));
14
+ } catch (e) {
15
+ reject(e);
16
+ }
17
+ };
18
+ var rejected = (value) => {
19
+ try {
20
+ step(generator.throw(value));
21
+ } catch (e) {
22
+ reject(e);
23
+ }
24
+ };
25
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
26
+ step((generator = generator.apply(__this, __arguments)).next());
27
+ });
28
+ };
29
+
30
+ // src/config/index.ts
31
+ var GALILEO_ENDPOINT = "https://galileotelemetry.tencent.com/collect";
32
+ var TOPIC = "SDK-42a0ae29a90bc4f6a218";
33
+ var SCHEME = "v2";
34
+ var TYPE = "normal";
35
+ var REPORT_TIMEOUT = 5e3;
36
+ var DEFAULT_ENV = "production";
37
+
38
+ // src/index.ts
39
+ function getAegisV2() {
40
+ const aegisV2 = window == null ? void 0 : window.aegisV2;
41
+ if (typeof (aegisV2 == null ? void 0 : aegisV2.error) === "function" && typeof (aegisV2 == null ? void 0 : aegisV2.info) === "function") {
42
+ return aegisV2;
43
+ }
44
+ return void 0;
45
+ }
46
+ function reportToGalileo(level, message, config) {
47
+ return __async(this, null, function* () {
48
+ var _a;
49
+ const fields = JSON.stringify({
50
+ type: TYPE,
51
+ level
52
+ });
53
+ const ext = JSON.stringify({
54
+ tusi_app_id: config.appId,
55
+ tusi_app_version: config.version,
56
+ tusi_mode: config.mode
57
+ });
58
+ const payload = {
59
+ topic: TOPIC,
60
+ bean: {
61
+ env: (_a = config.env) != null ? _a : DEFAULT_ENV
62
+ },
63
+ ext,
64
+ scheme: SCHEME,
65
+ d2: [
66
+ {
67
+ fields,
68
+ message: [JSON.stringify({ msg: message })],
69
+ timestamp: Date.now()
70
+ }
71
+ ]
72
+ };
73
+ try {
74
+ yield axios__default.default.post(GALILEO_ENDPOINT, JSON.stringify(payload), {
75
+ headers: {
76
+ "content-type": "text/plain;charset=UTF-8"
77
+ },
78
+ timeout: REPORT_TIMEOUT
79
+ });
80
+ } catch (e) {
81
+ }
82
+ });
83
+ }
84
+ var Logger = class {
85
+ /**
86
+ * 创建日志上报器。
87
+ *
88
+ * @param config - 通道配置。不传时环境为 production,且没有内容前缀
89
+ */
90
+ constructor(config = {}) {
91
+ this.config = config;
92
+ }
93
+ /**
94
+ * 上报 info 级日志。
95
+ *
96
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
97
+ */
98
+ info(content) {
99
+ this.report("info", content);
100
+ }
101
+ /**
102
+ * 上报 error 级日志。
103
+ *
104
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
105
+ */
106
+ error(content) {
107
+ this.report("error", content);
108
+ }
109
+ report(level, content) {
110
+ const message = this.formatContent(content);
111
+ const aegisV2 = getAegisV2();
112
+ if (aegisV2) {
113
+ aegisV2[level](message);
114
+ return;
115
+ }
116
+ void reportToGalileo(level, message, this.config);
117
+ }
118
+ formatContent(content) {
119
+ const { contentPrefix } = this.config;
120
+ return contentPrefix ? `${contentPrefix} ${content}` : content;
121
+ }
122
+ };
123
+
124
+ exports.Logger = Logger;
@@ -0,0 +1,81 @@
1
+ /** Logger 构造配置 */
2
+ interface LoggerConfig {
3
+ /**
4
+ * 上报环境标识,写入伽利略通道 bean.env(production 进正式环境,其他值进测试环境);
5
+ * 未传时回落默认值 production;aegisV2 通道忽略不使用
6
+ */
7
+ env?: string;
8
+ /**
9
+ * 日志内容前缀,与 content 直接拼接(不加任何修饰,格式由调用方自行控制,
10
+ * 如传 `'geolocation: '`);各插件传自己的名字便于在日志平台检索区分来源
11
+ */
12
+ contentPrefix?: string;
13
+ /** 应用 ID(伽利略通道 ext.tusi_app_id;aegisV2 通道忽略不使用) */
14
+ appId?: string;
15
+ /** 应用版本(伽利略通道 ext.tusi_app_version) */
16
+ version?: string;
17
+ /** 运行模式(伽利略通道 ext.tusi_mode) */
18
+ mode?: string;
19
+ }
20
+ /** 日志级别 */
21
+ type LogLevel = 'info' | 'error';
22
+
23
+ /**
24
+ * @tusi-ai/logger —— 统一日志上报(plugins / services 共用的通用层)
25
+ *
26
+ * 通道策略(每次调用时判定,注入时序安全):
27
+ * 1. window.aegisV2 存在(Aegis V2 前端监控 SDK,外部脚本注入)→ 直接走 Aegis 上报,
28
+ * env / appId / version / mode 不参与,日志前拼 contentPrefix
29
+ * 2. 否则 → 伽利略可观测平台 HTTP 上报(axios,异步不阻塞、失败静默、超时 5s),
30
+ * env 写入 bean.env;appId / version / mode 写入 ext 的 tusi_app_id / tusi_app_version / tusi_mode
31
+ *
32
+ * 端点与协议对齐现有实现(app-generator-vite-config/src/utils/logger.ts):
33
+ * - https://galileotelemetry.tencent.com/collect,scheme v2,type normal
34
+ * - TOPIC:SDK-42a0ae29a90bc4f6a218(保持不变);常量集中定义于 @/config
35
+ *
36
+ * 用法:
37
+ * const logger = new Logger({
38
+ * env: 'production',
39
+ * contentPrefix: 'geolocation',
40
+ * appId: 'xxx',
41
+ * version: '1.0.0',
42
+ * mode: 'preview',
43
+ * });
44
+ * logger.error('获取定位失败');
45
+ * logger.info('环境判定完成');
46
+ */
47
+
48
+ /**
49
+ * 统一日志上报器
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const logger = new Logger({ env: 'production', contentPrefix: 'geolocation: ', appId: 'app-123', mode: 'preview' });
54
+ * logger.error('获取定位失败'); // 上报内容:geolocation: 获取定位失败
55
+ * ```
56
+ */
57
+ declare class Logger {
58
+ private readonly config;
59
+ /**
60
+ * 创建日志上报器。
61
+ *
62
+ * @param config - 通道配置。不传时环境为 production,且没有内容前缀
63
+ */
64
+ constructor(config?: LoggerConfig);
65
+ /**
66
+ * 上报 info 级日志。
67
+ *
68
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
69
+ */
70
+ info(content: string): void;
71
+ /**
72
+ * 上报 error 级日志。
73
+ *
74
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
75
+ */
76
+ error(content: string): void;
77
+ private report;
78
+ private formatContent;
79
+ }
80
+
81
+ export { type LogLevel, Logger, type LoggerConfig };
@@ -0,0 +1,81 @@
1
+ /** Logger 构造配置 */
2
+ interface LoggerConfig {
3
+ /**
4
+ * 上报环境标识,写入伽利略通道 bean.env(production 进正式环境,其他值进测试环境);
5
+ * 未传时回落默认值 production;aegisV2 通道忽略不使用
6
+ */
7
+ env?: string;
8
+ /**
9
+ * 日志内容前缀,与 content 直接拼接(不加任何修饰,格式由调用方自行控制,
10
+ * 如传 `'geolocation: '`);各插件传自己的名字便于在日志平台检索区分来源
11
+ */
12
+ contentPrefix?: string;
13
+ /** 应用 ID(伽利略通道 ext.tusi_app_id;aegisV2 通道忽略不使用) */
14
+ appId?: string;
15
+ /** 应用版本(伽利略通道 ext.tusi_app_version) */
16
+ version?: string;
17
+ /** 运行模式(伽利略通道 ext.tusi_mode) */
18
+ mode?: string;
19
+ }
20
+ /** 日志级别 */
21
+ type LogLevel = 'info' | 'error';
22
+
23
+ /**
24
+ * @tusi-ai/logger —— 统一日志上报(plugins / services 共用的通用层)
25
+ *
26
+ * 通道策略(每次调用时判定,注入时序安全):
27
+ * 1. window.aegisV2 存在(Aegis V2 前端监控 SDK,外部脚本注入)→ 直接走 Aegis 上报,
28
+ * env / appId / version / mode 不参与,日志前拼 contentPrefix
29
+ * 2. 否则 → 伽利略可观测平台 HTTP 上报(axios,异步不阻塞、失败静默、超时 5s),
30
+ * env 写入 bean.env;appId / version / mode 写入 ext 的 tusi_app_id / tusi_app_version / tusi_mode
31
+ *
32
+ * 端点与协议对齐现有实现(app-generator-vite-config/src/utils/logger.ts):
33
+ * - https://galileotelemetry.tencent.com/collect,scheme v2,type normal
34
+ * - TOPIC:SDK-42a0ae29a90bc4f6a218(保持不变);常量集中定义于 @/config
35
+ *
36
+ * 用法:
37
+ * const logger = new Logger({
38
+ * env: 'production',
39
+ * contentPrefix: 'geolocation',
40
+ * appId: 'xxx',
41
+ * version: '1.0.0',
42
+ * mode: 'preview',
43
+ * });
44
+ * logger.error('获取定位失败');
45
+ * logger.info('环境判定完成');
46
+ */
47
+
48
+ /**
49
+ * 统一日志上报器
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const logger = new Logger({ env: 'production', contentPrefix: 'geolocation: ', appId: 'app-123', mode: 'preview' });
54
+ * logger.error('获取定位失败'); // 上报内容:geolocation: 获取定位失败
55
+ * ```
56
+ */
57
+ declare class Logger {
58
+ private readonly config;
59
+ /**
60
+ * 创建日志上报器。
61
+ *
62
+ * @param config - 通道配置。不传时环境为 production,且没有内容前缀
63
+ */
64
+ constructor(config?: LoggerConfig);
65
+ /**
66
+ * 上报 info 级日志。
67
+ *
68
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
69
+ */
70
+ info(content: string): void;
71
+ /**
72
+ * 上报 error 级日志。
73
+ *
74
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
75
+ */
76
+ error(content: string): void;
77
+ private report;
78
+ private formatContent;
79
+ }
80
+
81
+ export { type LogLevel, Logger, type LoggerConfig };
package/dist/index.js ADDED
@@ -0,0 +1,118 @@
1
+ import axios from 'axios';
2
+
3
+ var __async = (__this, __arguments, generator) => {
4
+ return new Promise((resolve, reject) => {
5
+ var fulfilled = (value) => {
6
+ try {
7
+ step(generator.next(value));
8
+ } catch (e) {
9
+ reject(e);
10
+ }
11
+ };
12
+ var rejected = (value) => {
13
+ try {
14
+ step(generator.throw(value));
15
+ } catch (e) {
16
+ reject(e);
17
+ }
18
+ };
19
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
20
+ step((generator = generator.apply(__this, __arguments)).next());
21
+ });
22
+ };
23
+
24
+ // src/config/index.ts
25
+ var GALILEO_ENDPOINT = "https://galileotelemetry.tencent.com/collect";
26
+ var TOPIC = "SDK-42a0ae29a90bc4f6a218";
27
+ var SCHEME = "v2";
28
+ var TYPE = "normal";
29
+ var REPORT_TIMEOUT = 5e3;
30
+ var DEFAULT_ENV = "production";
31
+
32
+ // src/index.ts
33
+ function getAegisV2() {
34
+ const aegisV2 = window == null ? void 0 : window.aegisV2;
35
+ if (typeof (aegisV2 == null ? void 0 : aegisV2.error) === "function" && typeof (aegisV2 == null ? void 0 : aegisV2.info) === "function") {
36
+ return aegisV2;
37
+ }
38
+ return void 0;
39
+ }
40
+ function reportToGalileo(level, message, config) {
41
+ return __async(this, null, function* () {
42
+ var _a;
43
+ const fields = JSON.stringify({
44
+ type: TYPE,
45
+ level
46
+ });
47
+ const ext = JSON.stringify({
48
+ tusi_app_id: config.appId,
49
+ tusi_app_version: config.version,
50
+ tusi_mode: config.mode
51
+ });
52
+ const payload = {
53
+ topic: TOPIC,
54
+ bean: {
55
+ env: (_a = config.env) != null ? _a : DEFAULT_ENV
56
+ },
57
+ ext,
58
+ scheme: SCHEME,
59
+ d2: [
60
+ {
61
+ fields,
62
+ message: [JSON.stringify({ msg: message })],
63
+ timestamp: Date.now()
64
+ }
65
+ ]
66
+ };
67
+ try {
68
+ yield axios.post(GALILEO_ENDPOINT, JSON.stringify(payload), {
69
+ headers: {
70
+ "content-type": "text/plain;charset=UTF-8"
71
+ },
72
+ timeout: REPORT_TIMEOUT
73
+ });
74
+ } catch (e) {
75
+ }
76
+ });
77
+ }
78
+ var Logger = class {
79
+ /**
80
+ * 创建日志上报器。
81
+ *
82
+ * @param config - 通道配置。不传时环境为 production,且没有内容前缀
83
+ */
84
+ constructor(config = {}) {
85
+ this.config = config;
86
+ }
87
+ /**
88
+ * 上报 info 级日志。
89
+ *
90
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
91
+ */
92
+ info(content) {
93
+ this.report("info", content);
94
+ }
95
+ /**
96
+ * 上报 error 级日志。
97
+ *
98
+ * @param content - 日志正文。已配置 `contentPrefix` 时拼在前面
99
+ */
100
+ error(content) {
101
+ this.report("error", content);
102
+ }
103
+ report(level, content) {
104
+ const message = this.formatContent(content);
105
+ const aegisV2 = getAegisV2();
106
+ if (aegisV2) {
107
+ aegisV2[level](message);
108
+ return;
109
+ }
110
+ void reportToGalileo(level, message, this.config);
111
+ }
112
+ formatContent(content) {
113
+ const { contentPrefix } = this.config;
114
+ return contentPrefix ? `${contentPrefix} ${content}` : content;
115
+ }
116
+ };
117
+
118
+ export { Logger };
package/package.json CHANGED
@@ -1,6 +1,36 @@
1
1
  {
2
2
  "name": "@tusi-ai/logger",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.0.1-beta.0",
4
+ "description": "吐司日志上报工具",
5
+ "main": "dist/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.ts",
12
+ "default": "./dist/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.ts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "sideEffects": false,
24
+ "dependencies": {
25
+ "axios": "^1.19.0"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org/"
30
+ },
31
+ "scripts": {
32
+ "build": "tsup",
33
+ "dev": "tsup --watch",
34
+ "typecheck": "tsc --noEmit"
35
+ }
6
36
  }