Skip to content

fix(logging): scope logRotator state per instance - #1175

Merged
kriszyp merged 1 commit into
mainfrom
kris/fix-log-rotator-regression
Jun 9, 2026
Merged

fix(logging): scope logRotator state per instance#1175
kriszyp merged 1 commit into
mainfrom
kris/fix-log-rotator-regression

Conversation

@kriszyp

@kriszyp kriszyp commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

utility/logging/logRotator.ts declared lastRotationTime and setIntervalId at module scope, so every logRotator() call overwrote the shared id. Once #1111 fixed the broken require and harper_logger.getFileLogger started creating real rotators, multiple instances (hdb, http, external) could coexist and any rotator.end() would clearInterval the most-recently-created interval instead of its own.

Move both into the function closure so each rotator owns its state.

Regression context

Before #1111, harper_logger.getFileLogger's internal require('./logRotator')() threw a TypeError (it was getting the CJS namespace object, not the function) and was swallowed by a catch, so log rotation was silently disabled and the module-level state was only ever touched by direct callers (e.g. the unit test). #1111 fixed the require, exposing the latent state-sharing bug.

The unit-test failure mode after #1111: harper_logger.test.js HTTP/global-logger after() hooks reassign httpLogger.path/externalLogger.path, which schedules a 100ms setTimeout in getFileLogger that calls logger.rotator?.end(). That end() resolves to clearInterval(module-level setIntervalId) — clobbering the logRotator unit test's own interval that was just created, so rotation never fires and getLastRotatedLogPath() returns undefined.

Verification

  • npm run test:unit:logging -> 49 passing (was 1 failing).
  • npm run test:unit:main -> the 5 remaining failures are pre-existing SQL Engine / analytics serialization / scopedImport issues unrelated to logging.
  • Codex review: no regressions identified.

Generated by Claude Opus 4.7.

`lastRotationTime` and `setIntervalId` were module-level. After #1111
fixed the broken require so harper_logger.getFileLogger actually
creates rotators, multiple rotators can exist concurrently (e.g. for
http logger, external logger, hdb logger). Every new rotator call
overwrites the shared `setIntervalId`, so `rotator.end()` on any
instance clears the most-recently-created interval — not its own.

This surfaced as a unit-test regression: the harper_logger HTTP and
global-logger tests trigger lingering setTimeouts (from the
`path =` setter calling getFileLogger) that fire ~100ms later. When
the logRotator test then created its rotator, the lingering
setTimeouts called `logger.rotator?.end()` -> `clearInterval(module-level setIntervalId)`,
which clobbered the test's interval. The rotation never fired and
`getLastRotatedLogPath()` returned undefined.

Move both variables into the function closure so each rotator owns
its own state and `end()` only clears its own interval.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@claude

claude Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Reviewed; no blockers found.

@kriszyp
kriszyp merged commit 7018834 into main Jun 9, 2026
72 of 75 checks passed
@kriszyp
kriszyp deleted the kris/fix-log-rotator-regression branch June 9, 2026 02:17
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.

1 participant