<h1 align="center">
<samp>fsmon</samp>
</h1>
<h3 align="center">Real-time file system change monitoring with process attribution.</h3>
đ **Select Language | éæŠč¯č¨**
- [English](./README.md)
- [įŽäŊ䏿](./README.zh-CN.md)
[](https://crates.io/crates/fsmon)
<div align="center">
<img width="1200" alt="fsmon demo" src="./images/fsmon.png" />
</div>
## Features
- **Real-time Monitoring**: Captures 8 core fanotify events (CREATE, DELETE, CLOSE_WRITE, ATTRIB, etc.)
- **Process Attribution**: Tracks PID, command name, and user for every file change â even short-lived processes like `touch`, `rm`, `mv`
- **Recursive Monitoring**: Watch entire directory trees with automatic tracking of newly created subdirectories
- **Complete Deletion Capture**: No more missing events during `rm -rf` â captures every file deleted in recursive operations
- **High Performance**: Written in Rust, <5MB memory footprint, zero-copy event parsing
- **Flexible Filtering**: Filter by time, size, process, user, and event type
- **Multiple Formats**: Human-readable, JSON, and CSV output
- **Systemd Service**: Install as systemd service for long-term auditing with auto-restart
## Why fsmon
Ever needed to answer "Who modified this file?" on a Linux server? That's exactly what fsmon is for.
Traditional file monitoring tools give you events without context â fsmon bridges that gap by attributing every file change to its responsible process. Whether it's a rogue script, an automated deployment, or a misconfigured service, you'll know exactly what happened, when, and who (or what) caused it.
## Quick Start
### Prerequisites
- **OS**: Linux 5.9+ (requires fanotify FID mode)
- **Filesystem**: ext4, XFS, tmpfs (btrfs partial support)
- **Build**: Rust toolchain (`cargo`)
```bash
# Verify kernel version
uname -r # requires âĨ 5.9
# Install Rust if needed
```
### Installation
```bash
# Build from source
git clone https://github.com/lenitain/fsmon.git
cd fsmon
cargo install --path .
# Or install from crates.io
cargo install fsmon
```
**Important: Fanotify requires root privileges**
```bash
# Method 1: Copy to /usr/local/bin (recommended)
sudo cp ~/.cargo/bin/fsmon /usr/local/bin/
# Method 2: Use full path directly
sudo ~/.cargo/bin/fsmon monitor ...
```
### Basic Usage
```bash
# Monitor a directory
sudo fsmon monitor /etc --types MODIFY
# Monitor with recursive watching
sudo fsmon monitor ~/myproject --recursive
# Install as systemd service for long-term auditing
sudo fsmon install /var/log /etc -o /var/log/fsmon-audit.log
# Query historical events
fsmon query --since 1h --cmd nginx
# Check service status
fsmon status
```
## Examples
### Investigate Configuration Changes
```bash
# Monitor /etc for modifications
sudo fsmon monitor /etc --types MODIFY --output /tmp/etc-monitor.log
# In another terminal, make a change
# Query the results
fsmon query --log-file /tmp/etc-monitor.log --since 1h --types MODIFY
```
### Track Large File Creation
```bash
# Watch for files larger than 50MB
sudo fsmon monitor /tmp --types CREATE --min-size 50MB --format json
# Trigger
dd if=/dev/zero of=/tmp/large_test.bin bs=1M count=100
```
### Audit Deletion Operations
```bash
# Capture complete recursive deletion
sudo fsmon monitor ~/test-project --types DELETE --recursive --output /tmp/deletes.log
# Trigger
rm -rf ~/test-project/build/
# Output shows every file deleted (even in subdirectories)
[2026-01-15 16:00:00] [DELETE] /home/pilot/test-project/build/output.o (PID: 34567, CMD: rm)
[2026-01-15 16:00:00] [DELETE] /home/pilot/test-project/build (PID: 34567, CMD: rm)
```
## Command Reference
```bash
fsmon monitor --help # Real-time monitoring
fsmon query --help # Query history logs
fsmon status # Check systemd service status
fsmon stop # Stop systemd service
fsmon start # Start systemd service
fsmon install --help # Install systemd service
fsmon uninstall # Uninstall systemd service
fsmon clean --help # Cleanup old logs
```
## Technical Architecture
- **fanotify (FID mode)**: Linux kernel pushes file events to a queue; user space consumes via non-blocking `read()`. No polling needed â events are delivered immediately.
- **Proc Connector**: Background thread caches process info at `exec()` time for accurate attribution of short-lived processes.
- **name_to_handle_at + dir cache**: Resolves file handles to paths, caches directory handles to recover paths of deleted files during `rm -rf`.
- **Rust + Tokio**: Single-threaded reactor loop (`while running` + 10ms sleep) with async Ctrl+C signal handling. Minimal concurrency â high efficiency instead.
### Event Types
Default captures 8 core events. Use `--all-events` for all 14.
**Default Events (8):**
| CLOSE_WRITE | File closed after write (best "modified" signal) |
| ATTRIB | Metadata changed (permissions, timestamps, owner) |
| CREATE | File/directory created |
| DELETE | File/directory deleted |
| DELETE_SELF | The monitored file/directory itself was deleted |
| MOVED_FROM | File moved out of monitored directory |
| MOVED_TO | File moved into monitored directory |
| MOVE_SELF | The monitored file/directory itself was moved |
**Additional Events (6, via --all-events):**
| ACCESS | File read |
| MODIFY | File content written (very noisy) |
| OPEN | File/directory opened |
| OPEN_EXEC | File opened for execution |
| CLOSE_NOWRITE | Read-only file closed |
| FS_ERROR | Filesystem error (Linux 5.16+)
## License
[MIT License](./LICENSE)