Puncte:0

Setați prioritatea INFO/EROARE pentru mesajele înregistrate în jurnal prin stdout și stderr?

drapel jp

Avem multe aplicații de producție (prime și terțe) care lasă conectarea la procesul care rulează aplicația și doar se conectează la stdout pentru INFO și stderr pentru EROARE jurnalele (adică doar 2 priorități de jurnal: INFO|EROARE).

Cu o unitate de service systemd pentru o aplicație, aceasta poate fi configurată astfel:

StandardOutput=jurnal
StandardError=jurnal

Acest lucru le permite devopților să gestioneze totul prin unități systemd și jurnal pentru a facilita colectarea centralizată a jurnalelor, monitorizarea... și nu trebuie să-și facă griji cu privire la localizarea și analizarea diferitelor jurnale în diferite formate/locații pentru fiecare aplicație pe care o implementează.

Jurnalul lui systemd are un sistem de prioritate a mesajelor compatibil cu sistemul de prioritate a mesajelor pe 7 niveluri Syslog. INFO este nivel 6 și EROARE este nivel 3. Consultați referințele pentru mai multe detalii.

Problema este... systemd/journal aparent nu face distincție între mesajele scrise în jurnal de la stdout și stderr. Ambele mesaje stdout și stderr sunt toate scrise în jurnal cu prioritate implicită de 6 (INFO).

Exemplu: „Aplicație de lux”

/opt/log-test.sh

#!/bin/bash

echo „Aceasta este EROARE” 1>&2
echo „Aceasta este INFO”

iesirea 0

/etc/systemd/system/log-test.service

[Unitate]
Descriere=test de jurnal pentru jurnal

[Serviciu]
Tip=simplu

ExecStart=/opt/log-test.sh

StandardOutput=jurnal
StandardError=jurnal
SyslogIdentifier=test-log

rulați-l și verificați jurnalul

$ systemctl start log-test
$ journalctl -u log-test
-- Jurnalele încep la joi 2022-04-07 08:17:16 UTC, se termină joi 2022-04-07 16:35:02 UTC. --
Apr 07 16:34:58 host.example.com systemd[1]: A început testul jurnalului pentru jurnal.
Apr 07 16:34:58 host.example.com log-test.sh[29909]: Aceasta este EROARE
Apr 07 16:34:58 host.example.com log-test.sh[29909]: Aceasta este INFO
$ journalctl -u log-test -p 6 # prioritatea informațiilor syslog
-- Jurnalele încep la joi 2022-04-07 08:17:16 UTC, se termină joi 2022-04-07 16:35:08 UTC. --
Apr 07 16:34:58 host.example.com systemd[1]: A început testul jurnalului pentru jurnal.
Apr 07 16:34:58 host.example.com log-test.sh[29909]: Aceasta este EROARE
Apr 07 16:34:58 host.example.com log-test.sh[29909]: Aceasta este INFO
$ journalctl -u log-test -p 3 # prioritatea erorii syslog
-- Fără intrări --
$

Puteți vedea că ambele mesaje stderr și stdout sunt setate la prioritate 6 (INFO) când sunt scrise în jurnal.

Aceasta este o problemă deoarece nu avem o modalitate ușoară de a diferenția ieșirea pe stdout de stderr atunci când folosim stdio->jurnal ca facilitate primară de exploatare forestieră.

Asta a fost discutat mai înainte și solutii sunt posibile, dar neimplementat. Sper că echipa systemd va implementa în cele din urmă acest lucru, dar între timp am nevoie de o soluție.

A găsit cineva o soluție rezonabilă pentru ca mesajele scrise în stdout și stderr să fie priorități diferite în jurnal fără a modifica modul în care o aplicație se înregistrează?

Nu vreau ca toate aplicațiile pe care le implementăm (nu toate scrise de noi) să fie nevoite să implementeze integrări de jurnal sau syslog pentru a obține prioritate de jurnal atunci când într-adevăr avem nevoie doar de două niveluri: INFO (stdout) și EROARE (stderr).

O mare parte din ceea ce implementăm nu este containerizat, deci baza pe facilitățile de înregistrare a containerului nu este nici o soluție pentru noi.

A avea stderr și stdout să meargă la jurnal/syslog cu priorități diferite în mod implicit este destul de critic pentru a face monitorizarea erorilor de jurnal distribuite mai ușoară (presupunând o bună igienă a dezvoltatorului în ceea ce privește scrierea doar a lucrurilor care necesită atenție stderr).

