Created
December 7, 2024 16:40
-
-
Save juzna/d6b2352963764904db6c6cd949e11e5b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import subprocess | |
import sys | |
import threading | |
def log_and_forward(input_stream, output_stream, log_file, direction): | |
""" | |
Reads from the input stream, writes to the output stream, and logs data. | |
Args: | |
input_stream: Stream to read data from (e.g., stdin of the user). | |
output_stream: Stream to write data to (e.g., stdin or stdout of the process). | |
log_file: File object to write logs to. | |
direction: Direction of traffic (e.g., 'stdin->process' or 'process->stdout'). | |
""" | |
while True: | |
data = input_stream.readline() | |
if not data: | |
break | |
log_file.write(f"[{direction}] {data}") | |
log_file.flush() | |
output_stream.write(data) | |
output_stream.flush() | |
def main(): | |
if len(sys.argv) < 2: | |
print("Usage: python log_stdio.py <command>") | |
sys.exit(1) | |
command = sys.argv[1:] # Command and its arguments | |
log_file_path = "traffic.log" | |
with open(log_file_path, "w") as log_file: | |
# Start the subprocess with pipes for stdin, stdout, and stderr | |
process = subprocess.Popen( | |
command, | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.STDOUT, # Log stderr along with stdout | |
text=True, # Use text mode | |
bufsize=1 # Line-buffered for interactive output | |
) | |
# Start threads to handle stdin and stdout | |
stdin_thread = threading.Thread( | |
target=log_and_forward, | |
args=(sys.stdin, process.stdin, log_file, "stdin->process"), | |
daemon=True | |
) | |
stdout_thread = threading.Thread( | |
target=log_and_forward, | |
args=(process.stdout, sys.stdout, log_file, "process->stdout"), | |
daemon=True | |
) | |
# Start the threads | |
stdin_thread.start() | |
stdout_thread.start() | |
# Wait for the process to complete | |
process.wait() | |
# Wait for threads to finish | |
stdin_thread.join() | |
stdout_thread.join() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment