2. LOGSTASH
Introduzione
Logstash è un tool per la gestione di eventi e log: è possibile utilizzarlo per
l'acquisizione di log (o più genericamente di file), il loro parsing e la conservazione per
un uso futuro.
Logstash è scritto in JRuby e funziona all'interno di una JVM.
La sua architettura è orientata ai messaggi ed è piuttosto semplice: è costituito da un
agent che viene configurato per combinare tra loro differenti funzioni (client / server).
3. LOGSTASH
Architettura
L'ecosistema nel quale viene utilizzato Logstash è composto da 4 componenti
fondamentali:
- lo Shipper: invia gli eventi a Logstash (tipicamente un agent remoto utilizza
unicamente questo componente);
- il Broker e l'Indexer: riceve e indicizza gli eventi;
- il Search and Storage: permette di cercare e memorizzare gli eventi;
- una Web Interface.
Tipicamente i server Logstash sono composti da uno o più di questi componenti: è
possibile combinarli indipendentemente l'uno dall'altro secondo le proprie necessità.
4. LOGSTASH
Agent Shipper
All'interno del file di configurazione dell'Agent Shipper Logstash dobbiamo specificare i
parametri di:
- input: corrisponde a ciò che arriva all'agent in ingresso (standard input o il contenuto
di un file);
- filter: opzione in grado di gestire il parsing dell'event in input, filtrare o aggiungere
informazioni;
- output: permette di specificare dove saranno inviati gli event (come, ad esempio,
standard output o ElasticSearch).
5. LOGSTASH
Filter
I filtri vengono utilizzati per filtrare ma anche per modificare i contenuti dei diversi
events. permettono anche di analizzare gli events (via grok ad esempio) per migliorare
poi la fase di indicizzazione e memorizzazione.
Possibili strategie di filtraggio:
- filtrare gli event con l'agent;
- filtrare gli event sul server centrale;
- emettere gli event nel formato più indicato.
Se si filtra a livello locale si riduce il carico sul server e ci si assicura la memorizzazione
nel formato desiderato: ciò comporta una configurazione più complessa dei diversi
agent.
Viceversa se il filtraggio avviene sul server centrale si dovrà disporre di risorse
hardware superiori in maniera da poter processare una grande mole di informazioni.
6. LOGSTASH
Cenni su Grok
Grok è lo strumento principale con il quale vengono eseguiti i filtri all'interno di Logstash
in quanto combinando i suoi comandi base e l'insieme delle diverse regular expressions
consente di ottenere facilmente la modifica del messaggio secondo quanto desiderato.
Ad esempio, utilizzando i comandi base possiamo:
- aggiungere/rimuovere campi o tag in base a determinati pattern;
- terminare il parsing non appena una data condizione è verificata;
- cancellare/ignorare determinati messaggi sulla base di pattern.
7. LOGSTASH
Architettura
Nella maggior parte dei casi, Logstash viene così configurato:
- un (o più) agent Logstash Shipper è in esecuzione all'interno degli host ed emette
informazioni quali eventi, registri delle applicazioni, servizi, log verso il server centrale.
- il server centrale Logstash sarà responsabile per l'esecuzione del Broker, Indexer,
Search, Storage e Web Interface per ricevere, processare e conservare i registri degli
eventi.
Shipper
Shipper
Shipper
Broker
Search
&
Storage
IndexerIndexerIndexer
serverclient
12. ELASTICSEARCH
Introduzione
Elasticsearch è un motore di ricerca open source costruito su Apache Lucene.
Lucene è la più avanzata e più completa (ma complessa) libreria per il search engine
tra tutte quelle presenti sia open source che proprietarie.
Lucene resta comunque una libreria: per sfruttare le sue potenzialità è necessario
lavorare in Java integrando Lucene direttamente nell'applicazione.
Elasticsearch, anch'esso scritto in Java, utilizza Lucene internamente per tutta
l'indicizzazione e la ricerca, ma mira a rendere facile la ricerca full-text nascondendo la
complessità di Lucene dietro una semplice API RESTful.
13. ELASTICSEARCH
Introduzione
Elasticsearch non è solo Lucene, non si limita infatti a essere uno strumento per la
ricerca Full Text. possiamo descriverlo come:
- un document store real time distribuito dove ogni campo è indicizzato e ricercabile;
- un motore di ricerca distribuito con analisi in tempo reale;
- scalabile in centinaia di server e capace di trattare petabytes di dati strutturati e non
strutturati.
Combina queste funzionalità in un server standalone alla quale un'applicazione terza
può interfacciarsi utilizzando delle API RESTful, utilizzando un client web (utilizzando
dei JSON) o anche la riga di comando.
16. ELASTICSEARCH
Architettura: componenti
In Elasticsearch sono presenti differenti componenti:
- un cluster è composto da uno o più nodi (istanze in esecuzione di Elasticsearch) che
condividono lo stesso cluster.name e che lavorano assieme condividendo i propri dati e il
carico di lavoro. Poiché i nodi possono essere aggiunti o rimossi dal cluster esso si
riorganizza per distribuire in maniera uniforme i dati;
- un indice è lo spazio logico, che indica uno o più shards fisici, dove vengono
immagazzinati i dati all'interno dei nodi;
- uno shard è l'unità di lavoro di basso livello che contiene una porzione dei dati facenti parti
dell'indice ed è costituito da una singola istanza di Lucene;
- il document rappresenta la porzione di dati strutturati da immagazzinare appartenenti a un
singolo oggetto.
17. ELASTICSEARCH
Architettura: nodi
All'interno del cluster uno dei nodi viene eletto come master node e si occupa della
gestione del cluster (creazione o eliminazione di un indice o aggiunta o rimozione di un
nodo).
Ogni nodo di un cluster può essere designato per essere un nodo master e, come
utenti, possiamo parlare a ognuno dei nodi presenti nel cluster.
Ciascun nodo conosce infatti la localizzazione di ogni document e può inoltrare la
nostra richiesta direttamente ai nodi che contengono il dato che ci interessa: sarà lo
stesso nodo che abbiamo interrogato a fornirci il risultato della ricerca astraendo la
complessità dell'architettura sottostante.
18. ELASTICSEARCH
Architettura: gli shards
Uno shard può essere un primary shard o un replica shard: ogni document nell'indice
appartiene a un singolo shard primario.
Un replica shard è una copia del primary shard: le repliche sono utilizzate per fornire una
ridondanza dei dati e vengono utilizzate anche per effettuare delle letture degli stessi.
Il numero degli shards primari viene fissato al momento in cui viene creato l'indice ma il
numero delle repliche può essere modificato in qualsiasi momento.
Quando il cluster cresce o si riduce di dimensione, Elasticsearch sposterà i dati tra i diversi
nodi per garantire un corretto bilanciamento. Ogni nuovo document inserito nell'indice viene
prima memorizzato nel primary shard e poi spostato nei replica shards associati.
19. ELASTICSEARCH
Architettura: Document - cenni
All'interno di Elasticsearch il Document rappresenta la porzione di dati strutturati da
immagazzinare appartenenti a un singolo oggetto.
Il Document è costituito da due componenti fondamentali:
- l'oggetto che rappresenta, serializzato in un JSON;
- dei specifici metadati relativi al Document stesso.
I metadati presenti all'interno di un Document devono essere almeno i tre seguenti:
- _index
- _type
- _id
Vi è la possibilità di utilizzare numerosi altri metadati qui non indicati.
20. ELASTICSEARCH
Architettura: Metadati - cenni
_index
Questo metadato identifica univocamente la collezione di dati, l'indice (assimilabile al
concetto di database negli RDBMS o di collection in MongoDB), dove salviamo e
indicizziamo i dati.
_type
Il metadato rappresenta la classe alla quale l'oggetto JSON appartiene. Ogni _type è
mappato su una differente definizione di schema: nello stesso indice possono infatti essere
presenti document di diversi tipi.
_id
Una stringa che, assieme all'_index e al _type identifica univocamente il Document in
Elasticsearch: quando creiamo un nuovo Document se non forniamo un _id sarà il sistema
stesso a generarne uno al posto nostro
22. ELASTICSEARCH
Architettura
Creando un indice, per impostazione predefinita, esso viene assegnato a cinque shards
primari. Ipotizziamo di aver configurato il nostro Elasticsearch per avere tre shards e una
replica per ciascuno di essi.
In questo caso la replica non viene realizzata in quanto non avrebbe senso duplicare i dati
sulla stessa macchina. Utilizzando una configurazione single node abbiamo un single point of
failure in quanto non è presente alcuna ridondanza.
NODE 1 MASTER
CLUSTER
P0 P1 P2
23. ELASTICSEARCH
Architettura
È sufficiente lanciare un ulteriore nodo, configurato con lo stesso cluster.name, per
ottenere la ridondanza desiderata
Il secondo nodo viene aggiunto automaticamente al cluster e vengono creati i replica
shards.
NODE 1 MASTER NODE 2
CLUSTER
P0 P1 P2 R0 R1 R2
24. ELASTICSEARCH
Architettura
Aggiungendo un ulteriore nodo al cluster, dal nodo 1 e dal nodo 2 vengono spostati
degli shards in maniera automatica per garantire la scalabilità orizzontale:
NODE 1 MASTER NODE 2 NODE 3
CLUSTER
P1 P2 R0 R1 P0 R2
26. ELASTICSEARCH
Architettura
Qualora uno dei nodi diventi inutilizzabile, ad esempio il nodo master, gli altri nodi
provvederanno ad eleggere un nuovo master e a ridistribuire gli shards:
NODE 2 MASTER NODE 3
CLUSTER
R0 R1 R2 P0 R2R1P1P2
27. ELASTICSEARCH
Linguaggio di interrogazione - cenni
All'interno di Elasticsearch è presente un apposito linguaggio di interrogazione Query
DSL: esso combina la potenza di ricerca di Lucene con una semplice interfaccia di
interrogazione di tipo JSON.
La generica query viene quindi espressa tramite una serie di coppie chiave valore
eventualmente annidate.
Il linguaggio Query DSL è in realtà costituito da due componenti:
- filter DSL
- query DSL
28. ELASTICSEARCH
Linguaggio di interrogazione - cenni
- filter DSL
pone una domanda la cui risposta è si/no in base al valore che assume uno specifico campo /
insieme di campi nel Document:
il Document ha data creazione nel range 2013 - 2014?
Il campo _status contiene il termine 'pubblicato'?
- query DSL
simile al filter, risponde alla domanda: quanto bene il Document effettua il match? Ad
esempio:
Document con miglior matching con le parole 'full text search'
Document che contiene la parola run, ma forse anche 'runs running jog sprint'
Una query calcola quindi quanto ogni Document è rilevante alla query associandolo a un
metadato di rilevanza _score il quale viene di seguito utilizzato per effettuare un sort dei
risultati della ricerca. Il concetto di rilevanza si adatta bene alla ricerca full-text dove
raramente è possibile identificare una risposta completamente corretta.
32. Demo
Caso affrontato: il generatore di Log
Il generatore di Log che viene utilizzato in questa demo, LogProducer.jar, è un semplice
programma JAVA che simula, in base a differenti parametri d'ingresso casuali, le variazioni
che possono subire degli AccessLog del webserver Apache2/Httpd.
I file di log finali prodotti saranno nel formato:
host1.dassia.crs4.it - - [16/04/2015:15:05:34.721 +0200] "POST http://dassia.it/page.php HTTP/1.0" 200 8342
LogProducer.jar ha fondamentalmente due funzioni:
- crea delle timeline di richieste previste
- processa le timeline generando quindi i file di log richiesti
33. Demo
Creazione della timeline
La timeline rappresenta l'andamento del numero delle richieste a un certo server web al
passare del tempo. In particolare con LogProducer.jar è possibile creare delle timeline con
alcuni andamenti prestabiliti
Flat Square
Triangular SawTooth
s
#
ht
lt
s
#
r
s
#
ht
lt
step
s
#
ht
lt
i i
34. Demo
Creazione della timeline
Il file contenente la timeline assegna una serie di parametri che verranno poi utilizzati per
generare delle righe di log pseudo casuali con:
- tipo di comando richiesto con differente probabilità di “uscita” (POST / GET / DELETE)
- risorsa richiesta in differenti sottocartelle
http://dassia.crs4.it/ BigData/ tutorial/ files.tar.gz
HadoopScripting/ webinar/ page.html
NoSQL/ ݺߣs/ crs4_logo.png
DataStreaming/
- risposta del server
200 (ok) 400 (bad request) 403 (forbidden) 404 (not found)
- dimensione restituita variabile in base al tipo del file / tipo comando / risposta del server
35. Demo
LogProducer.jar - Logstash
LogLogLog
Una volta lanciata l'elaborazione delle timeline il sistema inizierà a scrivere nella cartella,
indicata come destinazione dei log, un file di log per ogni timeline
sorgente.
A questo punto LogStash potrà andare a leggere i file di log,
filtrarli e interpretarli come da configurazione e “inoltrare” il JSON
derivante verso i sistemi opportuni (nel nostro caso kafka e
elasticsearch).
36. Demo
Configurazione di Logstash - Input
Nella configurazione dell'input assegneremo a uno specifico input una stringa identificativa
del “tipo in ingresso” e indicheremo a Logstash in quale cartella dovrà andare a leggere i file
di input.
input {
file {
type => "apache-access"
path => "/data/simulated_logs/*"
}
}
37. Demo
Configurazione di Logstash – Filter – Grok
Nella sezione filter andremo ad indicare a Logstash come filtrare ed effettuare il parsing dei
diversi tipi in ingresso.
filter {
grok {
type => "apache-access"
patterns_dir => "/opt/logstash/1.5.0.rc2/pattern"
pattern => "%{IPORHOST:clientip} %{USER:ident} %{USER:client} [%
{MYHTTPDATE:messageTimestamp} %{INT:timezone}] "%{WORD:verb} %
{NOTSPACE:request} *HTTP/%{NUMBER:httpversion}" %{NUMBER:response} (?:
%{NUMBER:bytes}|-)"
}
38. Demo
Configurazione di Logstash – Grok Pattern personalizzati
Il contenuto della cartella patterns_dir ls /opt/logstash/1.5.0.rc2/pattern
MYHTTPDATE %{MONTHDAY:giorno}/%{MONTHNUM:mese}/%{YEAR:anno}:%{TIME:ora}
timepattern
NAME RULE
MyPattern.foo
NAME RULE
39. Demo
Configurazione di Logstash – Filter – Date
date {
locale => "it"
timezone => "Europe/Rome"
match => [ "messageTimestamp","dd/MM/yyyy:HH:mm:ss.SSS"]
target => "messageTimestamp"
}
}
40. Demo
Configurazione di Logstash - Output
Nella sezione output andremo ad indicare a Logstash dove inoltrare i JSON risultanti dal
filtro appena effettuato.
output {
elasticsearch { cluster => elasticsearch }
kafka {
topic_id => "logstash_logs"
client_id => "logstash"
}
stdout { }
}