Skip to content

Rotation API ​

The Rotation module provides enterprise-grade log rotation capabilities, including time-based and size-based rotation, retention policies, compression, and flexible naming strategies.

Quick Reference: Method Aliases ​

Full MethodAlias(es)Description
init()create()Initialize rotation
deinit()destroy()Deinitialize rotation
withCompression()setCompression()Set compression config
withNaming()setNaming()Set naming strategy
withNamingFormat()namingFormat(), setNamingFormat()Set naming format
withMaxAge()maxAge(), setMaxAge()Set max age
setInterval()updateInterval()Set rotation interval directly
setIntervalFromString()configureInterval()Set interval from string or disable
setSizeLimit()updateSizeLimit()Set size limit directly
setRetentionCount()updateRetentionCount()Set retention count directly
setRetentionPolicy()configureRetention()Set retention count + max age
withArchiveDir()archiveDir(), setArchiveDir()Set archive directory
setCleanEmptyDirs()cleanEmptyDirs()Set clean empty dirs
withKeepOriginal()keepOriginal(), setKeepOriginal()Set keep original
withCompressOnRetention()compressOnRetention(), setCompressOnRetention()Set compress on retention
withDeleteAfterRetentionCompress()deleteAfterRetentionCompress(), setDeleteAfterRetentionCompress()Set delete after retention compress
applyConfig()configure(), applyConfiguration()Apply configuration
isEnabled()enabled()Check if enabled
intervalName()getIntervalName()Get interval name
getRotationReason()rotationReason(), getReason()Get current rotation trigger reason
shouldRotate()shouldRotateNow()Check if conditions currently require rotation
nextRotationInSeconds()secondsUntilNextRotation()Get remaining interval seconds
previewNextPath()previewPath(), nextPath()Preview next rotated file path
forceRotate()rotateNow(), force()Force rotation immediately
checkAndRotate()rotateIfNeeded(), maybeRotate()Check and rotate if needed
createRotatingSink()rotatingSink()Create rotating sink
createSizeRotatingSink()sizeSink()Create size rotating sink
seconds()duration(), intervalSeconds()Get seconds (RotationInterval)
fromString()parse(), fromStr()Parse from string (RotationInterval)
name()displayName(), string()Get name (RotationInterval)
reset()clear(), zero()Reset stats (RotationStats)
rotationCount()rotations(), totalRotations()Get rotation count (RotationStats)
errorCount()totalErrors()Get error count (RotationStats)
getFilesArchived()filesArchived(), archivedCount()Get files archived (RotationStats)
getFilesDeleted()filesDeleted(), deletedCount()Get files deleted (RotationStats)
getCompressionErrors()compressionErrors(), compressErrors()Get compression errors (RotationStats)
hasErrors()hasRotationErrors()Check if has errors (RotationStats)
successRate()successPercentage()Get success rate (RotationStats)
totalErrorRate()errorPercentage(), totalErrorPercentage()Get total error rate (RotationStats)
weekly4Weeks()weekly()Weekly preset (RotationPresets)
monthly12Months()monthly()Monthly preset (RotationPresets)
hourly24Hours()hourly()Hourly preset (RotationPresets)
daily7Days()daily()Daily preset (RotationPresets)

Rotation Struct ​

The core struct managing rotation logic.

zig
const Rotation = @import("logly").Rotation;

Initialization ​

zig
pub fn init(
    allocator: std.mem.Allocator,
    path: []const u8,
    interval_str: ?[]const u8, // "daily", "hourly", etc.
    size_limit: ?u64,          // Bytes
    retention: ?usize          // Max files to keep
) !Rotation

Configuration Methods ​

withCompression ​

Enables automatic compression of rotated files.

zig
pub fn withCompression(self: *Rotation, config: CompressionConfig) !void

Example:

zig
try rot.withCompression(.{ .algorithm = .deflate });

withNaming ​

Sets the naming strategy for rotated files.

zig
pub fn withNaming(self: *Rotation, strategy: NamingStrategy) void

Example:

zig
rot.withNaming(.iso_datetime);

