# LogRotator

A C# command-line tool that rotates log files with timestamp-based renaming, compression, and automatic cleanup based on configurable size limits. Rotation only occurs when the log file exceeds a configurable threshold size.

## Features

- **Conditional Rotation**: Only rotates log files when they exceed a configurable size threshold
- **Timestamp-based Renaming**: Renames rotated files with a customizable date/time format
- **Compression**: Supports ZIP and GZIP compression formats
- **Automatic Cleanup**: Deletes oldest archived files when total archive size exceeds a limit
- **Registry Toggle Support**: Optionally toggle registry keys to disable logging/file locks before rotation
- **Configurable**: All parameters can be specified via command-line arguments or JSON config file

## Requirements

- .NET 7.0 or later
- Windows, Linux, or macOS

## Building

### For Development/Testing
```bash
dotnet build
```

### For Production (Self-Contained Executable)
```bash
dotnet publish --configuration Release
```

The publish command creates a self-contained executable in `bin/Release/net7.0/win-x64/publish/` that includes the .NET runtime and can run without .NET installed.

<!-- Alternative: Production-only build instructions
## Building

```bash
dotnet publish --configuration Release
```

This creates a self-contained executable in `bin/Release/net7.0/win-x64/publish/` that includes the .NET runtime and can run without .NET installed.
-->

## Usage

### Basic Usage

```bash
LogRotator --log-file "C:\Logs\app.log" --rotation-threshold "10MB"
```

### Full Example

```bash
# Rotate only if log exceeds 10MB, keep archives under 500MB total, use ZIP compression
LogRotator --log-file "C:\Logs\app.log" --rotation-threshold "10MB" --size-limit "500MB" --compression zip
```

### Command-Line Arguments

#### Required Arguments

- `--log-file`, `-f <path>`: Path to the log file to rotate
- `--rotation-threshold`, `-t <size>`: Minimum size before rotation occurs (e.g., "10MB", "100MB"). Rotation only happens if the log file exceeds this size.

#### Optional Arguments

- `--size-limit`, `-s <size>`: Maximum total size for archived logs (e.g., "500MB", "1GB"). When exceeded, oldest archived files are deleted.
- `--archive-dir`, `-d <path>`: Directory for archived logs (default: same directory as log file)
- `--compression`, `-c <format>`: Compression format: `zip` or `gzip` (default: `zip`)
- `--date-format`, `-df <format>`: Date format pattern for timestamp in archived filenames (default: `yyyy-MM-dd_HH-mm-ss`)
- `--registry-key`, `-rk <path>`: Registry key path to toggle before rotation (e.g., `HKEY_LOCAL_MACHINE\SOFTWARE\MyApp\Settings`). Used to disable logging/file locks.
- `--registry-value-name`, `-rvn <name>`: Registry value name to modify (default: empty string for default value)
- `--registry-disable-value`, `-rdv <val>`: Value to set when disabling logging (e.g., `0`, `false`, `Disabled`). Required if `--registry-key` is specified.
- `--registry-delay`, `-rd <ms>`: Delay in milliseconds after setting registry value before attempting file move (default: 2000)
- `--help`, `-h`: Show help message

### Size Formats

Size values can be specified with the following units:
- `B` - Bytes
- `KB` - Kilobytes (1024 bytes)
- `MB` - Megabytes (1024 * 1024 bytes)
- `GB` - Gigabytes (1024 * 1024 * 1024 bytes)

Examples: `10MB`, `1GB`, `500KB`, `1024B`

### Date Format

The date format uses standard .NET DateTime format strings. Examples:
- `yyyy-MM-dd_HH-mm-ss` (default) - Produces: `2024-01-15_14-30-45`
- `yyyyMMdd_HHmmss` - Produces: `20240115_143045`
- `yyyy-MM-dd` - Produces: `2024-01-15`

## How It Works

