@vectorx/functions-framework 0.0.0-beta-20251112071234
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 +141 -0
- package/bin/rcb-ff.js +153 -0
- package/lib/async-context.js +61 -0
- package/lib/config.js +10 -0
- package/lib/constants.js +10 -0
- package/lib/error.js +47 -0
- package/lib/framework.js +183 -0
- package/lib/function-loader.js +63 -0
- package/lib/function-registry.js +20 -0
- package/lib/function-wrapper.js +170 -0
- package/lib/index.js +23 -0
- package/lib/logger.js +204 -0
- package/lib/middlewares/index.js +19 -0
- package/lib/middlewares/middle-apm-injection.js +37 -0
- package/lib/middlewares/middle-async-context.js +27 -0
- package/lib/middlewares/middle-common-logger.js +67 -0
- package/lib/middlewares/middle-context-injection.js +33 -0
- package/lib/middlewares/middle-event-id.js +20 -0
- package/lib/middlewares/middle-function-route.js +26 -0
- package/lib/middlewares/middle-logs-request.js +98 -0
- package/lib/middlewares/middle-open-gw-request.js +29 -0
- package/lib/request.js +162 -0
- package/lib/router.js +51 -0
- package/lib/server.js +115 -0
- package/lib/sse.js +258 -0
- package/lib/telemetry/langfuse.js +13 -0
- package/lib/types.js +2 -0
- package/lib/unified-responder.js +64 -0
- package/lib/user-logger.js +54 -0
- package/lib/utils/apm.config.js +7 -0
- package/lib/utils/apm.js +140 -0
- package/lib/utils/common.js +5 -0
- package/lib/utils/console-intercept.js +58 -0
- package/lib/utils/error-stack.js +30 -0
- package/lib/utils/helper.js +88 -0
- package/lib/utils/machineId.js +72 -0
- package/package.json +76 -0
- package/types/async-context.d.ts +17 -0
- package/types/config.d.ts +1 -0
- package/types/constants.d.ts +2 -0
- package/types/error.d.ts +20 -0
- package/types/framework.d.ts +32 -0
- package/types/function-loader.d.ts +26 -0
- package/types/function-registry.d.ts +4 -0
- package/types/function-wrapper.d.ts +3 -0
- package/types/index.d.ts +7 -0
- package/types/logger.d.ts +74 -0
- package/types/middlewares/index.d.ts +8 -0
- package/types/middlewares/middle-apm-injection.d.ts +2 -0
- package/types/middlewares/middle-async-context.d.ts +2 -0
- package/types/middlewares/middle-common-logger.d.ts +2 -0
- package/types/middlewares/middle-context-injection.d.ts +4 -0
- package/types/middlewares/middle-event-id.d.ts +2 -0
- package/types/middlewares/middle-function-route.d.ts +4 -0
- package/types/middlewares/middle-logs-request.d.ts +3 -0
- package/types/middlewares/middle-open-gw-request.d.ts +2 -0
- package/types/request.d.ts +46 -0
- package/types/router.d.ts +15 -0
- package/types/server.d.ts +33 -0
- package/types/sse.d.ts +23 -0
- package/types/telemetry/langfuse.d.ts +4 -0
- package/types/types.d.ts +18 -0
- package/types/unified-responder.d.ts +15 -0
- package/types/user-logger.d.ts +5 -0
- package/types/utils/apm.config.d.ts +6 -0
- package/types/utils/apm.d.ts +21 -0
- package/types/utils/common.d.ts +2 -0
- package/types/utils/console-intercept.d.ts +6 -0
- package/types/utils/error-stack.d.ts +5 -0
- package/types/utils/helper.d.ts +7 -0
- package/types/utils/machineId.d.ts +2 -0
package/lib/sse.js
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ServerSentEvent = void 0;
|
|
40
|
+
const events_1 = require("events");
|
|
41
|
+
const stream_1 = require("stream");
|
|
42
|
+
const util = __importStar(require("util"));
|
|
43
|
+
const langfuse_1 = __importDefault(require("./telemetry/langfuse"));
|
|
44
|
+
const helper_1 = require("./utils/helper");
|
|
45
|
+
const kDefaultEncoder = new util.TextEncoder();
|
|
46
|
+
class ServerSentEvent extends events_1.EventEmitter {
|
|
47
|
+
constructor(ctx) {
|
|
48
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
49
|
+
super();
|
|
50
|
+
this.closed = false;
|
|
51
|
+
this.encoder = kDefaultEncoder;
|
|
52
|
+
this.ctx = ctx;
|
|
53
|
+
this.stream = new stream_1.PassThrough({
|
|
54
|
+
objectMode: false,
|
|
55
|
+
});
|
|
56
|
+
this.stream.pipe(ctx.res);
|
|
57
|
+
ctx.respond = false;
|
|
58
|
+
ctx.req.once("close", () => {
|
|
59
|
+
this.emit("close");
|
|
60
|
+
this.closed = true;
|
|
61
|
+
});
|
|
62
|
+
if (ctx.req.socket) {
|
|
63
|
+
ctx.req.socket.setTimeout(0);
|
|
64
|
+
ctx.req.socket.setNoDelay(true);
|
|
65
|
+
ctx.req.socket.setKeepAlive(true, 0);
|
|
66
|
+
}
|
|
67
|
+
const headers = {
|
|
68
|
+
"Content-Type": "text/event-stream",
|
|
69
|
+
"Cache-Control": "no-cache",
|
|
70
|
+
Connection: "keep-alive",
|
|
71
|
+
};
|
|
72
|
+
if (ctx.state && ctx.state.eventID) {
|
|
73
|
+
headers["x-open-agent-trace-id"] = ctx.state.eventID;
|
|
74
|
+
}
|
|
75
|
+
ctx.set(headers);
|
|
76
|
+
ctx.status = 200;
|
|
77
|
+
ctx.flushHeaders();
|
|
78
|
+
for (const key of ["ctx", "stream", "encoder"]) {
|
|
79
|
+
Object.defineProperty(this, key, {
|
|
80
|
+
configurable: false,
|
|
81
|
+
enumerable: false,
|
|
82
|
+
writable: false,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const enabled = ((_c = (_b = (_a = ctx.state) === null || _a === void 0 ? void 0 : _a.frameworkOptions) === null || _b === void 0 ? void 0 : _b.redLangfuseConfig) === null || _c === void 0 ? void 0 : _c.enable) === true;
|
|
87
|
+
if (!enabled)
|
|
88
|
+
return;
|
|
89
|
+
const stage = process.env.OPEN_PLATFORM_STAGE || "development";
|
|
90
|
+
const openId = ctx.headers["open-id"] || undefined;
|
|
91
|
+
const eventID = (_d = ctx.state) === null || _d === void 0 ? void 0 : _d.eventID;
|
|
92
|
+
const agentInfo = ((_e = ctx.state) === null || _e === void 0 ? void 0 : _e.agentInfo) || {};
|
|
93
|
+
const name = [(agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.agentName) || (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.name), agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.version].filter(Boolean).join("@");
|
|
94
|
+
const metadata = {
|
|
95
|
+
http: { method: ctx.method, path: ctx.path },
|
|
96
|
+
eventID,
|
|
97
|
+
agent: {
|
|
98
|
+
id: agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.agentId,
|
|
99
|
+
name: (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.agentName) || (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.name),
|
|
100
|
+
version: agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.version,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
const trace = (_f = langfuse_1.default === null || langfuse_1.default === void 0 ? void 0 : langfuse_1.default.trace) === null || _f === void 0 ? void 0 : _f.call(langfuse_1.default, {
|
|
104
|
+
name: name || "chat-app-session",
|
|
105
|
+
userId: openId,
|
|
106
|
+
tags: [stage],
|
|
107
|
+
metadata,
|
|
108
|
+
});
|
|
109
|
+
if (trace) {
|
|
110
|
+
ctx.state.langfuseTrace = trace;
|
|
111
|
+
(_g = trace.event) === null || _g === void 0 ? void 0 : _g.call(trace, { name: "sse:start", input: (_j = (_h = ctx.state) === null || _h === void 0 ? void 0 : _h.event) !== null && _j !== void 0 ? _j : null, metadata: { path: ctx.path } });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (_k) { }
|
|
115
|
+
}
|
|
116
|
+
setEncoder(encoder) {
|
|
117
|
+
this.encoder = encoder;
|
|
118
|
+
}
|
|
119
|
+
emitMessage(event, data) {
|
|
120
|
+
if (this.closed)
|
|
121
|
+
return false;
|
|
122
|
+
const message = {
|
|
123
|
+
event,
|
|
124
|
+
data,
|
|
125
|
+
};
|
|
126
|
+
return this.send(message);
|
|
127
|
+
}
|
|
128
|
+
emit(event, ...args) {
|
|
129
|
+
return super.emit(event, ...args);
|
|
130
|
+
}
|
|
131
|
+
send(event) {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
const encoder = this.encoder;
|
|
134
|
+
const stream = this.stream;
|
|
135
|
+
if (this.closed) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
const events = Array.isArray(event) ? event : [event];
|
|
139
|
+
const bufs = [];
|
|
140
|
+
for (const event of events) {
|
|
141
|
+
if (Buffer.isBuffer(event)) {
|
|
142
|
+
bufs.push(event);
|
|
143
|
+
}
|
|
144
|
+
else if (typeof event === "string") {
|
|
145
|
+
bufs.push(Buffer.from(encoder.encode(event)));
|
|
146
|
+
}
|
|
147
|
+
else if ((0, helper_1.isPlainObject)(event)) {
|
|
148
|
+
const msgs = eventToMsgs(event);
|
|
149
|
+
for (const msg of msgs) {
|
|
150
|
+
if (Buffer.isBuffer(msg)) {
|
|
151
|
+
bufs.push(msg);
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
bufs.push(Buffer.from(encoder.encode(msg)));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const buf = Buffer.concat(bufs);
|
|
160
|
+
if (Buffer.byteLength(buf) > 0) {
|
|
161
|
+
const ok = stream.write(Buffer.concat(bufs));
|
|
162
|
+
try {
|
|
163
|
+
const lfTrace = (_a = this.ctx.state) === null || _a === void 0 ? void 0 : _a.langfuseTrace;
|
|
164
|
+
if (lfTrace) {
|
|
165
|
+
let output = null;
|
|
166
|
+
try {
|
|
167
|
+
if (!Array.isArray(event)) {
|
|
168
|
+
if (typeof event === "string")
|
|
169
|
+
output = event;
|
|
170
|
+
else if (Buffer.isBuffer(event))
|
|
171
|
+
output = event.toString("utf-8");
|
|
172
|
+
else if ((0, helper_1.isPlainObject)(event))
|
|
173
|
+
output = (_b = event.data) !== null && _b !== void 0 ? _b : null;
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const last = event[event.length - 1];
|
|
177
|
+
if (typeof last === "string")
|
|
178
|
+
output = last;
|
|
179
|
+
else if (Buffer.isBuffer(last))
|
|
180
|
+
output = last.toString("utf-8");
|
|
181
|
+
else if ((0, helper_1.isPlainObject)(last))
|
|
182
|
+
output = (_c = last.data) !== null && _c !== void 0 ? _c : null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
catch (_d) { }
|
|
186
|
+
lfTrace.event({
|
|
187
|
+
name: "sse:send",
|
|
188
|
+
input: null,
|
|
189
|
+
output,
|
|
190
|
+
metadata: { size: Buffer.byteLength(buf) },
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (_e) { }
|
|
195
|
+
return ok;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
end(msg) {
|
|
200
|
+
var _a, _b, _c, _d, _e, _f;
|
|
201
|
+
if (msg) {
|
|
202
|
+
this.send(msg);
|
|
203
|
+
}
|
|
204
|
+
this.stream.end();
|
|
205
|
+
this.ctx.res.end();
|
|
206
|
+
this.closed = true;
|
|
207
|
+
try {
|
|
208
|
+
const lfTrace = (_a = this.ctx.state) === null || _a === void 0 ? void 0 : _a.langfuseTrace;
|
|
209
|
+
const enabled = ((_d = (_c = (_b = this.ctx.state) === null || _b === void 0 ? void 0 : _b.frameworkOptions) === null || _c === void 0 ? void 0 : _c.redLangfuseConfig) === null || _d === void 0 ? void 0 : _d.enable) === true;
|
|
210
|
+
if (lfTrace) {
|
|
211
|
+
lfTrace.event({ name: "sse:end", input: null, output: null });
|
|
212
|
+
}
|
|
213
|
+
if (enabled && (langfuse_1.default === null || langfuse_1.default === void 0 ? void 0 : langfuse_1.default.shutdownAsync)) {
|
|
214
|
+
(_f = (_e = langfuse_1.default).shutdownAsync) === null || _f === void 0 ? void 0 : _f.call(_e);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
catch (_g) { }
|
|
218
|
+
}
|
|
219
|
+
get isClosed() {
|
|
220
|
+
return this.closed;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exports.ServerSentEvent = ServerSentEvent;
|
|
224
|
+
function eventToMsgs(event) {
|
|
225
|
+
const msgs = [];
|
|
226
|
+
if ("comment" in event) {
|
|
227
|
+
msgs.push(`: ${event.comment}\n`);
|
|
228
|
+
}
|
|
229
|
+
if ("event" in event) {
|
|
230
|
+
msgs.push(`event: ${event.event}\n`);
|
|
231
|
+
}
|
|
232
|
+
if ("id" in event) {
|
|
233
|
+
msgs.push(`id: ${event.id}\n`);
|
|
234
|
+
}
|
|
235
|
+
if ("retry" in event) {
|
|
236
|
+
msgs.push(`retry: ${event.retry}\n`);
|
|
237
|
+
}
|
|
238
|
+
if ("data" in event) {
|
|
239
|
+
msgs.push(toDataEventString(event.data));
|
|
240
|
+
}
|
|
241
|
+
if (msgs.length > 0) {
|
|
242
|
+
msgs.push("\n");
|
|
243
|
+
}
|
|
244
|
+
return msgs;
|
|
245
|
+
}
|
|
246
|
+
function toDataEventString(data) {
|
|
247
|
+
if (Buffer.isBuffer(data)) {
|
|
248
|
+
return Buffer.concat([Buffer.from("data: "), data, Buffer.from("\n")]);
|
|
249
|
+
}
|
|
250
|
+
if ((0, helper_1.isPlainObject)(data)) {
|
|
251
|
+
return toDataEventString(JSON.stringify(data));
|
|
252
|
+
}
|
|
253
|
+
const dataStr = typeof data !== "string" ? `${data}` : data;
|
|
254
|
+
return dataStr
|
|
255
|
+
.split(/[\r\n]+/)
|
|
256
|
+
.map((line) => `data: ${line}\n`)
|
|
257
|
+
.join("");
|
|
258
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.langfuse = void 0;
|
|
4
|
+
const langfuse_1 = require("langfuse");
|
|
5
|
+
const secretKey = process.env.LANGFUSE_SECRET_KEY;
|
|
6
|
+
const publicKey = process.env.LANGFUSE_PUBLIC_KEY;
|
|
7
|
+
const baseUrl = process.env.LANGFUSE_BASEURL;
|
|
8
|
+
exports.langfuse = new langfuse_1.Langfuse({
|
|
9
|
+
secretKey: "sk-lf-f389bb1e-24db-4b42-b506-8d6118f45044",
|
|
10
|
+
publicKey: "pk-lf-ee301553-7a64-4f0f-bf6b-a2ac1e5ca2df",
|
|
11
|
+
baseUrl: "https://xray-langfuse.devops.xiaohongshu.com",
|
|
12
|
+
});
|
|
13
|
+
exports.default = exports.langfuse;
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sendResponse = sendResponse;
|
|
4
|
+
const error_1 = require("./error");
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
function sendResponse(ctx, data, error, errStatusCode = 500, withStack = true) {
|
|
7
|
+
if (error) {
|
|
8
|
+
if (!ctx.response) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const errorStack = (0, error_1.decorateErrorStack)(error.cause);
|
|
12
|
+
logger_1.functionsLogger.log(logger_1.LogType.ACCESS, logger_1.LogLevel.ERROR, error.message, {
|
|
13
|
+
code: error.code,
|
|
14
|
+
stack: errorStack,
|
|
15
|
+
statusCode: errStatusCode,
|
|
16
|
+
});
|
|
17
|
+
console.error(`[ERROR] ${error.message}\n${errorStack}`);
|
|
18
|
+
ctx.status = errStatusCode;
|
|
19
|
+
if (withStack) {
|
|
20
|
+
data = {
|
|
21
|
+
code: error.code,
|
|
22
|
+
message: error.message,
|
|
23
|
+
stack: errorStack,
|
|
24
|
+
requestId: ctx.state.eventID,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
data = {
|
|
29
|
+
code: error.code,
|
|
30
|
+
message: error.message,
|
|
31
|
+
requestId: ctx.state.eventID,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (isIntegrationResponse(data)) {
|
|
36
|
+
return sendIntegrationResponse(ctx, data);
|
|
37
|
+
}
|
|
38
|
+
if (typeof data === "undefined" || data === null) {
|
|
39
|
+
ctx.status = 204;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
ctx.body = data;
|
|
43
|
+
}
|
|
44
|
+
const eResult = data;
|
|
45
|
+
if (eResult && eResult.code) {
|
|
46
|
+
ctx.state.errorResult = {
|
|
47
|
+
code: eResult.code,
|
|
48
|
+
message: eResult.message,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
function isIntegrationResponse(result) {
|
|
54
|
+
if (typeof result !== "object" || !result) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const { statusCode, headers } = result;
|
|
58
|
+
return typeof statusCode === "number" && typeof headers === "object";
|
|
59
|
+
}
|
|
60
|
+
function sendIntegrationResponse(ctx, result) {
|
|
61
|
+
ctx.set(result.headers);
|
|
62
|
+
ctx.body = result.body;
|
|
63
|
+
ctx.status = result.statusCode;
|
|
64
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.takeUserCodeLogs = takeUserCodeLogs;
|
|
4
|
+
exports.pushUserCodeLogs = pushUserCodeLogs;
|
|
5
|
+
exports.addUserCodeLog = addUserCodeLog;
|
|
6
|
+
exports.getUserCodeLogs = getUserCodeLogs;
|
|
7
|
+
const async_context_1 = require("./async-context");
|
|
8
|
+
const logger_1 = require("./logger");
|
|
9
|
+
const USER_CODE_LOGS_MAX_COUNT = 100;
|
|
10
|
+
const USER_CODE_LOGS_FLUSH_TIMER_TIMEOUT = 1000;
|
|
11
|
+
function lazyInitUserCodeLogs() {
|
|
12
|
+
const currentContext = (0, async_context_1.getCurrentAsyncContext)();
|
|
13
|
+
if (currentContext && currentContext.userCodeLogs === undefined) {
|
|
14
|
+
currentContext.userCodeLogs = [];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function takeUserCodeLogs() {
|
|
18
|
+
lazyInitUserCodeLogs();
|
|
19
|
+
const context = (0, async_context_1.getCurrentAsyncContext)();
|
|
20
|
+
if (context !== undefined) {
|
|
21
|
+
const logs = context.userCodeLogs || [];
|
|
22
|
+
context.userCodeLogs = [];
|
|
23
|
+
return logs;
|
|
24
|
+
}
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
function pushUserCodeLogs(log) {
|
|
28
|
+
lazyInitUserCodeLogs();
|
|
29
|
+
const context = (0, async_context_1.getCurrentAsyncContext)();
|
|
30
|
+
if (context === null || context === void 0 ? void 0 : context.userCodeLogs) {
|
|
31
|
+
context.userCodeLogs.push(log);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function addUserCodeLog(log) {
|
|
35
|
+
var _a;
|
|
36
|
+
lazyInitUserCodeLogs();
|
|
37
|
+
const userCodeLogs = ((_a = (0, async_context_1.getCurrentAsyncContext)()) === null || _a === void 0 ? void 0 : _a.userCodeLogs) || [];
|
|
38
|
+
if (userCodeLogs.length >= USER_CODE_LOGS_MAX_COUNT) {
|
|
39
|
+
logger_1.functionsLogger.logUserCodelog();
|
|
40
|
+
}
|
|
41
|
+
const currentContext = (0, async_context_1.getCurrentAsyncContext)();
|
|
42
|
+
if (currentContext && currentContext.done && !currentContext.userCodeLogsFlushTimer) {
|
|
43
|
+
currentContext.userCodeLogsFlushTimer = setTimeout(() => {
|
|
44
|
+
logger_1.functionsLogger.logUserCodelog();
|
|
45
|
+
currentContext.userCodeLogsFlushTimer = undefined;
|
|
46
|
+
}, USER_CODE_LOGS_FLUSH_TIMER_TIMEOUT);
|
|
47
|
+
}
|
|
48
|
+
pushUserCodeLogs(log);
|
|
49
|
+
}
|
|
50
|
+
function getUserCodeLogs() {
|
|
51
|
+
lazyInitUserCodeLogs();
|
|
52
|
+
const context = (0, async_context_1.getCurrentAsyncContext)();
|
|
53
|
+
return (context === null || context === void 0 ? void 0 : context.userCodeLogs) || [];
|
|
54
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defaultConfig = exports.APM_MEASUREMENT_NAME = void 0;
|
|
4
|
+
exports.APM_MEASUREMENT_NAME = "vectorx_kit_agent_runtime";
|
|
5
|
+
exports.defaultConfig = {
|
|
6
|
+
endpoint: "https://apm-fe.xiaohongshu.com/api/data",
|
|
7
|
+
};
|
package/lib/utils/apm.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.ApmReporter = void 0;
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
42
|
+
const uuid_1 = require("uuid");
|
|
43
|
+
const apm_config_1 = require("./apm.config");
|
|
44
|
+
const machineId_1 = require("./machineId");
|
|
45
|
+
class ApmReporter {
|
|
46
|
+
constructor() {
|
|
47
|
+
this.seq = 1;
|
|
48
|
+
this.reportQueue = [];
|
|
49
|
+
this.timer = null;
|
|
50
|
+
this.reportQueue = [];
|
|
51
|
+
this.apmContext = {
|
|
52
|
+
context_nameTracker: "nodeT",
|
|
53
|
+
context_platform: os.platform(),
|
|
54
|
+
context_appVersion: "unknown",
|
|
55
|
+
context_osVersion: os.release(),
|
|
56
|
+
context_userAgent: `Node/${process.version} ${os.platform()}/${os.release()} (${os.arch()})`,
|
|
57
|
+
context_artifactName: "xhsmpcloudbase",
|
|
58
|
+
context_deviceModel: "",
|
|
59
|
+
context_matchedPath: "",
|
|
60
|
+
context_deviceId: (0, machineId_1.machineIdSync)(true),
|
|
61
|
+
context_package: "",
|
|
62
|
+
context_networkType: "unknown",
|
|
63
|
+
context_networkQuality: "unknown",
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
getSequence() {
|
|
67
|
+
return {
|
|
68
|
+
context_sdkSeqId: this.seq++,
|
|
69
|
+
context_sdkSessionId: (0, uuid_1.v4)(),
|
|
70
|
+
context_pageSessionId: (0, uuid_1.v4)(),
|
|
71
|
+
clientTime: Date.now(),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
report(measurement_name, measurement_data = {}) {
|
|
75
|
+
const params = {
|
|
76
|
+
sequence: this.getSequence(),
|
|
77
|
+
measurement_name,
|
|
78
|
+
measurement_data,
|
|
79
|
+
};
|
|
80
|
+
if (!Array.isArray(this.reportQueue)) {
|
|
81
|
+
this.reportQueue = [];
|
|
82
|
+
}
|
|
83
|
+
this.reportQueue.push(params);
|
|
84
|
+
if (this.timer) {
|
|
85
|
+
clearTimeout(this.timer);
|
|
86
|
+
}
|
|
87
|
+
if (this.reportQueue.length >= 10) {
|
|
88
|
+
this.batchReport();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.timer = setTimeout(() => {
|
|
92
|
+
this.batchReport();
|
|
93
|
+
}, 200);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
batchReport() {
|
|
97
|
+
if (this.reportQueue.length === 0) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const queue = [...this.reportQueue];
|
|
101
|
+
this.reportQueue = [];
|
|
102
|
+
while (queue.length) {
|
|
103
|
+
this._request(queue.splice(0, 5));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
_request(params, retry = true) {
|
|
107
|
+
const list = Array.isArray(params) ? params : [params];
|
|
108
|
+
const merged = list.map((i) => {
|
|
109
|
+
return Object.assign(Object.assign(Object.assign({}, this.apmContext), i.sequence), { measurement_name: i.measurement_name, measurement_data: Object.assign({}, i.measurement_data) });
|
|
110
|
+
});
|
|
111
|
+
return (0, node_fetch_1.default)(apm_config_1.defaultConfig.endpoint, {
|
|
112
|
+
method: "post",
|
|
113
|
+
body: JSON.stringify(merged),
|
|
114
|
+
headers: {
|
|
115
|
+
accept: "*/*",
|
|
116
|
+
"accept-language": "zh-CN,zh;q=0.9",
|
|
117
|
+
batch: "true",
|
|
118
|
+
"biz-type": "apm_fe",
|
|
119
|
+
"cache-control": "no-cache",
|
|
120
|
+
"content-type": "application/json",
|
|
121
|
+
pragma: "no-cache",
|
|
122
|
+
},
|
|
123
|
+
})
|
|
124
|
+
.then((res) => res.json())
|
|
125
|
+
.then((res) => {
|
|
126
|
+
if (res === null || res === void 0 ? void 0 : res.success) {
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
throw new Error((res === null || res === void 0 ? void 0 : res.msg) || "APM request failed");
|
|
130
|
+
}
|
|
131
|
+
})
|
|
132
|
+
.catch((err) => {
|
|
133
|
+
if (retry) {
|
|
134
|
+
setTimeout(() => this._request(params, false), 1000);
|
|
135
|
+
}
|
|
136
|
+
process.stdout.write(`[⚡️] apm send failed: ${(err === null || err === void 0 ? void 0 : err.message) || null}`);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
exports.ApmReporter = ApmReporter;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Interceptor = void 0;
|
|
4
|
+
const console_1 = require("console");
|
|
5
|
+
const stream_1 = require("stream");
|
|
6
|
+
const util_1 = require("util");
|
|
7
|
+
const async_context_1 = require("../async-context");
|
|
8
|
+
const user_logger_1 = require("../user-logger");
|
|
9
|
+
const error_stack_1 = require("./error-stack");
|
|
10
|
+
const consoleMethods = ["debug", "info", "log", "trace", "warn", "error"];
|
|
11
|
+
class EmptyWritableStream extends stream_1.Writable {
|
|
12
|
+
_write(_chunk, _encoding, callback) {
|
|
13
|
+
callback();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const emptyWritableStream = new EmptyWritableStream();
|
|
17
|
+
class Interceptor {
|
|
18
|
+
constructor() { }
|
|
19
|
+
static intercept() {
|
|
20
|
+
Interceptor.interceptConsole();
|
|
21
|
+
}
|
|
22
|
+
static interceptConsole() {
|
|
23
|
+
function callAddUserCodeLog(level, message, ...optionalParams) {
|
|
24
|
+
if ((0, async_context_1.isInFrameworkAsyncContext)()) {
|
|
25
|
+
const log = {
|
|
26
|
+
"@timestamp": new Date().toISOString(),
|
|
27
|
+
caller: (0, error_stack_1.getCaller)(callAddUserCodeLog),
|
|
28
|
+
level: level,
|
|
29
|
+
content: (0, error_stack_1.truncateContent)((0, util_1.formatWithOptions)({ colors: false }, message, ...optionalParams)),
|
|
30
|
+
};
|
|
31
|
+
(0, user_logger_1.addUserCodeLog)(log);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const anotherConsole = new console_1.Console({
|
|
35
|
+
stdout: emptyWritableStream,
|
|
36
|
+
stderr: emptyWritableStream,
|
|
37
|
+
colorMode: false,
|
|
38
|
+
groupIndentation: 2,
|
|
39
|
+
inspectOptions: {},
|
|
40
|
+
});
|
|
41
|
+
const originalConsole = global.console;
|
|
42
|
+
for (const method of consoleMethods) {
|
|
43
|
+
anotherConsole[method] = (message, ...optionalParams) => {
|
|
44
|
+
if ((0, async_context_1.isInFrameworkAsyncContext)()) {
|
|
45
|
+
callAddUserCodeLog(method, message, ...optionalParams);
|
|
46
|
+
process.stdout.write((0, util_1.formatWithOptions)({ colors: false }, message, ...optionalParams));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
originalConsole[method](message, ...optionalParams);
|
|
50
|
+
process.stdout.write((0, util_1.formatWithOptions)({ colors: false }, message, ...optionalParams));
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
global.originalConsole = global.console;
|
|
55
|
+
global.console = anotherConsole;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.Interceptor = Interceptor;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCaller = getCaller;
|
|
4
|
+
exports.formatCallSite = formatCallSite;
|
|
5
|
+
exports.getStackTraces = getStackTraces;
|
|
6
|
+
exports.truncateContent = truncateContent;
|
|
7
|
+
const USER_CODE_LOGS_MAX_CONTENT_LENGTH = 1000;
|
|
8
|
+
function getCaller(belowFn = null, index = 1) {
|
|
9
|
+
const stackTraces = getStackTraces(belowFn);
|
|
10
|
+
return formatCallSite(stackTraces[index]);
|
|
11
|
+
}
|
|
12
|
+
function formatCallSite(stackTrace) {
|
|
13
|
+
return `at ${stackTrace.getFunctionName() || "<anonymous>"} (${stackTrace.getFileName()}:${stackTrace.getLineNumber()}:${stackTrace.getColumnNumber()})`;
|
|
14
|
+
}
|
|
15
|
+
function getStackTraces(belowFn = null) {
|
|
16
|
+
const originalPrepareStackTrace = Error.prepareStackTrace;
|
|
17
|
+
Error.prepareStackTrace = (dummyObject, stackTraces) => stackTraces;
|
|
18
|
+
const dummyObject = { stack: [] };
|
|
19
|
+
Error.captureStackTrace(dummyObject, belowFn || getStackTraces);
|
|
20
|
+
const stackTraces = dummyObject.stack;
|
|
21
|
+
Error.prepareStackTrace = originalPrepareStackTrace;
|
|
22
|
+
return stackTraces;
|
|
23
|
+
}
|
|
24
|
+
function truncateContent(content) {
|
|
25
|
+
if (content.length > USER_CODE_LOGS_MAX_CONTENT_LENGTH) {
|
|
26
|
+
return (content.slice(0, USER_CODE_LOGS_MAX_CONTENT_LENGTH) +
|
|
27
|
+
`... ${content.length - USER_CODE_LOGS_MAX_CONTENT_LENGTH} more characters`);
|
|
28
|
+
}
|
|
29
|
+
return content;
|
|
30
|
+
}
|