Forespørgsler til journald med journalctl i scripts
Filtrér systemd-journalposter efter unit, prioritet og tidspunkt til automatiseret triage af hændelser.
Forespørgsler til journald med journalctl i scripts er en gratis Intensiv DevOps-uddannelse-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Intensiv DevOps-uddannelse, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Intensiv DevOps-uddannelse-kurset indeholder 4 lektioner i alt.
Hvorfor journald til indledende hændelsesanalyse
Moderne Linux-systemer, der kører systemd, samler alt logoutput centralt i journalen — et struktureret, binært loglager, der administreres af systemd-journald. I modsætning til almindelige tekstfiler i /var/log indeholder hver journalpost omfattende metadata: enhedsnavn, prioritetsniveau, PID, UID, tidsstempel med mere.
I automatiserede scripts til indledende hændelsesanalyse lader disse metadata dig:
- Filtrere logge til én enkelt tjeneste uden kæder af
grep-kommandoer - Afgrænse forespørgsler til præcise tidsvinduer (de seneste 15 minutter, siden en udrulning)
- Udsende kun kritiske meddelelser og fejlmeddelelser, mens støj ignoreres
- Sende struktureret output direkte ind i alarmpipelines
Værktøjet, der giver adgang til alt dette, er journalctl. I denne lektion lærer du at styre det programmatisk i Bash-scripts.
Grundlæggende journalctl-kald
Den enkleste form af journalctl dumper hele journalen. I scripts ønsker du næsten aldrig dette — tilføj altid mindst ét filter. Her er de mest almindelige flag, som du kan kæde sammen:
-u <unit>— filtrer efter systemd-enhed (f.eks.nginx.service)-p <priority>— filtrer efter syslog-prioritet (0=emerg … 7=debug)--since/--until— tidsvindue-n <N>— de seneste N linjer--no-pager— deaktiver interaktiv sidevisning (vigtigt i scripts)-o <format>— outputformat (short,json,catosv.)
Angiv altid --no-pager i ikke-interaktive scripts, så journalctl ikke forsøger at starte less og går i stå.
#!/usr/bin/env bash
# Print the last 20 lines of the nginx service journal
journalctl --no-pager -u nginx.service -n 20Filtrering efter systemd-enhed
Flaget -u accepterer ethvert gyldigt enhedsnavn. Du kan angive det flere gange for at kombinere enheder, hvilket er nyttigt, når en enkelt applikation strækker sig over flere tjenester (f.eks. en API-tjeneste og dens ledsagende databasetjeneste).
Enhedsnavne følger mønsteret <name>.service, <name>.socket, <name>.timer osv. Jokertegn understøttes: -u 'myapp*' matcher myapp-api.service, myapp-worker.service og så videre.
I et script til indledende hændelsesanalyse modtager du typisk enhedsnavnet som et argument, så filteret bliver dynamisk.
#!/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 30Prioritetsniveauer og flaget -p
Flaget -p svarer til standardprioritetsniveauerne i syslog:
0— emerg1— alert2— crit3— err4— warning5— notice6— info7— debug
Du kan angive ét niveau (-p err) for kun at se dette niveau eller et interval (-p emerg..err) for at medtage alt fra nødsituationer til fejl — det mest almindelige valg til automatiseret alarmering.
Navngivne aliaser (err, warning, crit) accepteres sammen med numeriske værdier.
#!/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
fiFiltrering efter tidsinterval med --since og --until
Tidsfiltre er grundlaget for forespørgsler på hændelsesintervaller. journalctl accepterer fleksible, menneskeligt læsbare tidsstempler:
- Relative:
"10 minutes ago","2 hours ago","yesterday" - Absolutte:
"2026-06-11 14:00:00" - Særlige nøgleord:
today,yesterday,-1h(kort notation)
I deployscripts er et almindeligt mønster at gemme tidsstemplet lige før en deploy og derefter forespørge i journalen fra dette tidspunkt for at finde regressioner, som versionen har introduceret.
#!/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..warningStruktureret output i JSON-format
Til maskinlæsbare datapipelines skal du angive -o json (ét JSON-objekt pr. linje, NDJSON) eller -o json-pretty (formatteret). Hvert objekt indeholder alle journalfelter:
MESSAGE— logtekstenPRIORITY— numerisk prioritet (0–7)_SYSTEMD_UNIT— den enhed, som posten stammer fra__REALTIME_TIMESTAMP— mikrosekunder siden epoken_PID,_UID,_HOSTNAME— procesmetadata
Du kan pipe denne NDJSON-strøm ind i jq for at udtrække, filtrere eller omformatere felter til efterfølgende alarmeringssystemer som PagerDuty, Slack-webhooks eller SIEM-indlæsere.
#!/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}"
fiFølg journalen i realtid
Flaget -f får journalctl til at følge journalen live — på samme måde som tail -f på en logfil. Kombineret med filtre for enhed og prioritet bliver dette en målrettet realtidsovervågning.
I scriptbaserede datapipelines er det mere nyttige mønster cursorbaseret polling: Gem den aktuelle journalcursor, og angiv derefter --after-cursor=<cursor> ved hver polling for kun at læse nye poster siden den seneste kontrol. Det forhindrer, at gamle linjer behandles igen.
Hent den nyeste cursor med --show-cursor -n 0, og fortolk linjen -- cursor: fra outputtet.
#!/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'Forespørgsler begrænset til en opstart med -b
Flaget -b begrænser en forespørgsel til en bestemt opstartssession. Det er afgørende efter et nedbrud eller en uventet genstart, hvis du vil hente logfiler fra den forrige opstart i stedet for den aktuelle.
-b 0— aktuel opstart (standard)-b -1— forrige opstart-b -2— opstarten før den forrige--list-boots— vis alle registrerede opstartssessioner med tidsstempler
Efterbehandlingsscripts dumper ofte kritiske logfiler fra den forrige opstart (-b -1) for at diagnosticere, hvorfor systemet brød sammen, eller hvorfor en tjeneste mislykkedes under opstart.
#!/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-isoGrep i journalctl sammenlignet med indbyggede match
Du kan angive et råt grep-mønster efter alle flag, men journalctl understøtter også indbyggede feltmatch med syntaksen FIELD=value. Indbyggede match evalueres mod strukturerede metadata — langt hurtigere end efterbehandling af tekst med grep.
Almindelige nyttige match:
_PID=1234— logposter fra en bestemt proces_COMM=python3— logposter fra enhver proces med navnetpython3SYSLOG_IDENTIFIER=myapp— logposter med en brugerdefineret identifikator
Flere argumenter af typen FIELD=value kombineres med OG; et + mellem dem opretter et ELLER. Brug -g <regex> til fuldtekstsøgning med grep, når strukturerede metadata ikke er tilstrækkelige.
#!/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=catOpbygning af en genbrugelig triagefunktion
Når du har lært de enkelte flag, kan du kombinere dem i en genbrugelig Bash-funktion, som holder dine triagescripts rene og ensartede. En veldesignet funktion bør:
- Acceptere enhed, prioritetsinterval og tidsinterval som parametre
- Bruge sikre værdier med lavt støjniveau som standard, når argumenter udelades
- Returnere en afslutningskode forskellig fra nul, når der findes fejl (integreres med CI-datapipelines)
- Skrive resultater til både stdout og en tidsstemplet logfil til revisionsspor
#!/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"Automatiseret script til hændelsestriage
Det følgende komplette script samler alle begreberne i et praktisk, automatiseret triageværktøj. Det læser en liste over kritiske tjenester, forespørger i journalen for hver af dem over et konfigurerbart tilbageblik, samler resultaterne og afslutter med en fejlkode, hvis der blev fundet fejl — hvilket gør det velegnet som cronjob eller trin i et CI-sundhedstjek.
#!/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}"Videnstjek: Filtrering efter prioritetsinterval
Du skriver et script, der kun skal alarmere vagthavende teknikere, når en tjeneste logger med fejlniveau eller værre (det vil sige fejl, kritisk, alarm eller nødsituation). Hvilken kombination af journalctl-flag medtager præcis dette interval?
Opsummering af lektionen: journalctl i scripts
I denne lektion har du lært, hvordan du programmatisk forespørger i systemd-journalen til automatiseret hændelsestriage:
- Angiv altid
--no-pageri scripts for at forhindre interaktiv blokering. - Filtrering efter enhed (
-u) begrænser forespørgsler til én eller flere tjenester; jokertegn og flere-u-flag understøttes. - Prioritetsfiltrering (
-p emerg..err) medtager kun de fejlniveauer, du har brug for — husk, at lavere tal angiver større alvor. - Tidsintervaller (
--since/--until) begrænser logoutputtet til et deployinterval eller en tilbagebliksperiode ved hjælp af menneskeligt læsbare tidsstempler. - Begrænsning til opstart (
-b -1) gør det muligt for efterbehandlingsscripts at læse logfiler fra en tidligere nedbrudt session. - JSON-output (
-o json) ogjqmuliggør strukturerede datapipelines til alarmerings- eller SIEM-systemer. - Cursorbaseret polling med
--after-cursorforhindrer, at gamle poster behandles igen ved gentagne kørsler. - Indbyggede feltmatch (
_COMM=,SYSLOG_IDENTIFIER=) er hurtigere end at pipe tilgrep.
Hvis du kombinerer disse flag i en genbrugelig Bash-funktion, får du et triageværktøj i produktionskvalitet, som integreres problemfrit med cron, CI-datapipelines og alarmeringsarbejdsgange for vagthavende teknikere.
Lær Intensiv DevOps-uddannelse med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 142
- Lektioner
- 568
Ofte stillede spørgsmål
Er lektionen “Forespørgsler til journald med journalctl i scripts” gratis?
Ja — alle 3 lektioner i læringssporet Intensiv DevOps-uddannelse, inklusive “Forespørgsler til journald med journalctl i scripts”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Intensiv DevOps-uddannelse-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Forespørgsler til journald med journalctl i scripts”?
Filtrér systemd-journalposter efter unit, prioritet og tidspunkt til automatiseret triage af hændelser. Du øver dig i Intensiv DevOps-uddannelse med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på Intensiv DevOps-uddannelse?
Der kræves ingen tidligere erfaring. Intensiv DevOps-uddannelse på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.
Hvor lang tid tager lektionen “Forespørgsler til journald med journalctl i scripts”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne Intensiv DevOps-uddannelse-lektion?
Ja. Alle Intensiv DevOps-uddannelse-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Parsing af web- og applikationslogs i stor skala
- Logovervågning i realtid og streaming-alarmer
- Forespørgsler til journald med journalctl i scripts
- Beregning af metrikker og histogrammer fra logstreams