Betiklerde journalctl ile journald Sorgulama
Otomatik olay önceliklendirmesi için systemd günlük girdilerini birime, önceliğe ve zamana göre filtreleyin.
Betiklerde journalctl ile journald Sorgulama, CoddyKit'te ücretsiz bir DevOps Bootcamp dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DevOps Bootcamp öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DevOps Bootcamp kursu toplamda 4 dersten oluşur.
Olayların İlk İncelenmesinde journald Neden Kullanılır?
systemd çalıştıran modern Linux sistemleri, tüm günlük çıktısını günlükte merkezileştirir; bu günlük, systemd-journald tarafından yönetilen yapılandırılmış ve ikili bir günlük deposudur. /var/log içindeki düz metin dosyalarının aksine, her günlük girdisi birim adı, öncelik düzeyi, PID, UID, zaman damgası ve daha fazlası gibi zengin üst veriler taşır.
Otomatik olay ilk inceleme betiklerinde bu üst veriler şunları yapmanızı sağlar:
- Günlükleri
grepzincirleri olmadan tek bir hizmete filtreleme - Sorguları tam zaman aralıklarıyla sınırlandırma (son 15 dakika, dağıtımdan bu yana)
- Gürültüyü yok sayarak yalnızca kritik/hata iletilerini üretme
- Yapılandırılmış çıktıyı doğrudan uyarı iş akışlarına aktarma
Tüm bunları sunan araç journalctl komutudur. Bu derste, bu komutu BASH betikleri içinde programlı olarak kullanmayı öğreneceksiniz.
Temel journalctl Kullanımı
journalctl komutunun en basit biçimi günlüğün tamamını döker. Betiklerde neredeyse hiçbir zaman bunu istemezsiniz; her zaman en az bir filtre ekleyin. Birlikte zincirleyeceğiniz en yaygın seçenekler şunlardır:
-u <unit>— systemd birimine göre filtreleme (ör.nginx.service)-p <priority>— syslog önceliğine göre filtreleme (0=emerg … 7=debug)--since/--until— zaman aralığı-n <N>— son N satır--no-pager— etkileşimli sayfalama özelliğini devre dışı bırakma (betiklerde zorunludur)-o <format>— çıktı biçimi (short,json,catvb.)
Etkileşimli olmayan betiklerde her zaman --no-pager seçeneğini kullanın; böylece journalctl less komutunu çağırmayı deneyip takılmaz.
#!/usr/bin/env bash
# Print the last 20 lines of the nginx service journal
journalctl --no-pager -u nginx.service -n 20Systemd Birimine Göre Filtreleme
-u seçeneği geçerli herhangi bir birim adını kabul eder. Birimleri birleştirmek için bu seçeneği birden çok kez sağlayabilirsiniz; bu, tek bir uygulama birkaç hizmete yayıldığında (ör. bir API ve onun veritabanı yan hizmeti) kullanışlıdır.
Birim adları <name>.service, <name>.socket, <name>.timer vb. kalıbını izler. Kalıp eşleştirme desteklenir: -u 'myapp*', myapp-api.service, myapp-worker.service ve benzeri adlarla eşleşir.
Bir ilk inceleme betiğinde genellikle birim adını bağımsız değişken olarak alırsınız; bu da filtreyi dinamik hâle getirir.
#!/usr/bin/env bash
# Usage: ./unit_logs.sh nginx.service
UNIT="${1:?Usage: $0 <unit>}"
echo "=== Journal for ${UNIT} (last 50 lines) ==="
journalctl --no-pager -u "${UNIT}" -n 50
# Combine two related units
echo "=== Combined: api + worker ==="
journalctl --no-pager -u myapp-api.service -u myapp-worker.service -n 30Öncelik Düzeyleri ve -p Bayrağı
-p bayrağı, standart syslog öncelik düzeyleriyle eşleşir:
0— emerg1— alert2— crit3— err4— warning5— notice6— info7— debug
Yalnızca tek bir düzeyi (-p err) görüntülemek için belirtebilir veya acil durumlardan hatalara kadar her şeyi yakalamak için bir aralık (-p emerg..err) kullanabilirsiniz; otomatik uyarı sistemlerinde en sık tercih edilen seçenek budur.
Adlandırılmış takma adlar (err, warning, crit), sayısal değerlerle birlikte kabul edilir.
#!/usr/bin/env bash
# Extract only error-level and above entries for sshd
journalctl --no-pager \
-u sshd.service \
-p emerg..err \
--since "1 hour ago"
# Exit non-zero if any errors were found (useful in CI health checks)
ERROR_COUNT=$(journalctl --no-pager -u sshd.service -p emerg..err \
--since "1 hour ago" --output=cat | wc -l)
if [[ "${ERROR_COUNT}" -gt 0 ]]; then
echo "[ALERT] ${ERROR_COUNT} error(s) detected in sshd" >&2
exit 1
fi--since ve --until ile Zaman Aralığı Filtreleme
Zaman filtreleri, olay zaman aralığı sorgularının temelini oluşturur. journalctl, esnek ve insanların okuyabileceği zaman damgalarını kabul eder:
- Göreli:
"10 minutes ago","2 hours ago","yesterday" -
"2026-06-11 14:00:00" - Özel anahtar sözcükler:
today,yesterday,-1h(kısa biçim)
Dağıtım betiklerinde yaygın bir yöntem, dağıtımdan hemen önceki zaman damgasını almak ve ardından sürümün neden olduğu gerilemeleri tespit etmek için günlüğü bu noktadan itibaren sorgulamaktır.
#!/usr/bin/env bash
# Record deploy start time, then check logs afterwards
DEPLOY_START=$(date +"%Y-%m-%d %H:%M:%S")
echo "Deploying at ${DEPLOY_START}..."
# ... your deploy steps here ...
sleep 2 # simulate deploy
echo "=== Journal since deploy start ==="
journalctl --no-pager \
-u myapp.service \
--since "${DEPLOY_START}" \
-p emerg..warningJSON Biçimiyle Yapılandırılmış Çıktı
Makinelerce okunabilen işlem hatları için -o json (satır başına bir JSON nesnesi, NDJSON) veya -o json-pretty (biçimlendirilmiş) seçeneğini aktarın. Her nesne, günlüğün tüm alanlarını içerir:
MESSAGE— günlük metniPRIORITY— sayısal öncelik (0–7)_SYSTEMD_UNIT— kaynağı olan birim__REALTIME_TIMESTAMP— başlangıç zamanından bu yana geçen mikrosaniyeler_PID,_UID,_HOSTNAME— işlem üst verileri
Bu NDJSON akışını jq üzerinden geçirerek aşağı akıştaki PagerDuty, Slack web kancaları veya SIEM veri alıcıları gibi uyarı sistemleri için alanları ayıklayabilir, filtreleyebilir veya yeniden biçimlendirebilirsiniz.
#!/usr/bin/env bash
# Extract error messages as a clean list for a Slack notification
MESSAGES=$(journalctl --no-pager \
-u nginx.service \
-p emerg..err \
--since "30 minutes ago" \
-o json \
| jq -r '.MESSAGE' \
| sort -u)
if [[ -n "${MESSAGES}" ]]; then
echo "Errors detected:"
echo "${MESSAGES}"
fiGünlüğü Gerçek Zamanlı İzleme
-f bayrağı, journalctl'in günlüğün sonuna canlı olarak eklenen kayıtları izlemesini sağlar; bu, bir günlük dosyasında tail -f kullanımına benzer. Birim ve öncelik filtreleriyle birleştirildiğinde hedefe yönelik gerçek zamanlı bir izleyiciye dönüşür.
Betiğe alınmış işlem hatlarında daha kullanışlı yöntem imleç tabanlı yoklamadır: mevcut günlük imlecini kaydedin, ardından her yoklamada son kontrolden bu yana yalnızca yeni girdileri okumak için --after-cursor=<cursor> aktarın. Böylece eski satırların yeniden işlenmesi önlenir.
En son imleci --show-cursor -n 0 ile alın ve çıktıda bulunan -- cursor: satırını ayrıştırın.
#!/usr/bin/env bash
# Cursor-based polling: read only new journal entries each run
CURSOR_FILE="/tmp/triage_cursor"
if [[ -f "${CURSOR_FILE}" ]]; then
CURSOR=$(cat "${CURSOR_FILE}")
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--after-cursor="${CURSOR}" \
-o json)
else
# First run: look back 5 minutes
NEW_ENTRIES=$(journalctl --no-pager \
-u myapp.service \
-p emerg..err \
--since "5 minutes ago" \
-o json)
fi
# Save updated cursor for next poll
journalctl --no-pager -n 0 --show-cursor 2>&1 \
| grep '^-- cursor:' \
| sed 's/-- cursor: //' \
> "${CURSOR_FILE}"
echo "${NEW_ENTRIES}" | jq -r '.MESSAGE // empty'-b ile Önyükleme Oturumuna Özgü Sorgular
-b bayrağı, sorguyu belirli bir önyükleme oturumuyla sınırlar. Bir çökme veya beklenmedik yeniden başlatma sonrasında güncel önyükleme yerine önceki önyüklemenin günlüklerini almak için bu seçenek gereklidir.
-b 0— mevcut önyükleme (varsayılan)-b -1— önceki önyükleme-b -2— iki önyükleme önceki--list-boots— zaman damgalarıyla kaydedilmiş tüm önyükleme oturumlarını gösterir
Ölüm sonrası betikler, sistemin neden çöktüğünü veya bir hizmetin başlangıçta neden başarısız olduğunu teşhis etmek için genellikle önceki önyüklemedeki (-b -1) kritik günlükleri döker.
#!/usr/bin/env bash
# Post-mortem: collect critical logs from the previous boot
echo "=== Previous boot sessions ==="
journalctl --list-boots
echo ""
echo "=== Critical entries from previous boot ==="
journalctl --no-pager \
-b -1 \
-p emerg..crit \
-o short-isojournalctl İçinde Grep ve Yerel Eşleşmeler
Tüm bayraklardan sonra ham bir grep deseni aktarabilirsiniz; ancak journalctl, FIELD=value söz dizimini kullanarak yerel alan eşleşmelerini de destekler. Yerel eşleşmeler yapılandırılmış üst verilere göre değerlendirilir ve metni grep ile sonradan işlemekten çok daha hızlıdır.
Yaygın ve kullanışlı eşleşmeler:
_PID=1234— belirli bir işlemden gelen günlükler_COMM=python3— adıpython3olan tüm işlemlerden gelen günlüklerSYSLOG_IDENTIFIER=myapp— özel bir tanımlayıcıyla etiketlenmiş günlükler
Birden çok FIELD=value bağımsız değişkeni AND işlemiyle birleştirilir; aralarına eklenen + OR oluşturur. Yapılandırılmış üst veriler yetersiz kaldığında tam metin araması için -g <regex> kullanın.
#!/usr/bin/env bash
# Native field match: errors from the postgres process only
journalctl --no-pager \
_COMM=postgres \
-p emerg..err \
--since "1 hour ago"
# Full-text grep for a specific error string
journalctl --no-pager \
-u postgresql.service \
--since "1 hour ago" \
-g "FATAL|PANIC" \
--output=catYeniden Kullanılabilir Bir Triage İşlevi Oluşturma
Tek tek bayraklarda ustalaştıktan sonra bunları yeniden kullanılabilir bir Bash işlevinde birleştirmek, triage betiklerinizi temiz ve tutarlı tutar. İyi tasarlanmış bir işlev:
- Birim, öncelik aralığı ve zaman aralığını parametre olarak kabul etmelidir
- Bağımsız değişkenler verilmediğinde güvenli ve az gürültülü değerleri varsayılan olarak kullanmalıdır
- Hatalar bulunduğunda sıfır olmayan bir çıkış kodu döndürmelidir (CI işlem hatlarıyla tümleşir)
- Denetim kayıtları için bulguları hem stdout'a hem de zaman damgalı bir günlük dosyasına yazmalıdır
#!/usr/bin/env bash
# triage.sh — reusable journal triage function
triage_unit() {
local unit="${1:?unit required}"
local priority="${2:-emerg..err}"
local since="${3:-1 hour ago}"
local logfile="/tmp/triage_${unit//[^a-zA-Z0-9]/_}_$(date +%s).log"
echo "[$(date -Iseconds)] Triaging ${unit} | prio=${priority} | since='${since}'" | tee "${logfile}"
journalctl --no-pager \
-u "${unit}" \
-p "${priority}" \
--since "${since}" \
-o short-iso \
| tee -a "${logfile}"
local count
count=$(wc -l < "${logfile}")
# Subtract 1 for the header line
(( count-- ))
if [[ "${count}" -gt 0 ]]; then
echo "[ALERT] ${count} line(s) logged to ${logfile}" >&2
return 1
fi
return 0
}
# Example: triage nginx errors in the last 30 minutes
triage_unit nginx.service "emerg..err" "30 minutes ago"Otomatik Olay Triage Betiği
Aşağıdaki eksiksiz betik, tüm kavramları pratik bir otomatik triage aracında bir araya getirir. Kritik hizmetlerin listesini okur, yapılandırılabilir bir geriye dönük inceleme aralığında her biri için günlüğü sorgular, bulguları toplar ve herhangi bir hata tespit edilirse başarısızlık koduyla çıkar; bu nedenle cron işi veya CI sağlık denetimi adımı olarak kullanılabilir.
#!/usr/bin/env bash
# incident_triage.sh — automated multi-service journal triage
set -euo pipefail
LOOKBACK="${1:-15 minutes ago}"
PRIORITY="emerg..err"
SERVICES=(nginx.service postgresql.service myapp-api.service myapp-worker.service)
REPORT="/tmp/incident_report_$(date +%Y%m%d_%H%M%S).txt"
FAILED=0
{
echo "Incident Triage Report"
echo "Generated : $(date -Iseconds)"
echo "Lookback : ${LOOKBACK}"
echo "Priority : ${PRIORITY}"
echo "-----------------------------------"
} > "${REPORT}"
for svc in "${SERVICES[@]}"; do
ENTRIES=$(journalctl --no-pager \
-u "${svc}" \
-p "${PRIORITY}" \
--since "${LOOKBACK}" \
--output=cat 2>/dev/null || true)
COUNT=$(echo "${ENTRIES}" | grep -c . || true)
if [[ "${COUNT}" -gt 0 ]]; then
echo "[FAIL] ${svc}: ${COUNT} error(s)" | tee -a "${REPORT}"
echo "${ENTRIES}" >> "${REPORT}"
echo "-----------------------------------" >> "${REPORT}"
FAILED=1
else
echo "[OK] ${svc}"
fi
done
echo ""
echo "Full report: ${REPORT}"
exit "${FAILED}"Bilgi Kontrolü: Öncelik Aralığı Filtreleme
Bir hizmet yalnızca hata önem derecesinde veya daha ciddi (yani hata, kritik, uyarı ya da acil durum) iletiler günlüğe yazdığında nöbetçi mühendislere uyarı gönderen bir betik yazıyorsunuz. Tam olarak bu aralığı yakalayan journalctl bayrak birleşimi hangisidir?
Ders Özeti: Betiklerde journalctl
Bu derste otomatik olay triage işlemi için systemd günlüğünü programlı olarak nasıl sorgulayacağınızı öğrendiniz:
- Betiklerde her zaman
--no-pageraktarın; böylece etkileşimli engelleme önlenir. - Birim filtreleme (
-u), sorguları bir veya daha fazla hizmetle sınırlar; glob kullanımı ve birden çok-ubayrağı desteklenir. - Öncelik filtreleme (
-p emerg..err), yalnızca önem derecesiyle ilgilendiğiniz düzeyleri yakalar; düşük sayıların daha ciddi olduğunu unutmayın. - Zaman aralıkları (
--since/--until), insanların okuyabileceği zaman damgalarını kullanarak günlük çıktısını bir dağıtım aralığına veya geriye dönük inceleme dönemine sınırlar. - Önyükleme kapsamı (
-b -1), ölüm sonrası betiklerin önceki bir çökme oturumundaki günlükleri okumasını sağlar. - JSON çıktısı (
-o json) vejq, uyarı veya SIEM sistemlerine veri sağlayan yapılandırılmış işlem hatlarını mümkün kılar. - İmleç tabanlı yoklama,
--after-cursorile yinelenen çalıştırmalarda eski girdilerin yeniden işlenmesini önler. - Yerel alan eşleşmeleri (
_COMM=,SYSLOG_IDENTIFIER=), çıktıyıgrep'e aktarmaktan daha hızlıdır.
Bu bayrakları yeniden kullanılabilir bir Bash işlevinde birleştirmek; cron, CI işlem hatları ve nöbetçi uyarı iş akışlarıyla sorunsuz tümleşen, üretim düzeyinde bir triage aracı sağlar.
Sıkça Sorulan Sorular
“Betiklerde journalctl ile journald Sorgulama” dersi ücretsiz mi?
Evet — “Betiklerde journalctl ile journald Sorgulama” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DevOps Bootcamp kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DevOps Bootcamp kursu toplamda 4 dersten oluşur.
“Betiklerde journalctl ile journald Sorgulama” dersinde ne öğreneceğim?
Otomatik olay önceliklendirmesi için systemd günlük girdilerini birime, önceliğe ve zamana göre filtreleyin. DevOps Bootcamp ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
DevOps Bootcamp öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te DevOps Bootcamp, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Betiklerde journalctl ile journald Sorgulama” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu DevOps Bootcamp dersinde kod yazıp çalıştırabilir miyim?
Evet. Her DevOps Bootcamp dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Web ve Uygulama Günlüklerini Büyük Ölçekte Ayrıştırma
- Gerçek Zamanlı Günlük Takibi ve Akış Uyarıları
- Betiklerde journalctl ile journald Sorgulama
- Günlük Akışlarından Ölçümler ve Histogramlar Hesaplama