@geek-fun/serverlessinsight
Version:
Full life cycle cross providers serverless application management for your fast-growing business.
146 lines (145 loc) • 6.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateRequestId = exports.logApiGatewayRequest = exports.transformFCResponse = exports.addFCHeaders = exports.createAliyunContext = exports.createAliyunContextSerializable = exports.transformToAliyunEvent = void 0;
const crypto_1 = require("crypto");
const common_1 = require("../../common");
const createFCLogger = (requestId) => {
const formatLog = (level, message) => {
const timestamp = new Date().toISOString();
console.log(`${timestamp} ${requestId} [${level}] ${message}`);
};
return {
debug: (message) => formatLog('DEBUG', message),
info: (message) => formatLog('INFO', message),
warn: (message) => formatLog('WARNING', message),
error: (message) => formatLog('ERROR', message),
log: (message) => formatLog('INFO', message),
};
};
const transformToAliyunEvent = async (req, url, query) => {
const rawBody = await (0, common_1.readRequestBody)(req);
const pathParameters = {};
const event = {
path: url,
httpMethod: req.method || 'GET',
headers: req.headers,
queryParameters: query,
pathParameters,
body: rawBody || undefined,
isBase64Encoded: false,
};
const eventBuffer = Buffer.from(JSON.stringify(event));
return { event: eventBuffer, headers: req.headers };
};
exports.transformToAliyunEvent = transformToAliyunEvent;
const createAliyunContextSerializable = (iac, functionName, handler, memory, timeout, requestId) => {
return {
requestId,
region: iac.provider.region || 'cn-hangzhou',
accountId: process.env.ALIYUN_ACCOUNT_ID || '000000000000',
credentials: {
accessKeyId: process.env.ALIYUN_ACCESS_KEY_ID || 'mock-access-key-id',
accessKeySecret: process.env.ALIYUN_ACCESS_KEY_SECRET || 'mock-access-key-secret',
securityToken: process.env.ALIYUN_SECURITY_TOKEN || '',
},
function: {
name: functionName,
handler,
memory,
timeout,
initializer: '',
},
service: {
name: iac.service || 'default-service',
logProject: `${iac.service}-log-project`,
logStore: `${iac.service}-log-store`,
qualifier: 'LATEST',
versionId: '1',
},
tracing: {
spanContext: '',
jaegerEndpoint: '',
spanBaggages: {},
},
};
};
exports.createAliyunContextSerializable = createAliyunContextSerializable;
const createAliyunContext = (iac, functionName, handler, memory, timeout, requestId) => {
const baseContext = (0, exports.createAliyunContextSerializable)(iac, functionName, handler, memory, timeout, requestId);
return {
...baseContext,
tracing: {
...baseContext.tracing,
parseOpenTracingBaggages: () => ({}),
},
logger: createFCLogger(requestId),
};
};
exports.createAliyunContext = createAliyunContext;
const addFCHeaders = (context, headers) => {
return {
...headers,
'x-fc-request-id': context.requestId,
'x-fc-access-key-id': context.credentials.accessKeyId,
'x-fc-access-key-secret': context.credentials.accessKeySecret,
'x-fc-security-token': context.credentials.securityToken,
'x-fc-function-handler': context.function.handler,
'x-fc-function-memory': String(context.function.memory),
'x-fc-region': context.region,
'x-fc-account-id': context.accountId,
'x-fc-qualifier': context.service.qualifier,
'x-fc-version-id': context.service.versionId,
'x-fc-function-name': context.function.name,
'x-fc-service-logproject': context.service.logProject,
'x-fc-service-logstore': context.service.logStore,
'x-fc-control-path': '/http-invoke',
};
};
exports.addFCHeaders = addFCHeaders;
const transformFCResponse = (result) => {
if (result && typeof result === 'object' && 'statusCode' in result && 'body' in result) {
const { statusCode: rawStatus = 200, body: rawBody, isBase64Encoded, headers = {}, } = result;
const parsedStatus = typeof rawStatus === 'string' ? parseInt(rawStatus, 10) : rawStatus;
const statusCode = isNaN(parsedStatus) ? 200 : parsedStatus;
let body = rawBody;
if (isBase64Encoded && typeof body === 'string') {
body = Buffer.from(body, 'base64').toString('utf-8');
}
if (typeof body === 'string') {
try {
body = JSON.parse(body);
}
catch {
// If parsing fails, keep as string
}
}
return { statusCode, headers, body };
}
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: result,
};
};
exports.transformFCResponse = transformFCResponse;
const logApiGatewayRequest = (requestId, apiPath, statusCode, startTime, endTime, sourceIp) => {
const duration = ((endTime.getTime() - startTime.getTime()) / 1000).toFixed(1);
const startTimeStr = formatDateTime(startTime);
const endTimeStr = formatDateTime(endTime);
const timestamp = formatDateTime(new Date());
console.log(`${timestamp} | ${requestId} | ${apiPath} | Sync Call | local-app | Development | local-project | ${statusCode} | ${startTimeStr} | ${endTimeStr} | ${duration}s | - | ${sourceIp}`);
};
exports.logApiGatewayRequest = logApiGatewayRequest;
const formatDateTime = (date) => {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const seconds = String(date.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
const generateRequestId = () => {
return (0, crypto_1.randomUUID)().replace(/-/g, '');
};
exports.generateRequestId = generateRequestId;