withNamingFormat ​

Sets a custom format string for rotated files. Automatically sets strategy to .custom.

zig
pub fn withNamingFormat(self: *Rotation, format: []const u8) !void

Example:

zig
try rot.withNamingFormat("{base}-{date}{ext}");

withMaxAge ​

Sets a maximum age (in seconds) for retaining log files.

zig
pub fn withMaxAge(self: *Rotation, seconds: i64) void

Example:

zig
rot.withMaxAge(86400 * 7); // 7 days

setInterval ​

Sets interval rotation trigger directly.

zig
pub fn setInterval(self: *Rotation, interval: ?RotationInterval) void

setIntervalFromString ​

Sets interval from string ("daily", "hourly", etc.) or disables interval when passed null.

zig
pub fn setIntervalFromString(self: *Rotation, interval_str: ?[]const u8) bool

Returns true when update succeeds.

setSizeLimit ​

Sets size-based rotation threshold in bytes.

zig
pub fn setSizeLimit(self: *Rotation, size_limit: ?u64) void

setRetentionCount ​

Sets retention count directly.

zig
pub fn setRetentionCount(self: *Rotation, retention_count: ?usize) void

setRetentionPolicy ​

Sets retention count and max age in one call.

zig
pub fn setRetentionPolicy(self: *Rotation, retention_count: ?usize, max_age_seconds: ?i64) void

withArchiveDir ​

Sets a specific directory to move rotated files into.

zig
pub fn withArchiveDir(self: *Rotation, dir: []const u8) !void

Example:

zig
try rot.withArchiveDir("logs/archive");

withKeepOriginal ​

Set whether to keep original files after compression.

zig
pub fn withKeepOriginal(self: *Rotation, keep: bool) void

Example:

zig
rot.withKeepOriginal(true); // Keep both original and compressed files

withCompressOnRetention ​

Enable compression during retention cleanup instead of deletion.

zig
pub fn withCompressOnRetention(self: *Rotation, enable: bool) void

Example:

zig
rot.withCompressOnRetention(true); // Compress old files instead of deleting

withDeleteAfterRetentionCompress ​

Set whether to delete original files after retention compression.

zig
pub fn withDeleteAfterRetentionCompress(self: *Rotation, delete: bool) void

Example:

zig
rot.withDeleteAfterRetentionCompress(false); // Keep originals after compression

applyConfig ​

Applies global configuration settings to the rotation instance.

zig
pub fn applyConfig(self: *Rotation, config: RotationConfig) !void

Example:

zig
try rot.applyConfig(global_config.rotation);

Rotation Decision Helpers ​

getRotationReason(self: *Rotation, file_ptr: *std.fs.File) ?RotationReason ​

Returns why rotation would occur right now (interval, size, or interval_and_size).

shouldRotate(self: *Rotation, file_ptr: *std.fs.File) bool ​

Returns true when any rotation condition is currently met.

nextRotationInSeconds(self: *const Rotation) ?i64 ​

Returns remaining seconds until next interval rotation, or null if interval rotation is disabled.

previewNextPath(self: *Rotation) ![]u8 ​

Returns the next rotated path without mutating internal state.

forceRotate(self: *Rotation, file_ptr: *std.fs.File) !void ​

Forces an immediate rotation regardless of interval or size checks.

Configuration Structs ​

RotationConfig ​

Global configuration struct for rotation defaults.

zig
pub const RotationConfig = struct {
    enabled: bool = false,
    interval: ?[]const u8 = null,
    size_limit: ?u64 = null,
    size_limit_str: ?[]const u8 = null,
    retention_count: ?usize = null,
    max_age_seconds: ?i64 = null,
    naming_strategy: NamingStrategy = .timestamp,
    naming_format: ?[]const u8 = null,
    archive_dir: ?[]const u8 = null,
    clean_empty_dirs: bool = false,
    async_cleanup: bool = false,
    keep_original: bool = false,                    // Keep original after compression
    compress_on_retention: bool = false,            // Compress instead of delete during retention
    delete_after_retention_compress: bool = true,   // Delete originals after retention compression
    archive_root_dir: ?[]const u8 = null,           // Root directory for all archives
    create_date_subdirs: bool = false,              // Create YYYY/MM/DD subdirectories
    file_prefix: ?[]const u8 = null,                // Custom prefix for rotated files
    file_suffix: ?[]const u8 = null,                // Custom suffix for rotated files
    compression_algorithm: CompressionAlgorithm = .gzip,
    compression_level: CompressionLevel = .default,
};

