Log task adalah rekaman eksekusi satu task instance, dan kemampuan membacanya dengan cepat menentukan berapa lama pipeline berhenti. Topik ini membahas asal log task pada Airflow, forensik atas tiga kegagalan nyata yang jenisnya berbeda, dan status perintah baca log pada CLI Airflow 3. Bagian akhir menyajikan pola kegagalan yang tidak menyisakan traceback, sehingga diagnosisnya berbeda. Semua kegagalan pada topik ini benar-benar dieksekusi dan keluarannya diambil dari log eksekusi tersebut.
Asal log task#
Setiap task instance menulis log melalui logger Airflow, dan lokasi penyimpanannya dikendalikan oleh konfigurasi base_log_folder dengan nilai bawaan di bawah AIRFLOW_HOME/logs. Pada deployment yang berjalan penuh dengan scheduler dan worker, Airflow menyusun log task dalam struktur folder bernama dag_id=<nama dag>/run_id=<nama run>/task_id=<nama task>/attempt=<nomor percobaan>. Struktur tersebut membuat satu berkas log menggambarkan tepat satu percobaan eksekusi satu task. Antarmuka web menampilkan isi berkas yang sama pada tab Log panel task instance, sehingga membaca log melalui UI dan membaca berkas log secara langsung memberikan hasil yang identik.
Eksekusi lokal tidak membentuk berkas log per task. Perintah dags test mengeksekusi task di dalam satu proses Python dan seluruh log task menyatu pada keluaran perintahnya, sebagaimana digunakan pada seluruh latihan jalur ini. Pengetahuan yang sama tetap berlaku pada kedua bentuk log, yaitu blok traceback muncul tepat setelah pesan Task failed with exception, satu blok untuk setiap task yang gagal.
Forensik traceback pada log eksekusi#
Bukti forensik paling kaya berasal dari task yang gagal dengan jenis error yang berbeda-beda. DAG berikut memuat tiga task tanpa dependensi, dan ketiganya sengaja dibuat gagal, yaitu pembagian dengan nol, pencarian kunci kamus yang tidak ada, serta task yang melampaui batas waktunya.
"""DAG laporan suhu ruang ujian untuk latihan membaca log kegagalan.
Tiga task berjalan tanpa dependensi dan masing-masing sengaja gagal
dengan jenis error yang berbeda: ZeroDivisionError, KeyError, dan
pelampauan batas execution_timeout.
"""
import time
from datetime import timedelta
import pendulum
from airflow.sdk import dag, task
CATATAN = {
"R-101": [25.1, 26.3, 24.8],
"R-102": [24.8, 25.6],
}
@dag(
dag_id="laporan_suhu",
schedule=None,
start_date=pendulum.datetime(2026, 11, 1, tz="UTC"),
description="Tiga task yang sengaja gagal untuk latihan forensik log.",
)
def laporan_suhu():
@task
def hitung_rata() -> None:
"""Menghitung rata-rata suhu; membagi nol ketika data kosong."""
suhu = CATATAN.get("R-103", [])
rata = sum(suhu) / len(suhu)
print(f"rata-rata R-103: {rata}")
@task
def catat_rekap() -> None:
"""Menuliskan rekap; mencari kunci ruang yang tidak ada."""
maksimum = max(CATATAN["R-105"])
print(f"suhu maksimum: {maksimum}")
@task(execution_timeout=timedelta(seconds=5))
def kumpulkan_lama() -> None:
"""Menunggu sensor perangkat yang tidak pernah selesai."""
print("mulai mengumpulkan catatan perangkat")
time.sleep(60)
print("selesai")
hitung_rata()
catat_rekap()
kumpulkan_lama()
laporan_suhu()Argumen execution_timeout pada task ketiga memasang batas durasi lima detik, dan pelampauan batas itu memunculkan exception AirflowTaskTimeout. Lingkungan latihan disiapkan pada folder terpisah, berkas DAG dipastikan dapat diparse, lalu DAG dijalankan sekali. Kegagalan task membuat dags test berakhir dengan status gagal, sehingga perintahnya diakhiri || echo agar kejadian itu tercatat tanpa menghentikan urutan langkah.
# lingkungan latihan terpisah untuk topik ini
export AIRFLOW_HOME=/tmp/ra-debugging
export AIRFLOW__CORE__LOAD_EXAMPLES=False# salin berkas DAG ke folder yang dipindai Airflow
export AIRFLOW_HOME=/tmp/ra-debugging
mkdir -p "$AIRFLOW_HOME/dags"
cp dag_laporan_suhu.py "$AIRFLOW_HOME/dags/"# siapkan skema basis data metadata
# log migrasi berisi stempel waktu, sehingga tidak ditampilkan
export AIRFLOW_HOME=/tmp/ra-debugging
airflow db migrate > /dev/null 2>&1# jalankan DAG sekali secara lokal, lognya dialihkan ke berkas
# perintah diakhiri echo karena task yang gagal membuatnya berakhir gagal
export AIRFLOW_HOME=/tmp/ra-debugging
airflow dags test laporan_suhu 2026-11-04 > "$AIRFLOW_HOME/dags-test.log" 2>&1 || echo "dags test berakhir dengan task gagal"dags test berakhir dengan task gagalLognya berisi tiga blok traceback, satu untuk setiap task yang gagal. Baris-baris inti dari ketiga blok itu diambil dengan satu pola pencarian per task, yaitu baris kode task yang bersangkutan beserta baris pesan exception-nya. Pola per task menjaga urutan keluaran tetap sama antar eksekusi, karena tiga task tanpa dependensi berjalan bersamaan dan urutan kegagalannya pada log bisa berubah.
# ambil baris kode task dan baris exception dari setiap traceback
# satu pola per task agar urutan keluaran tidak bergantung pada log
export AIRFLOW_HOME=/tmp/ra-debugging
grep -E 'dag_laporan_suhu\.py", line [0-9]+, in catat_rekap|KeyError:' "$AIRFLOW_HOME/dags-test.log"
grep -E 'dag_laporan_suhu\.py", line [0-9]+, in kumpulkan_lama|raise AirflowTaskTimeout' "$AIRFLOW_HOME/dags-test.log"
grep -E 'dag_laporan_suhu\.py", line [0-9]+, in hitung_rata|ZeroDivisionError:' "$AIRFLOW_HOME/dags-test.log" File "/tmp/ra-debugging/dags/dag_laporan_suhu.py", line 36, in catat_rekap
KeyError: 'R-105'
File "/tmp/ra-debugging/dags/dag_laporan_suhu.py", line 43, in kumpulkan_lama
raise AirflowTaskTimeout(self.error_message)
File "/tmp/ra-debugging/dags/dag_laporan_suhu.py", line 30, in hitung_rata
ZeroDivisionError: division by zeroTraceback dibaca dari bawah ke atas. Baris terakhir selalu berisi jenis exception beserta pesannya, sedangkan baris di atasnya menyatakan lokasi kode yang memunculkan exception tersebut. Baris KeyError: 'R-105' menunjuk line 36, in catat_rekap, yaitu pencarian kunci R-105 pada kamus CATATAN yang memang tidak memuat ruang tersebut. Baris ZeroDivisionError: division by zero menunjuk line 30, in hitung_rata, yaitu pembagian dengan panjang list yang bernilai nol karena CATATAN.get("R-103", []) mengembalikan list kosong. Baris ketiga berasal dari kode internal Airflow, tetapi tetap mengarah ke task yang sama, yaitu kumpulkan_lama yang dihentikan oleh batas waktunya sebelum time.sleep(60) selesai.
Status akhir ketiga task dan dag run-nya memperkuat pembacaan tersebut. Tiga task berstatus gagal dan dag run ditutup dengan status yang sama.
# hitung task yang berstatus gagal dan dag run yang berstatus gagal
export AIRFLOW_HOME=/tmp/ra-debugging
grep -c "new_state=failed" "$AIRFLOW_HOME/dags-test.log"
grep -c "state=failed, run_type=manual" "$AIRFLOW_HOME/dags-test.log"3
1Membaca log melalui CLI#
Airflow 2.x menyediakan airflow tasks logs untuk menampilkan log task dari terminal, dan perintah tersebut dihapus pada Airflow 3. Perintah berikut memperlihatkan respons CLI Airflow 3 atas perintah lama itu. Karena kegagalan itulah yang hendak ditunjukkan, perintahnya diakhiri || true.
# perintah tasks logs tidak lagi tersedia pada Airflow 3
export AIRFLOW_HOME=/tmp/ra-debugging
airflow tasks logs laporan_suhu catat_rekap 2026-11-04 2>&1 | tail -n 1 || trueairflow tasks command error: argument COMMAND: invalid choice: 'logs' (choose from clear, failed-deps, list, render, state, states-for-dag-run, test), see help above.Kegagalan tanpa traceback#
Dua pola kegagalan yang paling sulit didiagnosis justru tidak menyisakan traceback sama sekali. Pola pertama adalah task yang dihentikan sistem operasi karena kehabisan memori. Kernel menghentikan proses worker yang kehabisan memori, sehingga log worker berhenti mendadak di tengah aktivitas tanpa baris Task failed with exception.
Task berstatus gagal tanpa satu pun pesan exception. Tanda konfirmasinya ada di log sistem operasi, misalnya dmesg atau journalctl yang memperlihatkan kernel menghentikan proses karena out of memory. Perbaikannya mengecilkan cakupan kerja per task, misalnya memproses data per partisi alih-alih seluruh rentang sekaligus.
Pola kedua adalah deadlock, yaitu dua proses saling menunggu kunci yang dipegang masing-masing sehingga tidak ada kemajuan. Task yang terjebak deadlock tetap berjalan, lognya terus menampilkan aktivitas menunggu, tetapi proses tidak pernah maju. Batas execution_timeout pada task yang membaca atau menulis basis data menjadi pengaman di sini. Pelampauan batas menghentikan task yang macet, sehingga kebuntuan tanpa batas waktu berubah menjadi kegagalan yang terlihat pada log.
Kesalahan umum#
- Membaca traceback dari atas. Frame atas pada traceback berisi kode internal Airflow yang panjang dan berbeda antar versi, sehingga pembacaannya memakan waktu tanpa hasil. Bacalah dari baris paling bawah, yaitu jenis exception dan pesannya, lalu lihat satu baris di atasnya untuk menemukan berkas dan nomor baris kode task yang bersangkutan.
- Mengandalkan
airflow tasks logspada Airflow 3. Perintah tersebut telah dihapus, sehingga alur kerja yang dibangun di atasnya berhenti. Gunakan tab Log pada antarmuka web, berkas log padabase_log_folder, atau keluarandags testuntuk eksekusi lokal. - Menjalankan task berat tanpa
execution_timeout. Task yang macet karena deadlock atau koneksi yang tidak pernah selesai menempati slot worker tanpa batas waktu. Pasang batas durasi pada setiap task yang mengakses layanan luar agar kegagalan macet terlihat sebagai kegagalan, bukan sebagai pipeline yang berhenti tanpa penjelasan.
Ringkasan#
- Log task per percobaan tersimpan di bawah
base_log_folderdengan strukturdag_id/run_id/task_id/attempt, sedangkandags testmenyatukan seluruh log task pada keluaran perintahnya. - Traceback dibaca dari bawah, yaitu jenis exception di baris terakhir, lalu berkas dan nomor baris kode task pada baris di atasnya, sebagaimana ditunjukkan kegagalan
KeyError,ZeroDivisionError, danAirflowTaskTimeout. - Perintah
airflow tasks logsdihapus pada Airflow 3, sehingga log task dibaca dari antarmuka web, berkas log, atau keluaran eksekusi lokal. - Task yang diakhiri kernel karena kehabisan memori dan task yang terjebak deadlock tidak menyisakan traceback. Keduanya didiagnosis melalui log sistem operasi serta dicegah dengan partisi data dan
execution_timeout.
Referensi#
- Logging and Monitoring — Apache Airflow — Gambaran mekanisme log task beserta pilihan penyimpanannya.
- Tasks — Apache Airflow
— Bagian Timeouts yang menjelaskan
execution_timeoutdan exceptionAirflowTaskTimeout. - Command Line Interface and Environment Variables Reference — Apache Airflow
— Rujukan perintah subperintah
airflow tasksyang berlaku pada Airflow 3.