Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: should invoke custom logger#12034

Open
gioboa wants to merge 13 commits intotypeorm:masterfrom
gioboa:fix/10174
Open

fix: should invoke custom logger#12034
gioboa wants to merge 13 commits intotypeorm:masterfrom
gioboa:fix/10174

Conversation

@gioboa
Copy link
Collaborator

@gioboa gioboa commented Feb 23, 2026

Close #10174

Description of change

Pull-Request Checklist

  • Code is up-to-date with the master branch
  • This pull request links relevant issues as Fixes #00000
  • There are new or updated tests validating the change (tests/**.test.ts)
  • Documentation has been updated to reflect this change (docs/docs/**.md)

@qodo-free-for-open-source-projects

User description

Close #10174

Description of change

Pull-Request Checklist

  • Code is up-to-date with the master branch
  • This pull request links relevant issues as Fixes #00000
  • There are new or updated tests validating the change (tests/**.test.ts)
  • Documentation has been updated to reflect this change (docs/docs/**.md)

PR Type

Bug fix, Tests


Description

  • Add setOptions() method to AbstractLogger for configuring logger instances

  • Update LoggerFactory to invoke setOptions() on custom logger instances

  • Add comprehensive test for custom logger extending AbstractLogger

  • Create test entity Post for logger functional tests


Diagram Walkthrough

flowchart LR
  A["LoggerFactory.create()"] -->|"receives custom logger"| B["Check if AbstractLogger instance"]
  B -->|"yes + options defined"| C["Invoke setOptions()"]
  C -->|"configure logger"| D["Return configured logger"]
  B -->|"no or no options"| D
  E["AbstractLogger.setOptions()"] -->|"stores options"| F["Logger ready for use"]
Loading

File Walkthrough

Relevant files
Enhancement
AbstractLogger.ts
Add setOptions method to AbstractLogger                                   

src/logger/AbstractLogger.ts

  • Add setOptions() method to allow configuration of logger instances
    after creation
  • Method accepts LoggerOptions parameter and stores it in protected
    options property
  • Includes JSDoc documentation explaining the method's purpose
+9/-0     
Bug fix
LoggerFactory.ts
Invoke setOptions on custom logger instances                         

src/logger/LoggerFactory.ts

  • Import AbstractLogger class for instanceof checks
  • Modify create() method to detect custom logger instances extending
    AbstractLogger
  • Call setOptions() on custom logger instances when options are provided
  • Preserve existing behavior for non-custom logger types
+7/-1     
Tests
custom-logger.test.ts
Add custom logger functional test suite                                   

test/functional/logger/custom-logger.test.ts

  • Create comprehensive test suite for custom logger extending
    AbstractLogger
  • Implement CustomLogger class that overrides writeLog() method
  • Test that custom logger receives and logs query events when logging is
    enabled
  • Verify fix for issue Custom logger not working #10174 by checking logger invocation on database
    operations
+62/-0   
Post.ts
Add Post entity for logger tests                                                 

test/functional/logger/entity/Post.ts

  • Create simple Post entity with id and title columns
  • Used as test fixture for custom logger functional tests
  • Decorated with TypeORM entity and column decorators
+12/-0   

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 23, 2026

commit: be13a90

@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Feb 23, 2026

PR Code Suggestions ✨

Latest suggestions up to aab5cec

CategorySuggestion                                                                                                                                    Impact
Possible issue
Preserve custom logger object handling

Fix a regression by ensuring custom logger objects are always returned, and only
update their options if options are provided and the logger supports it.

src/logger/LoggerFactory.ts [29-32]

-if (ObjectUtils.isObject(logger) && "options" in logger && options) {
-    logger.options = options
-    return logger
+if (ObjectUtils.isObject(logger)) {
+    if (options && "options" in (logger as any)) {
+        ;(logger as any).options = options
+    }
+    return logger as Logger
 }
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a regression bug where passing a custom logger object could fail, and provides a robust fix that preserves the intended functionality while also implementing the new feature.

High
  • More

Previous suggestions

Suggestions up to commit 6bb9a69
CategorySuggestion                                                                                                                                    Impact
Possible issue
Always return custom logger instances

Refactor the logic to ensure custom logger objects are always returned, and only
update their options if provided, preventing them from being incorrectly
processed as string-based logger types.

src/logger/LoggerFactory.ts [29-37]

-if (ObjectUtils.isObject(logger) && "options" in logger && options) {
-    logger.options = options
-    return logger
+if (ObjectUtils.isObject(logger)) {
+    if (
+        options &&
+        typeof (logger as any).options !== "undefined"
+    ) {
+        ;(logger as any).options = options
+    }
+    return logger as Logger
 }
 
 if (logger) {
     switch (logger) {
         case "simple-console":
             return new SimpleConsoleLogger(options)
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug introduced in the PR where passing a custom logger object without options would cause it to be incorrectly handled by the subsequent switch statement.

Medium
Suggestions up to commit 29c5cc2
CategorySuggestion                                                                                                                                    Impact
Possible issue
Preserve custom logger instance handling

Restore the previous behavior of always returning a custom logger instance if
it's an object, and optionally set its options if provided, to prevent a
regression where some custom loggers would be ignored.

src/logger/LoggerFactory.ts [29-37]

-if (ObjectUtils.isObject(logger) && "options" in logger && options) {
-    logger.options = options
-    return logger
+if (ObjectUtils.isObject(logger)) {
+    if (options && "options" in (logger as any)) {
+        ;(logger as any).options = options
+    }
+    return logger as Logger
 }
 
 if (logger) {
     switch (logger) {
         case "simple-console":
             return new SimpleConsoleLogger(options)
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a regression bug where custom logger objects might be ignored, and provides a robust fix that preserves existing functionality while adding the new feature.

High
General
Avoid exposing mutable configuration publicly

Revert the options property in the AbstractLogger constructor to protected and
introduce a public setOptions method to prevent uncontrolled external mutations.

src/logger/AbstractLogger.ts [17]

-constructor(public options?: LoggerOptions) {}
+constructor(protected options?: LoggerOptions) {}
 
+setOptions(options?: LoggerOptions) {
+    this.options = options
+}
+
Suggestion importance[1-10]: 6

__

Why: The suggestion proposes a good practice for encapsulation by making the options property protected and adding a setter, which improves code design and maintainability.

Low
✅ Suggestions up to commit 9aafcaf
CategorySuggestion                                                                                                                                    Impact
Possible issue
Fix object logger handling
Suggestion Impact:The commit modified the object-logger branch to guard option assignment by checking `"options" in logger` before mutating, partially addressing the unsafe mutation concern raised in the suggestion. However, it did not implement the suggested behavior of returning object loggers even when `options` is not provided, nor did it use `instanceof AbstractLogger`.

code diff:

-        if (ObjectUtils.isObject(logger) && options) {
-            const instance = logger as AbstractLogger
-            instance.options = options
-            return instance
+        if (ObjectUtils.isObject(logger) && "options" in logger && options) {
+            logger.options = options
+            return logger
         }

Restore the original behavior for custom object loggers by returning them
immediately, and only apply options if the logger is an instance of
AbstractLogger to avoid unsafe mutations and incorrect fall-through logic.

src/logger/LoggerFactory.ts [29-33]

-if (ObjectUtils.isObject(logger) && options) {
-    const instance = logger as AbstractLogger
-    instance.options = options
-    return instance
+if (ObjectUtils.isObject(logger)) {
+    if (options && logger instanceof AbstractLogger) {
+        logger.options = options
+    }
+    return logger as Logger
 }
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a regression and a bug introduced by the PR where custom object loggers are not handled correctly if options are not provided, and it also points out an unsafe type cast. The proposed fix is correct and robust.

High
General
Prevent cross-connection option bleed

To prevent options from one data source affecting another when a logger instance
is shared, create a new logger instance with the new options instead of mutating
the existing one.

src/logger/LoggerFactory.ts [29-33]

-if (ObjectUtils.isObject(logger) && options) {
-    const instance = logger as AbstractLogger
-    instance.options = options
-    return instance
+if (ObjectUtils.isObject(logger)) {
+    if (options && logger instanceof AbstractLogger) {
+        const Ctor = logger.constructor as new (options?: LoggerOptions) => AbstractLogger
+        return new Ctor(options)
+    }
+    return logger as Logger
 }
Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a potential issue with mutating a shared logger instance across multiple connections. However, the proposed solution of creating a new instance might be a significant breaking change and not always the desired behavior.

Medium
✅ Suggestions up to commit b57daa0
CategorySuggestion                                                                                                                                    Impact
General
Copy options to avoid mutation

In the setOptions method, create a shallow copy of the options object (e.g.,
using { ...options }) before assigning it to this.options to prevent unintended
side effects from external mutations.

src/logger/AbstractLogger.ts [28-30]

-setOptions(options: LoggerOptions) {
-    this.options = options
+setOptions(options: LoggerOptions): void {
+    this.options = { ...options }
 }
Suggestion importance[1-10]: 6

__

Why: This is a good defensive programming practice that makes the logger's configuration immutable after being set, preventing potential side effects from external mutations of the options object.

Low
Call custom option setter safely
Suggestion Impact:The commit refactored the logger-options handling by introducing a local casted variable (`instance`) and removing the `setOptions!` non-null assertion/call, instead setting options directly on an `AbstractLogger` instance.

code diff:

-        if (ObjectUtils.isObject(logger)) {
-            if (
-                options !== undefined &&
-                typeof (logger as Logger).setOptions === "function"
-            ) {
-                ;(logger as Logger).setOptions!(options)
-            }
-            return logger as Logger
+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
         }

Refactor the logic for setting logger options by first casting logger to a
customLogger variable, then using this variable for the type check and method
call to improve readability and remove the non-null assertion.

src/logger/LoggerFactory.ts [28-36]

 if (ObjectUtils.isObject(logger)) {
-    if (
-        options !== undefined &&
-        typeof (logger as Logger).setOptions === "function"
-    ) {
-        ;(logger as Logger).setOptions!(options)
+    const customLogger = logger as Logger
+    if (options !== undefined && typeof customLogger.setOptions === "function") {
+        customLogger.setOptions(options)
     }
-    return logger as Logger
+    return customLogger
 }
Suggestion importance[1-10]: 5

__

Why: The suggestion improves code readability and safety by introducing a typed local variable, which eliminates repeated type casting and a non-null assertion.

Low
Possible issue
Fix strict property initialization

Add definite assignment assertions (!) to the id and title properties in the
Post entity to prevent potential strictPropertyInitialization errors in
TypeScript.

test/functional/logger/entity/Post.ts [6-12]

 export class Post {
     @PrimaryGeneratedColumn()
-    id: number
+    id!: number
 
     @Column()
-    title: string
+    title!: string
 }
Suggestion importance[1-10]: 4

__

Why: The suggestion correctly points out a potential issue with strictPropertyInitialization and offers a valid fix, which is good practice for code in a new test file.

Low
✅ Suggestions up to commit 8045769
CategorySuggestion                                                                                                                                    Impact
Possible issue
Pass options even when falsy
Suggestion Impact:Updated the condition from `options &&` to `options !== undefined &&`, ensuring setOptions is invoked even when options is falsy.

code diff:

@@ -27,7 +27,7 @@
     ): Logger {
         if (ObjectUtils.isObject(logger)) {
             if (
-                options &&
+                options !== undefined &&
                 typeof (logger as Logger).setOptions === "function"
             ) {
                 ;(logger as Logger).setOptions!(options)

In LoggerFactory.ts, change the condition for calling setOptions from checking
truthiness of options to options !== undefined to correctly handle falsy values.

src/logger/LoggerFactory.ts [28-36]

 if (ObjectUtils.isObject(logger)) {
     if (
-        options &&
+        options !== undefined &&
         typeof (logger as Logger).setOptions === "function"
     ) {
         ;(logger as Logger).setOptions!(options)
     }
     return logger as Logger
 }
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a bug where falsy LoggerOptions (like false) would not be passed to the custom logger, which defeats the purpose of the change for disabling logging.

Medium
✅ Suggestions up to commit 216b2b3
CategorySuggestion                                                                                                                                    Impact
Possible issue
Always apply passed logger options
Suggestion Impact:Removed the this.options === undefined check so setOptions now unconditionally overwrites this.options with the passed options.

code diff:

     setOptions(options: LoggerOptions) {
-        if (this.options === undefined) {
-            this.options = options
-        }
+        this.options = options
     }

Modify the setOptions method to unconditionally assign the provided options,
removing the this.options === undefined check, to allow for overriding existing
logger configurations.

src/logger/AbstractLogger.ts [28-32]

 setOptions(options: LoggerOptions) {
-    if (this.options === undefined) {
-        this.options = options
-    }
+    this.options = options
 }
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies a logical flaw in the new setOptions method. The proposed change to always assign options makes the feature more robust and aligns better with expected behavior, especially when reusing logger instances or overriding default configurations.

Low
General
Use a type-safe options hook
Suggestion Impact:The commit removed the `any` casts around `setOptions` and replaced them with a `Logger` cast and a non-null assertion when invoking `setOptions`, improving type safety, though it did not implement the suggested structural intersection type guard.

code diff:

             if (
-                options !== undefined &&
-                typeof (logger as any).setOptions === "function"
+                options &&
+                typeof (logger as Logger).setOptions === "function"
             ) {
-                ;(logger as any).setOptions(options)
+                ;(logger as Logger).setOptions!(options)
             }

In LoggerFactory.ts, replace the any cast when calling setOptions with a
type-safe structural type guard to improve code quality and maintainability.

src/logger/LoggerFactory.ts [28-36]

 if (ObjectUtils.isObject(logger)) {
-    if (
-        options !== undefined &&
-        typeof (logger as any).setOptions === "function"
-    ) {
-        ;(logger as any).setOptions(options)
+    const configurableLogger = logger as Logger & {
+        setOptions?: (options: LoggerOptions) => void
     }
+
+    if (options !== undefined && typeof configurableLogger.setOptions === "function") {
+        configurableLogger.setOptions(options)
+    }
+
     return logger as Logger
 }
Suggestion importance[1-10]: 5

__

Why: The suggestion improves code quality by replacing an any cast with a more type-safe approach using an intersection type. This enhances type safety and readability without changing the runtime behavior.

Low
✅ Suggestions up to commit 58b6d04
CategorySuggestion                                                                                                                                    Impact
Possible issue
Ensure options are always applied
Suggestion Impact:The commit changed setOptions to always assign the provided options (removing the guard that prevented applying DataSource options when defaults already existed), but it did not implement the suggested merge with existing options.

code diff:

     setOptions(options: LoggerOptions) {
-        if (this.options === undefined) {
-            this.options = options
-        }
+        this.options = options
     }

Modify the setOptions method to merge the provided options with any existing
ones, ensuring that the DataSource options are always applied and take
precedence.

src/logger/AbstractLogger.ts [27-32]

 /**
  * Sets logger options. Used to pass DataSource logging options
  * to custom logger instances.
  * @param options
  */
 setOptions(options: LoggerOptions) {
-    if (this.options === undefined) {
-        this.options = options
-    }
+    this.options = { ...(this.options ?? {}), ...options }
 }
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly identifies that setOptions will not apply DataSource options if the custom logger already has default options, and proposes a fix to merge them, which is more robust.

Low
✅ Suggestions up to commit bc6cd5f
CategorySuggestion                                                                                                                                    Impact
General
Merge new logger options
Suggestion Impact:The commit changed setOptions to avoid overwriting existing options by only assigning when this.options is undefined, partially addressing the concern about losing pre-configured settings (but it does not merge options as suggested).

code diff:

     setOptions(options: LoggerOptions) {
-        this.options = options
+        if (this.options === undefined) {
+            this.options = options
+        }

In AbstractLogger.ts, modify the setOptions method to merge the new options with
any existing options, rather than completely overwriting them.

src/logger/AbstractLogger.ts [28-30]

-setOptions(options: LoggerOptions) {
-    this.options = options
+public setOptions(options: LoggerOptions): void {
+    this.options = { ...this.options, ...options }
 }
Suggestion importance[1-10]: 7

__

Why: This is a valuable improvement that makes the new setOptions method more robust by merging options instead of overwriting them, preventing the loss of pre-configured settings on a custom logger.

Medium
Avoid overwriting options with empty value
Suggestion Impact:The commit modified the same LoggerFactory option-application logic to only assign options when an options value is provided (truthy) and the logger has an "options" property, changing from calling setOptions to direct assignment. However, it did not implement the suggested non-empty (Object.keys(options).length > 0) guard, so empty-object overwrites may still occur.

code diff:

-        if (ObjectUtils.isObject(logger)) {
-            if (logger instanceof AbstractLogger && options !== undefined) {
-                logger.setOptions(options)
-            }
-            return logger as Logger
+        if (ObjectUtils.isObject(logger) && "options" in logger && options) {
+            logger.options = options
+            return logger
         }

In LoggerFactory.ts, avoid overwriting logger options by adding a check to
ensure the options object is not empty before calling
logger.setOptions(options).

src/logger/LoggerFactory.ts [30-35]

 if (ObjectUtils.isObject(logger)) {
-    if (logger instanceof AbstractLogger && options !== undefined) {
+    if (logger instanceof AbstractLogger && options !== undefined && Object.keys(options).length > 0) {
         logger.setOptions(options)
     }
     return logger as Logger
 }
Suggestion importance[1-10]: 6

__

Why: This suggestion correctly identifies a potential issue where logger options could be unintentionally overwritten with an empty object, and the proposed fix is a simple and effective guard against this behavior.

Low
Remove redundant fake reset inside test

Remove the redundant fakeLog.resetHistory() call from the test case in
custom-logger.test.ts, as it is already being called in the beforeEach hook.

test/functional/logger/custom-logger.test.ts [49]

-const fakeLog = sinon.fake()
+it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+    Promise.all(
+        dataSources.map(async (dataSource) => {
+            const repository = dataSource.getRepository(Post)
+            await repository.save({ title: "test" })
+            await repository.find()
 
-class CustomLogger extends AbstractLogger {
+            expect(fakeLog.called).to.be.true
+            const queryLogs = fakeLog
+                .getCalls()
+                .filter((call: any) => call.args[0] === "query")
+            expect(queryLogs.length).to.be.greaterThan(0)
+        }),
+    ))
Suggestion importance[1-10]: 3

__

Why: The suggestion correctly identifies a redundant line of code in the test suite. Removing it improves test code quality and clarity, although it has no impact on the production code.

Low

@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Feb 23, 2026

Code Review by Qodo

🐞 Bugs (42) 📘 Rule violations (39) 📎 Requirement gaps (0)

Grey Divider


Action required

1. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (72)
4. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. setOptions skips false🐞 Bug ✓ Correctness
Description
LoggerFactory only calls setOptions when options is truthy, so logging: false is never
propagated to custom logger instances. This can cause unexpected logging behavior when a custom
logger has its own internal default options and expects DataSource’s logging to override it.
Code

src/logger/LoggerFactory.ts[R29-34]

+            if (
+                options &&
+                typeof (logger as Logger).setOptions === "function"
+            ) {
+                ;(logger as Logger).setOptions!(options)
+            }
Evidence
LoggerOptions explicitly allows a boolean value, including false, but LoggerFactory guards
setOptions with options && ..., so it won’t run for false. Since DataSource passes
options.logging directly into LoggerFactory.create, a custom logger instance can miss the
intended logging configuration; for AbstractLogger-based loggers, whether query/error logs run
depends directly on this.options (e.g., this.options === true).

src/logger/LoggerFactory.ts[18-36]
src/logger/LoggerOptions.ts[1-7]
src/data-source/DataSource.ts[141-148]
src/logger/AbstractLogger.ts[242-259]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory` currently guards the `setOptions` invocation with `options && ...`, which prevents propagating `logging: false` (a valid `LoggerOptions`). This means custom logger instances may not reflect the DataSource’s desired logging configuration.
### Issue Context
- `LoggerOptions` includes `boolean`, so `false` is meaningful.
- `DataSource` passes `options.logging` to `LoggerFactory.create`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[28-36]
- src/logger/LoggerOptions.ts[1-7]
- src/data-source/DataSource.ts[145-148]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. Unsafe logger as AbstractLogger📘 Rule violation ✓ Correctness
Description
LoggerFactory.create() uses a type assertion to treat any object logger as AbstractLogger and
mutates instance.options without a runtime type guard. This bypasses type safety and can lead to
incorrect behavior when a custom logger object is not an AbstractLogger instance.
Code

src/logger/LoggerFactory.ts[R29-32]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
Evidence
The compliance checklist forbids type-bypassing casts/style noise; the new code asserts logger is
AbstractLogger and writes to options without verifying the object is actually an
AbstractLogger instance.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[29-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` currently uses `logger as AbstractLogger` and mutates `instance.options` without confirming the object is an `AbstractLogger`, which bypasses type safety and can mis-handle custom logger objects.
## Issue Context
The factory method accepts `Logger` (interface) instances; not all such objects are guaranteed to extend `AbstractLogger`. Add a runtime check before treating an object as `AbstractLogger`, and ensure custom logger objects that are not `AbstractLogger` are still returned/handled safely.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[29-33]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. Custom logger ignored🐞 Bug ✓ Correctness
Description
LoggerFactory.create only returns an object logger when options is truthy; if logging is
undefined or false, the provided custom logger instance is discarded and a default
AdvancedConsoleLogger is returned. This breaks the documented configuration pattern (`logger: new
MyCustomLogger() without logging`) and existing tests that pass a logger instance via
createLogger().
Code

src/logger/LoggerFactory.ts[R29-33]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
+        }
Evidence
LoggerFactory now gates returning a provided logger instance on options being truthy. DataSource
passes this.options.logging as options, which may be undefined or false; docs explicitly show
configuring a custom logger without setting logging; and at least one functional test passes a
logger instance without setting logging. With the new condition, those scenarios skip returning the
custom logger, then fall through the string switch (no cases match for an object) and return the
default AdvancedConsoleLogger.

src/logger/LoggerFactory.ts[19-55]
src/data-source/DataSource.ts[141-148]
src/logger/LoggerOptions.ts[1-7]
docs/docs/advanced-topics/5-logging.md[176-192]
test/functional/repository/find-options/repository-find-options.test.ts[241-252]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create` currently only returns a provided logger instance when `options` is truthy. When `logging` is `undefined` or `false`, the provided logger instance is ignored and the factory returns the default `AdvancedConsoleLogger`, breaking documented usage (`logger: new MyCustomLogger()` without `logging`) and existing tests.
### Issue Context
- `DataSource` passes `options.logging` to `LoggerFactory.create`, which can be `undefined` or `false`.
- `LoggerOptions` explicitly allows `false`.
- The logging docs show specifying a custom logger instance without specifying `logging`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[19-55]
### Suggested change (high level)
1. If `logger` is an object, always return it as `Logger`.
2. If the object is an `AbstractLogger` and `options !== undefined`, propagate `options` safely:
- Prefer `if (logger instanceof AbstractLogger && options !== undefined && logger.options === undefined) logger.options = options` to avoid clobbering logger instances already configured via their constructor.
- Do **not** cast/mutate arbitrary `Logger` implementations that don’t extend `AbstractLogger`.
3. Consider adding/adjusting a test to cover `createLogger` with `logging` omitted or set to `false` to prevent regressions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


16. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


18. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


19. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


20. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


21. Unsafe logger as AbstractLogger📘 Rule violation ✓ Correctness
Description
LoggerFactory.create() uses a type assertion to treat any object logger as AbstractLogger and
mutates instance.options without a runtime type guard. This bypasses type safety and can lead to
incorrect behavior when a custom logger object is not an AbstractLogger instance.
Code

src/logger/LoggerFactory.ts[R29-32]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
Evidence
The compliance checklist forbids type-bypassing casts/style noise; the new code asserts logger is
AbstractLogger and writes to options without verifying the object is actually an
AbstractLogger instance.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[29-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` currently uses `logger as AbstractLogger` and mutates `instance.options` without confirming th...

@coveralls
Copy link

coveralls commented Feb 24, 2026

Coverage Status

coverage: 81.424% (+0.004%) from 81.42%
when pulling 1d15330 on gioboa:fix/10174
into ef596c3 on typeorm:master.

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@gioboa gioboa requested a review from pkuczynski February 24, 2026 15:19
@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (12) 📘 Rule violations (11) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Unsafe logger as AbstractLogger 📘 Rule violation ✓ Correctness ⭐ New
Description
LoggerFactory.create() uses a type assertion to treat any object logger as AbstractLogger and
mutates instance.options without a runtime type guard. This bypasses type safety and can lead to
incorrect behavior when a custom logger object is not an AbstractLogger instance.
Code

src/logger/LoggerFactory.ts[R29-32]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
Evidence
The compliance checklist forbids type-bypassing casts/style noise; the new code asserts logger is
AbstractLogger and writes to options without verifying the object is actually an
AbstractLogger instance.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[29-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` currently uses `logger as AbstractLogger` and mutates `instance.options` without confirming the object is an `AbstractLogger`, which bypasses type safety and can mis-handle custom logger objects.

## Issue Context
The factory method accepts `Logger` (interface) instances; not all such objects are guaranteed to extend `AbstractLogger`. Add a runtime check before treating an object as `AbstractLogger`, and ensure custom logger objects that are not `AbstractLogger` are still returned/handled safely.

## Fix Focus Areas
- src/logger/LoggerFactory.ts[29-33]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Custom logger ignored 🐞 Bug ✓ Correctness ⭐ New
Description
LoggerFactory.create only returns an object logger when options is truthy; if logging is
undefined or false, the provided custom logger instance is discarded and a default
AdvancedConsoleLogger is returned. This breaks the documented configuration pattern (`logger: new
MyCustomLogger() without logging`) and existing tests that pass a logger instance via
createLogger().
Code

src/logger/LoggerFactory.ts[R29-33]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
+        }
Evidence
LoggerFactory now gates returning a provided logger instance on options being truthy. DataSource
passes this.options.logging as options, which may be undefined or false; docs explicitly show
configuring a custom logger without setting logging; and at least one functional test passes a
logger instance without setting logging. With the new condition, those scenarios skip returning the
custom logger, then fall through the string switch (no cases match for an object) and return the
default AdvancedConsoleLogger.

src/logger/LoggerFactory.ts[19-55]
src/data-source/DataSource.ts[141-148]
src/logger/LoggerOptions.ts[1-7]
docs/docs/advanced-topics/5-logging.md[176-192]
test/functional/repository/find-options/repository-find-options.test.ts[241-252]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`LoggerFactory.create` currently only returns a provided logger instance when `options` is truthy. When `logging` is `undefined` or `false`, the provided logger instance is ignored and the factory returns the default `AdvancedConsoleLogger`, breaking documented usage (`logger: new MyCustomLogger()` without `logging`) and existing tests.

### Issue Context
- `DataSource` passes `options.logging` to `LoggerFactory.create`, which can be `undefined` or `false`.
- `LoggerOptions` explicitly allows `false`.
- The logging docs show specifying a custom logger instance without specifying `logging`.

### Fix Focus Areas
- src/logger/LoggerFactory.ts[19-55]

### Suggested change (high level)
1. If `logger` is an object, always return it as `Logger`.
2. If the object is an `AbstractLogger` and `options !== undefined`, propagate `options` safely:
  - Prefer `if (logger instanceof AbstractLogger && options !== undefined && logger.options === undefined) logger.options = options` to avoid clobbering logger instances already configured via their constructor.
  - Do **not** cast/mutate arbitrary `Logger` implementations that don’t extend `AbstractLogger`.
3. Consider adding/adjusting a test to cover `createLogger` with `logging` omitted or set to `false` to prevent regressions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (12)
4. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Stale logger options 🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. setOptions skips false🐞 Bug ✓ Correctness
Description
LoggerFactory only calls setOptions when options is truthy, so logging: false is never
propagated to custom logger instances. This can cause unexpected logging behavior when a custom
logger has its own internal default options and expects DataSource’s logging to override it.
Code

src/logger/LoggerFactory.ts[R29-34]

+            if (
+                options &&
+                typeof (logger as Logger).setOptions === "function"
+            ) {
+                ;(logger as Logger).setOptions!(options)
+            }
Evidence
LoggerOptions explicitly allows a boolean value, including false, but LoggerFactory guards
setOptions with options && ..., so it won’t run for false. Since DataSource passes
options.logging directly into LoggerFactory.create, a custom logger instance can miss the
intended logging configuration; for AbstractLogger-based loggers, whether query/error logs run
depends directly on this.options (e.g., this.options === true).

src/logger/LoggerFactory.ts[18-36]
src/logger/LoggerOptions.ts[1-7]
src/data-source/DataSource.ts[141-148]
src/logger/AbstractLogger.ts[242-259]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory` currently guards the `setOptions` invocation with `options && ...`, which prevents propagating `logging: false` (a valid `LoggerOptions`). This means custom logger instances may not reflect the DataSource’s desired logging configuration.
### Issue Context
- `LoggerOptions` includes `boolean`, so `false` is meaningful.
- `DataSource` passes `options.logging` to `LoggerFactory.create`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[28-36]
- src/logger/LoggerOptions.ts[1-7]
- src/data-source/DataSource.ts[145-148]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. Stale logger options 🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

16. Test uses any cast📘 Rule violation ✓ Correctness
Description
The new functional test introduces an explicit any type in .filter((call: any) => ...), which is
a type-safety bypass. This violates the requirement to avoid AI-like noise such as any casts to
bypass type issues.
Code

test/functional/logger/custom-logger.test.ts[58]

+                    .filter((call: any) => call.args[0] === "query")
Evidence
The compliance checklist forbids introducing any casts to bypass typing. The added test uses
(call: any) even though Sinon call types can be inferred or typed more precisely.

Rule 4: Remove AI-generated noise
test/functional/logger/custom-logger.test.ts[56-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test introduces an explicit `any` cast in a filter callback, bypassing type safety.
## Issue Context
Rule 4 requires avoiding `any` casts added to silence or bypass TypeScript typing issues.
## Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[56-59] ևս

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. Shared logger options mutation🐞 Bug ✓ Correctness
Description
LoggerFactory.create mutates a user-supplied logger instance by calling setOptions. If the same
logger instance is reused across multiple DataSources (or reconfigured), the last options applied
can unexpectedly affect all users of that shared instance.
Code

src/logger/LoggerFactory.ts[R30-34]

+        if (ObjectUtils.isObject(logger)) {
+            if (logger instanceof AbstractLogger && options !== undefined) {
+                logger.setOptions(options)
+            }
+            return logger as Logger
Evidence
DataSource passes options.logger (which can be a user-provided object) into
LoggerFactory.create, and the factory now mutates that instance in-place by calling setOptions,
which directly overwrites AbstractLogger.options. This creates cross-DataSource coupling when a
single logger object is shared.

src/data-source/DataSource.ts[141-148]
src/logger/LoggerFactory.ts[30-35]
src/logger/AbstractLogger.ts[17-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` calls `setOptions()` on a user-provided logger instance. If consumers reuse the same logger object across multiple `DataSource`s with different `logging` options, the last `DataSource` to initialize (or update) will overwrite the options for all, producing confusing/incorrect logging.
### Issue Context
- `DataSource` passes `options.logger` into `LoggerFactory.create`.
- The factory now mutates the instance via `setOptions`, which overwrites the shared instance state.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[30-35]
- src/logger/AbstractLogger.ts[17-30]
- src/data-source/DataSource.ts[141-148]
### Suggested direction
Option A (behavioral mitigation): If `logger` is an object and supports `setOptions`, return a *wrapper* logger per `DataSource` that calls `logger.setOptions(options)` at the start of each log method, then delegates to the underlying logger. This reduces persistent cross-DataSource coupling while keeping the fix for #10174.
Option B (doc/API contract): Explicitly document (and potentially assert in dev) that `options.logger` must be a fresh instance per `DataSource` if it is stateful (like `AbstractLogger`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


18. Test uses any cast📘 Rule violation ✓ Correctness
Description
The new functional test introduces an explicit any type in .filter((call: any) => ...), which is
a type-safety bypass. This violates the requirement to avoid AI-like noise such as any casts to
bypass type issues.
Code

test/functional/logger/custom-logger.test.ts[58]

+                    .filter((call: any) => call.args[0] === "query")
Evidence
The compliance checklist forbids introducing any casts to bypass typing. The added test uses
(call: any) even though Sinon call types can be inferred or typed more precisely.

Rule 4: Remove AI-generated noise
test/functional/logger/custom-logger.test.ts[56-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test introduces an explicit `any` cast in a filter callback, bypassing type safety.
## Issue Context
Rule 4 requires avoiding `any` casts added to silence or bypass TypeScript typing issues.
## Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[56-59] ևս

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (5)
19. Shared logger options mutation🐞 Bug ✓ Correctness
Description
LoggerFactory.create mutates a user-supplied logger instance by calling setOptions. If the same
logger instance is reused across multiple DataSources (or reconfigured), the last options applied
can unexpectedly affect all users of that shared instance.
Code

src/logger/LoggerFactory.ts[R30-34]

+        if (ObjectUtils.isObject(logger)) {
+            if (logger instanceof AbstractLogger && options !== undefined) {
+                logger.setOptions(options)
+            }
+            return logger as Logger
Evidence
DataSource passes options.logger (which can be a user-provided object) into
LoggerFactory.create, and the factory now mutates that instance in-place by calling setOptions,
which directly overwrites AbstractLogger.options. This creates cross-DataSource coupling when a
single logger object is shared.

src/data-source/DataSource.ts[141-148]
src/logger/LoggerFactory.ts[30-35]
src/logger/AbstractLogger.ts[17-30]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` calls `setOptions()` on a user-provided logger instance. If consumers reuse the same logger object across multiple `DataSource`s with different `logging` options, the last `DataSource` to initialize (or update) will overwrite the options for all, producing confusing/incorrect logging.
### Issue Context
- `DataSource` passes `options.logger` into `LoggerFactory.create`.
- The factory now mutates the instance via `setOptions`, which overwrites the shared instance state.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[30-35]
- src/logger/AbstractLogger.ts[17-30]
- src/data-source/DataSource.ts[141-148]
### Suggested direction
Option A (behavioral mitigation): If `logger` is an object and supports `setOptions`, return a *wrapper* logger per `DataSource` that calls `logger.setOptions(options)` at the start of each log method, then delegates to the underlying logger. This reduces persistent cross-DataSource coupling while keeping the fix for #10174.
Option B (doc/API contract): Explicitly document (and potentially assert in dev) that `options.logger` must be a fresh instance per `DataSource` if it is stateful (like `AbstractLogger`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


20. Logger import cycle🐞 Bug ⛯ Reliability
Description
Logger.ts now imports LoggerOptions, while LoggerOptions.ts imports LogLevel from
Logger.ts, creating a module cycle. This is likely type-only, but using explicit import type
avoids potential runtime requires in some TS build configurations and clarifies intent.
Code

src/logger/Logger.ts[1]

+import { LoggerOptions } from "./LoggerOptions"
Evidence
The PR introduced an import from Logger to LoggerOptions in Logger.ts, while
LoggerOptions.ts already imports from Logger.ts. Even if this is commonly elided as type-only,
it’s a real circular dependency at the module level and can be made unambiguous via import type.

src/logger/Logger.ts[1-2]
src/logger/LoggerOptions.ts[1-2]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
There is a circular module dependency between `src/logger/Logger.ts` and `src/logger/LoggerOptions.ts` created by mutual imports.
### Issue Context
Even when imports are used only for types, some TS configurations (or future refactors) can emit them, and the cycle is avoidable.
### Fix Focus Areas
- src/logger/Logger.ts[1-2]
- src/logger/LoggerOptions.ts[1-2]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


21. Test uses any cast📘 Rule violation ✓ Correctness
Description
The new functional test introduces an explicit any type in .filter((call: any) => ...), which is
a type-safety bypass. This violates the requirement to avoid AI-like noise such as any casts to
bypass type issues.
Code

test/functional/logger/custom-logger.test.ts[58]

+                    .filter((call: any) => call.args[0] === "query")
Evidence
The compliance checklist forbids introducing any casts to bypass typing. The added test uses
(call: any) even though Sinon call types can be inferred or typed more precisely.

Rule 4: Remove AI-generated noise
test/functional/logger/custom-logger.test.ts[56-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test introduces an explicit `any` cast in a filter callback, bypassing type safety.
## Issue Context
Rule 4 requires avoiding `any` casts added to silence or bypass TypeScript typing issues.
## Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[56-59] ևս

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


22. Shared logger options mutation🐞 Bug ✓ Correctness
Description
LoggerFactory.create mutates a user-supplied logger instance by calling setOptions. If the same
logger instance is reused across multiple DataSources (or reconfigured), the last options applied
can unexpectedly affect all users of that shared instance.
Code

src/logger/LoggerFactory.ts[R30-34]

+        if (ObjectUtils.isObject(logger)) {
+            if (logger instanceof AbstractLogger && options !== undefined) {
+                logger.setOptions(options)
+            }
+            return logger as Logger
Evidence
DataSource passes options.logger (which can be a user-provided object) into
LoggerFactory.create, and the factory now mutates that instance in-place by calling setOptions,
which directly overwrites AbstractLogger.options. This creates cross-DataSource coupling when a
single logger object is shared.

src/data-source/DataSource.ts[141-148]
src/logger/LoggerFactory.ts[30-35]
[src/logger/AbstractLogger.ts[17-30]](https://github.com/typeorm/typeorm/blob/9aafcafb04717069e767b01cba172b00caa38ea...

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (21) 📘 Rule violations (21) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Unused AbstractLogger import 📘 Rule violation ✓ Correctness ⭐ New
Description
AbstractLogger is imported in LoggerFactory.ts but never referenced. This adds unnecessary noise
and may fail lint/build checks.
Code

src/logger/LoggerFactory.ts[9]

+import { AbstractLogger } from "./AbstractLogger"
Evidence
Compliance requires avoiding AI-like noise and inconsistent style; the PR adds an unused import
(AbstractLogger) without using it anywhere in LoggerFactory.ts.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[1-10]
src/logger/LoggerFactory.ts[19-54]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/logger/LoggerFactory.ts` imports `AbstractLogger` but never uses it, adding unnecessary noise and potentially breaking lint/build rules.

## Issue Context
The current implementation uses `"options" in logger` and does not reference `AbstractLogger`, so the import is redundant unless you intend to use `instanceof AbstractLogger` as an explicit type guard.

## Fix Focus Areas
- src/logger/LoggerFactory.ts[1-10]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (33)
4. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. setOptions skips false🐞 Bug ✓ Correctness
Description
LoggerFactory only calls setOptions when options is truthy, so logging: false is never
propagated to custom logger instances. This can cause unexpected logging behavior when a custom
logger has its own internal default options and expects DataSource’s logging to override it.
Code

src/logger/LoggerFactory.ts[R29-34]

+            if (
+                options &&
+                typeof (logger as Logger).setOptions === "function"
+            ) {
+                ;(logger as Logger).setOptions!(options)
+            }
Evidence
LoggerOptions explicitly allows a boolean value, including false, but LoggerFactory guards
setOptions with options && ..., so it won’t run for false. Since DataSource passes
options.logging directly into LoggerFactory.create, a custom logger instance can miss the
intended logging configuration; for AbstractLogger-based loggers, whether query/error logs run
depends directly on this.options (e.g., this.options === true).

src/logger/LoggerFactory.ts[18-36]
src/logger/LoggerOptions.ts[1-7]
src/data-source/DataSource.ts[141-148]
src/logger/AbstractLogger.ts[242-259]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory` currently guards the `setOptions` invocation with `options && ...`, which prevents propagating `logging: false` (a valid `LoggerOptions`). This means custom logger instances may not reflect the DataSource’s desired logging configuration.
### Issue Context
- `LoggerOptions` includes `boolean`, so `false` is meaningful.
- `DataSource` passes `options.logging` to `LoggerFactory.create`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[28-36]
- src/logger/LoggerOptions.ts[1-7]
- src/data-source/DataSource.ts[145-148]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. Unsafe logger as AbstractLogger 📘 Rule violation ✓ Correctness
Description
LoggerFactory.create() uses a type assertion to treat any object logger as AbstractLogger and
mutates instance.options without a runtime type guard. This bypasses type safety and can lead to
incorrect behavior when a custom logger object is not an AbstractLogger instance.
Code

src/logger/LoggerFactory.ts[R29-32]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
Evidence
The compliance checklist forbids type-bypassing casts/style noise; the new code asserts logger is
AbstractLogger and writes to options without verifying the object is actually an
AbstractLogger instance.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[29-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` currently uses `logger as AbstractLogger` and mutates `instance.options` without confirming the object is an `AbstractLogger`, which bypasses type safety and can mis-handle custom logger objects.
## Issue Context
The factory method accepts `Logger` (interface) instances; not all such objects are guaranteed to extend `AbstractLogger`. Add a runtime check before treating an object as `AbstractLogger`, and ensure custom logger objects that are not `AbstractLogger` are still returned/handled safely.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[29-33]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


16. Custom logger ignored 🐞 Bug ✓ Correctness
Description
LoggerFactory.create only returns an object logger when options is truthy; if logging is
undefined or false, the provided custom logger instance is discarded and a default
AdvancedConsoleLogger is returned. This breaks the documented configuration pattern (`logger: new
MyCustomLogger() without logging`) and existing tests that pass a logger instance via
createLogger().
Code

src/logger/LoggerFactory.ts[R29-33]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
+        }
Evidence
LoggerFactory now gates returning a provided logger instance on options being truthy. DataSource
passes this.options.logging as options, which may be undefined or false; docs explicitly show
configuring a custom logger without setting logging; and at least one functional test passes a
logger instance without setting logging. With the new condition, those scenarios skip returning the
custom logger, then fall through the string switch (no cases match for an object) and return the
default AdvancedConsoleLogger.

src/logger/LoggerFactory.ts[19-55]
src/data-source/DataSource.ts[141-148]
src/logger/LoggerOptions.ts[1-7]
docs/docs/advanced-topics/5-logging.md[176-192]
test/functional/repository/find-options/repository-find-options.test.ts[241-252]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create` currently only returns a provided logger instance when `options` is truthy. When `logging` is `undefined` or `false`, the provided logger instance is ignored and the factory returns the default `AdvancedConsoleLogger`, breaking documented usage (`logger: new MyCustomLogger()` without `logging`) and existing tests.
### Issue Context
- `DataSource` passes `options.logging` to `LoggerFactory.create`, which can be `undefined` or `false`.
- `LoggerOptions` explicitly allows `false`.
- The logging docs show specifying a custom logger instance without specifying `logging`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[19-55]
### Suggested change (high level)
1. If `logger` is an object, always return it as `Logger`.
2. If the object is an `AbstractLogger` and `options !== undefined`, propagate `options` safely:
- Prefer `if (logger instanceof AbstractLogger && options !== undefined && logger.options === undefined) logger.options = options` to avoid clobbering logger instances already configured via their constructor.
- Do **not** cast/mutate arbitrary `Logger` implementations that don’t extend `AbstractLogger`.
3. Consider adding/adjusting a test to cover `createLogger` with `logging` omitted or set to `false` to prevent regressions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


18. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


19. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


20. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


21. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

...

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (33) 📘 Rule violations (30) 📎 Requirement gaps (0)

Grey Divider


Action required

1. Custom logger silently replaced 🐞 Bug ✓ Correctness ⭐ New
Description
LoggerFactory.create no longer returns arbitrary Logger objects unless they have an options
property and the provided logging options are truthy. This can silently replace a user-provided
logger (including existing test loggers) with the default AdvancedConsoleLogger when logging is
undefined/false or the logger doesn’t expose options.
Code

src/logger/LoggerFactory.ts[R29-32]

+        if (ObjectUtils.isObject(logger) && "options" in logger && options) {
+            logger.options = options
+            return logger
+        }
Evidence
DataSource always routes options.logger through LoggerFactory along with options.logging, where
logging is optional and can be false. With the new condition, many valid Logger instances
(e.g., ones that implement the Logger interface but don’t have an options property) will fail the
check and then fall through to the string-switch path, which won’t match an object logger and will
default to AdvancedConsoleLogger—discarding the custom logger. This is not hypothetical: existing
tests configure custom loggers via createLogger without necessarily setting logging, and those
loggers (e.g., MemoryLogger) do not have an options property.

src/logger/LoggerFactory.ts[19-33]
src/data-source/DataSource.ts[141-148]
src/data-source/BaseDataSourceOptions.ts[68-83]
src/logger/LoggerOptions.ts[3-7]
test/github-issues/2703/memory-logger.ts[1-15]
test/github-issues/2703/issue-2703.test.ts[15-22]
test/utils/test-utils.ts[288-292]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`LoggerFactory.create()` currently returns a provided custom logger object only when it has an `options` property and when the passed `options` argument is truthy. This causes valid custom loggers to be silently discarded (replaced by the default logger) when:
- the logger does not expose an `options` property (implements `Logger` interface only)
- `options` is `undefined`
- `options` is `false` (valid LoggerOptions that disables logging)

### Issue Context
TypeORM supports passing a `Logger` instance via `DataSourceOptions.logger`, and `DataSourceOptions.logging` is optional.

### Fix Focus Areas
- src/logger/LoggerFactory.ts[19-33]

### Implementation notes
- Change the initial branch to:
 - if `logger` is an object, **return it** unconditionally
 - if it also has a configurable `options` field (or is `instanceof AbstractLogger`) and `options !== undefined`, apply it (do not use a truthiness check; `false` must be allowed)
- Consider adding a regression test for a custom logger that implements `Logger` but does **not** extend `AbstractLogger` and has no `options` property, ensuring it is still used.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (53)
4. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


8. setOptions skips false🐞 Bug ✓ Correctness
Description
LoggerFactory only calls setOptions when options is truthy, so logging: false is never
propagated to custom logger instances. This can cause unexpected logging behavior when a custom
logger has its own internal default options and expects DataSource’s logging to override it.
Code

src/logger/LoggerFactory.ts[R29-34]

+            if (
+                options &&
+                typeof (logger as Logger).setOptions === "function"
+            ) {
+                ;(logger as Logger).setOptions!(options)
+            }
Evidence
LoggerOptions explicitly allows a boolean value, including false, but LoggerFactory guards
setOptions with options && ..., so it won’t run for false. Since DataSource passes
options.logging directly into LoggerFactory.create, a custom logger instance can miss the
intended logging configuration; for AbstractLogger-based loggers, whether query/error logs run
depends directly on this.options (e.g., this.options === true).

src/logger/LoggerFactory.ts[18-36]
src/logger/LoggerOptions.ts[1-7]
src/data-source/DataSource.ts[141-148]
src/logger/AbstractLogger.ts[242-259]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory` currently guards the `setOptions` invocation with `options && ...`, which prevents propagating `logging: false` (a valid `LoggerOptions`). This means custom logger instances may not reflect the DataSource’s desired logging configuration.
### Issue Context
- `LoggerOptions` includes `boolean`, so `false` is meaningful.
- `DataSource` passes `options.logging` to `LoggerFactory.create`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[28-36]
- src/logger/LoggerOptions.ts[1-7]
- src/data-source/DataSource.ts[145-148]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


9. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


10. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


11. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


12. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


13. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


14. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


15. Unsafe logger as AbstractLogger📘 Rule violation ✓ Correctness
Description
LoggerFactory.create() uses a type assertion to treat any object logger as AbstractLogger and
mutates instance.options without a runtime type guard. This bypasses type safety and can lead to
incorrect behavior when a custom logger object is not an AbstractLogger instance.
Code

src/logger/LoggerFactory.ts[R29-32]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
Evidence
The compliance checklist forbids type-bypassing casts/style noise; the new code asserts logger is
AbstractLogger and writes to options without verifying the object is actually an
AbstractLogger instance.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[29-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` currently uses `logger as AbstractLogger` and mutates `instance.options` without confirming the object is an `AbstractLogger`, which bypasses type safety and can mis-handle custom logger objects.
## Issue Context
The factory method accepts `Logger` (interface) instances; not all such objects are guaranteed to extend `AbstractLogger`. Add a runtime check before treating an object as `AbstractLogger`, and ensure custom logger objects that are not `AbstractLogger` are still returned/handled safely.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[29-33]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


16. Custom logger ignored 🐞 Bug ✓ Correctness
Description
LoggerFactory.create only returns an object logger when options is truthy; if logging is
undefined or false, the provided custom logger instance is discarded and a default
AdvancedConsoleLogger is returned. This breaks the documented configuration pattern (`logger: new
MyCustomLogger() without logging`) and existing tests that pass a logger instance via
createLogger().
Code

src/logger/LoggerFactory.ts[R29-33]

+        if (ObjectUtils.isObject(logger) && options) {
+            const instance = logger as AbstractLogger
+            instance.options = options
+            return instance
+        }
Evidence
LoggerFactory now gates returning a provided logger instance on options being truthy. DataSource
passes this.options.logging as options, which may be undefined or false; docs explicitly show
configuring a custom logger without setting logging; and at least one functional test passes a
logger instance without setting logging. With the new condition, those scenarios skip returning the
custom logger, then fall through the string switch (no cases match for an object) and return the
default AdvancedConsoleLogger.

src/logger/LoggerFactory.ts[19-55]
src/data-source/DataSource.ts[141-148]
src/logger/LoggerOptions.ts[1-7]
docs/docs/advanced-topics/5-logging.md[176-192]
test/functional/repository/find-options/repository-find-options.test.ts[241-252]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create` currently only returns a provided logger instance when `options` is truthy. When `logging` is `undefined` or `false`, the provided logger instance is ignored and the factory returns the default `AdvancedConsoleLogger`, breaking documented usage (`logger: new MyCustomLogger()` without `logging`) and existing tests.
### Issue Context
- `DataSource` passes `options.logging` to `LoggerFactory.create`, which can be `undefined` or `false`.
- `LoggerOptions` explicitly allows `false`.
- The logging docs show specifying a custom logger instance without specifying `logging`.
### Fix Focus Areas
- src/logger/LoggerFactory.ts[19-55]
### Suggested change (high level)
1. If `logger` is an object, always return it as `Logger`.
2. If the object is an `AbstractLogger` and `options !== undefined`, propagate `options` safely:
- Prefer `if (logger instanceof AbstractLogger && options !== undefined && logger.options === undefined) logger.options = options` to avoid clobbering logger instances already configured via their constructor.
- Do **not** cast/mutate arbitrary `Logger` implementations that don’t extend `AbstractLogger`.
3. Consider adding/adjusting a test to cover `createLogger` with `logging` omitted or set to `false` to prevent regressions.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


17. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

src/logger/AbstractLogger.ts[R23-30]

+    /**
+     * Sets logger options. Used to pass DataSource logging options
+     * to custom logger instances.
+     * @param options
+     */
+    setOptions(options: LoggerOptions) {
+        this.options = options
+    }
Evidence
Compliance requires docs updates for user-facing changes. This PR adds a new public method
setOptions() and calls it when a custom logger is supplied, but the logging docs section about
custom loggers does not mention this options propagation behavior.

Rule 2: Docs updated for user-facing changes
src/logger/AbstractLogger.ts[23-30]
src/logger/LoggerFactory.ts[30-33]
docs/docs/advanced-topics/5-logging.md[102-114]
docs/docs/advanced-topics/5-logging.md[176-192]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new public API (`AbstractLogger.setOptions`) is introduced and used to pass `LoggerOptions` into custom loggers, but the user documentation for custom loggers does not explain this behavior.
## Issue Context
Users following the current "Using custom logger" docs may not realize options are now injected into `AbstractLogger` subclasses when providing `logger: new MyCustomLogger()`, and how to access them.
## Fix Focus Areas
- docs/docs/advanced-topics/5-logging.md[102-206]
- src/logger/AbstractLogger.ts[23-30]
- src/logger/LoggerFactory.ts[30-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


18. Flaky parallel logger test🐞 Bug ⛯ Reliability
Description
The new test runs per-DataSource checks in parallel while sharing a single fakeLog and resetting
its history inside each parallel task, which can drop log calls and make the test nondeterministic.
Code

test/functional/logger/custom-logger.test.ts[R46-61]

+    it("should invoke custom logger writeLog for queries when logging is enabled (issue #10174)", () =>
+        Promise.all(
+            dataSources.map(async (dataSource) => {
+                fakeLog.resetHistory()
+
+                const repository = dataSource.getRepository(Post)
+                await repository.save({ title: "test" })
+                await repository.find()
+
+                expect(fakeLog.called).to.be.true
+                const queryLogs = fakeLog
+                    .getCalls()
+                    .filter((call: any) => call.args[0] === "query")
+                expect(queryLogs.length).to.be.greaterThan(0)
+            }),
+        ))
Evidence
Promise.all(dataSources.map(...)) executes concurrently, but fakeLog is shared and
resetHistory() is called inside each async task; resets from one task can erase calls produced by
another task before assertions run.

test/functional/logger/custom-logger.test.ts[12-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test uses a shared `sinon.fake()` (`fakeLog`) but runs multiple DataSources in parallel via `Promise.all(...)` and calls `fakeLog.resetHistory()` inside each async task. This can erase log calls from other tasks and cause intermittent CI failures.
### Issue Context
`createTestingConnections` often returns multiple DataSources (per driver). The test currently parallelizes validation across them.
### Fix Focus Areas
- test/functional/logger/custom-logger.test.ts[46-61]
### Suggested direction
Option A (simplest): replace `Promise.all(dataSources.map(async ...))` with a sequential loop:
- `for (const dataSource of dataSources) { fakeLog.resetHistory(); ... await ...; expect(...) }`
Option B: create a distinct fake per DataSource by having `CustomLogger` accept a callback/fake in its constructor and using `createLogger` to create per-connection instances with isolated fakes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


19. logger as any type bypass📘 Rule violation ✓ Correctness
Description
The new setOptions invocation uses any casts to bypass typing, which is explicitly disallowed
and can hide real type errors. This introduces style/type-safety noise inconsistent with the rest of
the codebase.
Code

src/logger/LoggerFactory.ts[R28-35]

+        if (ObjectUtils.isObject(logger)) {
+            if (
+                options !== undefined &&
+                typeof (logger as any).setOptions === "function"
+            ) {
+                ;(logger as any).setOptions(options)
+            }
+            return logger as Logger
Evidence
Compliance ID 4 forbids adding any casts to bypass types; the PR introduces `(logger as
any).setOptions checks and invocation when logger` is an object.

Rule 4: Remove AI-generated noise
src/logger/LoggerFactory.ts[28-35]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LoggerFactory.create()` uses `(logger as any).setOptions(...)` and `typeof (logger as any).setOptions` which violates the no-`any`/no-noise requirement and can mask type errors.
## Issue Context
The PR introduces `AbstractLogger.setOptions(options: LoggerOptions)` and tries to call it for custom logger instances, but does so via `any` casts.
## Fix Focus Areas
- src/logger/LoggerFactory.ts[28-35]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


20. Stale logger options🐞 Bug ✓ Correctness
Description
AbstractLogger.setOptions only assigns when this.options is undefined, so subsequent attempts to
change logging (e.g., via DataSource.setOptions() or reuse of the same logger instance) will be
ignored and logging enablement can become incorrect.
Code

src/logger/AbstractLogger.ts[R28-32]

+    setOptions(options: LoggerOptions) {
+        if (this.options === undefined) {
+            this.options = options
+        }
+    }
Evidence
LoggerFactory will call setOptions(options) on an object logger whenever logging is provided,
and DataSource constructs/reconfigures the logger via LoggerFactory using options.logging.
However, AbstractLogger.setOptions is guarded and won’t update if options were previously set;
since AbstractLogger.isLogEnabledFor gates query/error/etc logs based on this.options, the
logger can keep stale gating behavior.

src/logger/AbstractLogger.ts[17-32]
src/logger/AbstractLogger.ts[244-301]
src/logger/LoggerFactory.ts[18-36]
src/data-source/DataSource.ts[141-148]
src/data-source/DataSource.ts[204-212]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`AbstractLogger.setOptions` currently only sets options once (`if (this.options === undefined)`), which prevents later logging configuration changes from taking effect when LoggerFactory calls `setOptions` again.
### Issue Context
- `LoggerFactory.create()` calls `setOptions(options)` on object loggers.
- `DataSource` constructs and can reconfigure its logger via `DataSource.setOptions()`, which re-invokes `LoggerFactory.create()`.
- `AbstractLogger.isLogEnabledFor()` gates logging based on `this.options`.
### Fix Focus Areas
- src/logger/AbstractLogger.ts[23-32]
- test/functional/logger/custom-logger.test.ts[1-61] (optional: add a regression test covering reconfiguration / repeated setOptions)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


21. AbstractLogger setOptions undocumented📘 Rule violation ✓ Correctness
Description
A new public AbstractLogger.setOptions() API is added and invoked by LoggerFactory, changing how
custom loggers receive LoggerOptions. The logging documentation for custom loggers is not updated
to describe this behavior, risking user confusion and misuse.
Code

...

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

1 similar comment
@qodo-free-for-open-source-projects

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom logger not working

3 participants