Linux Professional Institute Learning Logo.
Torna al contenuto principale
  • Home
    • Tutte le Risorse
    • LPI Learning Materials
    • Collabora
    • Publishing Partner
    • Diventa un Publishing Partner
    • FAQ
    • Collaboratori
    • Contatto
  • LPI.org
108.2 Lezione 2
Argomento 105: Shell e Script di Shell
105.1 Personalizzare e utilizzare l'ambiente di shell
  • 105.1 Lezione 1
  • 105.1 Lezione 2
  • 105.1 Lezione 3
105.2 Personalizzare o scrivere semplici script
  • 105.2 Lezione 1
  • 105.2 Lezione 2
Argomento 106: Interfacce Utente e Desktop
106.1 Installare e configurare X11
  • 106.1 Lezione 1
106.2 Desktop grafici
  • 106.2 Lezione 1
106.3 Accessibilità
  • 106.3 Lezione 1
Argomento 107: Attività Amministrative
107.1 Gestire account utente e gruppo e file di sistema correlati
  • 107.1 Lezione 1
  • 107.1 Lezione 2
107.2 Automatizzare le attività di amministrazione del sistema attraverso la pianificazione
  • 107.2 Lezione 1
  • 107.2 Lezione 2
107.3 Localizzazione e internazionalizzazione
  • 107.3 Lezione 1
Argomento 108: Servizi Essenziali di Sistema
108.1 Mantenere l'orario di sistema
  • 108.1 Lezione 1
  • 108.1 Lezione 2
108.2 Logging di sistema
  • 108.2 Lezione 1
  • 108.2 Lezione 2
108.3 Concetti base dei Mail Transfer Agent (MTA)
  • 108.3 Lezione 1
108.4 Gestire stampa e stampanti
  • 108.4 Lezione 1
Argomento 109: Fondamenti di Networking
109.1 Fondamenti dei protocolli Internet
  • 109.1 Lezione 1
  • 109.1 Lezione 2
109.2 Configurazione di rete persistente
  • 109.2 Lezione 1
  • 109.2 Lezione 2
109.3 Risoluzione dei problemi di base di una rete
  • 109.3 Lezione 1
  • 109.3 Lezione 2
109.4 Configurare un client DNS
  • 109.4 Lezione 1
Argomento 110: Sicurezza
110.1 Eseguire attività di amministrazione della sicurezza
  • 110.1 Lezione 1
110.2 Configurare la sicurezza dell'host
  • 110.2 Lezione 1
110.3 Proteggere i dati con la crittografia
  • 110.3 Lezione 1
  • 110.3 Lezione 2
How to get certified
  1. Argomento 108: Servizi Essenziali di Sistema
  2. 108.2 Logging di sistema
  3. 108.2 Lezione 2

108.2 Lezione 2

Certificazione:

LPIC-1

Versione:

5.0

Argomento:

108 Servizi Essenziali di Sistema

Obiettivo:

108.2 Logging di sistema

Lezione:

2 di 2

Introduzione

Con l’adozione generale di systemd da parte di tutte le principali distribuzioni, il demone journal (systemd-journald) è diventato il servizio di log standard. In questa lezione discuteremo come funziona e come puoi usarlo per fare un certo numero di cose: interrogarlo, filtrare le sue informazioni con diversi criteri, configurare la sua memorizzazione e la sua dimensione, cancellare i vecchi dati, recuperare i suoi dati da un sistema di salvataggio o da una copia del filesystem e — ultimo ma non meno importante — capire la sua interazione con rsyslogd.

Fondamenti di systemd

Introdotto per la prima volta in Fedora, systemd ha progressivamente sostituito SysV Init come system e service manager nella maggior parte delle principali distribuzioni Linux. Tra i suoi punti di forza:

  • Facilità di configurazione: unit file rispetto agli script SysV Init.

  • Gestione versatile: oltre a demoni e processi, gestisce anche dispositivi, socket e punti di montaggio.

  • Retrocompatibilità con SysV Init e Upstart.

  • Caricamento parallelo durante l’avvio (al contrario che in Sysv Init che li carica in modo sequenziale).

  • Presenta un servizio di logging chiamato journal che presenta i seguenti vantaggi:

    • Centralizza tutti i log in un unico posto.

    • Non richiede la rotazione dei log.

    • I log possono essere disabilitati, caricati in RAM o resi persistenti.

Unit e Target

systemd opera su unit. Una unità è una qualsiasi risorsa che systemd può gestire (per esempio, rete, bluetooth, ecc.). Le unità, a loro volta, sono governate da unit file. Questi sono file di testo semplice che risiedono in /lib/systemd/system e includono le impostazioni di configurazione — sotto forma di sezioni e direttive — per una particolare risorsa da gestire. Ci sono diversi tipi di unità: service, mount, automount, swap, timer, device, socket, path, timer, snapshot, slice, scope e target. Così, ogni nome di file di unità segue lo schema <nome_risorsa>.<tipo_unità> (per esempio, reboot.service).

Un target è un tipo speciale di unità che assomiglia ai classici runlevel di SysV Init. Questo perché un target unit riunisce varie risorse per rappresentare un particolare stato del sistema (per esempio, graphical.target è simile a runlevel 5, ecc.) Per controllare il target corrente nel tuo sistema, usa il comando systemctl get-default:

carol@debian:~$ systemctl get-default
graphical.target

D’altra parte, i target e i runlevel differiscono in quanto i primi sono reciprocamente inclusivi, mentre i secondi no. Così un target può portarne con se altri, cosa che non è possibile con i runlevel.

Note

Una spiegazione di come funzionano le unità systemd va oltre lo scopo di questa lezione.

Il Sistema Journal: systemd-journald

systemd-journald è il servizio di sistema che si occupa di ricevere informazioni di log da una varietà di fonti: messaggi del kernel, messaggi di sistema semplici e strutturati, standard output e standard error dei servizi, nonché record di audit dal sottosistema di audit del kernel (per ulteriori dettagli vedere la pagina di manuale per systemd-journald). La sua missione è quella di creare e mantenere un diario strutturato e indicizzato.

Il suo file di configurazione è /etc/systemd/journald.conf e — come per qualsiasi altro servizio — si può usare il comando systemctl per avviarlo, riavviarlo, fermarlo o — semplicemente — controllare il suo stato:

