Document version 3.0.0 changes and migration
This commit is contained in:
1 parent
5a2418f438
commit
8982a96856
2 files changed
+96
-4
No files matched your search
@@ -0,0 +1,89 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 3.0.0
|
||||||
|
|
||||||
|
This release reworks logging ownership for Nim's ORC memory manager, fixes
|
||||||
|
background writer shutdown, and switches generated timestamps to UTC. It
|
||||||
|
introduces breaking API changes from 2.1.2. Nim 2.2.0 or later remains required.
|
||||||
|
|
||||||
|
### Breaking changes and migration
|
||||||
|
|
||||||
|
- **Service handles and local caches are separate types.** `LogService` is now
|
||||||
|
a copyable handle that keeps shared configuration alive. Pass a copy to each
|
||||||
|
worker, then call `threadLocalRef()` inside that worker. Keep
|
||||||
|
`ThreadLocalLogService` and its loggers in the thread that creates them. Use
|
||||||
|
`local.service` instead of `local[]` to obtain a shared handle.
|
||||||
|
- **`ensureFreshness(LogService)` has been removed.** Refresh the relevant
|
||||||
|
`ThreadLocalLogService` instead. Configuration methods remain available on
|
||||||
|
both types; `LogService.appenders()` returns clones of the current shared
|
||||||
|
configuration.
|
||||||
|
- **Custom appender callbacks now receive `state: var T`.**
|
||||||
|
`initCustomLogAppender` copies supported value state into each clone and
|
||||||
|
rejects ordinary references, closures, and embedded synchronization
|
||||||
|
primitives, including nested ones. Use `SharedLogState[T]` for shared mutable
|
||||||
|
value data, or `initFactoryCustomLogAppender` for independently created state
|
||||||
|
containing references or closures.
|
||||||
|
- **Appenders now accept `LogFormatter` objects.** The former
|
||||||
|
`LogMessageFormatter` callback type is replaced by `StatefulLogFormatterFunc`
|
||||||
|
and `StatelessLogFormatterFunc`. Noncapturing formatter functions still
|
||||||
|
convert automatically. Replace directly supplied captured closures with
|
||||||
|
`initLogFormatter(seed, factory)`, and use `formatter.format(message)` to
|
||||||
|
invoke a formatter directly. Custom appender and formatter clones must own
|
||||||
|
independent state or use explicit shared-state handles.
|
||||||
|
- **Generated timestamps now use UTC.** `LogMessage.ts` remains a `DateTime`;
|
||||||
|
structured JSON output uses a `Z` suffix. Explicit timestamps supplied in
|
||||||
|
caller-constructed messages are preserved.
|
||||||
|
- **The test collector returns value snapshots.** `LoggedMessages.get()` now
|
||||||
|
returns `seq[RecordedLogMessage]` instead of `seq[LogMessage]`. Timestamps are
|
||||||
|
`Time` values, additional JSON data is serialized text, and exceptions retain
|
||||||
|
their name, message, and stacktrace as text. Use the collector's methods
|
||||||
|
instead of accessing its former `messages` field.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `SharedLogState[T]` and `initSharedLogState` provide copyable ownership of
|
||||||
|
shared value data. Use `withState` for synchronized updates and `snapshot`
|
||||||
|
for independent copies. Raw pointers and custom copy/destruction hooks
|
||||||
|
remain the caller's responsibility.
|
||||||
|
- `FactoryCustomLogAppender` and `initFactoryCustomLogAppender` create custom
|
||||||
|
state lazily within the thread using each clone. Formatter factories provide
|
||||||
|
the same ownership pattern for captured formatter state. Configuration
|
||||||
|
refresh can replace clones and reset their local state; use shared-state
|
||||||
|
handles for data that must persist across refreshes.
|
||||||
|
|
||||||
|
### Fixed and clarified
|
||||||
|
|
||||||
|
- Service copies retain shared configuration without sharing ordinary ORC
|
||||||
|
reference ownership between threads. Workers can outlive the original
|
||||||
|
handle and the thread that created it.
|
||||||
|
- Local caches are built independently. Failed configuration refreshes preserve
|
||||||
|
the previous cache and retry on a later refresh without requiring another
|
||||||
|
configuration change.
|
||||||
|
- Background console and file writers drain queued records at normal process
|
||||||
|
exit, including empty messages and the final file batch. Shutdown excludes
|
||||||
|
further submissions and waits for writers to finish. Applications must join
|
||||||
|
their logging workers before exiting.
|
||||||
|
- Both message constructors avoid local-time conversion races by creating UTC
|
||||||
|
timestamps directly.
|
||||||
|
- `isEnabled` intentionally checks cached namespace thresholds without
|
||||||
|
refreshing configuration. Logging calls, `getLogger`, or an explicit local
|
||||||
|
refresh pick up changes. Applications that guard all logging should refresh
|
||||||
|
at suitable boundaries, such as the start of a request. The shared root
|
||||||
|
threshold is read only when no cached namespace threshold applies.
|
||||||
|
|
||||||
|
### Tests and known limitations
|
||||||
|
|
||||||
|
- `nimble test` runs all enabled unit, regression, and ThreadSanitizer suites
|
||||||
|
under ORC with threads enabled. Individual suites remain available through
|
||||||
|
`testUnit`, `testRegression`, and `testThreadSafety`.
|
||||||
|
- Validation passes 32 unit tests, 29 regression tests, and 11 sanitizer
|
||||||
|
scenarios. Two scenarios, `factory-state` and `allocator`, are temporarily
|
||||||
|
skipped because they expose a known race in Nim 2.2.10's default allocator.
|
||||||
|
Their code and assertions remain available; enable them with
|
||||||
|
`NSL_TEST_RUNTIME_ALLOCATOR=1 nimble testThreadSafety`.
|
||||||
|
- The allocator limitation remains unresolved and also reproduces without
|
||||||
|
importing this library. Passing the enabled tests does not establish full
|
||||||
|
validation of factory state under the default allocator. See
|
||||||
|
[the test documentation](tests/README.md) for details and diagnostic results.
|
||||||
|
|
||||||
|
See the [README](README.md) for usage and migration examples.
|
||||||
@@ -12,6 +12,8 @@ four main motivating features:
|
|||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
|
See the [changelog](CHANGELOG.md) for version 3.0.0 changes and migration notes.
|
||||||
|
|
||||||
Install the package via nimble:
|
Install the package via nimble:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -588,12 +590,13 @@ file system operations that might fail and cause cascading errors.
|
|||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
Run `nimble test` for all unit, regression, and ThreadSanitizer ownership tests.
|
Run `nimble test` for all enabled unit, regression, and ThreadSanitizer ownership tests.
|
||||||
It runs every suite even when an earlier suite fails. For focused debugging,
|
It runs every suite even when an earlier suite fails. For focused debugging,
|
||||||
use `nimble testUnit`, `nimble testRegression`, or `nimble testThreadSafety`.
|
use `nimble testUnit`, `nimble testRegression`, or `nimble testThreadSafety`.
|
||||||
The regression tests currently expose known defects and are expected to fail
|
Two scenarios that expose a known Nim allocator race are temporarily skipped
|
||||||
until those defects are fixed. See [tests/README.md](tests/README.md) for commands,
|
by default. Enable them with `NSL_TEST_RUNTIME_ALLOCATOR=1 nimble testThreadSafety`.
|
||||||
requirements, and coverage limitations.
|
See [tests/README.md](tests/README.md) for commands, requirements, and coverage
|
||||||
|
limitations.
|
||||||
|
|
||||||
[log4j]: https://logging.apache.org/log4j/2.x/
|
[log4j]: https://logging.apache.org/log4j/2.x/
|
||||||
[logback]: https://logback.qos.ch/
|
[logback]: https://logback.qos.ch/
|
||||||
|
|||||||
Reference in new issue
Block a user