@arms/rum-core 0.1.5 → 0.1.6

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.
@@ -0,0 +1,123 @@
1
+ /**
2
+ * SLS LogGroup Protobuf 编码器(最小化实现,零外部依赖)
3
+ *
4
+ * Schema:
5
+ * message Log {
6
+ * required uint32 Time = 1;
7
+ * message Content { required string Key = 1; required string Value = 2; }
8
+ * repeated Content Contents = 2;
9
+ * }
10
+ * message LogTag { required string Key = 1; required string Value = 2; }
11
+ * message LogGroup {
12
+ * repeated Log Logs = 1;
13
+ * optional string Topic = 3;
14
+ * optional string Source = 4;
15
+ * repeated LogTag LogTags = 6;
16
+ * }
17
+ */
18
+
19
+ var WIRE_TYPE_VARINT = 0;
20
+ var WIRE_TYPE_LEN = 2;
21
+
22
+ /**
23
+ * UTF-8 编码 fallback(当 TextEncoder 不可用时使用,如部分小程序环境)
24
+ */
25
+ function encodeUtf8Fallback(str) {
26
+ var bytes = [];
27
+ for (var i = 0; i < str.length; i++) {
28
+ var charCode = str.charCodeAt(i);
29
+ if (charCode < 0x80) {
30
+ bytes.push(charCode);
31
+ } else if (charCode < 0x800) {
32
+ bytes.push(0xc0 | charCode >> 6);
33
+ bytes.push(0x80 | charCode & 0x3f);
34
+ } else if (charCode >= 0xd800 && charCode <= 0xdbff) {
35
+ // 代理对处理
36
+ i++;
37
+ var low = str.charCodeAt(i);
38
+ charCode = 0x10000 + (charCode - 0xd800 << 10) + (low - 0xdc00);
39
+ bytes.push(0xf0 | charCode >> 18);
40
+ bytes.push(0x80 | charCode >> 12 & 0x3f);
41
+ bytes.push(0x80 | charCode >> 6 & 0x3f);
42
+ bytes.push(0x80 | charCode & 0x3f);
43
+ } else {
44
+ bytes.push(0xe0 | charCode >> 12);
45
+ bytes.push(0x80 | charCode >> 6 & 0x3f);
46
+ bytes.push(0x80 | charCode & 0x3f);
47
+ }
48
+ }
49
+ return new Uint8Array(bytes);
50
+ }
51
+ var utf8Encoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : {
52
+ encode: encodeUtf8Fallback
53
+ };
54
+ var ProtobufWriter = /*#__PURE__*/function () {
55
+ function ProtobufWriter() {
56
+ this.buf = [];
57
+ }
58
+ var _proto = ProtobufWriter.prototype;
59
+ _proto.writeVarint = function writeVarint(value) {
60
+ // Base-128 可变长整数编码(仅处理非负整数)
61
+ var v = value >>> 0;
62
+ while (v > 0x7f) {
63
+ this.buf.push(v & 0x7f | 0x80);
64
+ v = v >>> 7;
65
+ }
66
+ this.buf.push(v & 0x7f);
67
+ };
68
+ _proto.writeTag = function writeTag(fieldNumber, wireType) {
69
+ this.writeVarint(fieldNumber << 3 | wireType);
70
+ };
71
+ _proto.writeString = function writeString(fieldNumber, value) {
72
+ var bytes = utf8Encoder.encode(value);
73
+ this.writeTag(fieldNumber, WIRE_TYPE_LEN);
74
+ this.writeVarint(bytes.length);
75
+ for (var i = 0; i < bytes.length; i++) {
76
+ this.buf.push(bytes[i]);
77
+ }
78
+ };
79
+ _proto.writeUint32 = function writeUint32(fieldNumber, value) {
80
+ this.writeTag(fieldNumber, WIRE_TYPE_VARINT);
81
+ this.writeVarint(value);
82
+ };
83
+ _proto.writeBytes = function writeBytes(fieldNumber, data) {
84
+ this.writeTag(fieldNumber, WIRE_TYPE_LEN);
85
+ this.writeVarint(data.length);
86
+ for (var i = 0; i < data.length; i++) {
87
+ this.buf.push(data[i]);
88
+ }
89
+ };
90
+ _proto.finish = function finish() {
91
+ return new Uint8Array(this.buf);
92
+ };
93
+ return ProtobufWriter;
94
+ }();
95
+ function encodeContent(key, value) {
96
+ var w = new ProtobufWriter();
97
+ w.writeString(1, key);
98
+ w.writeString(2, value);
99
+ return w.finish();
100
+ }
101
+ function encodeLog(time, contents) {
102
+ var w = new ProtobufWriter();
103
+ w.writeUint32(1, time);
104
+ for (var i = 0; i < contents.length; i++) {
105
+ var c = contents[i];
106
+ w.writeBytes(2, encodeContent(c.key, c.value));
107
+ }
108
+ return w.finish();
109
+ }
110
+ export function encodeLogGroup(logs, topic, source) {
111
+ var w = new ProtobufWriter();
112
+ for (var i = 0; i < logs.length; i++) {
113
+ var log = logs[i];
114
+ w.writeBytes(1, encodeLog(log.time, log.contents));
115
+ }
116
+ if (topic !== undefined) {
117
+ w.writeString(3, topic);
118
+ }
119
+ if (source !== undefined) {
120
+ w.writeString(4, source);
121
+ }
122
+ return w.finish();
123
+ }
package/lib/index.d.ts CHANGED
@@ -19,4 +19,5 @@ export * from './utils/trace';
19
19
  export * from './utils/verify';