1. **Size Check**: The tool first checks if the log file exists and if its size exceeds the rotation threshold.
   - If the file is below the threshold, the tool exits successfully without performing any rotation.

2. **Registry Toggle** (if configured): Before attempting to move the log file:
   - Reads the current registry value from the specified key
   - Sets the registry value to the disable value (to stop logging/release file locks)
   - Waits for the configured delay period to allow the logging service to release the file lock

3. **Rotation**: If the threshold is met:
   - The current log file is renamed with a timestamp: `{original-name}_{timestamp}.{ext}`

4. **Registry Restore** (if configured): After rotation (or if rotation fails):
   - Restores the original registry value to re-enable logging

5. **Compression**: The renamed file is compressed using the specified format (ZIP or GZIP), and the uncompressed file is deleted.

6. **Cleanup**: If a size limit is configured:
   - The tool calculates the total size of all archived log files
   - If the total exceeds the limit, it sorts files by modification time (oldest first)
   - Oldest files are deleted until the total size is below the limit

## Examples

### Example 1: Basic Rotation

```bash
LogRotator -f "app.log" -t "50MB"
```

This will rotate `app.log` only if it exceeds 50MB. Archived files will be stored in the same directory.

### Example 2: With Archive Size Limit

```bash
LogRotator -f "C:\Logs\app.log" -t "10MB" -s "500MB" -d "C:\Logs\Archive"
```

This will:
- Rotate `app.log` when it exceeds 10MB
- Store archives in `C:\Logs\Archive`
- Delete oldest archives when total archive size exceeds 500MB

### Example 3: Custom Date Format and GZIP Compression

```bash
LogRotator -f "app.log" -t "100MB" -c gzip -df "yyyyMMdd_HHmmss"
```

This will:
- Rotate when file exceeds 100MB
- Use GZIP compression
- Use date format `yyyyMMdd_HHmmss` for archived filenames

### Example 4: With Registry Toggle

```bash
LogRotator -f "app.log" -t "10MB" --registry-key "HKEY_LOCAL_MACHINE\SOFTWARE\MyApp\Logging" --registry-value-name "Enabled" --registry-disable-value "0" --registry-delay 3000
```

This will:
- Rotate when file exceeds 10MB
- Before rotation, set the registry value `HKEY_LOCAL_MACHINE\SOFTWARE\MyApp\Logging\Enabled` to `0` to disable logging
- Wait 3 seconds for the logging service to release the file lock
- Attempt to rotate the log file
- Restore the original registry value after rotation (or if rotation fails)

## Exit Codes

- `0`: Success (rotation completed or not needed)
- `1`: Error (file not found, invalid arguments, etc.)

## Error Handling

The tool includes comprehensive error handling:
- Validates file paths and permissions
- Handles file locks gracefully
- Provides clear error messages
- Validates all command-line arguments
- Continues operation even if compression fails (with warning)
- If registry toggle fails, the rotation operation fails immediately
- Registry value is always restored in a finally block, even if rotation fails

## Notes

- The tool will create the archive directory if it doesn't exist
- If compression fails, the uncompressed archived file is retained
- The tool only processes archived files that match the naming pattern (contain an underscore, indicating a timestamp)
- File operations are performed synchronously to ensure data integrity
- Registry toggle functionality requires administrator privileges for `HKEY_LOCAL_MACHINE` keys
- The registry delay allows time for the logging service to release file locks before attempting rotation
- Registry values support DWORD (integers), String, and Boolean types (booleans are stored as DWORD: 0 or 1)

## License

This software is provided as freeware. See [LICENCE.txt](LICENCE.txt) for full license terms and warranty disclaimers.

**Summary:**
- Free to use for personal or commercial purposes
- Modification, reverse engineering, and redistribution are prohibited
- Provided "AS IS" without warranty

## Author / Contact

**Developer:** Shawn Ferrier  
**Company:** Madriam Services Inc.  
**Email:** shawn.ferrier@madriamservices.com

For support or questions, please contact the developer.

