Skip to content

Commit 1dcaaca

Browse files
committed
Added private logging channel
Split the communication into two channels, one for "SDK" and one for the 3rd party user called "USER". The channel name is written in front of the message (e.g: `[SDK] Uploading users`). The SDK needs to do additional steps to use the SDK channel, but 3rd party users don't.
1 parent 1ef6281 commit 1dcaaca

18 files changed

+391
-42
lines changed

src/attachments-streaming/attachments-streaming-pool.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ describe(AttachmentsStreamingPool.name, () => {
217217
await pool.streamAll();
218218

219219
expect(console.warn).toHaveBeenCalledWith(
220-
"SDK: ", ["Skipping attachment with ID attachment-2 due to error: Error: Processing failed"]
220+
"Skipping attachment with ID attachment-2 due to error: Error: Processing failed"
221221
);
222222
expect(mockAdapter.state.toDevRev!.attachmentsMetadata.lastProcessedAttachmentsIdsList).toEqual([
223223
'attachment-1',

src/attachments-streaming/attachments-streaming-pool.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
} from '../types';
66
import { AttachmentsStreamingPoolParams } from './attachments-streaming-pool.interfaces';
77
import { WorkerAdapter } from '../workers/worker-adapter';
8-
import { SdkConsole as console } from '../sdkconsole';
98

109
export class AttachmentsStreamingPool<ConnectorState> {
1110
private adapter: WorkerAdapter<ConnectorState>;

src/common/helpers.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
import { readFileSync } from 'fs';
1414
import * as path from 'path';
1515
import { MAX_DEVREV_FILENAME_EXTENSION_LENGTH, MAX_DEVREV_FILENAME_LENGTH } from './constants';
16-
import { SdkConsole as console } from '../sdkconsole';
1716

1817
export function getTimeoutErrorEventType(eventType: EventType): {
1918
eventType: ExtractorEventType | LoaderEventType;

src/common/install-initial-domain-mapping.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import { AirdropEvent } from '../types/extraction';
44
import { InitialDomainMapping } from '../types/common';
55
import { serializeError } from '../logger/logger';
66

7-
import { SdkConsole as console } from '../sdkconsole';
8-
97
export async function installInitialDomainMapping(
108
event: AirdropEvent,
119
initialDomainMappingJson: InitialDomainMapping

src/http/axios-client-internal.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import axios, { AxiosError } from 'axios';
22
import axiosRetry from 'axios-retry';
3-
import { SdkConsole as console } from '../sdkconsole';
43

54
const axiosClient = axios.create();
65

src/http/axios-client.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525
import axios, { AxiosError } from 'axios';
2626
import axiosRetry from 'axios-retry';
2727

28-
import { SdkConsole as console } from '../sdkconsole';
29-
3028
const axiosClient = axios.create();
3129

3230
axiosRetry(axiosClient, {

src/logger/logger.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ describe(Logger.name, () => {
8383

8484
expect(mockConsoleInfo).toHaveBeenCalledWith(
8585
JSON.stringify({
86-
message,
86+
message: '[USER] ' + message,
8787
...mockEvent.payload.event_context,
8888
dev_oid: mockEvent.payload.event_context.dev_oid,
8989
})
@@ -101,7 +101,7 @@ describe(Logger.name, () => {
101101
});
102102
expect(mockConsoleInfo).toHaveBeenCalledWith(
103103
JSON.stringify({
104-
message: expectedMessage,
104+
message: '[USER] ' + expectedMessage,
105105
...mockEvent.payload.event_context,
106106
dev_oid: mockEvent.payload.event_context.dev_oid,
107107
})
@@ -120,7 +120,7 @@ describe(Logger.name, () => {
120120
});
121121
expect(mockConsoleInfo).toHaveBeenCalledWith(
122122
JSON.stringify({
123-
message: `${text} ${expectedDataMessage}`,
123+
message: `[USER] ${text} ${expectedDataMessage}`,
124124
...mockEvent.payload.event_context,
125125
dev_oid: mockEvent.payload.event_context.dev_oid,
126126
})
@@ -140,7 +140,7 @@ describe(Logger.name, () => {
140140
});
141141
expect(mockConsoleInfo).toHaveBeenCalledWith(
142142
JSON.stringify({
143-
message: `${text1} ${expectedDataMessage} ${text2}`,
143+
message: `[USER] ${text1} ${expectedDataMessage} ${text2}`,
144144
...mockEvent.payload.event_context,
145145
dev_oid: mockEvent.payload.event_context.dev_oid,
146146
})
@@ -162,7 +162,7 @@ describe(Logger.name, () => {
162162

163163
logger.info(message, data);
164164

165-
expect(mockConsoleInfo).toHaveBeenCalledWith(message, data);
165+
expect(mockConsoleInfo).toHaveBeenCalledWith('[USER]', message, data);
166166
});
167167
});
168168

@@ -210,7 +210,7 @@ describe(Logger.name, () => {
210210
const callArgs = mockConsoleInfo.mock.calls[0][0];
211211
const logObject = JSON.parse(callArgs);
212212

213-
expect(logObject.message).toBe('');
213+
expect(logObject.message).toBe('[USER] ');
214214
expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_oid);
215215
expect(logObject.request_id).toBe(
216216
mockEvent.payload.event_context.request_id
@@ -225,7 +225,7 @@ describe(Logger.name, () => {
225225
const logObject = JSON.parse(callArgs);
226226

227227
// inspect shows 'null' and 'undefined' as strings
228-
expect(logObject.message).toBe('test null undefined');
228+
expect(logObject.message).toBe('[USER] test null undefined');
229229
expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_oid);
230230
});
231231

@@ -250,7 +250,7 @@ describe(Logger.name, () => {
250250
compact: false,
251251
depth: Infinity,
252252
});
253-
expect(logObject.message).toBe(expectedMessage);
253+
expect(logObject.message).toBe('[USER] ' + expectedMessage);
254254
expect(logObject.dev_oid).toBe(mockEvent.payload.event_context.dev_oid);
255255
expect(typeof logObject.callback_url).toBe('string');
256256
});

src/logger/logger.ts

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ import { WorkerAdapterOptions, WorkerMessageSubject } from '../types/workers';
1212
import { AxiosError, RawAxiosResponseHeaders, isAxiosError } from 'axios';
1313
import { getCircularReplacer } from '../common/helpers';
1414
import { EventContext } from '../types/extraction';
15+
import { INTERNAL_CHANNEL, verificationToken } from './private_logger';
1516

1617
export class Logger extends Console {
1718
private options?: WorkerAdapterOptions;
1819
private tags: EventContext & { dev_oid: string };
20+
private isVerifiedChannel: boolean = false; // false = unverified (default), true = verified
1921

2022
constructor({ event, options }: LoggerFactoryInterface) {
2123
super(process.stdout, process.stderr);
@@ -26,6 +28,33 @@ export class Logger extends Console {
2628
};
2729
}
2830

31+
// Internal method to create a verified logger
32+
private [INTERNAL_CHANNEL](token: string): Logger {
33+
if (token === verificationToken) {
34+
const verifiedLogger = Object.create(this);
35+
verifiedLogger.isVerifiedChannel = true;
36+
// Ensure the verified logger retains the internal channel method
37+
verifiedLogger[INTERNAL_CHANNEL] = this[INTERNAL_CHANNEL].bind(this);
38+
// Override the logFn method to use the verified logger's context
39+
verifiedLogger.logFn = this.logFn.bind(verifiedLogger);
40+
// Override the logging methods to use the custom logFn
41+
verifiedLogger.log = (...args: unknown[]): void => {
42+
verifiedLogger.logFn(args, LogLevel.INFO);
43+
};
44+
verifiedLogger.info = (...args: unknown[]): void => {
45+
verifiedLogger.logFn(args, LogLevel.INFO);
46+
};
47+
verifiedLogger.warn = (...args: unknown[]): void => {
48+
verifiedLogger.logFn(args, LogLevel.WARN);
49+
};
50+
verifiedLogger.error = (...args: unknown[]): void => {
51+
verifiedLogger.logFn(args, LogLevel.ERROR);
52+
};
53+
return verifiedLogger;
54+
}
55+
throw new Error('Unauthorized access to internal channel');
56+
}
57+
2958
private valueToString(value: unknown): string {
3059
if (typeof value === 'string') {
3160
return value;
@@ -39,20 +68,25 @@ export class Logger extends Console {
3968
}
4069

4170
logFn(args: unknown[], level: LogLevel): void {
71+
// Always add prefix based on verification status
72+
// false = unverified ([USER] prefix), true = verified ([SDK] prefix)
73+
const prefix = this.isVerifiedChannel ? '[SDK]' : '[USER]';
74+
const processedArgs = [prefix, ...args];
75+
4276
if (isMainThread) {
4377
if (this.options?.isLocalDevelopment) {
44-
console[level](...args);
78+
console[level](...processedArgs);
4579
} else {
4680
let message: string;
47-
if (args.length === 1 && typeof args[0] === 'string') {
81+
if (processedArgs.length === 1 && typeof processedArgs[0] === 'string') {
4882
// Single string argument - use directly
49-
message = args[0];
50-
} else if (args.length === 1) {
83+
message = processedArgs[0];
84+
} else if (processedArgs.length === 1) {
5185
// Single non-string argument - convert to string properly
52-
message = this.valueToString(args[0]);
86+
message = this.valueToString(processedArgs[0]);
5387
} else {
5488
// Multiple arguments - create a readable format
55-
message = args.map((arg) => this.valueToString(arg)).join(' ');
89+
message = processedArgs.map((arg) => this.valueToString(arg)).join(' ');
5690
}
5791

5892
const logObject = {
@@ -66,7 +100,7 @@ export class Logger extends Console {
66100
parentPort?.postMessage({
67101
subject: WorkerMessageSubject.WorkerMessageLog,
68102
payload: {
69-
args: args.map((arg) => this.valueToString(arg)),
103+
args: processedArgs.map((arg) => this.valueToString(arg)),
70104
level,
71105
},
72106
});

0 commit comments

Comments
 (0)