Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(NODE-5169): Implement emergency logger #3610

Merged
merged 48 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a8d42ad
refactor(NODE-4813): WIP
W-A-James Mar 27, 2023
6b053d9
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
W-A-James Mar 29, 2023
e0b1db2
refactor(NODE-4813): start first draft of logger implementation
W-A-James Mar 29, 2023
d2ff692
style(NODE-4813): eslint
W-A-James Mar 29, 2023
a52b1ae
refactor(NODE-4813): Add changes to MongoLogger and ConnectionClosedE…
W-A-James Mar 29, 2023
16fee3f
test(NODE-4813): WIP - start adding tests
W-A-James Mar 31, 2023
b88003e
fix(NODE-4813): use HostAddress
W-A-James Apr 3, 2023
06a1bf0
fix(NODE-4813): Add Loggable interface
W-A-James Apr 3, 2023
3501a35
test(NODE-4813): Add connection events tests
W-A-James Apr 3, 2023
bf591b9
fix(NODE-4813): omit nullish fields
W-A-James Apr 3, 2023
36e2e32
test(NODE-4813): update tests
W-A-James Apr 3, 2023
80fbecd
refactor(NODE-4813): Update mongo client to accept @@mdb.internalLogC…
W-A-James Apr 4, 2023
da4f89c
test(NODE-4813): Add integration tests
W-A-James Apr 4, 2023
3c76aeb
test(NODE-4813): ensure that mongo logger works with MongoDBLogWritab…
W-A-James Apr 4, 2023
a39965f
style(NODE-4813): remove todo comment
W-A-James Apr 4, 2023
8bf2176
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
W-A-James Apr 4, 2023
97c8eba
refactor(NODE-5169): Change name getter on events to a property
W-A-James Apr 5, 2023
bcd88a8
Merge branch 'NODE-4813/Implement_severity_logging_methods' of github…
W-A-James Apr 5, 2023
d4b6300
refactor(NODE-5169): refactor to make use of existing constants
W-A-James Apr 5, 2023
ac7223c
test(NODE-5169): Updates tests for ConnectionClosedEvent logging
W-A-James Apr 5, 2023
f46ab9b
refactor(NODE-5169): Update logging of ConnectionClosedEvent to inclu…
W-A-James Apr 5, 2023
c7d8f8d
refactor(NODE-5619): continue refactor to use minimal writable interface
W-A-James Apr 5, 2023
993058f
refactor(NODE-5619): fix janky typecasting
W-A-James Apr 5, 2023
124702e
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
W-A-James Apr 6, 2023
0d91ccd
style(NODE-5169): eslint
W-A-James Apr 6, 2023
0fe2d2b
test(NODE-5169): Remove unneeded tests
W-A-James Apr 6, 2023
6ff5413
Merge branch 'NODE-4813/Implement_severity_logging_methods' of github…
W-A-James Apr 6, 2023
0a5b9cd
refactor(NODE-5169): Start implementing review changes
W-A-James Apr 7, 2023
bdde7cf
fix(NODE-5169): review comments
W-A-James Apr 10, 2023
f11f9d2
test(NODE-5169): add feature flag tests
W-A-James Apr 10, 2023
e70de2a
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
W-A-James Apr 10, 2023
3c742d6
refactor(NODE-5169): Change log signature
W-A-James Apr 10, 2023
4db07e6
fix(NODE-5169): fix check
W-A-James Apr 10, 2023
896a010
test(NODE-5169): test wip
W-A-James Apr 10, 2023
af2d8ed
refactor(NODE-5169): Refactor of resolveOptions and DEFAULT_LOG_TRANS…
W-A-James Apr 11, 2023
3e262c0
refactor(NODE-5169): Export appropriate constants
W-A-James Apr 11, 2023
18ed1e8
refactor(NODE-5169): Address review comments
W-A-James Apr 11, 2023
666221b
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
W-A-James Apr 12, 2023
b76ba6d
fix(NODE-5169): Remove createdStdioLogger from export
W-A-James Apr 12, 2023
4db4913
refactor(NODE-5169): Addres review comments
W-A-James Apr 12, 2023
be04325
test(NODE-5169): remove unneeded test file
W-A-James Apr 12, 2023
2299478
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
nbbeeken Apr 12, 2023
57a643c
fix(NODE-5169): Addres review comments and fix ConnectionCheckOutFail…
W-A-James Apr 13, 2023
c456ce9
fix(NODE-5169): update signature
W-A-James Apr 14, 2023
f258901
fix(NODE-5169): convert to MongoError
W-A-James Apr 14, 2023
442557b
style(NODE-5169): eslint
W-A-James Apr 14, 2023
dd66ea3
refactor(NODE-5169): update function signature
W-A-James Apr 14, 2023
369216d
Merge branch 'main' into NODE-4813/Implement_severity_logging_methods
W-A-James Apr 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/cmap/command_monitoring_events.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import type { Document, ObjectId } from '../bson';
import { LEGACY_HELLO_COMMAND, LEGACY_HELLO_COMMAND_CAMEL_CASE } from '../constants';
import {
COMMAND_FAILED,
COMMAND_STARTED,
COMMAND_SUCCEEDED,
LEGACY_HELLO_COMMAND,
LEGACY_HELLO_COMMAND_CAMEL_CASE
} from '../constants';
import { calculateDurationInMs, deepCopy } from '../utils';
import { Msg, WriteProtocolMessageType } from './commands';
import type { Connection } from './connection';
Expand All @@ -18,6 +24,8 @@ export class CommandStartedEvent {
address: string;
connectionId?: string | number;
serviceId?: ObjectId;
/** @internal */
name = COMMAND_STARTED;
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved

/**
* Create a started event
Expand Down Expand Up @@ -65,6 +73,8 @@ export class CommandSucceededEvent {
commandName: string;
reply: unknown;
serviceId?: ObjectId;
/** @internal */
name = COMMAND_SUCCEEDED;

/**
* Create a succeeded event
Expand Down Expand Up @@ -113,6 +123,8 @@ export class CommandFailedEvent {
commandName: string;
failure: Error;
serviceId?: ObjectId;
/** @internal */
name = COMMAND_FAILED;

/**
* Create a failure event
Expand Down
1 change: 1 addition & 0 deletions src/cmap/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ function makeConnection(options: MakeConnectionOptions, _callback: Callback<Stre

if ('authorizationError' in socket) {
if (socket.authorizationError && rejectUnauthorized) {
// TODO(NODE-5192): wrap this with a MongoError subclass
return callback(socket.authorizationError);
}
}
Expand Down
18 changes: 14 additions & 4 deletions src/cmap/connection_pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,10 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
}
}

private destroyConnection(connection: Connection, reason: string) {
private destroyConnection(
connection: Connection,
reason: 'error' | 'idle' | 'stale' | 'poolClosed'
) {
this.emit(
ConnectionPool.CONNECTION_CLOSED,
new ConnectionClosedEvent(this, connection, reason)
Expand Down Expand Up @@ -701,7 +704,13 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
this[kPending]--;
this.emit(
ConnectionPool.CONNECTION_CLOSED,
new ConnectionClosedEvent(this, { id: connectOptions.id, serviceId: undefined }, 'error')
new ConnectionClosedEvent(
this,
{ id: connectOptions.id, serviceId: undefined },
'error',
// TODO(NODE-5192): Remove this cast
err as MongoError
)
);
if (err instanceof MongoNetworkError || err instanceof MongoServerError) {
err.connectionGeneration = connectOptions.generation;
Expand Down Expand Up @@ -812,7 +821,7 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
const error = this.closed ? new PoolClosedError(this) : new PoolClearedError(this);
this.emit(
ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
new ConnectionCheckOutFailedEvent(this, reason)
new ConnectionCheckOutFailedEvent(this, reason, error)
);
if (waitQueueMember.timer) {
clearTimeout(waitQueueMember.timer);
Expand Down Expand Up @@ -865,7 +874,8 @@ export class ConnectionPool extends TypedEventEmitter<ConnectionPoolEvents> {
if (err) {
this.emit(
ConnectionPool.CONNECTION_CHECK_OUT_FAILED,
new ConnectionCheckOutFailedEvent(this, 'connectionError')
// TODO(NODE-5192): Remove this cast
new ConnectionCheckOutFailedEvent(this, 'connectionError', err as MongoError)
);
} else if (connection) {
this[kCheckedOut].add(connection);
Expand Down
74 changes: 68 additions & 6 deletions src/cmap/connection_pool_events.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import type { ObjectId } from '../bson';
import type { AnyError } from '../error';
import {
CONNECTION_CHECK_OUT_FAILED,
CONNECTION_CHECK_OUT_STARTED,
CONNECTION_CHECKED_IN,
CONNECTION_CHECKED_OUT,
CONNECTION_CLOSED,
CONNECTION_CREATED,
CONNECTION_POOL_CLEARED,
CONNECTION_POOL_CLOSED,
CONNECTION_POOL_CREATED,
CONNECTION_POOL_READY,
CONNECTION_READY
} from '../constants';
import type { MongoError } from '../error';
import type { Connection } from './connection';
import type { ConnectionPool, ConnectionPoolOptions } from './connection_pool';

Expand All @@ -8,11 +21,24 @@ import type { ConnectionPool, ConnectionPoolOptions } from './connection_pool';
* @public
* @category Event
*/
export class ConnectionPoolMonitoringEvent {
export abstract class ConnectionPoolMonitoringEvent {
baileympearson marked this conversation as resolved.
Show resolved Hide resolved
/** A timestamp when the event was created */
time: Date;
/** The address (host/port pair) of the pool */
address: string;
/** @internal */
abstract name:
| typeof CONNECTION_CHECK_OUT_FAILED
| typeof CONNECTION_CHECK_OUT_STARTED
| typeof CONNECTION_CHECKED_IN
| typeof CONNECTION_CHECKED_OUT
| typeof CONNECTION_CLOSED
| typeof CONNECTION_CREATED
| typeof CONNECTION_POOL_CLEARED
| typeof CONNECTION_POOL_CLOSED
| typeof CONNECTION_POOL_CREATED
| typeof CONNECTION_POOL_READY
| typeof CONNECTION_READY;

/** @internal */
constructor(pool: ConnectionPool) {
Expand All @@ -29,6 +55,8 @@ export class ConnectionPoolMonitoringEvent {
export class ConnectionPoolCreatedEvent extends ConnectionPoolMonitoringEvent {
/** The options used to create this connection pool */
options?: ConnectionPoolOptions;
/** @internal */
name = CONNECTION_POOL_CREATED;

/** @internal */
constructor(pool: ConnectionPool) {
Expand All @@ -43,6 +71,9 @@ export class ConnectionPoolCreatedEvent extends ConnectionPoolMonitoringEvent {
* @category Event
*/
export class ConnectionPoolReadyEvent extends ConnectionPoolMonitoringEvent {
/** @internal */
name = CONNECTION_POOL_READY;

/** @internal */
constructor(pool: ConnectionPool) {
super(pool);
Expand All @@ -55,6 +86,9 @@ export class ConnectionPoolReadyEvent extends ConnectionPoolMonitoringEvent {
* @category Event
*/
export class ConnectionPoolClosedEvent extends ConnectionPoolMonitoringEvent {
/** @internal */
name = CONNECTION_POOL_CLOSED;

/** @internal */
constructor(pool: ConnectionPool) {
super(pool);
Expand All @@ -69,6 +103,8 @@ export class ConnectionPoolClosedEvent extends ConnectionPoolMonitoringEvent {
export class ConnectionCreatedEvent extends ConnectionPoolMonitoringEvent {
/** A monotonically increasing, per-pool id for the newly created connection */
connectionId: number | '<monitor>';
/** @internal */
name = CONNECTION_CREATED;

/** @internal */
constructor(pool: ConnectionPool, connection: { id: number | '<monitor>' }) {
Expand All @@ -85,6 +121,8 @@ export class ConnectionCreatedEvent extends ConnectionPoolMonitoringEvent {
export class ConnectionReadyEvent extends ConnectionPoolMonitoringEvent {
/** The id of the connection */
connectionId: number | '<monitor>';
/** @internal */
name = CONNECTION_READY;

/** @internal */
constructor(pool: ConnectionPool, connection: Connection) {
Expand All @@ -104,17 +142,23 @@ export class ConnectionClosedEvent extends ConnectionPoolMonitoringEvent {
/** The reason the connection was closed */
reason: string;
serviceId?: ObjectId;
/** @internal */
name = CONNECTION_CLOSED;
/** @internal */
error: MongoError | null;
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved

/** @internal */
constructor(
pool: ConnectionPool,
connection: Pick<Connection, 'id' | 'serviceId'>,
reason: string
reason: 'idle' | 'stale' | 'poolClosed' | 'error',
error?: MongoError
) {
super(pool);
this.connectionId = connection.id;
this.reason = reason || 'unknown';
this.reason = reason;
this.serviceId = connection.serviceId;
this.error = error ?? null;
}
}

Expand All @@ -124,6 +168,9 @@ export class ConnectionClosedEvent extends ConnectionPoolMonitoringEvent {
* @category Event
*/
export class ConnectionCheckOutStartedEvent extends ConnectionPoolMonitoringEvent {
/** @internal */
name = CONNECTION_CHECK_OUT_STARTED;

/** @internal */
constructor(pool: ConnectionPool) {
super(pool);
Expand All @@ -137,12 +184,21 @@ export class ConnectionCheckOutStartedEvent extends ConnectionPoolMonitoringEven
*/
export class ConnectionCheckOutFailedEvent extends ConnectionPoolMonitoringEvent {
/** The reason the attempt to check out failed */
reason: AnyError | string;
reason: string;
/** @internal */
error?: MongoError;
/** @internal */
name = CONNECTION_CHECK_OUT_FAILED;

/** @internal */
constructor(pool: ConnectionPool, reason: AnyError | string) {
constructor(
pool: ConnectionPool,
reason: 'poolClosed' | 'timeout' | 'connectionError',
error?: MongoError
) {
super(pool);
this.reason = reason;
this.error = error;
}
}

Expand All @@ -154,6 +210,8 @@ export class ConnectionCheckOutFailedEvent extends ConnectionPoolMonitoringEvent
export class ConnectionCheckedOutEvent extends ConnectionPoolMonitoringEvent {
/** The id of the connection */
connectionId: number | '<monitor>';
/** @internal */
name = CONNECTION_CHECKED_OUT;

/** @internal */
constructor(pool: ConnectionPool, connection: Connection) {
Expand All @@ -170,6 +228,8 @@ export class ConnectionCheckedOutEvent extends ConnectionPoolMonitoringEvent {
export class ConnectionCheckedInEvent extends ConnectionPoolMonitoringEvent {
/** The id of the connection */
connectionId: number | '<monitor>';
/** @internal */
name = CONNECTION_CHECKED_IN;

/** @internal */
constructor(pool: ConnectionPool, connection: Connection) {
Expand All @@ -188,6 +248,8 @@ export class ConnectionPoolClearedEvent extends ConnectionPoolMonitoringEvent {
serviceId?: ObjectId;

interruptInUseConnections?: boolean;
/** @internal */
name = CONNECTION_POOL_CLEARED;

/** @internal */
constructor(
Expand Down
3 changes: 2 additions & 1 deletion src/connection_string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1280,5 +1280,6 @@ export const DEFAULT_OPTIONS = new CaseInsensitiveMap(
*/
export const FEATURE_FLAGS = new Set([
Symbol.for('@@mdb.skipPingOnConnect'),
Symbol.for('@@mdb.enableMongoLogger')
Symbol.for('@@mdb.enableMongoLogger'),
Symbol.for('@@mdb.internalLoggerConfig')
nbbeeken marked this conversation as resolved.
Show resolved Hide resolved
]);
11 changes: 11 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,27 @@ export const SERVER_DESCRIPTION_CHANGED = 'serverDescriptionChanged' as const;
export const TOPOLOGY_OPENING = 'topologyOpening' as const;
export const TOPOLOGY_CLOSED = 'topologyClosed' as const;
export const TOPOLOGY_DESCRIPTION_CHANGED = 'topologyDescriptionChanged' as const;
/** @internal */
export const CONNECTION_POOL_CREATED = 'connectionPoolCreated' as const;
/** @internal */
export const CONNECTION_POOL_CLOSED = 'connectionPoolClosed' as const;
/** @internal */
export const CONNECTION_POOL_CLEARED = 'connectionPoolCleared' as const;
/** @internal */
export const CONNECTION_POOL_READY = 'connectionPoolReady' as const;
/** @internal */
export const CONNECTION_CREATED = 'connectionCreated' as const;
/** @internal */
export const CONNECTION_READY = 'connectionReady' as const;
/** @internal */
export const CONNECTION_CLOSED = 'connectionClosed' as const;
/** @internal */
export const CONNECTION_CHECK_OUT_STARTED = 'connectionCheckOutStarted' as const;
/** @internal */
export const CONNECTION_CHECK_OUT_FAILED = 'connectionCheckOutFailed' as const;
/** @internal */
export const CONNECTION_CHECKED_OUT = 'connectionCheckedOut' as const;
/** @internal */
export const CONNECTION_CHECKED_IN = 'connectionCheckedIn' as const;
export const CLUSTER_TIME_RECEIVED = 'clusterTimeReceived' as const;
export const COMMAND_STARTED = 'commandStarted' as const;
Expand Down
20 changes: 19 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,20 @@ export type { ConnectionPoolMetrics } from './cmap/metrics';
export type { StreamDescription, StreamDescriptionOptions } from './cmap/stream_description';
export type { CompressorName } from './cmap/wire_protocol/compression';
export type { CollectionOptions, CollectionPrivate, ModifyResult } from './collection';
export type { MONGO_CLIENT_EVENTS } from './constants';
export type {
CONNECTION_CHECK_OUT_FAILED,
CONNECTION_CHECK_OUT_STARTED,
CONNECTION_CHECKED_IN,
CONNECTION_CHECKED_OUT,
CONNECTION_CLOSED,
CONNECTION_CREATED,
CONNECTION_POOL_CLEARED,
CONNECTION_POOL_CLOSED,
CONNECTION_POOL_CREATED,
CONNECTION_POOL_READY,
CONNECTION_READY,
MONGO_CLIENT_EVENTS
} from './constants';
export type {
AbstractCursorEvents,
AbstractCursorOptions,
Expand Down Expand Up @@ -290,6 +303,11 @@ export type {
WithSessionCallback
} from './mongo_client';
export type {
Log,
LogConvertible,
Loggable,
LoggableEvent,
MongoDBLogWritable,
MongoLoggableComponent,
MongoLogger,
MongoLoggerEnvOptions,
Expand Down