diff --git a/docs/api/file-rotation-config-to-json.md b/docs/api/file-rotation-config-to-json.md index ebbc370..b95ff5d 100644 --- a/docs/api/file-rotation-config-to-json.md +++ b/docs/api/file-rotation-config-to-json.md @@ -33,8 +33,9 @@ pub fn file_rotation_config_to_json(config : FileRotation) -> @json_parser.JsonV Detailed rules explaining key parameters and behaviors -- The output includes `max_bytes` and `max_backups`. -- Both numeric fields are exported as JSON numbers. +- The output always includes `max_bytes` and `max_backups`. +- Both of those compatibility fields are exported as JSON numbers. +- If the policy carries a wide threshold from `file_rotation_i64(...)`, the output also includes `max_bytes_i64` as a JSON string for exact roundtrip transport. - This helper serializes the rotation config object itself rather than sink availability, failure counters, or file state. - The same JSON shape is reused by `sink_config_to_json(...)`, file sink state export helpers, and larger logger config serialization paths. @@ -61,6 +62,16 @@ let rotation_json = file_rotation_config_to_json(rotation) In this example, callers can carry the nested rotation shape without exporting a full sink config. +#### When Need Exact Wide-threshold Roundtrip + +When a native large-file policy should preserve the original `Int64` threshold in JSON: +```moonbit +let rotation = file_rotation_i64(4294967296L, max_backups=2) +let rotation_json = file_rotation_config_to_json(rotation) +``` + +In this example, the JSON value includes the compatibility `max_bytes` view plus `max_bytes_i64` as a string. + ### Error Case e.g.: @@ -73,3 +84,5 @@ e.g.: 1. Use this helper when downstream code expects `JsonValue` rather than a typed `FileRotation` value. 2. Pair it with `file_rotation(...)` when building rotation policy in code before export. + +3. For `file_rotation_i64(...)`, treat `max_bytes_i64` as the exact roundtrip field and `max_bytes` as the compatibility view. diff --git a/docs/api/file-rotation-i64.md b/docs/api/file-rotation-i64.md new file mode 100644 index 0000000..6b9bab8 --- /dev/null +++ b/docs/api/file-rotation-i64.md @@ -0,0 +1,74 @@ +--- +name: file-rotation-i64 +group: api +category: sink +update-time: 20260705 +description: Create a native-focused large-file rotation policy using an Int64 byte threshold. +key-word: + - file + - rotation + - i64 + - native +--- + +## File-rotation-i64 + +Create a size-based file rotation policy with an `Int64` byte threshold. This helper is the opt-in native-focused path for large-file rotation scenarios that exceed the default `Int`-based contract. + +### Interface + +```moonbit +pub fn file_rotation_i64(max_bytes : Int64, max_backups~ : Int = 1) -> FileRotation {} +``` + +#### input + +- `max_bytes : Int64` - Maximum active file size threshold before rotation on the native-focused wide path. +- `max_backups : Int` - Number of retained backup files. + +#### output + +- `FileRotation` - Rotation policy value that preserves a native wide threshold while staying compatible with the existing file sink API surface. + +### Explanation + +- `max_bytes <= 0L` is normalized to `1L`. +- `max_backups <= 0` is normalized to `1`. +- Rotation is size-based only. +- This helper keeps the existing `FileRotation` type but stores an additional native wide threshold internally for runtime rotation checks. +- The helper is intended for native file backends and advanced large-file scenarios. +- JSON config export helpers preserve the exact threshold through `max_bytes_i64` while still exposing a compatibility `max_bytes` view. + +### How to Use + +#### When Need Native Large-file Rotation Thresholds + +```moonbit +let sink = file_sink( + "app.log", + rotation=Some(file_rotation_i64(5368709120L, max_backups=4)), +) +``` + +In this example, the active rotation threshold is expressed with `Int64` rather than the default `Int` path. + +#### When Need A Wide Policy Value First + +```moonbit +let rotation = file_rotation_i64(3221225472L, max_backups=2) +let sink = file_sink("app.log", rotation=Some(rotation)) +``` + +In this example, the wide threshold policy is assembled separately and then reused. + +### Error Case + +- If `max_bytes` is non-positive, it is clamped to `1L`. +- This API does not make non-native targets gain real file support; callers should still use `native_files_supported()` when portability matters. + +### Notes + +1. This API is additive and does not replace the default `file_rotation(...)` contract. +2. Prefer the default `Int` path unless a native large-file threshold is actually required. +3. String-based JSON roundtrip uses `max_bytes_i64` for the exact threshold and keeps `max_bytes` as the compatibility field. +4. This helper is designed for advanced use and target-aware code. diff --git a/docs/api/file-rotation-type.md b/docs/api/file-rotation-type.md index 410e691..369a022 100644 --- a/docs/api/file-rotation-type.md +++ b/docs/api/file-rotation-type.md @@ -13,7 +13,7 @@ key-word: ## File-rotation-type -`FileRotation` is the public file sink rotation policy type used for native size-based log file rollover. It is a direct alias to the sink model that stores the byte limit and retained backup count. +`FileRotation` is the public file sink rotation policy type used for native size-based log file rollover. It is a direct alias to the sink model that stores the standard byte limit, retained backup count, and additive native wide-threshold metadata for the optional `Int64` path. ### Interface @@ -23,14 +23,14 @@ pub type FileRotation = @utils.FileRotation #### output -- `FileRotation` - Public file rotation policy object containing `max_bytes` and `max_backups`. +- `FileRotation` - Public file rotation policy object containing the standard `max_bytes` view, `max_backups`, and additive native wide-threshold support for advanced rotation flows. ### Explanation Detailed rules explaining key parameters and behaviors - This is a type alias, not a file sink or rotation trigger by itself. -- The current fields are `max_bytes : Int` and `max_backups : Int`. +- The current fields are `max_bytes : Int`, `max_backups : Int`, and additive native wide-threshold metadata used by the optional `file_rotation_i64(...)` path. - `file_rotation(...)` constructs this type as the main public helper. - The same value type is consumed by `file_sink(...)`, `FileSinkPolicy::new(...)`, `SinkConfig`, file runtime inspection APIs, and logger config serialization helpers. @@ -65,6 +65,8 @@ e.g.: ### Notes -1. Use `file_rotation(...)` when you need a value of this type in code. +1. Use `file_rotation(...)` when you need the default `Int`-based value of this type in code. -2. Use `native_files_supported()` or the target verification guidance when portability matters across non-native targets. +2. Use `file_rotation_i64(...)` when a native large-file threshold must exceed the default `Int` contract. + +3. Use `native_files_supported()` or the target verification guidance when portability matters across non-native targets. diff --git a/docs/api/file-rotation.md b/docs/api/file-rotation.md index a3ed8e5..a83da09 100644 --- a/docs/api/file-rotation.md +++ b/docs/api/file-rotation.md @@ -38,6 +38,9 @@ Detailed rules explaining key parameters and behaviors - `max_backups <= 0` is normalized to `1`. - Rotation is size-based only. - This policy is consumed by `file_sink(...)`, file policy helpers, and config-driven file sink assembly. +- The default `max_bytes : Int` path follows the current 32-bit `Int` contract used by the standard file rotation APIs. +- On native targets, that default path is intended for ordinary log-file ranges rather than explicit large-file guarantees beyond the 32-bit `Int` boundary. +- If a native large-file threshold is required, prefer `file_rotation_i64(...)`. ### How to Use @@ -79,3 +82,5 @@ e.g.: 2. Rotation currently focuses on size thresholds rather than time schedules or compression. +3. The default API keeps the portable `Int`-based contract stable; the wider native-only path is exposed separately through `file_rotation_i64(...)`. + diff --git a/docs/api/file-sink-policy-to-json.md b/docs/api/file-sink-policy-to-json.md index f6d86ee..bf6a304 100644 --- a/docs/api/file-sink-policy-to-json.md +++ b/docs/api/file-sink-policy-to-json.md @@ -38,6 +38,7 @@ Detailed rules explaining key parameters and behaviors - This helper exports runtime file policy, not current file health counters or availability. - The JSON value is useful for policy snapshots, comparisons, and diagnostics payloads. - Typical inputs come from `FileSink::policy()`, `RuntimeSink::file_policy()`, or `ConfiguredLogger::file_policy()`. +- If the active rotation policy originated from `file_rotation_i64(...)`, the nested rotation JSON includes both the compatibility `max_bytes` number and `max_bytes_i64` as the exact string form. ### How to Use @@ -74,3 +75,5 @@ e.g.: 1. Use this helper when downstream code expects `JsonValue` rather than text. 2. It pairs naturally with `FileSink::policy()`, `RuntimeSink::file_policy()`, and related default-policy accessors. + +3. For wide native rotation policies, downstream code should read `rotation.max_bytes_i64` when exact threshold recovery matters. diff --git a/docs/api/file-sink-state-to-json.md b/docs/api/file-sink-state-to-json.md index ab4cfc5..f394db7 100644 --- a/docs/api/file-sink-state-to-json.md +++ b/docs/api/file-sink-state-to-json.md @@ -38,6 +38,7 @@ Detailed rules explaining key parameters and behaviors - This helper exports state snapshots, not mutable runtime control handles. - It is useful when file sink state should be embedded into larger diagnostics payloads. - Typical inputs come from `FileSink::state()`, `RuntimeSink::file_state()`, or `ConfiguredLogger::file_state()`. +- If the live rotation policy was created from `file_rotation_i64(...)`, the nested `rotation` JSON includes `max_bytes_i64` as a string alongside the compatibility `max_bytes` number. ### How to Use @@ -73,3 +74,5 @@ e.g.: 1. Use this helper when diagnostics consumers expect `JsonValue`. 2. It pairs naturally with `FileSink::state()`, `RuntimeSink::file_state()`, and `ConfiguredLogger::file_state()`. + +3. For wide native rotation policies, `rotation.max_bytes_i64` is the exact roundtrip field. diff --git a/docs/api/file-sink.md b/docs/api/file-sink.md index 057f914..1a7b42c 100644 --- a/docs/api/file-sink.md +++ b/docs/api/file-sink.md @@ -32,7 +32,7 @@ pub fn file_sink( - `path : String` - Destination file path. - `append : Bool` - Whether opening/reopening should append rather than truncate. - `auto_flush : Bool` - Whether flush is attempted after each write. -- `rotation : FileRotation?` - Optional size-based rotation policy. +- `rotation : FileRotation?` - Optional size-based rotation policy. The default helper path is `file_rotation(...)`; advanced native large-file callers can also pass a policy created by `file_rotation_i64(...)`. - `formatter : RecordFormatter` - Formatter used to render each record before writing. #### output diff --git a/docs/api/file.md b/docs/api/file.md index df4f931..ee91c52 100644 --- a/docs/api/file.md +++ b/docs/api/file.md @@ -38,7 +38,7 @@ pub fn file( - `timestamp : Bool` - Whether the built logger should emit timestamps. - `append : Bool` - Whether file writes should append instead of truncate-on-open behavior. - `auto_flush : Bool` - Whether writes should be flushed automatically. -- `rotation : FileRotation?` - Optional size-based file rotation policy. +- `rotation : FileRotation?` - Optional size-based file rotation policy. The default `file_rotation(...)` path uses the standard `Int`-based threshold contract, while advanced native large-file callers can opt into `file_rotation_i64(...)`. - `text_formatter : TextFormatterConfig` - Formatter config used for file text rendering. #### output diff --git a/docs/api/index.md b/docs/api/index.md index 165503c..e6c5636 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -178,6 +178,7 @@ BitLogger API navigation. - [file-sink-type.md](./file-sink-type.md) - [native-files-supported.md](./native-files-supported.md) - [file-rotation.md](./file-rotation.md) +- [file-rotation-i64.md](./file-rotation-i64.md) - [file-rotation-type.md](./file-rotation-type.md) - [file-sink-policy-to-json.md](./file-sink-policy-to-json.md) - [file-sink-policy.md](./file-sink-policy.md) @@ -244,6 +245,7 @@ BitLogger API navigation. - [file.md](./file.md) - [with-queue.md](./with-queue.md) - [with-file-rotation.md](./with-file-rotation.md) +- [with-file-rotation-i64.md](./with-file-rotation-i64.md) ## Async logger diff --git a/docs/api/runtime-file-state-to-json.md b/docs/api/runtime-file-state-to-json.md index 602fde3..e5ee687 100644 --- a/docs/api/runtime-file-state-to-json.md +++ b/docs/api/runtime-file-state-to-json.md @@ -37,6 +37,7 @@ Detailed rules explaining key parameters and behaviors - `file` is itself exported as a nested file sink state object. - This helper is richer than `file_sink_state_to_json(...)` because it also carries queue wrapping context. - It is useful for `RuntimeSink::file_runtime_state()`, `ConfiguredLogger::file_runtime_state()`, and similar queued-file diagnostics flows. +- Any `file_rotation_i64(...)` policy nested under `file` includes both the compatibility `max_bytes` number and `max_bytes_i64` as a string. ### How to Use @@ -78,3 +79,5 @@ e.g.: 1. Use this helper when file and queue runtime context should stay together. 2. It is especially useful for queued file runtime paths, whether accessed directly or through configured loggers. + +3. For wide native rotation policies nested under `file.rotation`, use `max_bytes_i64` when exact threshold recovery matters. diff --git a/docs/api/with-file-rotation-i64.md b/docs/api/with-file-rotation-i64.md new file mode 100644 index 0000000..5203101 --- /dev/null +++ b/docs/api/with-file-rotation-i64.md @@ -0,0 +1,78 @@ +--- +name: with-file-rotation-i64 +group: api +category: config +update-time: 20260705 +description: Add or replace native-focused Int64 file rotation on an existing file logger config preset. +key-word: + - preset + - file + - rotation + - i64 +--- + +## With-file-rotation-i64 + +Add or replace a size-based file rotation policy with an `Int64` byte threshold on an existing `LoggerConfig`. This helper is the additive native-focused counterpart to `with_file_rotation(...)` for large-file rotation thresholds. + +### Interface + +```moonbit +pub fn with_file_rotation_i64( + config : LoggerConfig, + max_bytes : Int64, + max_backups~ : Int = 1, +) -> LoggerConfig { +``` + +#### input + +- `config : LoggerConfig` - Base logger config to inspect and possibly update. +- `max_bytes : Int64` - Native-focused wide file size threshold. +- `max_backups : Int` - Number of rotated backup files to retain. + +#### output + +- `LoggerConfig` - Updated file config with a wide rotation policy, or the original config unchanged when the sink is not file-based. + +### Explanation + +- `with_file_rotation_i64(...)` only applies to file presets or other configs whose `sink.kind=SinkKind::File`. +- If the input config is not file-based, the helper returns the config unchanged. +- When the input config is file-based, the helper preserves all existing config fields while replacing `sink.rotation` with a wide native-focused policy. +- Rotation policy creation follows `file_rotation_i64(...)` normalization rules. +- When the resulting config is exported to JSON, the nested rotation object preserves the exact threshold through `max_bytes_i64` and keeps `max_bytes` as the compatibility view. + +### How to Use + +#### When Need A Wide Threshold On A File Preset + +```moonbit +let config = with_file_rotation_i64(file("service.log"), 4294967296L, max_backups=3) +``` + +In this example, the file preset gains an `Int64` rotation threshold. + +#### When Compose Queue And Wide Rotation Together + +```moonbit +let config = with_file_rotation_i64( + with_queue(file("service.log"), max_pending=32), + 3221225472L, + max_backups=2, +) +``` + +In this example, queue settings are preserved while a wide native-focused rotation policy is added. + +### Error Case + +- If the input config is not file-based, no error is raised and the config is returned unchanged. +- If `max_bytes` is non-positive, normalization behavior follows `file_rotation_i64(...)`. + +### Notes + +1. This helper is additive and does not replace `with_file_rotation(...)`. +2. Prefer the default helper unless the file size threshold must exceed the standard `Int` contract. +3. JSON roundtrip preserves the exact wide threshold through `max_bytes_i64`. +4. This helper is intended for advanced, native-aware configuration flows. diff --git a/docs/api/with-file-rotation.md b/docs/api/with-file-rotation.md index ae446bf..b1e610b 100644 --- a/docs/api/with-file-rotation.md +++ b/docs/api/with-file-rotation.md @@ -43,6 +43,8 @@ Detailed rules explaining key parameters and behaviors - If the input config is not file-based, the helper returns the config unchanged. - When the input config is file-based, the helper preserves `min_level`, `target`, `timestamp`, file path, append mode, auto-flush, formatter, and queue settings while replacing `sink.rotation`. - Rotation policy creation follows `file_rotation(...)` normalization rules for `max_bytes` and `max_backups`. +- The default `max_bytes : Int` path keeps the standard 32-bit `Int` contract for config-built file rotation. +- If a native-only large-file threshold is required, use `with_file_rotation_i64(...)` rather than overloading the default `Int` path. ### How to Use @@ -84,3 +86,5 @@ e.g.: 1. This helper is a no-op for `console(...)`, `json_console(...)`, and `text_console(...)` presets. 2. Use `file(...)` when you need to provide the initial file path, because `with_file_rotation(...)` does not create a file sink from a non-file config. + +3. The wider `with_file_rotation_i64(...)` path is additive and native-focused; it does not replace the default config contract. diff --git a/docs/changes/1.0.1(0.6.1).md b/docs/changes/1.0.1(0.6.1).md new file mode 100644 index 0000000..3deca94 --- /dev/null +++ b/docs/changes/1.0.1(0.6.1).md @@ -0,0 +1,36 @@ +## BitLogger Update Changes + +version 1.0.1(0.6.1) + +### Runtime + +- feat: add an additive `file_rotation_i64(...)` path so native large-file thresholds can exceed the default `Int` contract without replacing the existing API +- feat: add `with_file_rotation_i64(...)` for file preset and config composition on the same wide-threshold path +- fix: switch native file-size checks used by rotation decisions to 64-bit file positions so wide thresholds are enforced by the runtime backend + +### Config + +- feat: allow logger config parsing to prefer `max_bytes_i64` when present and keep `max_bytes` as the compatibility numeric view +- feat: export wide rotation thresholds through `file_rotation_config_to_json(...)` using `max_bytes_i64` as a string for exact JSON roundtrip +- feat: propagate the same wide-threshold JSON shape through sink config, file sink policy/state, and runtime file-state helpers + +### Docs + +- docs: add dedicated API references for `file_rotation_i64(...)` and `with_file_rotation_i64(...)` +- docs: clarify the default `Int`-based file rotation contract versus the advanced native wide-threshold path across file sink and preset APIs +- docs: document that JSON export keeps `max_bytes` as the compatibility field and `max_bytes_i64` as the exact roundtrip field + +### Test + +- test: cover wide-threshold metadata preservation in direct rotation helpers and preset helpers +- test: cover logger config parse/stringify roundtrip behavior for `max_bytes_i64` +- test: cover nested wide-threshold JSON export in config, file policy, file state, and runtime file-state helpers + +### Verification + +- verify: keep the repository passing `moon fmt`, `moon check`, and `moon test` after the wide-threshold rotation update + +### Notes + +- the default public contract remains the existing `Int`-based file rotation API; the `Int64` route is additive and opt-in +- wide-threshold JSON transport now uses `max_bytes_i64` as a string to avoid precision loss in JavaScript-shaped consumers diff --git a/docs/changes/index.md b/docs/changes/index.md index d2ccabf..572bfe0 100644 --- a/docs/changes/index.md +++ b/docs/changes/index.md @@ -2,7 +2,8 @@ Versioned BitLogger change summaries. -- [1.0.0](./1.0.0.md) +- [1.0.1](./1.0.1(0.6.1).md) +- [1.0.0](./1.0.0(0.6.0).md) - [0.5.3](./0.5.3.md) - [0.5.2](./0.5.2.md) - [0.5.1](./0.5.1.md)