RotationConfig Field Reference ​

FieldTypeDefaultDescription
enabledboolfalseEnable rotation
interval?[]const u8nullTime-based interval (e.g., "daily")
size_limit?u64nullSize-based rotation threshold (bytes)
retention_count?usizenullMax files to retain
max_age_seconds?i64nullMax age for rotated files
naming_strategyNamingStrategy.timestampFile naming strategy
archive_dir?[]const u8nullDirectory for rotated files
archive_root_dir?[]const u8nullCentralized archive root
create_date_subdirsboolfalseCreate YYYY/MM/DD subdirs
file_prefix?[]const u8nullPrefix for rotated file names
file_suffix?[]const u8nullSuffix for rotated file names
compression_algorithmCompressionAlgorithm.gzipAlgorithm for compression (gzip, zlib, deflate, zstd v0.1.5+)
compression_levelCompressionLevel.defaultCompression level
keep_originalboolfalseKeep original after compression
compress_on_retentionboolfalseCompress instead of delete
delete_after_retention_compressbooltrueDelete after retention compression
clean_empty_dirsboolfalseRemove empty directories

Enums ​

RotationInterval ​

Defines the time interval for rotation.

ValueDescription
.minutelyRotate every minute.
.hourlyRotate every hour.
.dailyRotate every day (24 hours).
.weeklyRotate every week.
.monthlyRotate every 30 days.
.yearlyRotate every 365 days.

NamingStrategy ​

Defines how rotated files are named.

ValueExample (app.log)Notes
.timestampapp.log.167882233Default for size/hourly rotation.
.dateapp.log.2023-01-01Default for daily/weekly/monthly.
.iso_datetimeapp.log.2023-01-01T12-00-00High precision.
.indexapp.log.1, app.log.2Rolling log style.
.customapp-2023-01-01.logUses naming_format.

RotationReason ​

Explains which trigger caused rotation.

ValueDescription
.intervalTime interval threshold reached.
.sizeFile size threshold reached.
.interval_and_sizeBoth interval and size thresholds reached.

Custom Format Placeholders ​

When using .custom (or setting naming_format), you can use:

PlaceholderDescription
{base}Filename without extension
{ext}Extension (including dot)
{date}YYYY-MM-DD
{time}HH-mm-ss
{timestamp}Unix timestamp
{iso}ISO 8601 Datetime

Flexible Date/Time Placeholders: You can also use {YYYY}, {YY}, {MM}, {M}, {DD}, {D}, {HH}, {H}, {mm}, {m}, {ss}, {s} and any separators. Example: app-{YYYY}/{M}/{D}.log -> app-2023/10/5.log

Statistics ​

The RotationStats struct provides insights into the rotation process.

FieldTypeDescription
total_rotationsAtomicUnsignedTotal number of rotations performed.
files_archivedAtomicUnsignedNumber of files successfully compressed.
files_deletedAtomicUnsignedNumber of files deleted due to retention policy.
last_rotation_time_msAtomicUnsignedDuration of the last rotation operation.
rotation_errorsAtomicUnsignedCount of rotation failures.
compression_errorsAtomicUnsignedCount of compression failures.

Getter Methods ​

MethodReturnDescription
getTotalRotations()u64Get total rotations performed
getFilesArchived()u64Get files archived count
getFilesDeleted()u64Get files deleted count
getRotationErrors()u64Get rotation error count
getCompressionErrors()u64Get compression error count
getTotalErrors()u64Get total error count

Boolean Checks ​

MethodReturnDescription
hasRotated()boolCheck if any rotations have occurred
hasErrors()boolCheck if any errors have occurred
hasCompressionErrors()boolCheck for compression errors
hasArchived()boolCheck if any files have been archived