20
20
  export * from './utils/url';
21
21
  export * from './utils/events';
22
+ export * from './monitor';
22
23
  export { Client, Context, Reporter, Shell };
package/lib/index.js CHANGED
@@ -134,4 +134,11 @@ Object.keys(_events).forEach(function (key) {
134
134
  if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
135
135
  if (key in exports && exports[key] === _events[key]) return;
136
136
  exports[key] = _events[key];
137
+ });
138
+ var _monitor = require("./monitor");
139
+ Object.keys(_monitor).forEach(function (key) {
140
+ if (key === "default" || key === "__esModule") return;
141
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
142
+ if (key in exports && exports[key] === _monitor[key]) return;
143
+ exports[key] = _monitor[key];
137
144
  });
@@ -4,13 +4,14 @@ import { RumEvent } from '../types/rum-event';
4
4
  import { IProcessor } from '../types/processor';
5
5
  import { ICollector } from '../types/collector';
6
6
  import { IReporter } from '../types/reporter';
7
+ import { IMonitorReporter } from '../monitor/types';
7
8
  declare class Client implements IClient {
8
9
  private emitter;
9
10
  private collectors;
10
11
  private processors;
11
12
  private reporter;
12
13
  private ctx;
13
- init(config: IConfiguration, rumSession?: IRumSession, configManager?: IConfigManager): void;
14
+ init(config: IConfiguration, rumSession?: IRumSession, configManager?: IConfigManager, monitorReporter?: IMonitorReporter): void;
14
15
  sendEvent: (payload: RumEvent) => void;
15
16
  setContext(ctx: IContext): void;
16
17
  getContext(): IContext;
@@ -5,6 +5,7 @@ exports.__esModule = true;
5
5
  exports["default"] = void 0;
6
6
  var _client = require("../types/client");
7
7
  var _events = require("../utils/events");
8
+ var _telemetry = require("../monitor/telemetry");
8
9
  var _context = _interopRequireDefault(require("./context"));
9
10
  var _is = require("../utils/is");
10
11
  function _createForOfIteratorHelperLoose(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (t) return (t = t.call(r)).next.bind(t); if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var o = 0; return function () { return o >= r.length ? { done: !0 } : { done: !1, value: r[o++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -23,9 +24,34 @@ var Client = /*#__PURE__*/function () {
23
24
  };
24
25
  }
25
26
  var _proto = Client.prototype;
26
- _proto.init = function init(config, rumSession, configManager) {
27
+ _proto.init = function init(config, rumSession, configManager, monitorReporter) {
27
28
  var _this2 = this;
28
29
  this.ctx = new _context["default"](config, rumSession, configManager);
30
+
31
+ // Telemetry 初始化 —— 统一在 Core 中完成,各平台仅需传入 reporter
32
+ if (monitorReporter) {
33
+ var telemetryConfig = {
34
+ appType: (rumSession === null || rumSession === void 0 ? void 0 : rumSession.appType) || '',
35
+ sdkVersion: (rumSession === null || rumSession === void 0 ? void 0 : rumSession.sdkVersion) || '',
36
+ endpoint: config.endpoint,
37
+ getSessionId: rumSession ? function () {
38
+ return rumSession.getSessionId();
39
+ } : undefined,
40
+ getSessionSampled: rumSession ? function () {
41
+ return rumSession.getSampled();
42
+ } : undefined,
43
+ getViewId: function getViewId() {
44
+ var _this2$ctx;
45
+ var views = (_this2$ctx = _this2.ctx) === null || _this2$ctx === void 0 ? void 0 : _this2$ctx.getViews();
46
+ return views && views.length ? views[views.length - 1].id : undefined;
47
+ },
48
+ selfMonitor: config.selfMonitor
49
+ };
50
+ if (config.pid) {
51
+ telemetryConfig['app.id'] = config.pid;
52
+ }
53
+ _telemetry.Telemetry.init(telemetryConfig, monitorReporter);
54
+ }
29
55
  var ctx = this.ctx,
30
56
  collectors = this.collectors,
31
57
  processors = this.processors,
@@ -6,6 +6,7 @@ exports["default"] = void 0;
6
6
  var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
7
7
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
8
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _logger = require("../monitor/logger");
9
10
  var _rumEvent = require("../types/rum-event");
10
11
  var _exception = require("../utils/exception");
11
12
  var _is = require("../utils/is");
@@ -222,6 +223,8 @@ var Reporter = exports["default"] = /*#__PURE__*/function () {
222
223
  setTimeout(function () {
223
224
  return _this2.tryRequest(bundle, retry + 1);
224
225
  }, retryDelay);
226
+ } else {
227
+ _logger.logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", _t);
225
228
  }
226
229
  case 4:
227
230
  case "end":
@@ -0,0 +1,6 @@
1
+ export { logger, callMonitored } from './logger';
2
+ export type { ILogger } from './logger';
3
+ export { Telemetry, convertBundlesToLogGroup } from './telemetry';
4
+ export type { TelemetryContext } from './telemetry';
5
+ export type { MonitorLogEvent, MonitorLogLevel, MonitorEventBundle, IMonitorReporter, ISelfMonitorConfig } from './types';
6
+ export { encodeLogGroup } from '../utils/protobuf';
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.logger = exports.encodeLogGroup = exports.convertBundlesToLogGroup = exports.callMonitored = exports.Telemetry = void 0;
5
+ var _logger = require("./logger");
6
+ exports.logger = _logger.logger;
7
+ exports.callMonitored = _logger.callMonitored;
8
+ var _telemetry = require("./telemetry");
9
+ exports.Telemetry = _telemetry.Telemetry;
10
+ exports.convertBundlesToLogGroup = _telemetry.convertBundlesToLogGroup;
11
+ var _protobuf = require("../utils/protobuf");
12
+ exports.encodeLogGroup = _protobuf.encodeLogGroup;
@@ -0,0 +1,34 @@
1
+ import { MonitorLogEvent, MonitorLogLevel } from './types';
2
+ type LogArgs = [module: string, message: string, error?: unknown, context?: Record<string, unknown>];
3
+ export interface ILogger {
4
+ debug(...args: LogArgs): void;
5
+ info(...args: LogArgs): void;
6
+ warn(...args: LogArgs): void;
7
+ error(...args: LogArgs): void;
8
+ crash(...args: LogArgs): void;
9
+ }
10
+ declare class Logger implements ILogger {
11
+ private console;
12
+ private reportLevels;
13
+ private onError?;
14
+ setConsole(enabled: boolean): void;
15
+ setReportLevels(levels: MonitorLogLevel[]): void;
16
+ setOnError(handler?: (event: MonitorLogEvent) => void): void;
17
+ debug(...args: LogArgs): void;
18
+ info(...args: LogArgs): void;
19
+ warn(...args: LogArgs): void;
20
+ error(...args: LogArgs): void;
21
+ crash(...args: LogArgs): void;
22
+ private log;
23
+ /**
24
+ * 函数包装器 — 用于箭头函数属性
25
+ * 用法: private handler = logger.wrap((e) => {...}, 'module', 'message?')
26
+ */
27
+ wrap<T extends (...args: any[]) => unknown>(fn: T, module: string, message?: string): T;
28
+ }
29
+ export declare const logger: Logger;
30
+ /**
31
+ * 执行被监控函数,异常时自动上报
32
+ */
33
+ export declare function callMonitored<T extends (...args: any[]) => unknown>(fn: T, context?: any, args?: any, module?: string, message?: string): ReturnType<T> | undefined;
34
+ export {};
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.callMonitored = callMonitored;
5
+ exports.logger = void 0;
6
+ var DEFAULT_REPORT_LEVELS = ['debug', 'error', 'crash'];
7
+ var Logger = /*#__PURE__*/function () {
8
+ function Logger() {
9
+ this.console = false;
10
+ this.reportLevels = DEFAULT_REPORT_LEVELS;
11
+ this.onError = void 0;
12
+ }
13
+ var _proto = Logger.prototype;
14
+ _proto.setConsole = function setConsole(enabled) {
15
+ this.console = enabled;
16
+ };
17
+ _proto.setReportLevels = function setReportLevels(levels) {
18
+ this.reportLevels = levels;
19
+ };
20
+ _proto.setOnError = function setOnError(handler) {
21
+ this.onError = handler;
22
+ };
23
+ _proto.debug = function debug() {
24
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
25
+ args[_key] = arguments[_key];
26
+ }
27
+ this.log('debug', args);
28
+ };
29
+ _proto.info = function info() {
30
+ for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
31
+ args[_key2] = arguments[_key2];
32
+ }
33
+ this.log('info', args);
34
+ };
35
+ _proto.warn = function warn() {
36
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
37
+ args[_key3] = arguments[_key3];
38
+ }
39
+ this.log('warn', args);
40
+ };
41
+ _proto.error = function error() {
42
+ for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
43
+ args[_key4] = arguments[_key4];
44
+ }
45
+ this.log('error', args);
46
+ };
47
+ _proto.crash = function crash() {
48
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
49
+ args[_key5] = arguments[_key5];
50
+ }
51
+ this.log('crash', args);
52
+ };
53
+ _proto.log = function log(level, _ref) {
54
+ var _this$onError;
55
+ var module = _ref[0],
56
+ message = _ref[1],
57
+ error = _ref[2],
58
+ context = _ref[3];
59
+ if (this.console) {
60
+ var consoleFn = level === 'crash' ? 'error' : level === 'debug' ? 'log' : level;
61
+ console[consoleFn]("[RUM-SDK][" + module + "]", message, error || '');
62
+ }
63
+
64
+ // 仅上报配置中指定的级别
65
+ if (!this.reportLevels.includes(level)) return;
66
+ var stack;
67
+ if (error instanceof Error) {
68
+ stack = error.stack;
69
+ } else if (error && typeof error === 'object' && 'stack' in error) {
70
+ stack = String(error.stack);
71
+ }
72
+
73
+ // 截断过长的 stack(与 content 同等 12KB 上限)
74
+ if (stack && stack.length > 12288) {
75
+ stack = stack.slice(0, 12288);
76
+ }
77
+ (_this$onError = this.onError) === null || _this$onError === void 0 ? void 0 : _this$onError.call(this, Object.assign({
78
+ level: level,
79
+ content: message,
80
+ type: module,
81
+ stack: stack
82
+ }, context));
83
+ }
84
+
85
+ /**
86
+ * 函数包装器 — 用于箭头函数属性
87
+ * 用法: private handler = logger.wrap((e) => {...}, 'module', 'message?')
88
+ */;
89
+ _proto.wrap = function wrap(fn, module, message) {
90
+ return function () {
91
+ for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
92
+ args[_key6] = arguments[_key6];
93
+ }
94
+ return callMonitored(fn, this, args, module, message);
95
+ };
96
+ };
97
+ return Logger;
98
+ }();
99
+ var logger = exports.logger = new Logger();
100
+
101
+ /**
102
+ * 执行被监控函数,异常时自动上报
103
+ */
104
+ function callMonitored(fn, context, args, module, message) {
105
+ try {
106
+ var result = fn.apply(context, args);
107
+ // 检测 async 函数返回的 Promise,附加 .catch 处理
108
+ if (result && typeof result["catch"] === 'function') {
109
+ result["catch"](function (e) {
110
+ logger.error(module || 'unknown', message || (e instanceof Error ? e.message : String(e)), e);
111
+ });
112
+ }
113
+ return result;
114
+ } catch (e) {
115
+ logger.error(module || 'unknown', message || (e instanceof Error ? e.message : String(e)), e);
116
+ }
117
+ }
@@ -0,0 +1,42 @@
1
+ import { MonitorLogEvent, MonitorEventBundle, IMonitorReporter, ISelfMonitorConfig } from './types';
2
+ export interface TelemetryContext {
3
+ appType: string;
4
+ sdkVersion: string;
5
+ endpoint: string;
6
+ getSessionId?: () => string | undefined;
7
+ getViewId?: () => string | undefined;
8
+ getSessionSampled?: () => boolean;
9
+ /** 自监控配置 */
10
+ selfMonitor?: ISelfMonitorConfig | boolean;
11
+ [key: string]: unknown;
12
+ }
13
+ export declare class Telemetry {
14
+ private static instance;
15
+ static init(context: TelemetryContext, reporter?: IMonitorReporter): Telemetry;
16
+ static get(): Telemetry | undefined;
17
+ private buffer;
18
+ private queue;
19
+ private sentEvents;
20
+ private started;
21
+ private enabled;
22
+ private sampled;
23
+ private timer;
24
+ private reporter?;
25
+ private context;
26
+ private isReporting;
27
+ private endpointParams;
28
+ constructor(context: TelemetryContext, reporter?: IMonitorReporter);
29
+ private start;
30
+ addEvent(event: MonitorLogEvent): void;
31
+ flush(): void;
32
+ setReporter(reporter: IMonitorReporter): void;
33
+ private flushBuffer;
34
+ private processSnapshot;
35
+ private shouldSend;
36
+ private buildBundle;
37
+ private sendBatch;
38
+ }
39
+ /**
40
+ * 将 MonitorEventBundle 数组转换并编码为 SLS LogGroup Protobuf 格式
41
+ */
42
+ export declare function convertBundlesToLogGroup(data: MonitorEventBundle[]): Uint8Array;
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ exports.__esModule = true;
5
+ exports.Telemetry = void 0;
6
+ exports.convertBundlesToLogGroup = convertBundlesToLogGroup;
7
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
8
+ var _logger = require("./logger");
9
+ var _url = require("../utils/url");
10
+ var _protobuf = require("../utils/protobuf");
11
+ var _number = require("../utils/number");
12
+ var _Telemetry;
13
+ var MAX_EVENTS_PER_PAGE = 15;
14
+ var BUFFER_SIZE = 100;
15
+ var LOG_CONTENT_MAX_SIZE = 12288;
16
+ var FLUSH_TIME = 5000;
17
+ var MAX_BATCH_SIZE = 10;
18
+ var DEFAULT_SAMPLE_RATE = 100;
19
+
20
+ /** 事件快照:在事件产生时就捕获上下文 */
21
+ var Telemetry = exports.Telemetry = /*#__PURE__*/function () {
22
+ function Telemetry(context, reporter) {
23
+ this.buffer = [];
24
+ this.queue = [];
25
+ this.sentEvents = new Set();
26
+ this.started = false;
27
+ this.enabled = true;
28
+ this.sampled = void 0;
29
+ this.timer = null;
30
+ this.reporter = void 0;
31
+ this.context = void 0;
32
+ this.isReporting = false;
33
+ this.endpointParams = void 0;
34
+ this.context = context;
35
+ this.reporter = reporter;
36
+ this.endpointParams = (0, _url.getUrlParams)(context.endpoint);
37
+
38
+ // 解析自监控配置
39
+ var selfMonitor = context.selfMonitor;
40
+ if (typeof selfMonitor === 'boolean') {
41
+ this.enabled = selfMonitor;
42
+ this.sampled = (0, _number.performDraw)(DEFAULT_SAMPLE_RATE);
43
+ } else if (selfMonitor && typeof selfMonitor === 'object') {
44
+ this.enabled = selfMonitor.enable !== false;
45
+ var rate = selfMonitor.sampling;
46
+ this.sampled = (0, _number.performDraw)(typeof rate === 'number' && rate >= 0 && rate <= 100 ? rate : DEFAULT_SAMPLE_RATE);
47
+ if (selfMonitor.console) {
48
+ _logger.logger.setConsole(true);
49
+ }
50
+ if (selfMonitor.reportLevels) {
51
+ _logger.logger.setReportLevels(selfMonitor.reportLevels);
52
+ }
53
+ } else {
54
+ this.enabled = true;
55
+ this.sampled = (0, _number.performDraw)(DEFAULT_SAMPLE_RATE);
56
+ }
57
+ }
58
+ Telemetry.init = function init(context, reporter) {
59
+ if (Telemetry.instance) {
60
+ Telemetry.instance.flush();
61
+ }
62
+ Telemetry.instance = new Telemetry(context, reporter);
63
+ Telemetry.instance.start();
64
+ return Telemetry.instance;
65
+ };
66
+ Telemetry.get = function get() {
67
+ return Telemetry.instance;
68
+ };
69
+ var _proto = Telemetry.prototype;
70
+ _proto.start = function start() {
71
+ var _this = this;
72
+ if (this.started) return;
73
+ this.started = true;
74
+ _logger.logger.setOnError(function (event) {
75
+ return _this.addEvent(event);
76
+ });
77
+ this.flushBuffer();
78
+ };
79
+ _proto.addEvent = function addEvent(event) {
80
+ var _this$context$getSess, _this$context, _this$context$getView, _this$context2;
81
+ if (!this.enabled || !event) return;
82
+ if (event.content && event.content.length > LOG_CONTENT_MAX_SIZE) {
83
+ event = (0, _extends2["default"])({}, event, {
84
+ content: event.content.slice(0, LOG_CONTENT_MAX_SIZE)
85
+ });
86
+ }
87
+ if (event.stack && event.stack.length > LOG_CONTENT_MAX_SIZE) {
88
+ event = (0, _extends2["default"])({}, event, {
89
+ stack: event.stack.slice(0, LOG_CONTENT_MAX_SIZE)
90
+ });
91
+ }
92
+
93
+ // 在事件产生时就捕获快照
94
+ var snapshot = {
95
+ event: event,
96
+ sessionId: (_this$context$getSess = (_this$context = this.context).getSessionId) === null || _this$context$getSess === void 0 ? void 0 : _this$context$getSess.call(_this$context),
97
+ viewId: (_this$context$getView = (_this$context2 = this.context).getViewId) === null || _this$context$getView === void 0 ? void 0 : _this$context$getView.call(_this$context2),
98
+ timestamp: Date.now()
99
+ };
100
+ if (!this.started || !this.reporter) {
101
+ if (this.buffer.length < BUFFER_SIZE) {
102
+ this.buffer.push(snapshot);
103
+ }
104
+ return;
105
+ }
106
+ this.processSnapshot(snapshot);
107
+ };
108
+ _proto.flush = function flush() {
109
+ if (this.timer) {
110
+ clearTimeout(this.timer);
111
+ this.timer = null;
112
+ }
113
+ this.sendBatch();
114
+ };
115
+ _proto.setReporter = function setReporter(reporter) {
116
+ this.reporter = reporter;
117
+ if (this.started) {
118
+ this.flushBuffer();
119
+ }
120
+ };
121
+ _proto.flushBuffer = function flushBuffer() {
122
+ var _this2 = this;
123
+ var buffered = this.buffer.splice(0);
124
+ buffered.forEach(function (snapshot) {
125
+ return _this2.processSnapshot(snapshot);
126
+ });
127
+ };
128
+ _proto.processSnapshot = function processSnapshot(snapshot) {
129
+ var _this3 = this;
130
+ if (!this.shouldSend(snapshot.event)) return;
131
+ var bundle = this.buildBundle(snapshot);
132
+ this.queue.push(bundle);
133
+ if (this.queue.length >= MAX_BATCH_SIZE) {
134
+ this.flush();
135
+ } else if (!this.timer) {
136
+ this.timer = setTimeout(function () {
137
+ return _this3.flush();
138
+ }, FLUSH_TIME);
139
+ }
140
+ };
141
+ _proto.shouldSend = function shouldSend(event) {
142
+ // 先检查 Session 采样,未命中则不上报
143
+ if (this.context.getSessionSampled && !this.context.getSessionSampled()) return false;
144
+ // 再检查自监控自身采样
145
+ if (!this.sampled) return false;
146
+ if (this.sentEvents.size >= MAX_EVENTS_PER_PAGE) return false;
147
+ var key = (event.content || '') + (event.stack || '');
148
+ if (this.sentEvents.has(key)) return false;
149
+ this.sentEvents.add(key);
150
+ return true;
151
+ };
152
+ _proto.buildBundle = function buildBundle(snapshot) {
153
+ var _this$context3 = this.context,
154
+ appType = _this$context3.appType,
155
+ sdkVersion = _this$context3.sdkVersion,
156
+ endpoint = _this$context3.endpoint;
157
+ return (0, _extends2["default"])({
158
+ 'app.type': appType,
159
+ _v: sdkVersion,
160
+ endpoint: endpoint,
161
+ 'session.id': snapshot.sessionId,
162
+ 'view.id': snapshot.viewId,
163
+ timestamp: snapshot.timestamp,
164
+ event_type: 'log',
165
+ log: snapshot.event
166
+ }, this.endpointParams);
167
+ };
168
+ _proto.sendBatch = function sendBatch() {
169
+ if (this.queue.length === 0 || !this.reporter) return;
170
+ if (this.isReporting) return;
171
+ var batch = this.queue.splice(0);
172
+ this.isReporting = true;
173
+ try {
174
+ this.reporter.send(batch);
175
+ } catch (e) {
176
+ // 不通过 logger(避免反馈循环),直接 console 仅供开发调试
177
+ try {
178
+ console.warn('[RUM-Telemetry] send failed:', e);
179
+ } catch (_) {}
180
+ } finally {
181
+ this.isReporting = false;
182
+ }
183
+ };
184
+ return Telemetry;
185
+ }();
186
+ /**
187
+ * 将 MonitorEventBundle 数组转换并编码为 SLS LogGroup Protobuf 格式
188
+ */
189
+ _Telemetry = Telemetry;
190
+ Telemetry.instance = void 0;
191
+ function convertBundlesToLogGroup(data) {
192
+ var logs = data.map(function (bundle) {
193
+ var contents = [];
194
+
195
+ // 遍历 bundle 顶层字段,跳过 timestamp(映射到 time),对象类型整体序列化
196
+ for (var _i = 0, _Object$entries = Object.entries(bundle); _i < _Object$entries.length; _i++) {
197
+ var _Object$entries$_i = _Object$entries[_i],
198
+ _key = _Object$entries$_i[0],
199
+ val = _Object$entries$_i[1];
200
+ if (_key === 'timestamp') continue;
201
+ if (val !== undefined && val !== null) {
202
+ contents.push({
203
+ key: _key,
204
+ value: typeof val === 'object' ? JSON.stringify(val) : String(val)
205
+ });
206
+ }
207
+ }
208
+ return {
209
+ time: Math.floor(bundle.timestamp / 1000),
210
+ contents: contents
211
+ };
212
+ });
213
+ return (0, _protobuf.encodeLogGroup)(logs);
214
+ }