logstash - DaSSIA
Transcript
logstash - DaSSIA
LOGSTASH 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). 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à. 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). 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. 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. 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 Broker Indexer Indexer Indexer Search & Storage Shipper client server LOGSTASH Architettura Ecosistema LOGSTASH LOGSTASH REDIS Indexer Indexer LOGSTASH ELASTICSEARCH LOGSTASH client server KIBANA LOGSTASH Architettura Ecosistema Alternativa SYSLOG SYSLOG Indexer Indexer LOGSTASH ELASTICSEARCH SYSLOG client server KIBANA LOGSTASH Scalabilità broker Indexer Indexer LOGSTASH ELASTICSEARCH Search & storage LOGSTASH broker Indexer Indexer LOGSTASH ELASTICSEARCH 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. 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. ELASTICSEARCH Breve storia ELASTICSEARCH Ulteriori integrazioni 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. 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. 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. 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. 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 ELASTICSEARCH Architettura Quando avviamo per la prima volta Elasticsearch in un nodo senza dati né indici ci troviamo in una situazione di questo tipo: NODE 1 CLUSTER MASTER 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. NODE 1 P0 MASTER P1 P2 CLUSTER 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. ELASTICSEARCH Architettura È sufficiente lanciare un ulteriore nodo, configurato con lo stesso cluster.name, per ottenere la ridondanza desiderata NODE 1 P0 MASTER P1 P2 NODE 2 R0 R1 R2 CLUSTER Il secondo nodo viene aggiunto automaticamente al cluster e vengono creati i replica shards. 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 P1 CLUSTER P2 NODE 2 R0 NODE 3 R1 P0 R2 ELASTICSEARCH Architettura Incrementando poi il fattore di replica incrementiamo ulteriormente la robustezza del sistema: NODE 1 R0 MASTER P1 CLUSTER P2 NODE 2 R0 NODE 3 R1 R2 P0 R1 R2 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 R0 CLUSTER MASTER R1 R2 P2 NODE 3 P0 R1 P1 R2 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 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. Demo l Architecture - Generale Demo l Architecture - Generale Demo Caso affrontato Log Log Log 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 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 # r Square # step ht lt s # Triangular i ht lt s s # SawTooth i ht lt s 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/ Slides/ 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 Demo LogProducer.jar - Logstash 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 Log Log Log derivante verso i sistemi opportuni (nel nostro caso kafka e elasticsearch). 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/*" } } 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}|-)" } Demo Configurazione di Logstash – Grok Pattern personalizzati Il contenuto della cartella patterns_dir ls /opt/logstash/1.5.0.rc2/pattern timepattern MYHTTPDATE %{MONTHDAY:giorno}/%{MONTHNUM:mese}/%{YEAR:anno}:%{TIME:ora} NAME RULE MyPattern.foo NAME RULE Demo Configurazione di Logstash – Filter – Date date { locale => "it" timezone => "Europe/Rome" match => [ "messageTimestamp","dd/MM/yyyy:HH:mm:ss.SSS"] target => "messageTimestamp" } } 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 { } } Demo Configurazione di Logstash input { file { type => "apache-access" path => "/data/simulated_logs/*" filter { grok { } type => "apache-access" } patterns_dir => "..." pattern => "..." } date { ... target => "messageTimestamp" } output { } kafka { topic_id => "logstash_logs" client_id => "logstash" } }