Skip to content

Commit 225040d

Browse files
authored
[log] log contextId and userId (#18688)
1 parent 49d1d4f commit 225040d

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

components/gitpod-protocol/src/util/logging.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,17 @@ export interface LogContext {
2020
workspaceId?: string;
2121
instanceId?: string;
2222
}
23+
24+
/**
25+
* allows to globally augment the log context, default is an identity function
26+
*/
27+
let logContextAugmenter: LogContext.Augmenter = (context) => context;
28+
2329
export namespace LogContext {
30+
export type Augmenter = (context: LogContext | undefined) => LogContext | undefined;
31+
export function setAugmenter(augmenter: Augmenter): void {
32+
logContextAugmenter = augmenter;
33+
}
2434
export function from(params: { userId?: string; user?: any; request?: any }) {
2535
return <LogContext>{
2636
sessionId: params.request?.requestID,
@@ -306,6 +316,7 @@ function makeLogItem(
306316
if (context !== undefined && Object.keys(context).length == 0) {
307317
context = undefined;
308318
}
319+
context = logContextAugmenter(context);
309320
context = scrubPayload(context, plainLogging);
310321

311322
let reportedErrorEvent: {} = {};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
3+
* Licensed under the GNU Affero General Public License (AGPL).
4+
* See License.AGPL.txt in the project root for license information.
5+
*/
6+
7+
import { LogContext } from "@gitpod/gitpod-protocol/lib/util/logging";
8+
import { AsyncLocalStorage } from "node:async_hooks";
9+
import { v4 } from "uuid";
10+
11+
// we are installing a special augmenter that enhances the log context if executed within `runWithContext`
12+
// with a contextId and a contextTimeMs, which denotes the amount of milliseconds since the context was created.
13+
type EnhancedLogContext = LogContext & {
14+
contextId?: string;
15+
contextTimeMs: number;
16+
};
17+
const asyncLocalStorage = new AsyncLocalStorage<EnhancedLogContext>();
18+
const augmenter: LogContext.Augmenter = (ctx) => {
19+
const globalContext = asyncLocalStorage.getStore();
20+
const contextTime = globalContext?.contextTimeMs ? Date.now() - globalContext.contextTimeMs : undefined;
21+
return {
22+
...globalContext,
23+
contextTime,
24+
...ctx,
25+
};
26+
};
27+
LogContext.setAugmenter(augmenter);
28+
29+
export async function runWithContext<T>(context: LogContext, fun: () => T): Promise<T> {
30+
return asyncLocalStorage.run(
31+
{
32+
...context,
33+
contextId: v4(),
34+
contextTimeMs: Date.now(),
35+
},
36+
fun,
37+
);
38+
}

components/server/src/websocket/websocket-connection-manager.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import * as opentracing from "opentracing";
4949
import { TraceContext } from "@gitpod/gitpod-protocol/lib/util/tracing";
5050
import { GitpodHostUrl } from "@gitpod/gitpod-protocol/lib/util/gitpod-host-url";
5151
import { maskIp } from "../analytics";
52+
import { runWithContext } from "../util/log-context";
5253

5354
export type GitpodServiceFactory = () => GitpodServerImpl;
5455

@@ -373,6 +374,18 @@ class GitpodJsonRpcProxyFactory<T extends object> extends JsonRpcProxyFactory<T>
373374
}
374375

375376
protected async onRequest(method: string, ...args: any[]): Promise<any> {
377+
const userId = this.clientMetadata.userId;
378+
return runWithContext(
379+
{
380+
userId,
381+
},
382+
() => {
383+
return this.internalOnRequest(method, ...args);
384+
},
385+
);
386+
}
387+
388+
private async internalOnRequest(method: string, ...args: any[]): Promise<any> {
376389
const span = TraceContext.startSpan(method, undefined);
377390
const ctx = { span };
378391
const userId = this.clientMetadata.userId;

0 commit comments

Comments
 (0)