Skip to content

Route adapt-migrations logs to a file via a config option #199

@taylortom

Description

@taylortom

Problem

`adapt-migrations` uses its own `Logger` singleton (`Logger.getInstance()`) which writes `info`/`debug`/`warn` directly to `console`. The AT's `logLevels` config has no effect on it.

In a typical run there are hundreds of lines per migrated combo:

```
(date) -- info -- Describe -- ... -- Registered
(date) -- info -- whereFromPlugin -- ... -- (stopped/success)
(date) -- info -- whereContent -- ... -- (success)
(date) -- info -- mutateContent -- ... -- (success)
(date) -- info -- checkContent -- ... -- (success)
(date) -- info -- updatePlugin -- ... -- (success)
```

This makes the AT's own logs (and any `console.log` debugging) practically unreadable during imports/updates. It's also unhelpful: the migration trace is rarely useful unless something goes wrong, and it's gone by the time you'd want to inspect it.

Why a custom `logger` arg won't fix it

Some sites in adapt-migrations (`Task.runApplicable`, `Task.run`, `Task.load`) accept a `logger` argument. But a number of others — `api/describe.js`, `api/tests.js`, `api/errors.js`, `lib/lifecycle.js` — call `Logger.getInstance()` directly. Replacing the singleton's methods is the only way to capture every call site.

Proposed fix

Add an optional config to this module: `migrationLogFile` (string path).

  • Unset (default): existing behaviour (logs to stdout). Backwards-compatible.
  • Set: in `AdaptFrameworkModule.init()`, monkey-patch `Logger.getInstance().info` / `.debug` / `.warn` to append to the configured file with a timestamp prefix.
  • Leave `logger.error` on stdout (and also write to file), so genuine failures aren't hidden.

Sketch:

```js
const logFile = this.getConfig('migrationLogFile')
if (logFile) {
const { Logger } = await import('adapt-migrations')
const logger = Logger.getInstance()
const stream = fs.createWriteStream(logFile, { flags: 'a' })
const route = (level) => (...args) =>
stream.write(`[${new Date().toISOString()}] ${level} ${args.map(String).join(' ')}\n`)
logger.info = route('info')
logger.debug = route('debug')
logger.warn = route('warn')
}
```

Schema entry:

```json
"migrationLogFile": {
"description": "When set, info/debug/warn output from migrations is appended to the given file instead of stdout. Errors still surface to stdout.",
"type": "string"
}
```

Notes

  • Could also live upstream in `adapt-migrations` itself (e.g. `Logger.setLevel()` or `Logger.setOutput()`) — that'd benefit every consumer of the library — but the AT-side patch is much cheaper to land and self-contained.
  • Reduces the appeal of the bigger ask of "respect AT log levels", which would require a larger refactor.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions