Go kqueue Event Monitoring System
This challenge requires you to build a Go program that leverages the kqueue system call to efficiently monitor file system events for a specified directory. This is a foundational skill for building real-time applications, file synchronization tools, and systems that react to changes in the environment.
Problem Description
You need to create a Go application that acts as a file system event monitor using kqueue. The program should:
- Initialize
kqueue: Open a newkqueuefile descriptor. - Register for Events: Register a specific directory for monitoring
kqueueevents. You should focus on events related to file modifications, creations, and deletions within that directory. - Process Events: Continuously read and process events from the
kqueue. When an event occurs, the program should print a human-readable message indicating the type of event and the file path involved. - Handle Multiple Events: The system should be capable of handling multiple events that might occur in rapid succession.
- Graceful Shutdown: Implement a mechanism to allow the program to shut down gracefully upon receiving a signal (e.g., SIGINT).
Examples
Example 1:
Imagine you are monitoring the directory /tmp/watch_dir.
-
Scenario:
- A new file named
new_file.txtis created in/tmp/watch_dir. - The file
existing_file.login/tmp/watch_diris modified. - The file
old_document.pdfin/tmp/watch_diris deleted.
- A new file named
-
Input: The program is started with the argument
/tmp/watch_dir. -
Expected Output (order might vary slightly depending on exact timing):
Event: ADDED /tmp/watch_dir/new_file.txt Event: MODIFIED /tmp/watch_dir/existing_file.log Event: REMOVED /tmp/watch_dir/old_document.pdf
Example 2:
Monitoring a directory /data/logs.
-
Scenario:
- The program starts.
- A file
app.logis renamed toapp.log.1. - A new directory
archiveis created within/data/logs.
-
Input: The program is started with the argument
/data/logs. -
Expected Output:
Event: RENAMED /data/logs/app.log -> /data/logs/app.log.1 Event: ADDED /data/logs/archive
Constraints
- The program must be written in Go.
- You should primarily use the
golang.org/x/sys/unixpackage forkqueuesystem calls. - The program should accept the directory to monitor as a command-line argument.
- The program should monitor file modifications (
EVFILT_VFS_EVENT_TYPE_MODIFY), creations (EVFILT_VFS_EVENT_TYPE_CREATE), and deletions (EVFILT_VFS_EVENT_TYPE_DELETE). For simplicity, you can also monitor renames (EVFILT_VFS_EVENT_TYPE_RENAME). - The program should be able to handle at least 10 concurrent events without significant performance degradation.
- The program should exit gracefully when it receives a SIGINT (Ctrl+C).
Notes
kqueueis a BSD-derived system call. While it's available on macOS and FreeBSD, its behavior and availability on Linux differ significantly (Linux typically usesinotify). This challenge is specifically targeted at platforms wherekqueueis natively supported.- You will need to understand how to use
unix.Keventto register file descriptors and receive events. - Pay close attention to the event flags (
EV_ADD,EV_ENABLE, etc.) and the filter type (EVFILT_VFS). - Consider how to map the raw
kqueueevent data to human-readable descriptions of file system actions. - A common approach for monitoring directories with
kqueueis to register a file descriptor for the directory itself and then process events that indicate changes within that directory.