karawaci.kode

← Semua snippet

Python Pemula Utility

Tee output ke file + stdout simultan (Python)

Print ke terminal sekaligus log ke file. Tidak perlu redirect manual. Wrap stdout dengan custom class. 10 lines.

Dipublikasikan 26 Mei 2026

Sering: jalan script Python, ingin lihat output di terminal LIVE, sekaligus simpan ke log file untuk review nanti. Bash tee lakukan ini tapi butuh setup di shell. Snippet ini do it dari dalam Python.

Kode

import sys
from pathlib import Path

class Tee:
    """Write to multiple file-like objects."""
    def __init__(self, *streams):
        self.streams = streams
    
    def write(self, msg):
        for s in self.streams:
            s.write(msg)
            s.flush()
    
    def flush(self):
        for s in self.streams:
            s.flush()

# Usage: redirect stdout
log_file = Path("run.log").open("w", encoding="utf-8")
sys.stdout = Tee(sys.__stdout__, log_file)

# Sekarang print ke terminal + log file
print("Mulai job pada 2026-06-04 10:30")
print("Processing batch 1/12...")
# ... rest of program

Pemakaian

Skenario 1: script ETL panjang yang ingin di-review setelah selesai

import sys
from pathlib import Path
from datetime import datetime

log_path = Path("logs") / f"etl-{datetime.now():%Y%m%d-%H%M%S}.log"
log_path.parent.mkdir(exist_ok=True)
log_file = log_path.open("w", encoding="utf-8")

sys.stdout = Tee(sys.__stdout__, log_file)

print(f"=== ETL run {datetime.now()} ===")

# Process data...
for batch in range(12):
    print(f"Batch {batch + 1}/12 processed")

print("=== Done ===")
log_file.close()

Skenario 2: print yang juga capture untuk testing

from io import StringIO

capture = StringIO()
sys.stdout = Tee(sys.__stdout__, capture)

run_my_function()

sys.stdout = sys.__stdout__  # restore
output = capture.getvalue()
assert "expected message" in output

Kapan dipakai

  • Cron job yang butuh log untuk review setelah selesai
  • Debug session dengan banyak print yang ingin di-save
  • CI/CD script yang ingin tahu apa yang terjadi di run gagal

Kapan JANGAN dipakai

  • Production logging: pakai logging module dengan handler. Lebih konfigurable, log level, format, dll.
  • Long-running daemon: log file tidak rotate. Pakai logging module dengan RotatingFileHandler.
  • High-throughput print: setiap print flush ke disk, lambat. Untuk 10k+ print/sec, butuh buffering.

Catatan

  • sys.__stdout__ preserve original stdout. Kalau script di-pipe (python script.py | grep ...), tetap kerja.
  • encoding="utf-8" important untuk content Indonesia (rupiah symbol, dll). Default Python pakai system encoding yang di Windows masih cp1252.
  • flush after write supaya tidak buffer di Python — kalau script crash, log tetap punya output sampai crash point.

Variasi: redirect both stdout + stderr

log_file = Path("run.log").open("w", encoding="utf-8")
sys.stdout = Tee(sys.__stdout__, log_file)
sys.stderr = Tee(sys.__stderr__, log_file)

# Sekarang print() dan raise Exception (yang print to stderr) keduanya tee

Untuk production, loguru library (third-party) handle ini sebagai default — log ke file dengan rotation otomatis. Snippet ini untuk script sederhana zero-dep.

# tags

pythonloggingstdoutio

Ditulis oleh Asti Larasati · 26 Mei 2026