@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
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildFnId = buildFnId;
|
|
4
|
+
exports.registerFunction = registerFunction;
|
|
5
|
+
exports.getRegisteredFunction = getRegisteredFunction;
|
|
6
|
+
exports.clearRegistry = clearRegistry;
|
|
7
|
+
const functionRegistry = new Map();
|
|
8
|
+
function buildFnId(fnName, functionName) {
|
|
9
|
+
return `${fnName}:${functionName}`;
|
|
10
|
+
}
|
|
11
|
+
function registerFunction(fnName, fn) {
|
|
12
|
+
const fnId = buildFnId("@fn", fnName);
|
|
13
|
+
functionRegistry.set(fnId, fn);
|
|
14
|
+
}
|
|
15
|
+
function getRegisteredFunction(fnId) {
|
|
16
|
+
return functionRegistry.get(fnId);
|
|
17
|
+
}
|
|
18
|
+
function clearRegistry() {
|
|
19
|
+
functionRegistry.clear();
|
|
20
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.wrapHandlerFunction = wrapHandlerFunction;
|
|
46
|
+
const config_1 = require("./config");
|
|
47
|
+
const error_1 = require("./error");
|
|
48
|
+
const logger_1 = require("./logger");
|
|
49
|
+
const request_1 = require("./request");
|
|
50
|
+
const sse_1 = require("./sse");
|
|
51
|
+
const unified_responder_1 = require("./unified-responder");
|
|
52
|
+
const helper_1 = require("./utils/helper");
|
|
53
|
+
const wrapEventFunction = (execute, projectConfig) => {
|
|
54
|
+
return (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
55
|
+
var _a;
|
|
56
|
+
let event;
|
|
57
|
+
if (ctx.request.files) {
|
|
58
|
+
const filesWithBuffer = {};
|
|
59
|
+
const fs = yield Promise.resolve().then(() => __importStar(require("fs")));
|
|
60
|
+
for (const [key, fileOrFiles] of Object.entries(ctx.request.files)) {
|
|
61
|
+
const files = Array.isArray(fileOrFiles) ? fileOrFiles : [fileOrFiles];
|
|
62
|
+
const processedFiles = yield Promise.all(files.map((file) => __awaiter(void 0, void 0, void 0, function* () {
|
|
63
|
+
if (file && typeof file === "object" && (file.filepath || file.path)) {
|
|
64
|
+
const filePath = file.filepath || file.path;
|
|
65
|
+
try {
|
|
66
|
+
const buffer = fs.readFileSync(filePath);
|
|
67
|
+
try {
|
|
68
|
+
fs.unlinkSync(filePath);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
}
|
|
72
|
+
return Object.assign(Object.assign({}, file), { buffer });
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
return file;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return file;
|
|
79
|
+
})));
|
|
80
|
+
filesWithBuffer[key] = Array.isArray(fileOrFiles) ? processedFiles : processedFiles[0];
|
|
81
|
+
}
|
|
82
|
+
event = Object.assign(Object.assign({}, filesWithBuffer), ctx.request.body);
|
|
83
|
+
}
|
|
84
|
+
else if (ctx.request.body) {
|
|
85
|
+
event = ctx.request.body;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
event = ctx.rawBody;
|
|
89
|
+
}
|
|
90
|
+
let executeDone = false;
|
|
91
|
+
let hasSwitchSSEMode = false;
|
|
92
|
+
const context = {
|
|
93
|
+
ctxId: ctx.state.eventID,
|
|
94
|
+
eventID: ctx.state.eventID,
|
|
95
|
+
eventType: ctx.state.eventType,
|
|
96
|
+
timestamp: ctx.state.timestamp,
|
|
97
|
+
httpContext: ctx.httpContext,
|
|
98
|
+
baseUrl: (0, config_1.getBaseUrl)(),
|
|
99
|
+
request: new request_1.Request({
|
|
100
|
+
timeout: 30000,
|
|
101
|
+
timeoutMsg: "请求超时",
|
|
102
|
+
restrictedMethods: ["get", "post", "upload", "download"],
|
|
103
|
+
defaultHeaders: {
|
|
104
|
+
"agent-id": projectConfig.agentId,
|
|
105
|
+
"open-id": ctx.request.headers["open-id"],
|
|
106
|
+
"x-open-agent-trace-id": ctx.state.eventID,
|
|
107
|
+
},
|
|
108
|
+
}),
|
|
109
|
+
logger: logger_1.functionsLogger,
|
|
110
|
+
sse: () => {
|
|
111
|
+
var _a;
|
|
112
|
+
const sseInstance = (_a = ctx.sse) === null || _a === void 0 ? void 0 : _a.call(ctx);
|
|
113
|
+
if (sseInstance) {
|
|
114
|
+
return sseInstance;
|
|
115
|
+
}
|
|
116
|
+
if (ctx.res.headersSent || executeDone) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
hasSwitchSSEMode = true;
|
|
120
|
+
const sse = new sse_1.ServerSentEvent(ctx);
|
|
121
|
+
ctx.sse = () => sse;
|
|
122
|
+
return sse;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
const contextToFreeze = {
|
|
126
|
+
ctxId: context.ctxId,
|
|
127
|
+
eventID: context.eventID,
|
|
128
|
+
eventType: context.eventType,
|
|
129
|
+
timestamp: context.timestamp,
|
|
130
|
+
httpContext: context.httpContext,
|
|
131
|
+
baseUrl: context.baseUrl,
|
|
132
|
+
request: context.request,
|
|
133
|
+
};
|
|
134
|
+
(0, helper_1.deepFreeze)(contextToFreeze);
|
|
135
|
+
const frozenContext = Object.assign(Object.assign({}, contextToFreeze), { logger: context.logger, sse: context.sse });
|
|
136
|
+
ctx.state.event = event;
|
|
137
|
+
ctx.state.contextInjected = frozenContext;
|
|
138
|
+
let result;
|
|
139
|
+
try {
|
|
140
|
+
result = yield execute(event, context);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
console.log("============>>>>>>>>>> function wrapper error ", e);
|
|
144
|
+
ctx.state.error = e;
|
|
145
|
+
if (hasSwitchSSEMode) {
|
|
146
|
+
const sse = (_a = ctx.sse) === null || _a === void 0 ? void 0 : _a.call(ctx);
|
|
147
|
+
if (sse && !sse.isClosed) {
|
|
148
|
+
const errorEvent = {
|
|
149
|
+
event: "error",
|
|
150
|
+
data: e.message,
|
|
151
|
+
comment: "uncaught-exception-from-user-code",
|
|
152
|
+
};
|
|
153
|
+
console.log("============>>>>>>>>>> errorEvent ", errorEvent);
|
|
154
|
+
sse.emit("error", errorEvent);
|
|
155
|
+
console.log("============>>>>>>>>>> sse.end(errorEvent) ");
|
|
156
|
+
sse.end(errorEvent);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
executeDone = true;
|
|
161
|
+
if (hasSwitchSSEMode) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const e = ctx.state.error ? (0, error_1.newSysErr)(ctx.state.error) : null;
|
|
165
|
+
return (0, unified_responder_1.sendResponse)(ctx, result, e);
|
|
166
|
+
});
|
|
167
|
+
};
|
|
168
|
+
function wrapHandlerFunction(userFunction, projectConfig) {
|
|
169
|
+
return wrapEventFunction(userFunction, projectConfig);
|
|
170
|
+
}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./framework"), exports);
|
|
18
|
+
__exportStar(require("./router"), exports);
|
|
19
|
+
__exportStar(require("./function-loader"), exports);
|
|
20
|
+
__exportStar(require("./function-registry"), exports);
|
|
21
|
+
__exportStar(require("./sse"), exports);
|
|
22
|
+
__exportStar(require("./server"), exports);
|
|
23
|
+
__exportStar(require("./logger"), exports);
|
package/lib/logger.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.functionsLogger = exports.LogLevel = exports.LogType = void 0;
|
|
16
|
+
const fs_1 = __importDefault(require("fs"));
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const winston_1 = __importDefault(require("winston"));
|
|
19
|
+
const winston_daily_rotate_file_1 = __importDefault(require("winston-daily-rotate-file"));
|
|
20
|
+
const async_context_1 = require("./async-context");
|
|
21
|
+
const user_logger_1 = require("./user-logger");
|
|
22
|
+
const apm_config_1 = require("./utils/apm.config");
|
|
23
|
+
var LogType;
|
|
24
|
+
(function (LogType) {
|
|
25
|
+
LogType["ACCESS"] = "ACCESS";
|
|
26
|
+
LogType["USERCODE"] = "USERCODE";
|
|
27
|
+
})(LogType || (exports.LogType = LogType = {}));
|
|
28
|
+
var LogLevel;
|
|
29
|
+
(function (LogLevel) {
|
|
30
|
+
LogLevel["ERROR"] = "error";
|
|
31
|
+
LogLevel["WARN"] = "warn";
|
|
32
|
+
LogLevel["INFO"] = "info";
|
|
33
|
+
LogLevel["DEBUG"] = "debug";
|
|
34
|
+
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
35
|
+
const DEFAULT_LOG_DIRNAME = path_1.default.join(process.cwd(), "logs");
|
|
36
|
+
const DEFAULT_MAX_LOG_FILE_SIZE = "10m";
|
|
37
|
+
const DEFAULT_MAX_LOG_FILES = 7;
|
|
38
|
+
class FunctionsLogger {
|
|
39
|
+
constructor() {
|
|
40
|
+
this.tLoggers = new Map();
|
|
41
|
+
}
|
|
42
|
+
setApmReporter(reporter) {
|
|
43
|
+
this.apmReporter = reporter;
|
|
44
|
+
}
|
|
45
|
+
init(opts) {
|
|
46
|
+
if (!fs_1.default.existsSync(DEFAULT_LOG_DIRNAME)) {
|
|
47
|
+
fs_1.default.mkdirSync(DEFAULT_LOG_DIRNAME, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
opts.forEach(({ type, options }) => {
|
|
50
|
+
this.tLoggers.set(type, this.createWinstonLogger({
|
|
51
|
+
filename: type,
|
|
52
|
+
dirname: options.dirname || DEFAULT_LOG_DIRNAME,
|
|
53
|
+
maxSize: options.maxSize || DEFAULT_MAX_LOG_FILE_SIZE,
|
|
54
|
+
maxFiles: options.maxFiles || DEFAULT_MAX_LOG_FILES,
|
|
55
|
+
}));
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
formatLogMessage(level, message, metadata) {
|
|
59
|
+
const eventId = (0, async_context_1.getCurrentEventID)();
|
|
60
|
+
const logEntry = Object.assign({ "@timestamp": new Date().toISOString(), level,
|
|
61
|
+
eventId,
|
|
62
|
+
message }, metadata);
|
|
63
|
+
return JSON.stringify(logEntry);
|
|
64
|
+
}
|
|
65
|
+
logAccesslog(level, message, metadata) {
|
|
66
|
+
this.log(LogType.ACCESS, level, message, metadata);
|
|
67
|
+
const asyncContext = (0, async_context_1.getCurrentAsyncContext)();
|
|
68
|
+
const eventId = (asyncContext === null || asyncContext === void 0 ? void 0 : asyncContext.eventID) || "";
|
|
69
|
+
if (this.apmReporter && (asyncContext === null || asyncContext === void 0 ? void 0 : asyncContext.apmMeasurementData)) {
|
|
70
|
+
const measurementData = Object.assign({}, asyncContext.apmMeasurementData);
|
|
71
|
+
this.apmReporter.report(apm_config_1.APM_MEASUREMENT_NAME, Object.assign(Object.assign({}, measurementData), { kit_runtime_event_type: LogType.ACCESS, kit_runtime_event_id: eventId, kit_runtime_event_data: message, kit_event_extInfo: {} }));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
logUserCodelog() {
|
|
75
|
+
const logs = (0, user_logger_1.takeUserCodeLogs)();
|
|
76
|
+
if (logs.length > 0) {
|
|
77
|
+
const now = new Date().toISOString();
|
|
78
|
+
const asyncContext = (0, async_context_1.getCurrentAsyncContext)();
|
|
79
|
+
const eventId = (asyncContext === null || asyncContext === void 0 ? void 0 : asyncContext.eventID) || "";
|
|
80
|
+
const userCodeLog = {
|
|
81
|
+
"@timestamp": now,
|
|
82
|
+
level: "info",
|
|
83
|
+
module: "@vectorx/functions-framework",
|
|
84
|
+
name: "",
|
|
85
|
+
logType: LogType.USERCODE,
|
|
86
|
+
eventId: eventId,
|
|
87
|
+
requestId: eventId,
|
|
88
|
+
scene: (asyncContext === null || asyncContext === void 0 ? void 0 : asyncContext.done) ? "logAfterReturn" : "logBeforeReturn",
|
|
89
|
+
logs: logs,
|
|
90
|
+
};
|
|
91
|
+
const logDetail = JSON.stringify(userCodeLog);
|
|
92
|
+
this.log(LogType.USERCODE, LogLevel.INFO, logDetail);
|
|
93
|
+
if (this.apmReporter && (asyncContext === null || asyncContext === void 0 ? void 0 : asyncContext.apmMeasurementData)) {
|
|
94
|
+
const measurementData = Object.assign({}, asyncContext.apmMeasurementData);
|
|
95
|
+
this.apmReporter.report(apm_config_1.APM_MEASUREMENT_NAME, Object.assign(Object.assign({}, measurementData), { kit_runtime_event_type: LogType.USERCODE, kit_runtime_event_id: eventId, kit_runtime_event_data: logDetail }));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
log(type, level, message, metadata) {
|
|
100
|
+
var _a;
|
|
101
|
+
const formattedMessage = this.formatLogMessage(level, message, metadata);
|
|
102
|
+
(_a = this.tLoggers.get(type)) === null || _a === void 0 ? void 0 : _a.log(level, formattedMessage);
|
|
103
|
+
}
|
|
104
|
+
getLogs(type_1) {
|
|
105
|
+
return __awaiter(this, arguments, void 0, function* (type, limit = 100) {
|
|
106
|
+
const logs = [];
|
|
107
|
+
const logDir = DEFAULT_LOG_DIRNAME;
|
|
108
|
+
const files = fs_1.default
|
|
109
|
+
.readdirSync(logDir)
|
|
110
|
+
.filter((file) => file.startsWith(type) && file.endsWith(".log"))
|
|
111
|
+
.sort()
|
|
112
|
+
.reverse();
|
|
113
|
+
let index = 0;
|
|
114
|
+
for (const file of files) {
|
|
115
|
+
const content = fs_1.default.readFileSync(path_1.default.join(logDir, file), "utf-8");
|
|
116
|
+
const lines = content.split("\n").filter(Boolean);
|
|
117
|
+
for (const line of lines) {
|
|
118
|
+
try {
|
|
119
|
+
const log = JSON.parse(line);
|
|
120
|
+
log.id = index++;
|
|
121
|
+
logs.push(log);
|
|
122
|
+
if (logs.length >= limit) {
|
|
123
|
+
return logs;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (e) {
|
|
127
|
+
console.error("Failed to parse log line:", line);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return logs;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
getLogsPaginated(options) {
|
|
135
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
+
const { type, pageNum = 1, pageSize = 50 } = options;
|
|
137
|
+
const allLogs = yield this.getAllLogs(type);
|
|
138
|
+
const total = allLogs.length;
|
|
139
|
+
const offset = (pageNum - 1) * pageSize;
|
|
140
|
+
const logs = allLogs.slice(offset, offset + pageSize);
|
|
141
|
+
const hasMore = pageNum * pageSize < total;
|
|
142
|
+
return {
|
|
143
|
+
logs,
|
|
144
|
+
pageNum,
|
|
145
|
+
pageSize: logs.length,
|
|
146
|
+
total,
|
|
147
|
+
hasMore,
|
|
148
|
+
};
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
getAllLogs(type) {
|
|
152
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
153
|
+
const logs = [];
|
|
154
|
+
const logDir = DEFAULT_LOG_DIRNAME;
|
|
155
|
+
const files = fs_1.default
|
|
156
|
+
.readdirSync(logDir)
|
|
157
|
+
.filter((file) => file.startsWith(type) && file.endsWith(".log"))
|
|
158
|
+
.sort()
|
|
159
|
+
.reverse();
|
|
160
|
+
let globalId = 0;
|
|
161
|
+
for (const file of files) {
|
|
162
|
+
const content = fs_1.default.readFileSync(path_1.default.join(logDir, file), "utf-8");
|
|
163
|
+
const lines = content.split("\n").filter(Boolean).reverse();
|
|
164
|
+
for (const line of lines) {
|
|
165
|
+
try {
|
|
166
|
+
const log = JSON.parse(line);
|
|
167
|
+
log.id = globalId++;
|
|
168
|
+
logs.push(log);
|
|
169
|
+
}
|
|
170
|
+
catch (e) {
|
|
171
|
+
console.error("Failed to parse log line:", line);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return logs;
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
createWinstonLogger(options) {
|
|
179
|
+
const transports = [
|
|
180
|
+
new winston_daily_rotate_file_1.default({
|
|
181
|
+
dirname: options.dirname,
|
|
182
|
+
datePattern: "YYYY-MM-DD-HH-mm",
|
|
183
|
+
frequency: "720m",
|
|
184
|
+
filename: options.filename,
|
|
185
|
+
extension: ".log",
|
|
186
|
+
auditFile: path_1.default.join(options.dirname, `${options.filename}.audit.json`),
|
|
187
|
+
maxSize: options.maxSize,
|
|
188
|
+
maxFiles: options.maxFiles,
|
|
189
|
+
}),
|
|
190
|
+
];
|
|
191
|
+
return winston_1.default.createLogger({
|
|
192
|
+
exitOnError: false,
|
|
193
|
+
level: "info",
|
|
194
|
+
transports,
|
|
195
|
+
format: winston_1.default.format.printf(({ message }) => message),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
logError(error, metadata) {
|
|
199
|
+
const errorMessage = error instanceof Error ? error.message : error;
|
|
200
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
201
|
+
this.log(LogType.ACCESS, LogLevel.ERROR, errorMessage, Object.assign(Object.assign({}, metadata), { stack: errorStack, timestamp: new Date().toISOString() }));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.functionsLogger = new FunctionsLogger();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.apmMiddleware = exports.openGwRequestMiddleware = exports.logsQueryMiddleware = exports.loggerMiddleware = exports.functionRouteMiddleware = exports.eventIdMiddleware = exports.contextInjectionMiddleware = exports.asyncContextMiddleware = void 0;
|
|
4
|
+
var middle_async_context_1 = require("./middle-async-context");
|
|
5
|
+
Object.defineProperty(exports, "asyncContextMiddleware", { enumerable: true, get: function () { return middle_async_context_1.asyncContextMiddleware; } });
|
|
6
|
+
var middle_context_injection_1 = require("./middle-context-injection");
|
|
7
|
+
Object.defineProperty(exports, "contextInjectionMiddleware", { enumerable: true, get: function () { return middle_context_injection_1.contextInjectionMiddleware; } });
|
|
8
|
+
var middle_event_id_1 = require("./middle-event-id");
|
|
9
|
+
Object.defineProperty(exports, "eventIdMiddleware", { enumerable: true, get: function () { return middle_event_id_1.eventIdMiddleware; } });
|
|
10
|
+
var middle_function_route_1 = require("./middle-function-route");
|
|
11
|
+
Object.defineProperty(exports, "functionRouteMiddleware", { enumerable: true, get: function () { return middle_function_route_1.functionRouteMiddleware; } });
|
|
12
|
+
var middle_common_logger_1 = require("./middle-common-logger");
|
|
13
|
+
Object.defineProperty(exports, "loggerMiddleware", { enumerable: true, get: function () { return middle_common_logger_1.loggerMiddleware; } });
|
|
14
|
+
var middle_logs_request_1 = require("./middle-logs-request");
|
|
15
|
+
Object.defineProperty(exports, "logsQueryMiddleware", { enumerable: true, get: function () { return middle_logs_request_1.logsQueryMiddleware; } });
|
|
16
|
+
var middle_open_gw_request_1 = require("./middle-open-gw-request");
|
|
17
|
+
Object.defineProperty(exports, "openGwRequestMiddleware", { enumerable: true, get: function () { return middle_open_gw_request_1.openGwRequestMiddleware; } });
|
|
18
|
+
var middle_apm_injection_1 = require("./middle-apm-injection");
|
|
19
|
+
Object.defineProperty(exports, "apmMiddleware", { enumerable: true, get: function () { return middle_apm_injection_1.apmMiddleware; } });
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.apmMiddleware = apmMiddleware;
|
|
13
|
+
const async_context_1 = require("../async-context");
|
|
14
|
+
const common_1 = require("../utils/common");
|
|
15
|
+
function apmMiddleware() {
|
|
16
|
+
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
var _a;
|
|
18
|
+
if (common_1.AGENT_HEALTH_REG.test(ctx.path)) {
|
|
19
|
+
return yield next();
|
|
20
|
+
}
|
|
21
|
+
const agentInfo = ctx.state.agentInfo || {};
|
|
22
|
+
const kitInfo = ((_a = ctx.state.frameworkOptions) === null || _a === void 0 ? void 0 : _a.kitInfo) || {};
|
|
23
|
+
const env = process.env.OPEN_PLATFORM_STAGE === "production" ? 0 : 1;
|
|
24
|
+
const baseMeasurementData = {
|
|
25
|
+
kit_agent_desc: agentInfo.desc,
|
|
26
|
+
kit_agent_id: agentInfo.agentId,
|
|
27
|
+
kit_agent_version: agentInfo.version,
|
|
28
|
+
context_artifactVersion: kitInfo.agentRuntimeVersion,
|
|
29
|
+
kit_agent_runtime_version: kitInfo.agentRuntimeVersion,
|
|
30
|
+
kit_function_framework_version: kitInfo.functionsFrameworkVersion,
|
|
31
|
+
kit_cloud_env: env,
|
|
32
|
+
kit_runtime_event_id: (0, async_context_1.getCurrentEventID)(),
|
|
33
|
+
};
|
|
34
|
+
ctx.state.apmMeasurementData = baseMeasurementData;
|
|
35
|
+
yield next();
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.asyncContextMiddleware = void 0;
|
|
13
|
+
const async_context_1 = require("../async-context");
|
|
14
|
+
const asyncContextMiddleware = () => {
|
|
15
|
+
return (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
const executionContext = (0, async_context_1.newExecutionContext)(ctx.state.eventID, ctx.state.apmMeasurementData);
|
|
17
|
+
yield (0, async_context_1.wrapWithAsyncContext)(executionContext, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
18
|
+
try {
|
|
19
|
+
yield next();
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
(0, async_context_1.done)();
|
|
23
|
+
}
|
|
24
|
+
}));
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
exports.asyncContextMiddleware = asyncContextMiddleware;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.loggerMiddleware = loggerMiddleware;
|
|
16
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
17
|
+
const async_context_1 = require("../async-context");
|
|
18
|
+
const logger_1 = require("../logger");
|
|
19
|
+
const common_1 = require("../utils/common");
|
|
20
|
+
function loggerMiddleware() {
|
|
21
|
+
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
const startTime = Date.now();
|
|
23
|
+
const eventId = (0, async_context_1.getCurrentEventID)();
|
|
24
|
+
if (ctx.path.match(common_1.AGENT_HEALTH_REG)) {
|
|
25
|
+
yield next();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
process.stdout.write(chalk_1.default.greenBright(`▶️ ${chalk_1.default.gray(`[${new Date().toLocaleString()} - ${ctx.method}:${eventId}]`)} ${ctx.url}`));
|
|
29
|
+
try {
|
|
30
|
+
const accessLog = {
|
|
31
|
+
type: "HTTP_ACCESS",
|
|
32
|
+
scene: "SERVER_REQUEST_START",
|
|
33
|
+
method: ctx.method,
|
|
34
|
+
url: ctx.url,
|
|
35
|
+
headers: ctx.headers,
|
|
36
|
+
data: ctx.request.body,
|
|
37
|
+
eventId,
|
|
38
|
+
ip: ctx.ip,
|
|
39
|
+
userAgent: ctx.headers["user-agent"],
|
|
40
|
+
};
|
|
41
|
+
logger_1.functionsLogger.logAccesslog(logger_1.LogLevel.INFO, JSON.stringify(accessLog));
|
|
42
|
+
yield next();
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
const endTime = Date.now();
|
|
46
|
+
const duration = endTime - startTime;
|
|
47
|
+
const accessLog = {
|
|
48
|
+
type: "HTTP_ACCESS",
|
|
49
|
+
method: ctx.method,
|
|
50
|
+
scene: "SERVER_REQUEST_END",
|
|
51
|
+
url: ctx.url,
|
|
52
|
+
status: ctx.status,
|
|
53
|
+
duration: `${duration}ms`,
|
|
54
|
+
headers: ctx.headers,
|
|
55
|
+
data: ctx.request.body,
|
|
56
|
+
response: ctx.response,
|
|
57
|
+
eventId,
|
|
58
|
+
ip: ctx.ip,
|
|
59
|
+
userAgent: ctx.headers["user-agent"],
|
|
60
|
+
};
|
|
61
|
+
logger_1.functionsLogger.logAccesslog(logger_1.LogLevel.INFO, JSON.stringify(accessLog));
|
|
62
|
+
logger_1.functionsLogger.logUserCodelog();
|
|
63
|
+
process.stdout.write(chalk_1.default.greenBright(`▶️ ${chalk_1.default.gray(`[${new Date().toLocaleString()} - ${eventId.slice(0, -10)}]`)} - ${duration}ms\n`));
|
|
64
|
+
process.stdout.write(chalk_1.default.greenBright(`\n`));
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.contextInjectionMiddleware = contextInjectionMiddleware;
|
|
13
|
+
function contextInjectionMiddleware(frameworkOptions, projectConfig) {
|
|
14
|
+
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
|
|
15
|
+
if (!ctx.state) {
|
|
16
|
+
ctx.state = {};
|
|
17
|
+
}
|
|
18
|
+
ctx.state.eventType = "http";
|
|
19
|
+
ctx.state.timestamp = new Date().toISOString();
|
|
20
|
+
ctx.state.frameworkOptions = frameworkOptions;
|
|
21
|
+
ctx.httpContext = {
|
|
22
|
+
url: ctx.URL.toString(),
|
|
23
|
+
httpMethod: ctx.method,
|
|
24
|
+
headers: Object.assign({}, ctx.headers),
|
|
25
|
+
};
|
|
26
|
+
ctx.state.agentInfo = {
|
|
27
|
+
agentId: projectConfig.agentId,
|
|
28
|
+
version: projectConfig.version || "",
|
|
29
|
+
desc: projectConfig.desc || "",
|
|
30
|
+
};
|
|
31
|
+
yield next();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.eventIdMiddleware = void 0;
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
const eventIdMiddleware = () => {
|
|
15
|
+
return (ctx, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
16
|
+
ctx.state.eventID = ctx.headers["x-open-agent-trace-id"] || `event-${(0, uuid_1.v4)()}`;
|
|
17
|
+
yield next();
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
exports.eventIdMiddleware = eventIdMiddleware;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.functionRouteMiddleware = functionRouteMiddleware;
|
|
13
|
+
const function_wrapper_1 = require("../function-wrapper");
|
|
14
|
+
const router_1 = require("../router");
|
|
15
|
+
function functionRouteMiddleware(router, projectConfig) {
|
|
16
|
+
return (ctx, next) => __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
const { routeDefinition, handleFunction } = (0, router_1.routeFunction)(router, ctx.path);
|
|
18
|
+
if (routeDefinition) {
|
|
19
|
+
ctx.state.matchedRoute = routeDefinition;
|
|
20
|
+
}
|
|
21
|
+
if (handleFunction) {
|
|
22
|
+
return yield (0, function_wrapper_1.wrapHandlerFunction)(handleFunction, projectConfig)(ctx, next);
|
|
23
|
+
}
|
|
24
|
+
return next();
|
|
25
|
+
});
|
|
26
|
+
}
|