Referinte:

Puncte:1
drapel tz

Dacă trebuie să utilizați stdout/stderr, puteți folosi sd-daemon prefix de înregistrare.

Pregătiți-vă stderr cu <3> a trimite un EROARE prioritate journald Buturuga.

Folosind dvs log-test.sh și log-test.serviciu:

#!/bin/bash

>&2 echo „<3>Aceasta este EROARE”
echo „Aceasta este INFO”

iesirea 0

Și jurnalctl ieșire:

$ journalctl -u log-test -p 3
02 mai 01:22:58 host.example.com log-test.sh[29909]: Aceasta este EROARE

Dacă ale tale fantezie-aplicație are orice API la care să scrie syslog, puteți folosi asta pentru a scrie în datagrama UNIX /dev/log (de obicei, se poate scrie în mod implicit și se conectează la journald) în loc de stdout/stderr. Utilizați eticheta syslog pentru a vă identifica fantezie-aplicație, prioritate syslog la eroare sau info în funcție de nevoile dvs. și de orice facilitate syslog.

De exemplu, în Bash putem folosi logger:

# emite mesaj INFO către journalctl
$ logger -t fancy-app -u /dev/log -p user.info „Aceasta este INFO”

# emite un mesaj de EROARE către journalctl
$ logger -t fancy-app -u /dev/log -p user.error „Aceasta este EROARE”

# afișează mesaje jurnal pentru fancy-app
$ journalctl -t fancy-app
02 mai 01:23:38 host.example.com fancy-app[27302]: Aceasta este INFO
02 mai 01:23:39 host.example.com fancy-app[27303]: Aceasta este EROARE

# afișează mesajele de EROARE din jurnal pentru fancy-app
$ journalctl -t fancy-app -p 3
02 mai 01:23:39 host.example.com fancy-app[27303]: Aceasta este EROARE

Rețineți că în majoritatea distribuțiilor journald intrările sunt transmise de obicei către demonul syslog local (syslog-ng, rsyslog, ...), așa că probabil verificați filtrele Syslog, sau poate utilizați local0...local7 facilităţi.

Avem multe aplicații de producție (prime și terțe) care lasă înregistrarea în container și doar se conectează la stdout pentru INFO și stderr pentru jurnalele de EROARE (adică doar 2 priorități de jurnal: INFO|EROARE).

Majoritatea motorului containerului ar trebui să se poată conecta la syslog. Fără să vă cunosc motorul containerului, voi folosi Docker ca exemplu.

Docker are driver de înregistrare syslog care poate fi folosit pentru a trimite mesaje de jurnal folosind formatul syslog către orice țintă syslog. Ar trebui să vă puteți conecta la journald cu ceva de genul:

docker run \
    --log-driver syslog \
    --log-opt syslog-address=unix:///dev/log \
    --log-opt syslog-facility=utilizator \
    --log-opt tag=fancy-app \
    fancy-app: cele mai recente

Docker are și el driver de logare journald disponibil. De exemplu:

docker run \
    --log-driver journald \
    --log-opt tag=fancy-app \
    fancy-app: cele mai recente

Ambii drivere de logare (syslog și journald) suportă separarea între stdout și stderr; adică stdout mesajele vor fi înregistrate cu INFO prioritate, și stderr mesajele vor fi înregistrate cu EROARE prioritate.

Lăsând deoparte filosofiile și războaiele cu flăcări, de ce să nu te conectezi la Syslog real? Este mai ușor, stocat în format text și, în general, este acceptat de software-urile de gestionare a jurnalelor (vezi Graylog, Logstash, Urma de hartie).

mattpr avatar
drapel jp
Mulțumesc pentru răspuns, voi digera detaliile mai târziu astăzi, după alte cafele. Nu folosim containere pentru multe lucruri, așa că aceasta nu este o soluție instantanee. Unele din restul par utile. Facem agregare centrală a jurnalelor cu ELK sau Graylog (în prezent graylog) și putem folosi/transporta atât syslog, cât și jurnal (prin journalbeat now filebeat) pentru a înregistra clusterul de agregare. Problema este că adesea nu putem controla codul aplicației pe care îl implementăm (de exemplu, aplicația terță parte pentru care nu dorim să menținem un patch de logare) și adesea aplicațiile implicit la stdout/stderr... sau mai rău propriile fișiere de jurnalizare /formate.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.