Rate Calculations ​

MethodReturnDescription
successRate()f64Calculate success rate (0.0 - 1.0)
errorRate()f64Calculate error rate (0.0 - 1.0)
totalErrorRate()f64Calculate total error rate including compression
archiveRate()f64Calculate archive rate (archived / rotated)

Reset ​

MethodDescription
reset()Reset all statistics to initial state

Presets ​

The RotationPresets struct offers comprehensive pre-configured rotation strategies for common use cases.

Time-Based Presets ​

MethodIntervalRetentionDescription
daily7Days()daily7Standard weekly cleanup
daily30Days()daily30Monthly cleanup
daily90Days()daily90Quarterly cleanup
daily365Days()daily365Yearly archive
hourly24Hours()hourly24Daily cleanup
hourly48Hours()hourly48Two-day buffer
hourly7Days()hourly168Weekly retention
weekly4Weeks()weekly4Monthly cleanup
weekly12Weeks()weekly12Quarterly cleanup
monthly12Months()monthly12Yearly retention
minutely60()minutely60Debug/testing

Size-Based Presets ​

MethodSize LimitRetentionDescription
size1MB()1 MB5Small logs
size5MB()5 MB5Compact logs
size10MB()10 MB5Standard size
size25MB()25 MB10Medium size
size50MB()50 MB10Large size
size100MB()100 MB10Enterprise size
size250MB()250 MB5High volume
size500MB()500 MB3Very high volume
size1GB()1 GB2Maximum size

Hybrid Presets (Time + Size) ​

MethodIntervalSize LimitRetentionDescription
dailyOr100MB()daily100 MB30Rotate on time OR size
hourlyOr50MB()hourly50 MB48Fast rotation
dailyOr500MB()daily500 MB7High volume

Production Presets ​

MethodDescription
production()Daily, 30 days, gzip compression, date naming
enterprise()Daily, 90 days, best compression, ISO naming, compress on retention
debug()Minutely, 60 files, timestamp naming, no compression
highVolume()Hourly OR 500MB, 7 days, ISO naming, compression
audit()Daily, 365 days, best compression, keep all archives
minimal()Size 10MB, 3 files, index naming (embedded systems)

Sink Configuration Helpers ​

MethodDescription
dailySink(path, retention)Create daily rotation sink config
hourlySink(path, retention)Create hourly rotation sink config
weeklySink(path, retention)Create weekly rotation sink config
monthlySink(path, retention)Create monthly rotation sink config
sizeSink(path, bytes, retention)Create size-based rotation sink config

Preset Aliases ​

AliasTarget
dailydaily7Days
hourlyhourly24Hours
weeklyweekly4Weeks
monthlymonthly12Months

Example Usage ​

zig
const RotationPresets = @import("logly").RotationPresets;

// Quick preset usage
var rot = try RotationPresets.daily7Days(allocator, "app.log");
defer rot.deinit();

// Using alias
var rot2 = try RotationPresets.daily(allocator, "server.log");
defer rot2.deinit();

// Production preset with compression enabled
var prod = try RotationPresets.production(allocator, "production.log");
defer prod.deinit();

// Enterprise preset with full archival
var ent = try RotationPresets.enterprise(allocator, "enterprise.log");
defer ent.deinit();

// Audit log with maximum retention
var audit = try RotationPresets.audit(allocator, "audit.log");
defer audit.deinit();

// Hybrid: rotate daily OR when file reaches 100MB
var hybrid = try RotationPresets.dailyOr100MB(allocator, "hybrid.log");
defer hybrid.deinit();

// Create sink configs for logger
const sink = RotationPresets.dailySink("logs/app.log", 30);
try logger.addSink(sink);

Example Usage ​

zig
var rotation = try Rotation.init(allocator, "app.log", "daily", null, 30);

// Enable compression
try rotation.withCompression(.{ .algorithm = .deflate });

// Logic ensures checks are fast
try rotation.checkAndRotate(&file);

Released under the MIT License.