Skip to content

Commit 4b97cb0

Browse files
fengmk2rockdai
andauthored
feat: add custom logging (ali-sdk#122) (#11)
pick from ali-sdk#122 closes #9 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced configurable logging capabilities for database operations. Users can now enable logging to capture SQL queries along with execution details and error information. - **Tests** - Expanded test coverage validates the new logging functionality, ensuring queries are accurately captured and formatted during execution. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Dai Wenzhuo <[email protected]>
1 parent db72b8e commit 4b97cb0

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

src/client.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class RDSClient extends Operator {
6767
constructor(options: RDSClientOptions) {
6868
super();
6969
options.connectTimeout = options.connectTimeout ?? 500;
70-
const { connectionStorage, connectionStorageKey, poolWaitTimeout, ...mysqlOptions } = options;
70+
const { connectionStorage, connectionStorageKey, poolWaitTimeout, logging, ...mysqlOptions } = options;
7171
// get connection options from getConnectionConfig method every time
7272
if (mysqlOptions.getConnectionConfig) {
7373
this.#pool = new Pool({ config: new RDSPoolConfig(mysqlOptions, mysqlOptions.getConnectionConfig) } as any) as unknown as PoolPromisify;
@@ -108,6 +108,7 @@ export class RDSClient extends Operator {
108108
connection,
109109
} as ConnectionMessage);
110110
});
111+
this.logging = logging;
111112
}
112113

113114
async query<T = any>(sql: string, values?: object | any[], options?: QueryOptions): Promise<T> {
@@ -177,6 +178,7 @@ export class RDSClient extends Operator {
177178
try {
178179
const _conn = await this.getConnectionWithTimeout();
179180
const conn = new RDSConnection(_conn);
181+
conn.setLogging(this.logging);
180182
if (this.beforeQueryHandlers.length > 0) {
181183
for (const handler of this.beforeQueryHandlers) {
182184
conn.beforeQuery(handler);

src/operator.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
SelectOption,
1010
UpdateOption, UpdateResult, UpdateRow,
1111
PoolConnectionPromisify,
12+
Logging,
1213
} from './types';
1314
import channels from './channels';
1415
import type { QueryStartMessage, QueryEndMessage } from './channels';
@@ -20,6 +21,8 @@ const debug = debuglog('ali-rds:operator');
2021
*/
2122
export abstract class Operator {
2223
#connection: PoolConnectionPromisify;
24+
logging?: Logging;
25+
2326
constructor(connection?: PoolConnectionPromisify) {
2427
if (connection) {
2528
this.#connection = connection;
@@ -43,6 +46,10 @@ export abstract class Operator {
4346
this.afterQueryHandlers.push(afterQueryHandler);
4447
}
4548

49+
setLogging(logging?: Logging) {
50+
this.logging = logging;
51+
}
52+
4653
escape(value: any, stringifyObjects?: boolean, timeZone?: string): string {
4754
return SqlString.escape(value, stringifyObjects, timeZone);
4855
}
@@ -80,6 +87,9 @@ export abstract class Operator {
8087
}
8188
}
8289
debug('[connection#%s] query %o', this.threadId, sql);
90+
if (typeof this.logging === 'function') {
91+
this.logging(sql, { threadId: this.threadId });
92+
}
8393
const queryStart = performance.now();
8494
let rows: any;
8595
let lastError: Error | undefined;

src/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface RDSClientOptions extends PoolOptions {
99
connectionStorage?: AsyncLocalStorage<Record<PropertyKey, RDSTransaction>>;
1010
getConnectionConfig?: GetConnectionConfig;
1111
poolWaitTimeout?: number;
12+
logging?: Logging;
1213
}
1314

1415
export interface PoolConnectionPromisify extends Omit<PoolConnection, 'query'> {
@@ -67,3 +68,5 @@ export type AfterQueryHandler = (sql: string, result: any, execDuration: number,
6768

6869
export type TransactionContext = Record<PropertyKey, RDSTransaction | null>;
6970
export type TransactionScope = (transaction: RDSTransaction) => Promise<any>;
71+
72+
export type Logging = (message: string, ...args: any[]) => any;

test/client.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,30 @@ describe('test/client.test.ts', () => {
338338
});
339339
});
340340

341+
describe('logging', () => {
342+
const mockLogs: string[] = [];
343+
344+
it('should logging sql', async () => {
345+
const db = new RDSClient({
346+
...config,
347+
logging: (sql, { threadId }) => {
348+
assert.equal(typeof threadId, 'number');
349+
mockLogs.push(sql);
350+
},
351+
});
352+
353+
await db.query('show tables');
354+
assert.deepEqual(mockLogs, [ 'show tables' ]);
355+
// logging SQL string with variable replaced
356+
await db.query('select * from ?? where email = ? limit 1',
357+
[ table, prefix + '[email protected]' ]);
358+
assert.deepEqual(mockLogs, [
359+
'show tables',
360+
`select * from \`${table}\` where email = '${prefix + '[email protected]'}' limit 1`,
361+
]);
362+
});
363+
});
364+
341365
describe('beginTransactionScope(scope)', () => {
342366
it('should beginTransactionScope() error', async () => {
343367
const failDB = new RDSClient({

0 commit comments

Comments
 (0)