root@debian:~# systemctl status systemd-journald
 systemd-journald.service - Journal Service
   Loaded: loaded (/lib/systemd/system/systemd-journald.service; static; vendor preset: enabled)
   Active: active (running) since Sat 2019-10-12 13:43:06 CEST; 5min ago
     Docs: man:systemd-journald.service(8)
           man:journald.conf(5)
 Main PID: 178 (systemd-journal)
   Status: "Processing requests..."
    Tasks: 1 (limit: 4915)
   CGroup: /system.slice/systemd-journald.service
           └─178 /lib/systemd/systemd-journald
(...)

Sono anche possibili file di configurazione del tipo journal.conf.d/*.conf — che possono includere configurazioni specifiche del servizio — (consultare la pagina di manuale di journald.conf per saperne di più).

Se abilitato, il journal può essere memorizzato in modo persistente su disco o in modo volatile su un filesystem basato sulla RAM. Il journal non è un file di testo semplice, è binario. Quindi non si possono usare strumenti di analisi del testo come less o more per leggere il suo contenuto; si usa invece il comando journalctl.

Interrogare il Contenuto del Journal

journalctl è l’utilità che si usa per interrogare il journal di systemd. Devi essere root o usare sudo per invocarlo. Se interrogato senza opzioni, mostrerà l’intero journal in ordine cronologico (con le voci più vecchie elencate per prime):

root@debian:~# journalctl
-- Logs begin at Sat 2019-10-12 13:43:06 CEST, end at Sat 2019-10-12 14:19:46 CEST. --
Oct 12 13:43:06 debian kernel: Linux version 4.9.0-9-amd64 (debian-kernel@lists.debian.org) (...)
Oct 12 13:43:06 debian kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-9-amd64 root=UUID=b6be6117-5226-4a8a-bade-2db35ccf4cf4 ro qu
(...)

Si possono fare ricerche più specifiche usando un certo numero di opzioni:

-r

I messaggi del journal saranno mostrati in ordine inverso:

root@debian:~# journalctl -r
-- Logs begin at Sat 2019-10-12 13:43:06 CEST, end at Sat 2019-10-12 14:30:30 CEST. --
Oct 12 14:30:30 debian sudo[1356]: pam_unix(sudo:session): session opened for user root by carol(uid=0)
Oct 12 14:30:30 debian sudo[1356]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/journalctl -r
Oct 12 14:19:53 debian sudo[1348]: pam_unix(sudo:session): session closed for user root
(...)
-f

Mostrerà i messaggi del journal più recenti e continuerà a farlo con le nuove voci che man mano verranno aggiunte — in modo simile a tail -f:

root@debian:~# journalctl -f
-- Logs begin at Sat 2019-10-12 13:43:06 CEST. --
(...)
Oct 12 14:44:42 debian sudo[1356]: pam_unix(sudo:session): session closed for user root
Oct 12 14:44:44 debian sudo[1375]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/journalctl -f
Oct 12 14:44:44 debian sudo[1375]: pam_unix(sudo:session): session opened for user root by carol(uid=0)

(...)
-e

Salterà alla fine del journal in modo che le ultime voci siano visibili all’interno della visualizzazione:

root@debian:~# journalctl -e
(...)
Oct 12 14:44:44 debian sudo[1375]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/journalctl -f
Oct 12 14:44:44 debian sudo[1375]: pam_unix(sudo:session): session opened for user root by carol(uid=0)
Oct 12 14:45:57 debian sudo[1375]: pam_unix(sudo:session): session closed for user root
Oct 12 14:48:39 debian sudo[1378]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/journalctl -e
Oct 12 14:48:39 debian sudo[1378]: pam_unix(sudo:session): session opened for user root by carol(uid=0)
-n <value>, --lines=<value>

Mostrerà le n linee più recenti (se non viene specificato <value>, il valore predefinito è 10):

root@debian:~# journalctl -n 5
(...)
Oct 12 14:44:44 debian sudo[1375]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/journalctl -f
Oct 12 14:44:44 debian sudo[1375]: pam_unix(sudo:session): session opened for user root by carol(uid=0)
Oct 12 14:45:57 debian sudo[1375]: pam_unix(sudo:session): session closed for user root
Oct 12 14:48:39 debian sudo[1378]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/journalctl -e
Oct 12 14:48:39 debian sudo[1378]: pam_unix(sudo:session): session opened for user root by carol(uid=0)
-k, --dmesg

Equivalente all’uso del comando dmesg:

root@debian:~# journalctl -k
-- Logs begin at Sat 2019-10-12 13:43:06 CEST, end at Sat 2019-10-12 14:53:20 CEST. --
Oct 12 13:43:06 debian kernel: Linux version 4.9.0-9-amd64 (debian-kernel@lists.debian.org) (gcc version 6.3.0 20170516 (Debian 6.3.0-18
Oct 12 13:43:06 debian kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-9-amd64 root=UUID=b6be6117-5226-4a8a-bade-2db35ccf4cf4 ro qu
Oct 12 13:43:06 debian kernel: x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
Oct 12 13:43:06 debian kernel: x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
(...)
Muoversi e Cercare all’Interno del Journal

Si può navigare nell’outuput del journal con:

  • PageUp, PageDown e i tasti freccia per muoversi in alto, in basso, a sinistra e a destra.

  • > per andare alla fine dell’output.

  • < per andare all’inizio dell’output.

È possibile cercare stringhe sia in avanti che indietro rispetto alla posizione di visualizzazione corrente:

  • Ricerca in avanti: Premere / e inserire la stringa da cercare, poi premere Enter.

  • Ricerca a ritroso: Premere ? e inserire la stringa da cercare, poi premere Enter.

Per navigare tra le corrispondenze nelle ricerche, usa N per andare alla prossima occorrenza della corrispondenza e Shift+N per andare alla precedente.

Filtrare i Dati del Journal

Il journal permette di filtrare i dati di log secondo diversi criteri:

Boot number
--list-boots

Elenca tutti i boot disponibili. L’output consiste di tre colonne; la prima specifica il numero di avvio (0 si riferisce all’avvio corrente, -1 è quello precedente, -2 quello prima del precedente e così via); la seconda colonna è l’ID dell’avvio; la terza mostra gli indicatori di tempo:

root@debian:~# journalctl --list-boots
 0 83df3e8653474ea5aed19b41cdb45b78 Sat 2019-10-12 18:55:41 CEST—Sat 2019-10-12 19:02:24 CEST
-b, --boot

Mostra tutti i messaggi dell’avvio corrente. Per vedere i messaggi di log dei boot precedenti, basta aggiungere un parametro di offset come spiegato sopra. Per esempio, per avere i messaggi dell’avvio precedente stampati, digiterai journalctl -b -1. Ricorda, però, che per recuperare informazioni dai log precedenti, la persistenza del journal deve essere abilitata (imparerai come farlo nella prossima sezione):

root@debian:~# journalctl -b -1
Specifying boot ID has no effect, no persistent journal was found
Priority
-p

È interessante notare che si può anche filtrare per gravità/priorità con l’opzione -p:

root@debian:~# journalctl -b -0 -p err
-- No entries --

Il journal ci informa che — finora — non ci sono stati messaggi con una priorità di errore (o superiore) dall’avvio corrente. Nota: -b -0 può essere omesso quando ci si riferisce all’avvio corrente.

Note

Far riferimento alla lezione precedente per una lista completa di tutte le severità (o priorità) del syslog.

Time Interval

Puoi fare in modo che journalctl stampi solo i messaggi registrati in uno specifico lasso di tempo usando gli interruttori --since e --until. La specifica della data dovrebbe seguire il formato YYYY-MM-DD HH:MM:SS. La mezzanotte sarà assunta se si omette la componente temporale. Allo stesso modo, se la data viene omessa, si assume il giorno corrente. Per esempio, per vedere i messaggi registrati dalle 19:00 alle 19:01, si digiterà:

root@debian:~# journalctl --since "19:00:00" --until "19:01:00"
-- Logs begin at Sat 2019-10-12 18:55:41 CEST, end at Sat 2019-10-12 20:10:50 CEST. --
Oct 12 19:00:14 debian systemd[1]: Started Run anacron jobs.
Oct 12 19:00:14 debian anacron[1057]: Anacron 2.3 started on 2019-10-12
Oct 12 19:00:14 debian anacron[1057]: Normal exit (0 jobs run)
Oct 12 19:00:14 debian systemd[1]: anacron.timer: Adding 2min 47.988096s random time.

Allo stesso modo puoi usare una specifica temporale leggermente diversa: "integer time-unit ago". Così, per vedere i messaggi registrati due minuti fa si digiterà sudo journalctl --since "2 minutes ago". È anche possibile usare + e - per specificare tempi relativi al tempo corrente, quindi --since "-2 minutes" e --since "-2 minutes ago" sono equivalenti.

Oltre alle espressioni numeriche, puoi specificare un certo numero di parole chiave:

yesterday

A partire dalla mezzanotte del giorno precedente il giorno corrente.

today

A partire dalla mezzanotte del giorno corrente.

tomorrow

A partire dalla mezzanotte del giorno dopo il giorno corrente.

now

L’ora corrente.

Vediamo tutti i messaggi dalla mezzanotte scorsa fino alle 21:00 di oggi:

root@debian:~# journalctl --since "today" --until "21:00:00"
-- Logs begin at Sat 2019-10-12 20:45:29 CEST, end at Sat 2019-10-12 21:06:15 CEST. --
Oct 12 20:45:29 debian sudo[1416]:    carol : TTY=pts/0 ; PWD=/home/carol ; USER=root ; COMMAND=/bin/systemctl r
Oct 12 20:45:29 debian sudo[1416]: pam_unix(sudo:session): session opened for user root by carol(uid=0)
Oct 12 20:45:29 debian systemd[1]: Stopped Flush Journal to Persistent Storage.
(...)
Note

Per saperne di più sulle diverse sintassi per le specifiche di tempo, consultare la pagina di manuale systemd.time.

Program

Per vedere i messaggi del journal relativi a uno specifico eseguibile si usa la seguente sintassi: journalctl /path/to/executable:

root@debian:~# journalctl /usr/sbin/sshd
-- Logs begin at Sat 2019-10-12 20:45:29 CEST, end at Sat 2019-10-12 21:54:49 CEST. --
Oct 12 21:16:28 debian sshd[1569]: Accepted password for carol from 192.168.1.65 port 34050 ssh2
Oct 12 21:16:28 debian sshd[1569]: pam_unix(sshd:session): session opened for user carol by (uid=0)
Oct 12 21:16:54 debian sshd[1590]: Accepted password for carol from 192.168.1.65 port 34052 ssh2
Oct 12 21:16:54 debian sshd[1590]: pam_unix(sshd:session): session opened for user carol by (uid=0)
Unit

Ricorda: una unit è qualsiasi risorsa gestita da systemd; è possibile filtrare anche per unit.

-u

Mostra i messaggi di un’unità specifica:

root@debian:~# journalctl -u ssh.service
-- Logs begin at Sun 2019-10-13 10:50:59 CEST, end at Sun 2019-10-13 12:22:59 CEST. --
Oct 13 10:51:00 debian systemd[1]: Starting OpenBSD Secure Shell server...
Oct 13 10:51:00 debian sshd[409]: Server listening on 0.0.0.0 port 22.
Oct 13 10:51:00 debian sshd[409]: Server listening on :: port 22.
(...)
Note

Per stampare tutte le unità caricate e attive, usa systemctl list-units; per vedere tutti i file delle unità installate usa systemctl list-unit-files.

Fields

Il journal può anche essere filtrato da specifici campi attraverso una delle seguenti sintassi:

  • <field-name>=<value>

  • _<field-name>=<value>_

  • __<field-name>=<value>

    PRIORITY=

    Uno degli otto possibili valori di priorità syslog formattati come una stringa decimale:

    root@debian:~# journalctl PRIORITY=3
    -- Logs begin at Sun 2019-10-13 10:50:59 CEST, end at Sun 2019-10-13 14:30:50 CEST. --
    Oct 13 10:51:00 debian avahi-daemon[314]: chroot.c: open() failed: No such file or directory

    Nota come avresti potuto ottenere lo stesso risultato usando il comando sudo journalctl -p err che abbiamo visto precedentemente.

    SYSLOG_FACILITY=

    Uno qualsiasi dei possibili numeri di codice della facility formattato come una stringa decimale. Per esempio, per vedere tutti i messaggi a livello utente:

    root@debian:~# journalctl SYSLOG_FACILITY=1
    -- Logs begin at Sun 2019-10-13 10:50:59 CEST, end at Sun 2019-10-13 14:42:52 CEST. --
    Oct 13 10:50:59 debian mtp-probe[227]: checking bus 1, device 2: "/sys/devices/pci0000:00/0000:00:06.0/usb1/1-1"
    Oct 13 10:50:59 debian mtp-probe[227]: bus: 1, device: 2 was not an MTP device
    Oct 13 10:50:59 debian mtp-probe[238]: checking bus 1, device 2: "/sys/devices/pci0000:00/0000:00:06.0/usb1/1-1"
    Oct 13 10:50:59 debian mtp-probe[238]: bus: 1, device: 2 was not an MTP device
    _PID=

    Mostra i messaggi prodotti da uno specifico ID di processo. Per vedere tutti i messaggi prodotti da systemd, si dovrebbe digitare:

    root@debian:~# journalctl _PID=1
    -- Logs begin at Sun 2019-10-13 10:50:59 CEST, end at Sun 2019-10-13 14:50:15 CEST. --
    Oct 13 10:50:59 debian systemd[1]: Mounted Debug File System.
    Oct 13 10:50:59 debian systemd[1]: Mounted POSIX Message Queue File System.
    Oct 13 10:50:59 debian systemd[1]: Mounted Huge Pages File System.
    Oct 13 10:50:59 debian systemd[1]: Started Remount Root and Kernel File Systems.
    Oct 13 10:50:59 debian systemd[1]: Starting Flush Journal to Persistent Storage...
    (...)
    _BOOT_ID

    In base al suo ID di avvio si possono individuare i messaggi da un avvio specifico, per esempio: sudo journalctl _BOOT_ID=83df3e8653474ea5aed19b41cdb45b78.

    _TRANSPORT

    Mostra i messaggi ricevuti da un trasporto specifico. I valori possibili sono: audit (sottosistema di audit del kernel), driver (generato internamente), syslog (socket syslog), journal (protocollo journal nativo), stdout (output standard dei servizi o errore standard), kernel (ring buffer del kernel — lo stesso di dmesg, journalctl -k o journalctl --dmesg):

    root@debian:~# journalctl _TRANSPORT=journal
    -- Logs begin at Sun 2019-10-13 20:19:58 CEST, end at Sun 2019-10-13 20:46:36 CEST. --
    Oct 13 20:19:58 debian systemd[1]: Started Create list of required static device nodes for the current kernel.
    Oct 13 20:19:58 debian systemd[1]: Starting Create Static Device Nodes in /dev...
    Oct 13 20:19:58 debian systemd[1]: Started Create Static Device Nodes in /dev.
    Oct 13 20:19:58 debian systemd[1]: Starting udev Kernel Device Manager...
    (...)
Combinare Campi

I campi non si escludono a vicenda, quindi puoi usarne più di uno nella stessa query. Tuttavia, saranno mostrati solo i messaggi che corrispondono al valore di entrambi i campi contemporaneamente:

root@debian:~# journalctl PRIORITY=3 SYSLOG_FACILITY=0
-- No entries --
root@debian:~# journalctl PRIORITY=4 SYSLOG_FACILITY=0
-- Logs begin at Sun 2019-10-13 20:19:58 CEST, end at Sun 2019-10-13 20:21:55 CEST. --
Oct 13 20:19:58 debian kernel: acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended PCI configuration (...)

A meno che tu non usi il separatore + per combinare due espressioni alla maniera di un OR logico:

root@debian:~# journalctl PRIORITY=3 + SYSLOG_FACILITY=0
-- Logs begin at Sun 2019-10-13 20:19:58 CEST, end at Sun 2019-10-13 20:24:02 CEST. --
Oct 13 20:19:58 debian kernel: Linux version 4.9.0-9-amd64 (debian-kernel@lists.debian.org) (...9
Oct 13 20:19:58 debian kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-4.9.0-9-amd64 root=UUID= (...)
(...)

D’altra parte, puoi fornire due valori per lo stesso campo e tutte le voci che corrispondono a uno dei due valori vengano mostrate:

root@debian:~# journalctl PRIORITY=1
-- Logs begin at Sun 2019-10-13 17:16:24 CEST, end at Sun 2019-10-13 17:30:14 CEST. --
-- No entries --
root@debian:~# journalctl PRIORITY=1 PRIORITY=3
-- Logs begin at Sun 2019-10-13 17:16:24 CEST, end at Sun 2019-10-13 17:32:12 CEST. --
Oct 13 17:16:27 debian connmand[459]: __connman_inet_get_pnp_nameservers: Cannot read /pro
Oct 13 17:16:27 debian connmand[459]: The name net.connman.vpn was not provided by any .se
Note

I campi Journal rientrano in una delle seguenti categorie: “Campi journal dell’utente”, “Campi journal di fiducia”, “Campi journal del kernel”, “Campi per conto di un programma diverso” e “Campi indirizzo”. Per maggiori informazioni su questo argomento — inclusa una lista completa dei campi — si veda la pagina man per systemd.journal-fields(7).

Voci Manuali nel System Journal: systemd-cat

Proprio come il comando logger è usato per inviare messaggi dalla linea di comando al log di sistema (come abbiamo visto nella lezione precedente), il comando systemd-cat ha uno scopo simile, ma più completo, con il journal di sistema. Ci permette di inviare input standard (stdin), output (stdout) ed errori (stderr) al diario.

Se invocato senza parametri, invierà tutto ciò che legge da stdin al journal. Una volta finito, premi Ctrl+C:.

carol@debian:~$ systemd-cat
This line goes into the journal.
^C

Se gli viene passato l’output di un comando, anche questo sarà inviato al diario:

carol@debian:~$ echo "And so does this line." | systemd-cat

Se seguito da un comando, anche l’output di quel comando sarà inviato al journal — insieme a stderr (se presente):

carol@debian:~$ systemd-cat echo "And so does this line too."

C’è anche la possibilità di specificare un livello di priorità con l’opzione -p:

carol@debian:~$ systemd-cat -p emerg echo "This is not a real emergency."

Fate riferimento alla pagina man di systemd-cat per conoscere le altre opzioni.

Per vedere le ultime quattro righe del journal:

carol@debian:~$ journalctl -n 4
(...)
-- Logs begin at Sun 2019-10-20 13:43:54 CEST. --
Nov 13 23:14:39 debian cat[1997]: This line goes into the journal.
Nov 13 23:19:16 debian cat[2027]: And so does this line.
Nov 13 23:23:21 debian echo[2030]: And so does this line too.
Nov 13 23:26:48 debian echo[2034]: This is not a real emergency.
Note

Le voci del journal con un livello di priorità di emergency saranno mostrate in grassetto rosso sulla maggior parte dei sistemi.

Salvataggio Persistente del Journal

Come detto in precedenza, si hanno tre opzioni quando si tratta della posizione del journal:

  • Il journaling può essere disattivato del tutto (il reindirizzamento ad altre strutture come la console è però ancora possibile).

  • Mantenerlo in memoria — il che lo rende volatile — e sbarazzarsi dei log ad ogni riavvio del sistema. In questo scenario, la directory /run/log/journal sarà creata e utilizzata.

  • Renderlo persistente in modo che scriva i log su disco. In questo caso, i messaggi di log andranno nella directory /var/log/journal.

Il comportamento predefinito è il seguente: se /var/log/journal/ non esiste, i log saranno salvati in modo volatile in una directory in /run/log/journal/ e — quindi — persi al riavvio. Il nome della directory — il /etc/machine-id — è una stringa esadecimale di 32 caratteri minuscoli terminata da una linea nuova:

carol@debian:~$ ls /run/log/journal/8821e1fdf176445697223244d1dfbd73/
system.journal

Se provi a leggerlo con less riceverai un avvertimento, quindi usa invece il comando journalctl:

root@debian:~# less /run/log/journal/9a32ba45ce44423a97d6397918de1fa5/system.journal
"/run/log/journal/9a32ba45ce44423a97d6397918de1fa5/system.journal" may be a binary file.  See it anyway?
root@debian:~# journalctl
-- Logs begin at Sat 2019-10-05 21:26:38 CEST, end at Sat 2019-10-05 21:31:27 CEST. --
(...)
Oct 05 21:26:44 debian systemd-journald[1712]: Runtime journal (/run/log/journal/9a32ba45ce44423a97d6397918de1fa5) is 4.9M, max 39.5M, 34.6M free.
Oct 05 21:26:44 debian systemd[1]: Started Journal Service.
(...)

Se /var/log/journal/ esiste, i log vi saranno memorizzati in modo persistente. Se questa directory venisse cancellata, systemd-journald non la ricreerebbe ma scriverebbe invece su /run/log/journal. Non appena creeremo nuovamente /var/log/journal/ e riavvieremo il demone, la registrazione persistente sarà ristabilita:

root@debian:~# mkdir /var/log/journal/
root@debian:~# systemctl restart systemd-journald
root@debian:~# journalctl
(...)
Oct 05 21:33:49 debian systemd-journald[1712]: Received SIGTERM from PID 1 (systemd).
Oct 05 21:33:49 debian systemd[1]: Stopped Journal Service.
Oct 05 21:33:49 debian systemd[1]: Starting Journal Service...
Oct 05 21:33:49 debian systemd-journald[1768]: Journal started
Oct 05 21:33:49 debian systemd-journald[1768]: System journal (/var/log/journal/9a32ba45ce44423a97d6397918de1fa5) is 8.0M, max 1.1G, 1.1G free.
Oct 05 21:33:49 debian systemd[1]: Started Journal Service.
Oct 05 21:33:49 debian systemd[1]: Starting Flush Journal to Persistent Storage...
(...)
Note

Per impostazione predefinita, ci saranno file di journal specifici per ogni utente loggato, situati in /var/log/journal/, quindi — insieme ai file system.journal — troverai anche file del tipo user-1000.journal.

Oltre a ciò che abbiamo appena menzionato, il modo in cui il demone journal si occupa della memorizzazione dei log può essere cambiato dopo l’installazione modificando il suo file di configurazione: /etc/systemd/journald.conf. L’opzione chiave è Storage= e può avere i seguenti valori:

Storage=volatile

I dati di log saranno memorizzati esclusivamente in memoria — sotto /run/log/journal/. Se non è presente, la directory verrà creata.

Storage=persistent

Per default i dati di log saranno memorizzati su disco — sotto /var/log/journal/ — con un fallback alla memoria (/run/log/journal/) durante le prime fasi di avvio e se il disco non è scrivibile. Entrambe le directory saranno create se necessario.

Storage=auto

auto è simile a persistent, ma la directory /var/log/journal non viene creata se necessario. Questo è il default.

Storage=none

Tutti i dati di log saranno scartati. L’inoltro ad altre destinazioni come la console, il buffer di log del kernel o un socket syslog sono comunque possibili.

Per esempio, per far sì che systemd-journald crei /var/log/journal/ e passi alla memorizzazione persistente, si dovrebbe modificare /etc/systemd/journald.conf e impostare Storage=persistent, salvare il file e riavviare il demone con sudo systemctl restart systemd-journald. Per assicurarti che il riavvio sia avvenuto senza problemi, puoi sempre controllare lo stato del demone:

root@debian:~# systemctl status systemd-journald
 systemd-journald.service - Journal Service
   Loaded: loaded (/lib/systemd/system/systemd-journald.service; static; vendor preset: enabled)
   Active: active (running) since Wed 2019-10-09 10:03:40 CEST; 2s ago
     Docs: man:systemd-journald.service(8)
           man:journald.conf(5)
 Main PID: 1872 (systemd-journal)
   Status: "Processing requests..."
    Tasks: 1 (limit: 3558)
   Memory: 1.1M
   CGroup: /system.slice/systemd-journald.service
           └─1872 /lib/systemd/systemd-journald

Oct 09 10:03:40 debian10 systemd-journald[1872]: Journal started
Oct 09 10:03:40 debian10 systemd-journald[1872]: System journal (/var/log/journal/9a32ba45ce44423a97d6397918de1fa5) is 8.0M, max 1.2G, 1.2G free.
Note

I file del diario in /var/log/journal/<machine-id>/ o /run/log/journal/<machine-id>/ hanno il suffisso .journal (es. system.journal). Tuttavia, se vengono trovati corrotti o se il demone viene fermato in modo poco pulito, saranno rinominati con l’aggiunta di ~ (per esempio, system.journal~) e il demone inizierà a scrivere su un nuovo file pulito.

Cancellare i Dati del Vecchio Journal: Dimensione del Journal

I log sono salvati in journal file i cui nomi finiscono con .journal o .journal~ e si trovano nella directory appropriata (/run/log/journal o /var/log/journal come configurato). Per controllare quanto spazio su disco è attualmente occupato dai file di journal (sia archiviati sia attivi), usa lo switch --disk-usage:

root@debian:~# journalctl --disk-usage
Archived and active journals take up 24.0M in the filesystem.

I log di systemd hanno di default un massimo del 10% della dimensione del filesystem in cui sono memorizzati. Per esempio su un filesystem da 1GB non occuperanno più di 100MB. Una volta raggiunto questo limite, i vecchi log inizieranno a scomparire così che si rimanga vicini a questo valore.

Tuttavia, l’applicazione dei limiti di dimensione sui file di journal memorizzati può essere gestita modificando una serie di opzioni di configurazione in /etc/systemd/journald.conf. Queste opzioni rientrano in due categorie a seconda del tipo di filesystem usato: persistente (/var/log/journal) o in-memoria (/run/log/journal). Il primo usa opzioni che sono precedute dalla parola System e si applicano solo se il logging persistente è correttamente abilitato e una volta che il sistema è completamente avviato. I nomi delle opzioni nel secondo iniziano con la parola Runtime e si applicano nei seguenti scenari:

SystemMaxUse=, RuntimeMaxUse=

Controllano la quantità di spazio su disco che può essere occupata dal journal. Il valore predefinito è il 10% della dimensione del filesystem, ma può essere modificato (per esempio, SystemMaxUse=500M) purché non superi un massimo di 4GiB.

SystemKeepFree=, RuntimeKeepFree=

Controllano la quantità di spazio su disco che dovrebbe essere lasciato libero per altri utenti. Il valore predefinito è il 15% della dimensione del filesystem, ma può essere modificato (per esempio, SystemKeepFree=500M) finché non supera un massimo di 4GiB.

Per quanto riguarda la precedenza di *MaxUse e *KeepFree, systemd-journald li soddisferà entrambi usando il più piccolo dei due valori. Allo stesso modo, si tenga presente che solo i file di journal archiviati (al contrario di quelli attivi) vengono cancellati.

SystemMaxFileSize=, RuntimeMaxFileSize=

Controllano la dimensione massima a cui possono crescere i singoli file del diario. Il valore predefinito è 1/8 di *MaxUse. La riduzione della dimensione viene effettuata in modo sincrono e i valori possono essere specificati in byte o usando K, M, G, T, P, E per Kibibyte, Mebibyte, Gibibyte, Tebibyte, Pebibyte e Exbibyte, rispettivamente.

SystemMaxFiles=, RuntimeMaxFiles=

Stabiliscono il numero massimo di file di journal individuali e archiviati da memorizzare (i file di journal attivi non sono interessati). Il valore predefinito è 100.

Oltre alla cancellazione basata sulle dimensioni e alla rotazione dei messaggi di log, systemd-journald permette anche criteri basati sul tempo utilizzando le seguenti due opzioni: MaxRetentionSec= e MaxFileSec=. Fai riferimento alla pagina di manuale di journald.conf per maggiori informazioni su queste e altre opzioni.

Note

Ogni volta che si modifica il comportamento predefinito di systemd-journald decommentando e modificando le opzioni in /etc/systemd/journald.conf, è necessario riavviare il demone perché le modifiche abbiano effetto.

Pulire il Journal

Puoi pulire manualmente i file di journal archiviati in qualsiasi momento con una delle seguenti tre opzioni:

--vacuum-time=

Questa opzione basata sul tempo eliminerà tutti i messaggi nei file di journal con un timestamp più vecchio dell’intervallo di tempo specificato. I valori devono essere scritti con uno dei seguenti suffissi: s, m, h, days (o d), months, weeks (o w) e years (o y). Per esempio, per sbarazzarsi di tutti i messaggi nei file di journal archiviati che sono più vecchi di 1 mese:

root@debian:~# journalctl --vacuum-time=1months
Deleted archived journal /var/log/journal/7203088f20394d9c8b252b64a0171e08/system@27dd08376f71405a91794e632ede97ed-0000000000000001-00059475764d46d6.journal (16.0M).
Deleted archived journal /var/log/journal/7203088f20394d9c8b252b64a0171e08/user-1000@e7020d80d3af42f0bc31592b39647e9c-000000000000008e-00059479df9677c8.journal (8.0M).
--vacuum-size=

Questa opzione basata sulla dimensione cancellerà i file di journal archiviati fino a quando non occuperanno un valore inferiore alla dimensione specificata. I valori devono essere scritti con uno dei seguenti suffissi: K, M, G o T. Per esempio, per eliminare i file di journal archiviati finché non sono al di sotto di 100 Mebibytes:

root@debian:~# journalctl --vacuum-size=100M
Vacuuming done, freed 0B of archived journals from /run/log/journal/9a32ba45ce44423a97d6397918de1fa5.
--vacuum-files=

Questa opzione farà in modo che non rimangano più file di journal archiviati del numero specificato. Il valore è un numero intero. Per esempio, per limitare il numero di file archiviati a 10:

root@debian:~# journalctl --vacuum-files=10
Vacuuming done, freed 0B of archived journals from /run/log/journal/9a32ba45ce44423a97d6397918de1fa5.

La cancellazione rimuove solo i file di journal archiviati. Se vuoi sbarazzarti di tutto (inclusi i file attivi), devi usare un segnale (SIGUSR2) che inneschi la rotazione immediata dei file di journal con l’opzione --rotate. Altri segnali importanti possono essere invocati con le seguenti opzioni:

--flush (SIGUSR1)

Richiede lo svuotamento dei file del journal da /run/ a /var/ per rendere il journal persistente. Richiede che il logging persistente sia abilitato e che /var/ sia montato.

--sync (SIGRTMIN+1)

Si usa per richiedere che tutti i dati di registro non ancora scritti siano scritti su disco.

Note

Per controllare la coerenza interna del file di journal, usa journalctl con l’opzione --verify. Vedrai una barra di progresso man mano che il controllo viene fatto e ogni possibile problema verrà mostrato.

Recuperare i Dati del Journal da un Rescue System

Come amministratore di sistema, potresti trovarti in una situazione in cui hai bisogno di accedere ai file del journal sul disco rigido di una macchina difettosa attraverso un rescue system (un CD avviabile o una chiave USB contenente una distribuzione Linux live).

journalctl cerca i file del journal in /var/log/journal/<machine-id>/. Poiché gli ID delle macchine sul sistema rescue e su quello guasto saranno diversi, devi usare la seguente opzione:

-D </path/to/dir>, --directory=</path/to/dir>

Con questa opzione si specifica un percorso di directory in cui journalctl cercherà i file del journal invece delle posizioni predefinite di runtime e di sistema.

Quindi, è necessario montare il rootfs del sistema difettoso (/dev/sda1) sul filesystem del sistema di salvataggio e procedere alla lettura dei file del diario in questo modo:

root@debian:~# journalctl -D /media/carol/faulty.system/var/log/journal/
-- Logs begin at Sun 2019-10-20 12:30:45 CEST, end at Sun 2019-10-20 12:32:57 CEST. --
oct 20 12:30:45 suse-server kernel: Linux version 4.12.14-lp151.28.16-default (geeko@buildhost) (...)
oct 20 12:30:45 suse-server kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-4.12.14-lp151.28.16-default root=UUID=7570f67f-4a08-448e-aa09-168769cb9289 splash=>
oct 20 12:30:45 suse-server kernel: x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'
oct 20 12:30:45 suse-server kernel: x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers'
(...)

Altre opzioni che possono essere utili in questo scenario sono:

-m, --merge

Unisce le voci di tutti i journal disponibili sotto /var/log/journal, inclusi quelli remoti.

--file

Mostra le voci in un file specifico, per esempio: journalctl --file /var/log/journal/64319965bda04dfa81d3bc4e7919814a/user-1000.journal.

--root

Un percorso che indichi la directory principale è passato come argomento. journalctl cercherà lì i file del journal (per esempio journalctl --root /faulty.system/).

Vedere la pagina man di journalctl per maggiori informazioni.

Inoltrare i Dati di Log a un Demone Standard syslog

I dati di log del journal possono essere resi disponibili a un demone standard syslog:

  • Inoltro dei messaggi al file socket /run/systemd/journal/syslog per la lettura di syslogd. Questa funzione è abilitata con l’opzione ForwardToSyslog=yes.

  • Avere un demone syslog che si comporti come journalctl, quindi leggere i messaggi di log direttamente dai file di journal. In questo caso, l’opzione rilevante è quella di Storage; deve avere un valore diverso da none.

Note

Allo stesso modo, puoi inoltrare i messaggi di log ad altre destinazioni con le seguenti opzioni: ForwardToKMsg (kernel log buffer  — kmsg), ForwardToConsole (la console di sistema) o ForwardToWall (tutti gli utenti connessi tramite wall). Per maggiori informazioni, consulta la pagina man di journald.conf.

Esercizi Guidati

  1. Supponendo che tu sia root, completa la tabella con il comando appropriato "journalctl":

    Scopo Comando

    Mostra le voci del kernel

    Mostra i messaggi del secondo avvio a partire dall’inizio del journal

    Mostra i messaggi del secondo avvio a partire dalla fine del journal

    Mostra i messaggi di log più recenti e continua a guardare se ce ne sono di nuovi

    Mostra solo i nuovi messaggi da ora, e aggiorna l’output continuamente

    Mostra i messaggi dell’avvio precedente con una priorità di warning e in ordine inverso

  2. Il comportamento del demone journal riguardo allo storage è controllato principalmente dal valore dell’opzione Storage in /etc/systemd/journald.conf. Indica quale comportamento è legato a quale valore nella tabella seguente:

    Behaviour Storage=auto Storage=none Storage=persistent Storage=volatile

    I dati di log vengono buttati via ma l’inoltro è possibile.

    Una volta che il sistema si è avviato, i dati di log saranno memorizzati in /var/log/journal. Se non è già presente, la directory verrà creata.

    Una volta che il sistema si è avviato, i dati di log saranno memorizzati in /var/log/journal. Se non è già presente, la directory non verrà creata.

    I dati di log saranno memorizzati sotto /var/run/journal ma non sopravviveranno ai riavvii.

  3. Come hai ormai imparato, il journal può essere ripulito manualmente in base al tempo, alla dimensione e al numero di file. Completa i seguenti compiti usando journalctl e le opzioni appropriate:

    • Controlla quanto spazio su disco è occupato dai file del journal:

    • Riduci la quantità di spazio riservato ai file di journal archiviati e imposta a 200MiB:

    • Controlla di nuovo lo spazio su disco e spiega i risultati:

Esercizi Esplorativi

  1. Quali opzioni dovresti modificare in /etc/systemd/journald.conf in modo che i messaggi siano inoltrati a /dev/tty5? Quali valori dovrebbero avere le opzioni?

  2. Fornisci il corretto filtro journalctl per mostrare quanto segue:

    Scopo Filtro + Valore

    Mostra i messaggi che appartengono ad un utente specifico.

    Mostra i messaggi da un host chiamato debian.

    Mostra i messaggi che appartengono a un gruppo specifico.

    Mostra i messaggi appartenenti a root

    In base al percorso dell’eseguibile, mostra i messaggi di sudo

    In base al nome del comando, mostra i messaggi di sudo

  3. Quando si filtra per priorità, anche i log con una priorità più alta di quella indicata saranno inclusi nell’elenco; per esempio journalctl -p err stamperà i messaggi error, critical, alert e emergency. Tuttavia, puoi fare in modo che journalctl mostri solo un intervallo specifico. Quale comando useresti per far mostrare a journalctl solo i messaggi nei livelli di priorità warning, error e critical?

  4. I livelli di priorità possono anche essere specificati numericamente. Riscrivi il comando dell’esercizio precedente usando la rappresentazione numerica dei livelli di priorità:

Sommario

In questa lezione abbiamo imparato:

  • I vantaggi di usare systemd come gestore di sistemi e servizi.

  • Le basi delle unit e dei target di systemd.

  • Da dove systemd-journald prende i dati di logging.

  • Le opzioni che puoi passare a systemctl per controllare systemd-journald: start, status, restart e stop.

  • Dove si trova il file di configurazione del journal — /etc/systemd/journald.conf — e le sue opzioni principali.

  • Come interrogare il journal in modo generale e per dati specifici utilizzando i filtri.

  • Come navigare e cercare nel journal.

  • Come gestire la memorizzazione dei file di journal: in memoria o su disco.

  • Come disabilitare del tutto il journaling.

  • Come controllare lo spazio su disco occupato dal journal, imporre limiti di dimensione ai file di journal archiviati e pulire manualmente i file di journal archiviati (vacumming).

  • Come recuperare i dati del journal da un sistema di rescue.

  • Come inoltrare i dati di log a un demone standard syslog.

Comandi utilizzati in questa lezione:

systemctl

Controlla il sistema systemd e il gestore dei servizi.

journalctl

Interroga il journal di systemd.

ls

Elenca il contenuto della directory.

less

Visualizza il contenuto del file.

mkdir

Crea directories.

Risposte agli Esercizi Guidati

  1. Supponendo che tu sia root, completa la tabella con il comando appropriato "journalctl":

    Scopo Comando

    Mostra le voci del kernel

    journalctl -k o journalctl --dmesg

    Mostra i messaggi del secondo avvio a partire dall’inizio del journal

    journalctl -b 2

    Mostra i messaggi del secondo avvio a partire dalla fine del journal

    journalctl -b -2 -r o journalctl -r -b -2

    Mostra i messaggi di log più recenti e continua a guardare se ce ne sono di nuovi

    journalctl -f

    Mostra solo i nuovi messaggi da ora, e aggiorna l’output continuamente

    journalctl --since "now" -f

    Mostra i messaggi dell’avvio precedente con una priorità di warning e in ordine inverso

    journalctl -b -1 -p warning -r

  2. Il comportamento del demone journal riguardo allo storage è controllato principalmente dal valore dell’opzione Storage in /etc/systemd/journald.conf. Indica quale comportamento è legato a quale valore nella tabella seguente:

    Behaviour Storage=auto Storage=none Storage=persistent Storage=volatile

    I dati di log vengono buttati via ma l’inoltro è possibile.

    x

    Una volta che il sistema si è avviato, i dati di log saranno memorizzati in /var/log/journal. Se non è già presente, la directory verrà creata.

    x

    Una volta che il sistema si è avviato, i dati di log saranno memorizzati in /var/log/journal. Se non è già presente, la directory non verrà creata.

    x

    I dati di log saranno memorizzati sotto /var/run/journal ma non sopravviveranno ai riavvii.

    x

  3. Come hai imparato, il journal può essere ripulito manualmente in base al tempo, alla dimensione e al numero di file. Completa i seguenti compiti usando journalctl e le opzioni appropriate:

    • Controlla quanto spazio su disco è occupato dai file del journal:

      journalctl --disk-usage
    • Riduci la quantità di spazio riservato ai file di journal archiviati e imposta a 200MiB:

      journalctl --vacuum-size=200M
    • Controlla di nuovo lo spazio su disco e spiega i risultati:

      journalctl --disk-usage

      Non c’è correlazione perché --disk-usage mostra lo spazio occupato da entrambi i file di giornale attivi e archiviati mentre --vacuum-size si applica solo ai file archiviati.

Risposte agli Esercizi Esplorativi

  1. Quali opzioni dovresti modificare in /etc/systemd/journald.conf in modo che i messaggi siano inoltrati a /dev/tty5? Quali valori dovrebbero avere le opzioni?

    ForwardToConsole=yes
    TTYPath=/dev/tty5
  2. Fornisci il corretto filtro journalctl per mostrare quanto segue:

    Scopo Filtro + Valore

    Mostra i messaggi che appartengono ad un utente specifico.

    _ID=<user-id>

    Mostra i messaggi da un host chiamato debian.

    _HOSTNAME=debian

    Mostra i messaggi che appartengono a un gruppo specifico.

    _GID=<group-id>

    Mostra i messaggi appartenenti a root.

    _UID=0

    In base al percorso dell’eseguibile, mostra i messaggi di sudo.

    _EXE=/usr/bin/sudo

    In base al nome del comando, mostra i messaggi di sudo.

    _COMM=sudo

  3. Quando si filtra per priorità, anche i log con una priorità più alta di quella indicata saranno inclusi nell’elenco; per esempio journalctl -p err stamperà i messaggi error, critical, alert e emergency. Tuttavia, puoi fare in modo che journalctl mostri solo un intervallo specifico. Quale comando useresti per far mostrare a journalctl solo i messaggi nei livelli di priorità warning, error e critical?

    journalctl -p warning..crit
  4. I livelli di priorità possono anche essere specificati numericamente. Riscrivi il comando dell’esercizio precedente usando la rappresentazione numerica dei livelli di priorità:

    journalctl -p 4..2

Linux Professional Institute Inc. Tutti i diritti riservati. Visita il sito Learning Materials: https://learning.lpi.org
Quest'opera è sotto la licenza 'Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License'.

Prossima Lezione

108.3 Concetti base dei Mail Transfer Agent (MTA) (108.3 Lezione 1)

Leggi la prossima Lezione

Linux Professional Institute Inc. Tutti i diritti riservati. Visita il sito Learning Materials: https://learning.lpi.org
Quest'opera è sotto la licenza 'Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License'.

LPI è una organizzazione non-profit.

© 2023 Linux Professional Institute (LPI) è lo standard di certificazione globale e l'organizzazione di supporto alla carriera per i Professionisti Open Source. Con più di 200,000 titolari di Certificazione, è il primo e il più grande ente di Certificazione Open Source e Linux vendor-neutral. LPI ha professionisti certificati in oltre 180 Paesi, offre i suoi Esami in più lingue e ha centinaia di Partner di formazione in tutto il mondo.

La nostra missione è promuovere l'uso dell'Open Source supportando le persone che vi lavorano.

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • Contattaci
  • Privacy & Cookie Policy

Trovato un errore? Per favore scrivi a contattaci.

© 1999–2023 The Linux Professional Institute Inc. Tutti i diritti riservati.