@mikro-orm/core 7.0.0-dev.337 → 7.0.0-dev.338
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/connections/Connection.d.ts +1 -0
- package/connections/Connection.js +27 -11
- package/logging/DefaultLogger.js +3 -2
- package/logging/Logger.d.ts +2 -1
- package/package.json +1 -1
- package/utils/Configuration.d.ts +23 -0
- package/utils/Configuration.js +16 -0
- package/utils/Utils.js +1 -1
|
@@ -6,6 +6,7 @@ import type { Platform } from '../platforms/Platform.js';
|
|
|
6
6
|
import type { TransactionEventBroadcaster } from '../events/TransactionEventBroadcaster.js';
|
|
7
7
|
import type { IsolationLevel } from '../enums.js';
|
|
8
8
|
export declare abstract class Connection {
|
|
9
|
+
#private;
|
|
9
10
|
protected readonly config: Configuration;
|
|
10
11
|
protected readonly type: ConnectionType;
|
|
11
12
|
protected metadata: MetadataStorage;
|
|
@@ -7,6 +7,12 @@ export class Connection {
|
|
|
7
7
|
options;
|
|
8
8
|
logger;
|
|
9
9
|
connected = false;
|
|
10
|
+
get #connectionLabel() {
|
|
11
|
+
return {
|
|
12
|
+
type: this.type,
|
|
13
|
+
name: this.options.name || this.config.get('name') || this.options.host || this.options.dbName,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
10
16
|
constructor(config, options, type = 'write') {
|
|
11
17
|
this.config = config;
|
|
12
18
|
this.type = type;
|
|
@@ -120,28 +126,38 @@ export class Connection {
|
|
|
120
126
|
const now = Date.now();
|
|
121
127
|
try {
|
|
122
128
|
const res = await cb();
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
affected: Utils.isPlainObject(res) ? res.affectedRows : undefined,
|
|
128
|
-
});
|
|
129
|
+
const took = Date.now() - now;
|
|
130
|
+
const results = Array.isArray(res) ? res.length : undefined;
|
|
131
|
+
const affected = Utils.isPlainObject(res) ? res.affectedRows : undefined;
|
|
132
|
+
this.logQuery(query, { ...context, took, results, affected });
|
|
129
133
|
return res;
|
|
130
134
|
}
|
|
131
135
|
catch (e) {
|
|
132
|
-
|
|
136
|
+
const took = Date.now() - now;
|
|
137
|
+
this.logQuery(query, { ...context, took, level: 'error' });
|
|
133
138
|
throw e;
|
|
134
139
|
}
|
|
135
140
|
}
|
|
136
141
|
logQuery(query, context = {}) {
|
|
142
|
+
const connection = this.#connectionLabel;
|
|
137
143
|
this.logger.logQuery({
|
|
138
144
|
level: 'info',
|
|
139
|
-
connection
|
|
140
|
-
type: this.type,
|
|
141
|
-
name: this.options.name || this.config.get('name') || this.options.host,
|
|
142
|
-
},
|
|
145
|
+
connection,
|
|
143
146
|
...context,
|
|
144
147
|
query,
|
|
145
148
|
});
|
|
149
|
+
const threshold = this.config.get('slowQueryThreshold');
|
|
150
|
+
if (threshold != null && (context.took ?? 0) >= threshold) {
|
|
151
|
+
this.config.getSlowQueryLogger().logQuery({
|
|
152
|
+
...context,
|
|
153
|
+
// `enabled: true` bypasses the debug-mode check in isEnabled(),
|
|
154
|
+
// ensuring slow query logs are always emitted regardless of the `debug` setting.
|
|
155
|
+
enabled: true,
|
|
156
|
+
level: context.level ?? 'warning',
|
|
157
|
+
namespace: 'slow-query',
|
|
158
|
+
connection,
|
|
159
|
+
query,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
146
162
|
}
|
|
147
163
|
}
|
package/logging/DefaultLogger.js
CHANGED
|
@@ -68,7 +68,8 @@ export class DefaultLogger {
|
|
|
68
68
|
* @inheritDoc
|
|
69
69
|
*/
|
|
70
70
|
logQuery(context) {
|
|
71
|
-
|
|
71
|
+
const namespace = context.namespace ?? 'query';
|
|
72
|
+
if (!this.isEnabled(namespace, context)) {
|
|
72
73
|
return;
|
|
73
74
|
}
|
|
74
75
|
/* v8 ignore next */
|
|
@@ -86,7 +87,7 @@ export class DefaultLogger {
|
|
|
86
87
|
if (this.usesReplicas && context.connection) {
|
|
87
88
|
msg += colors.cyan(` (via ${context.connection.type} connection '${context.connection.name}')`);
|
|
88
89
|
}
|
|
89
|
-
return this.log(
|
|
90
|
+
return this.log(namespace, msg, context);
|
|
90
91
|
}
|
|
91
92
|
static create(options) {
|
|
92
93
|
return new DefaultLogger(options);
|
package/logging/Logger.d.ts
CHANGED
|
@@ -22,10 +22,11 @@ export interface Logger {
|
|
|
22
22
|
setDebugMode(debugMode: boolean | LoggerNamespace[]): void;
|
|
23
23
|
isEnabled(namespace: LoggerNamespace, context?: LogContext): boolean;
|
|
24
24
|
}
|
|
25
|
-
export type LoggerNamespace = 'query' | 'query-params' | 'schema' | 'discovery' | 'info' | 'deprecated';
|
|
25
|
+
export type LoggerNamespace = 'query' | 'query-params' | 'schema' | 'discovery' | 'info' | 'deprecated' | 'slow-query';
|
|
26
26
|
export interface LogContext extends Dictionary {
|
|
27
27
|
query?: string;
|
|
28
28
|
label?: string;
|
|
29
|
+
namespace?: LoggerNamespace;
|
|
29
30
|
params?: readonly unknown[];
|
|
30
31
|
took?: number;
|
|
31
32
|
results?: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mikro-orm/core",
|
|
3
|
-
"version": "7.0.0-dev.
|
|
3
|
+
"version": "7.0.0-dev.338",
|
|
4
4
|
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"data-mapper",
|
package/utils/Configuration.d.ts
CHANGED
|
@@ -36,6 +36,11 @@ export declare class Configuration<D extends IDatabaseDriver = IDatabaseDriver,
|
|
|
36
36
|
* Gets Logger instance.
|
|
37
37
|
*/
|
|
38
38
|
getLogger(): Logger;
|
|
39
|
+
/**
|
|
40
|
+
* Gets the logger instance for slow queries.
|
|
41
|
+
* Falls back to the main logger if no custom slow query logger factory is configured.
|
|
42
|
+
*/
|
|
43
|
+
getSlowQueryLogger(): Logger;
|
|
39
44
|
getDataloaderType(): DataloaderType;
|
|
40
45
|
getSchema(skipDefaultSchema?: boolean): string | undefined;
|
|
41
46
|
/**
|
|
@@ -671,6 +676,24 @@ export interface Options<Driver extends IDatabaseDriver = IDatabaseDriver, EM ex
|
|
|
671
676
|
* @default DefaultLogger.create
|
|
672
677
|
*/
|
|
673
678
|
loggerFactory?: (options: LoggerOptions) => Logger;
|
|
679
|
+
/**
|
|
680
|
+
* Threshold in milliseconds for logging slow queries.
|
|
681
|
+
* Queries taking at least this long will be logged via the 'slow-query' namespace at warning level.
|
|
682
|
+
* Slow query logs are always emitted when the threshold is met, regardless of the `debug` setting.
|
|
683
|
+
* Set to `0` to log every query as slow.
|
|
684
|
+
* @default undefined (slow query logging disabled)
|
|
685
|
+
*/
|
|
686
|
+
slowQueryThreshold?: number;
|
|
687
|
+
/**
|
|
688
|
+
* Factory function to create a custom logger instance for slow queries.
|
|
689
|
+
* Has the same shape as `loggerFactory`. When not provided, the main logger instance is used.
|
|
690
|
+
*
|
|
691
|
+
* Note: slow query log entries are emitted with `context.enabled = true` to bypass the
|
|
692
|
+
* debug-mode check. Custom logger implementations must respect `context.enabled` in their
|
|
693
|
+
* `isEnabled()` method (as `DefaultLogger` does) to ensure slow query logs are always emitted.
|
|
694
|
+
* @default undefined (falls back to main logger)
|
|
695
|
+
*/
|
|
696
|
+
slowQueryLoggerFactory?: (options: LoggerOptions) => Logger;
|
|
674
697
|
/**
|
|
675
698
|
* Custom error handler for `em.findOneOrFail()` when no entity is found.
|
|
676
699
|
* @param entityName - Name of the entity being queried
|
package/utils/Configuration.js
CHANGED
|
@@ -130,6 +130,7 @@ const DEFAULTS = {
|
|
|
130
130
|
export class Configuration {
|
|
131
131
|
#options;
|
|
132
132
|
#logger;
|
|
133
|
+
#slowQueryLogger;
|
|
133
134
|
#driver;
|
|
134
135
|
#platform;
|
|
135
136
|
#cache = new Map();
|
|
@@ -195,6 +196,20 @@ export class Configuration {
|
|
|
195
196
|
getLogger() {
|
|
196
197
|
return this.#logger;
|
|
197
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Gets the logger instance for slow queries.
|
|
201
|
+
* Falls back to the main logger if no custom slow query logger factory is configured.
|
|
202
|
+
*/
|
|
203
|
+
getSlowQueryLogger() {
|
|
204
|
+
this.#slowQueryLogger ??=
|
|
205
|
+
this.#options.slowQueryLoggerFactory?.({
|
|
206
|
+
debugMode: this.#options.debug,
|
|
207
|
+
writer: this.#options.logger,
|
|
208
|
+
highlighter: this.#options.highlighter,
|
|
209
|
+
usesReplicas: (this.#options.replicas?.length ?? 0) > 0,
|
|
210
|
+
}) ?? this.#logger;
|
|
211
|
+
return this.#slowQueryLogger;
|
|
212
|
+
}
|
|
198
213
|
getDataloaderType() {
|
|
199
214
|
if (typeof this.#options.dataloader === 'boolean') {
|
|
200
215
|
return this.#options.dataloader ? DataloaderType.ALL : DataloaderType.NONE;
|
|
@@ -337,6 +352,7 @@ export class Configuration {
|
|
|
337
352
|
sync() {
|
|
338
353
|
setEnv('MIKRO_ORM_COLORS', this.#options.colors);
|
|
339
354
|
this.#logger.setDebugMode(this.#options.debug);
|
|
355
|
+
this.#slowQueryLogger = undefined;
|
|
340
356
|
}
|
|
341
357
|
validateOptions() {
|
|
342
358
|
/* v8 ignore next */
|
package/utils/Utils.js
CHANGED
|
@@ -123,7 +123,7 @@ export function parseJsonSafe(value) {
|
|
|
123
123
|
}
|
|
124
124
|
export class Utils {
|
|
125
125
|
static PK_SEPARATOR = '~~~';
|
|
126
|
-
static #ORM_VERSION = '7.0.0-dev.
|
|
126
|
+
static #ORM_VERSION = '7.0.0-dev.338';
|
|
127
127
|
/**
|
|
128
128
|
* Checks if the argument is instance of `Object`. Returns false for arrays.
|
|
129
129
|
*/
|