1 unstable release
Uses new Rust 2024
new 0.1.0 | Apr 19, 2025 |
---|
#5 in #stdio
125KB
2.5K
SLoC
fdintercept
A utility program that intercepts and logs stdin, stdout, and stderr for any target command.
Features
- Wraps any command and captures all I/O via stdin, stdout, and stderr.
- No need for manual pipe setup or shell redirection.
- Logs each stream to separate files.
- Cross-platform, supports Linux and MacOS.
- Clean configuration via the CLI, an environment variable, or a configuration file, including the target command.
- Configurable buffer size for I/O operations.
- Preserves original program exit codes.
- Handles process and child process termination gracefully.
Implementation Notes
While Linux-specific optimizations like splice()
were considered during
development, fdintercept prioritizes cross-platform compatibility to support
software engineers using both Linux and MacOS systems. For most development and
debugging use cases, the performance difference would be negligible, as the
tool is primarily meant for development and testing rather than production
deployments where every microsecond counts.
Installation
cargo install fdintercept
Usage
There are three ways to use fdintercept:
- Direct command line usage:
fdintercept -- your-command [args...]
- Via environment variable:
FDINTERCEPT_TARGET="your-command [args...]" fdintercept
- Via configuration file (see Configuration below for details):
target = "your-command [args...]"
Then simply run:
fdintercept
If defined in more than one way, the order of precedence in how the target command is resolved is:
- Command line arguments
- Environment variable
- Configuration file
Output
The program creates three log files in the current directory:
stdin.log
: Contains all input sent to the program.stdout.log
: Contains all standard output from the program.stderr.log
: Contains all error output from the program.
Configuration
fdintercept accepts configuration via CLI arguments, environment variables, and a configuration file. Precedence follows that order.
CLI arguments
These have the highest priority. If any setting is defined as a CLI argument, it won't be overridden by environment variables or a configuration file.
fdintercept accepts the following CLI arguments:
--conf
: Path to a configuration file. If relative, this is relative to the current working directory.--stdin-log
: Filename of the log file that will record stdin traffic. If relative, this is relative to the current working directory. Default:stdin.log
.--stdout-log
: Filename of the log file that will record stdout traffic. If relative, this is relative to the current working directory. Default:stdout.log
.--stderr-log
: Filename of the log file that will record stderr traffic. If relative, this is relative to the current working directory. Default:stderr.log
.--recreate-logs
: Re-create log files instead of appending to them. Default: false.--buffer-size
: Size in bytes of the buffer used for I/O operations. Default: 8 KiB.- After
--
: The target command that will be executed.
If at least one of --stdin-log
, --stdout-log
, and --stderr-log
is
specified, only the specified log files will be created. If none are specified,
they will all be created with their default values. (These can be mixed with
the configuration file fields and if any log filenames are specified here or
there, the defaults won't be created either.)
Examples
# Log all stdout I/O for a Python script with a custom buffer size.
fdintercept --stdout-log /tmp/stdout.log --buffer-size 1024 -- python script.py arg1 arg2
# Log all stdin, stdout, and stderr I/O for a Python script.
fdintercept -- python script.py arg1 arg2
# Use a specific configuration file.
fdintercept --conf /path/to/config.toml
Environment variables
These environment variables will be used, if defined:
FDINTERCEPTRC
: Path to a configuration file. If relative, this is relative to the current working directory.FDINTERCEPT_RECREATE_LOGS
: Re-create log files instead of appending to them. Default: false.FDINTERCEPT_BUFFER_SIZE
: Size in bytes of the buffer used for I/O operations. Default: 8 KiB.FDINTERCEPT_TARGET
: The target command that will be executed.
Configuration file
fdintercept will look for the configuration file in these locations, in this order:
- Path specified via
--conf
CLI argument - Path specified in
$FDINTERCEPTRC
environment variable ~/.fdinterceptrc.toml
$XDG_CONFIG_HOME/fdintercept/rc.toml
Here are the accepted fields:
stdin_log
: Filename of the log file that will record stdin traffic. If relative, this is relative to the current working directory. Default:stdin.log
.stdout_log
: Filename of the log file that will record stdout traffic. If relative, this is relative to the current working directory. Default:stdout.log
.stderr_log
: Filename of the log file that will record stderr traffic. If relative, this is relative to the current working directory. Default:stderr.log
.recreate_logs
: Re-create log files instead of appending to them. Default: false.buffer-size
: Size in bytes of the buffer used for I/O operations. Default: 8 KiB.target
: The target command that will be executed.
If at least one of stdin_log
, stdout_log
, and stderr_log
is specified,
only the specified log files will be created. If none are specified, they will
all be created with their default values. (These can be mixed with the CLI
arguments and if any log filenames are specified here or there, the defaults
won't be created either.)
Example
This will make fdintercept log all stdout I/O for a Python script with a custom buffer size:
target = "python script.py arg1 arg2"
stdout_log = "/tmp/stdout.log"
buffer_size = 1024
Building from source
This assumes you have the Rust toolchain installed locally.
git clone https://github.com/jpmelos/fdintercept
cd fdintercept
cargo build --release
cargo install --path .
Roadmap
- Transparently intercept stdin, stdout, and stderr
- Supply target command via configuration file
- Supply target command via environment variable (
$FDINTERCEPT_TARGET
) - Define log filenames via CLI
- Define log filenames via configuration file
- Look for configuration in
$XDG_CONFIG_HOME/fdintercept/rc.toml
- Look for configuration in a file passed in via the command line
- Look for configuration in a file passed in via an environment variable
(
$FDINTERCEPTRC
) - Configure buffer size for I/O operations
- Flag to re-create log files instead of appending to them.
- Allow definition of message schemas, add separators between messages
- Add timestamps to messages
- Allow intercepting arbitrary file descriptors
License
MIT License
Copyright (c) 2025 João Sampaio
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Dependencies
~3–12MB
~129K SLoC