2014-11-14 3 views
5

Ho un'applicazione Java che scrive in un file di registro in formato json. I campi che arrivano nei log sono variabili. Il logstash legge questo file di log e lo invia a Kibana.Pannello termini Logstash + Kibana senza parole di interruzione

Ho configurato il logstash con il seguente file:

input { 
     file { 
       path => ["[log_path]"] 
       codec => "json" 
     } 
} 

filter{ 
     json { 
       source => "message" 
     } 

     date { 
       match => [ "data", "dd-MM-yyyy HH:mm:ss.SSS" ] 
       timezone => "America/Sao_Paulo" 
     } 
} 

output { 
     elasticsearch_http { 
       flush_size => 1 
       host => "[host]" 
       index => "application-%{+YYYY.MM.dd}" 
     } 
} 

Sono riuscito a dimostrare in modo corretto tutto in Kibana senza alcuna mappatura. Ma quando provo a creare un pannello termini per mostrare un conteggio dei server che hanno inviato quei messaggi ho un problema. Ho un campo chiamato server nel mio json, che mostra il nome del server (come: a1-name-server1), ma il pannello dei termini divide il nome del server a causa del "-". Vorrei anche contare il numero di volte che appare un messaggio di errore, ma lo stesso problema si verifica, perché il pannello dei termini divide il messaggio di errore a causa degli spazi.

Sto utilizzando Kibana 3 e Logstash 1.4. Ho cercato molto sul web e non ho trovato nessuna soluzione. Ho provato anche a usare il .raw da logstash, ma non ha funzionato.

Come posso gestirlo?

Grazie per l'aiuto.

risposta

1

Poiché non è stata definita una mappatura in elasticsearch, le impostazioni predefinite vengono applicate per ogni campo del tipo nell'indice. Le impostazioni predefinite per i campi stringa (come il campo server) sono analizza il campo, il che significa che la ricerca elastica renderà i contenuti del campo. Ecco perché divide i nomi dei tuoi server in parti.

È possibile risolvere questo problema definendo una mappatura. Non è necessario definire tutti i campi, ma solo quelli che non si desidera analizzare con elasticsearch. Nel vostro caso particolare, inviando il seguente comando put farà il trucco:

http://[host]:9200/[index_name]/_mapping/[type] 

{ 
    "type" : { 
     "properties" : { 
      "server" : {"type" : "string", "index" : "not_analyzed"} 
     } 
    } 
} 

Non si può fare questo su un indice già esistente, perché il passaggio da analizzati per not_analyzed è un cambiamento importante nella mappatura.

4

Il tuo problema qui è che i tuoi dati sono tokenizzati. Questo è utile per effettuare qualsiasi ricerca sui tuoi dati. ES (per impostazione predefinita) dividerà il campo message diviso in parti diverse per poterli cercare. Ad esempio potresti voler cercare la parola ERROR nei tuoi registri, quindi probabilmente ti piacerebbe vedere nei risultati messaggi come "C'è stato un errore nel tuo cluster" o "Errore elaborando qualsiasi cosa". Se non si analizzano i dati per quel campo con tokenizers, non sarà possibile effettuare ricerche in questo modo.

Questo analizzato nel comportamento è utile quando si desidera cercare le cose, ma non consente di raggruppare quando messaggi diversi con lo stesso contenuto. Questo è il tuo caso. La soluzione a questo è aggiornare la mappatura mettendo not_analyzed per quel campo specifico che non vuoi dividere in token. Questo probabilmente funzionerà per il tuo campo host, ma probabilmente interromperà la ricerca.

Quello che faccio di solito per questo tipo di situazioni è utilizzare index templates e multifields. Il modello di indice mi consente di impostare una mappatura per ogni indice che corrisponde a un'espressione regolare ei campi multipli consentono di avere il comportamento analyzed e not_analyzed in uno stesso campo.

utilizzando la seguente query sarebbe fare il lavoro per il vostro problema:

curl -XPUT https://example.org/_template/name_of_index_template -d ' 
{ 
    "template": "indexname*", 
    "mappings": { 
     "type": { 
      "properties": { 
       "field_name": { 
        "type": "multi_field", 
        "fields": { 
        "field_name": { 
         "type": "string", 
         "index": "analyzed" 
        }, 
        "untouched": { 
         "type": "string", 
         "index": "not_analyzed" 
        }      
       } 
      } 
     } 
    } 
}' 

E poi nel tuo pannello di termini è possibile utilizzare field.untouched, di prendere in considerazione l'intero contenuto del campo quando si calcola il conteggio del diverso elementi.

Se non si desidera utilizzare i modelli di indice (forse i dati sono in un unico indice), l'impostazione del mapping con lo Put Mapping API farebbe anche il lavoro. E se si utilizzano i multi-campo, non è necessario reindicizzare i dati, poiché dal momento in cui si imposta la nuova mappatura per l'indice, i nuovi dati verranno duplicati in questi due sottocampi (field_name e field_name.untouched). Se si modifica la mappatura da analyzed a not_analyzed, non sarà possibile visualizzare alcuna modifica finché non si reindicheranno tutti i dati.

+0

Devo passare il nome del campo esatto anziché "nome_campo" o semplicemente farlo funzionare per tutti i campi? – brunodahora

+0

@brunodahora È necessario specificare il nome del campo. – Pigueiras