forked from GoogleCloudPlatform/functions-framework-nodejs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexecution_context.ts
69 lines (60 loc) · 1.87 KB
/
execution_context.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import * as semver from 'semver';
import {Request, Response, NextFunction} from 'express';
import {requriedNodeJsVersion} from './options';
export interface ExeuctionContext {
'logging.googleapis.com/labels': {
executionId: string;
};
'logging.googleapis.com/trace'?: string;
'logging.googleapis.com/spanId'?: string;
}
function generateExecutionId() {
const timestampPart = Date.now().toString(36).slice(-6);
const randomPart = Math.random().toString(36).slice(-6);
return timestampPart + randomPart;
}
let asyncLocalStorage: any;
export async function executionContextMiddleware(
req: Request,
res: Response,
next: NextFunction
) {
if (semver.gte(process.versions.node, requriedNodeJsVersion)) {
const asyncHooks = await import('node:async_hooks');
if (!asyncLocalStorage) {
asyncLocalStorage = new asyncHooks.AsyncLocalStorage();
}
let executionId = req.header('function-execution-id');
if (!executionId || executionId.length !== 12) {
executionId = generateExecutionId();
}
let traceId, spanId, options;
const cloudTraceContext = req.header('X-Cloud-Trace-Context');
const regex = /^(?<traceId>\w+)\/(?<spanId>\d+);o=(?<options>.+)$/;
if (cloudTraceContext) {
const match = cloudTraceContext.match(regex);
if (match?.groups) {
({traceId, spanId, options} = match.groups);
}
}
const executionContext = <ExeuctionContext>{
'logging.googleapis.com/labels': {
executionId: executionId,
},
'logging.googleapis.com/trace': traceId,
'logging.googleapis.com/spanId': spanId,
};
asyncLocalStorage.run(executionContext, () => {
next();
});
} else {
// Continue for unsupported Node.js version.
next();
}
}
export function getCurrentContext() {
if (!asyncLocalStorage) {
return undefined;
}
return asyncLocalStorage.getStore();
}