Beiträge zu “elasticsearch”

Kibana Webserver Logs nach User Agents auswerten

Nachdem nun die Logfiles eine Apaches Servers in einer Elasticsearch Datenbank gelandet sind wollte ich meine ersten Gehversuche mit der Auswertung der Daten in Kibana starten.

Für den Anfang wollte ich ein Kuchendiagramm mit den verwendeten Browsern und dem Betriebssystem erstellen

Leider wird bisher der Useragent an “einem Stück” von Logstash nach Elasticsearch geschrieben.

Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; rv:11.0) like Gecko

Glücklicherweise gibt es in Logstash einen Filter der einem diesen String schön in die Bestandteile zerlegt. Wenn man diese Zeilen seiner Logstash Konfiguration hinzufügt

 useragent {
    source => "agent"
    target => "useragent"
}

werden folgenden Daten später bereitgestellt

 "useragent" => {
       "name" => "IE",
         "os" => "Windows 8.1",
    "os_name" => "Windows 8.1",
     "device" => "Other",
      "major" => "11",
      "minor" => "0"

Diese kann man dann in Kibana in einem Kuchendiagramm so darstellen. Der innere Kreis zeigt die Browser an und auf dem äußeren Kreis werden die Betriebssysteme dargestellt.

Logstash Kibana Useragents
13.10.15
Weitere Beiträge zu: elasticsearch   kibana   logstash  

Webserver Logs in Elasticsearch importieren

Die Kombination von Elasticsearch, Logstash und Kibana (ELK) soll eine sehr mächtige Möglichkeit zur Auswertung von Logfiles sein. Meine ersten Versuche wollte ich mit Apache Logfiles machen. Vielleicht kann man ja damit die bei mir weggefallenen Web Analytics Anwendung Piwik ausgleichen. Da hier keine IP Adressen gespeichert werden und keine Auswertung der Browsersettings auf der Clientseite erfolgen ist zwar mit wenig aber vielleicht hilfreichen Informationen zu rechnen. Ich erwarte mir von dieser Möglichkeit auch andere Informationen aus anderen Log Daten.

Die drei Softwarepakete installieren sich für einen ersten Test recht einfach und schnell:

  • Download der Dateien von hier
  • Auspacken mit tar
  • Konfigurieren und Starten

Elasticsearch

Es ist keine Konfiguration notwendig wenn man hinter einer Firewall steht. Kann man einfach mit

 elasticsearch-x.y.z/bin/elasticsearch

gestartet werden und wenn man mag kann man mit http://localhost:9200/ sehen ob der Server antwortet

{
    "status" : 200,
    "name" : "Chondu the Mystic",
    "cluster_name" : "elasticsearch",
    "version" : {
      "number" : "1.7.2",
      "build_hash" : "e43676b1385b8125d647f593f7202acbd816e8ec",
      "build_timestamp" : "2015-09-14T09:49:53Z",
      "build_snapshot" : false,
      "lucene_version" : "4.10.4"
    },
    "tagline" : "You Know, for Search"
  }

Kibana

Kibana ist eine Anwendung zur Analyse und Visualisierung von Daten. Eine Konfiguration ist für den einfachen Fall nicht notwendig. Wenn man auf http://localhost:5601 geht bekommt die Standardoberfläche angezeigt.

Logstash

Logstash ist ein Programm das es erlaubt “beliebige” Logfiles und andere Datenquellen zu “normalisieren” und unter anderem in Elasticsearch abzulegen.

Wichtig für die unten angegebene einfach Konfiguration für den Import von existierenden Access Logs eines Apache Servers war, das diese im “combined” Format erzeugt wurden. Ansonsten funktioniert das in Logstash bereits vordefinierte “Normalisierungs Pattern” nicht. Also z.B.

 CustomLog /var/www/http/logs/access.log **combined**

Die Zeile mit date{ … } ist wichtig, wenn man existierende Logs importieren möchte. Lässt man die weg bekommen alle Zugriffe den Zeitstempel des Imports.

Die auskommentierte Zeile mit stdout kann hilfreich zur Fehlersuche sein. Dann bekommt man nämlich alles schön auf den Bildschirm dargestellt.

vi logstash.conf
 
input { stdin { type => "apache" } }
filter {
  grok {
    pattern => ["%{COMBINEDAPACHELOG}"]
    add_tag => "apache"    }
  date { match => [ "timestamp","dd/MMM/yyyy:HH:mm:ss Z" ] } 
    }
output {
 elasticsearch {
     cluster => "elasticsearch.local"
     host => "127.0.0.1"
     protocol => http
     index => "my-logs"
     index_type => "apache"
 }
# stdout { codec => rubydebug }
}

Mit

./logstash-1.5.4/bin/logstash --config ./logstash.conf < access.log

bekommt man dann alle Ereignisse aus dem Access.Log des Webservers importiert und das sieht dann in Kibana auf den ersten Blick so aus.

Apache Log ELK Import

So jetzt sind die Daten mal da. Was man damit wie machen kann muss ich nun als nächstes herausfinden.

12.10.15
Weitere Beiträge zu: elasticsearch   kibana   logstash  

Jekyll Inhalte mit Elasticsearch indexieren

Was länger währt wird manchmal ganz passabel. Nach längeren Vorarbeiten habe ich meine erste Version einer Elasticsearch Suche auf meinem statischen Jekyll Blog eingerichtet.

Rechts oben über die Lupe kommt man zu dem Formular.

Die wesentliche Schritte waren:

Was ist noch offen:

  • Ich würde gerne den Zugriff auf den Elasticsearch über einen Apache Proxy laufen lassen
  • Die Updates von neuen Inhalten geschehen aktuell über einen Cronjob der automatisiert jeden Abend die letzten 3 Beiträge in den Index lädt. Hier wäre ein Plugin schöner und für viele andere Anwender wahrscheinlich notwendig.
  • Eine Voransicht der Treffer mit Highlights der Suchbegriffe
  • Eine Sortierung der Jahreszahlen in den Facetten nach Jahr und nicht nach Anzahl der Treffer

Jekyll Elasticsearch

14.7.15
Weitere Beiträge zu: jekyll   elasticsearch  

Jekyll: ElasticsearchUI integrieren

Mit elasticsearchUI möchte ich einen Suchindex in Elasticsearch in meinem Jekyll Blog integrieren. Mit Hilfe der Demodateien konnte ich schon schnell meinen Index durchsuchen und Trefferlisten mit Facetten darstellen.

Die Integration in Jekyll ist im Prinzip auch ziemlich einfach. Man muss nur die Javascript Dateien im Header laden und den HTML Code aus dem Demodaten an die gewünschte Stelle in einem Markdown Template positionieren.

Wichtig ist dabei aber das man die AngularJS Anweisungen, die über eine doppelte Klammer gekennzeichnet sind, mit einem raw und endraw umschließt. Sonst werden diese beim Konvertieren durch Jekyll bereits als Liquid Tag interpretiert und gelöscht. Dann werden später auch keine Suchergebnisse angezeigt.

Da kann man dann schon mal die eine oder andere Stunde Fehlersuche betreiben.

1.7.15
Weitere Beiträge zu: elasticsearch   jekyll  

Elasticsearch: Vorläufige Auswahl des Service Providers

Meine ersten Tests mit Elasticsearch habe ich auf bonsai.io durchgeführt. Wesentliches Kriterium für die Auswahl war der kostenlose Tarif.

Nach den ersten erfolgreichen Gehversuchen stellte sich dann die Frage wie man die Daten in Elasticsearch (ES) absichern kann. ES bietet out of the Box keine Möglichkeit den Zugriff zu regeln. Die Autorisierung muss in der Anwendung erfolgen.

Im Prinzip kann jeder alles auf dem Index über die REST API machen. Eigentlich ist das für mich kein Problem da ich eh nur öffentliche Daten in meinem Index habe. Ich fände es allerdings schon uncool wenn jemand meinen Index löscht oder andere Spam Dokumente in meinen Index einfügt. Dann könnte ein Leser durch die Suche auf unfreundliche Seiten “geführt” werden.

Man kann ES durch verschiedene Möglichkeiten wie Apache Proxies absichern aber während meiner Recherche bin ich auf Facetflow.com gestoßen. Facetflow hat auch einen kleinen kostenlosen Tarif bietet aber die Möglichkeit über sogenannte API Keys eine Art Nutzer einzurichten und die Rechte auf dem Index zu verwalten. So gibt es einen Default Nutzer der nur lesen darf und einen Administrator der alles darf und diese Einschränkungen kann man auch noch mit IP Adressen ab härten.

Der kostenlose Tarif ist zwar etwas kleiner aber für meinen Blog sollte der reichen.

facetflow

29.6.15
Weitere Beiträge zu: elasticsearch  

ElasticsearchUI: ein Frontend für Elasticsearch

Update November 2017 Ist auf neueren Versionen nicht mehr möglich

Neben der Möglichkeit eine (hoffentlich) schnelle Volltextsuche zu bekommen interessiert mich am meisten die facetierte Suche. Dabei werden einem neben den Suchergebnissen auch weitere Begriffe oder Angaben angezeigt die in der Ergebnisliste vorgekommen.

Um das mal schnell auszuprobieren und die Geschwindigkeit zu testen habe ich die elasticsearchUI einmal ausprobiert.

Dazu muss man einfach nur die Demo HTML Datei laden, die URL des Servers, den Index und die Werte für die gewünschten Facetten angeben. Und schon geht es los.

Und es ist blitzschnell.

Für einen ersten Test schon recht beeindruckend. Jetzt muss ich noch sehen wie ich so eine Suche in Jekyll eingebunden bekomme.

elasticsearchui

25.6.15
Weitere Beiträge zu: elasticsearch   ElasticUI  

Elasticsearch: Bulk Upload

Nachdem ich meine ersten Geh- (Stolper)versuche mit Elasticsearch bestanden habe wolle ich im nächsten Schritt meinen Index mit für mich relevanten Daten füllen. Diese Daten sollen dann die Basis für meine ersten Erfahrungen mit sinnvollen Suchanfragen bilden.

Dieser Bulkupload soll später durch einen individuellen Upload einzelner Dokumente ersetzt werden um Bandbreiten zu sparen. Im Verlauf dieser Übung habe ich auch festgestellt das man mit so einem Upload auch schnell alle Probleme findet die sich ergeben wenn man umfangreichere Texte in einen Index überführen möchte.

Leider reicht dieser Beitrag doch nicht komplett. Das JSON File das hier erzeugt wird ist nicht für einen Bulkupload geeignet.

Hier das Template das ich verwendet habe und mit dem ich nach etwas probieren alle Beiträge in den Index hoch laden konnte.

---
layout: none
---
{% for post in site.posts %}
        {% if post.draft != true %}
{"index":{"_index":"blog2", "_type" : "post" , "_id": "{{ post.date | date: "%y%m%d%k%M"}}"}}\n
{"title": "{{ post.title | escape  }}", "url": "{{ site.url }}{{ post.url }}", "tags": "{% for tag in post.tags %}{{ tag }};{% endfor %}", "content": "{{ post.content | strip_html | strip_newlines | remove:  "   " | remove: "\" | escape  }}"}
        {% endif %}
{% endfor %}

Als _postid verwende ich einfach das Datum mit der Uhrzeit. Das ist mit Sicherheit nicht für alle Szenarien ausreichend aber für meinen Blog wird es wohl reichen. Die Filter für den Titel und den Content sind notwendig da ich an vielen Stellen Hochkommas in den Texten verwende die den Import stören. Wichtig ist auch das alles in einer Zeile steht. Sonst bekommt man beim Import eine Fehlermeldung die einen auf eine falsche Fährte führt.

Der Upload geht dann so

 curl -XPOST 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/_bulk'  --data-binary @_site/search.json

Als Ergebnis bekommt man dann die Fehlermeldungen bei denen der Import nicht geklappt hat. In meinem Fall musste ich etwas Zeit in die Filter für den Content investieren bis ich alle Sonderzeichen und unzulässigen Escapesequenzen heraus gefiltert hatte.

Irgendwann beginnt dann das Ergebnis mit

{"took":386,"errors":false,"items":[{

Dann hat man alle Fehler eliminiert und der Index ist mit allen Dokumenten des Jekyll Blogs gefüllt.

24.6.15
Weitere Beiträge zu: elasticsearch   jekyll  

Elasticsearch: meine ersten Gehversuche

Das Thema Suchengine interessiert mich schon länger aber seitdem ich mit Jekyll einen Blogsystem verwende das von Hause aus keine Suchmöglichkeit mitbringt gibt es einen echten persönlichen Bedarf. Bisher verwende ich dort DuckDuckGo aber so richtig zufrieden bin ich damit nicht. Außerdem interessiert mich wie man die Suchergebnisse durch Facetten besser gestalten kann.

Elasticsearch scheint momentan neben Solr das Werkzeug der Wahl zu sein. Aufgrund der zusätzlichen Möglichkeit der Logfile Analyse habe ich mich aber nach meinen ersten Versuchen mit Solr entschieden mit Elasticsearch weiterzumachen.

Um die ersten Schritte möglichst einfach zu gestalten verwende ich bonsai.io. Dort kann man einen kostenlosen Suchindex einrichten.

Elasticsearch möchte sein Input als Datei im JSON Format haben und auf Basis dieses Beitrages konnte ich schnell meinen Jekyll Blog in ein JSON Format überführen.

Richtet man seine Suchindex bei bonsai.io ein bekommt man eine URL über die man die notwendigen Aktionen ausführen kann. Dies Aktionen werden als http Operationen durchgeführt und da man das dann schön in einen Text überführen kann verwende ich curl auf der Kommandozeile um die Operationen auszuführen. Das sieht komplizierter aus als es ist.

Für die ersten Gehversuche möchte ich einen Index erstellen, zwei Dokumente einstellen und dann danach suchen.

Zuerst erstelle ich mir einen Index für meine Blog Dokumente

   curl -XPUT 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/blog'
   {"acknowledged":true}

Dann werden die ersten Dokumente erzeugt. Als Werte nehme ich Dokumente aus der JSON Datei die ich mit Jekyll erzeugt habe.

curl -XPOST 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/blog/posts' -d ' {
                 "title": "GPXViewer: Ein Werkzeug zur Darstellung von GPX Dateien",
                 "url": "http://127.0.0.1:4000/2015/06/gpxviewer.html",
                 "path": "/2015/06/gpxviewer.html",
                 "content": "Wenn man mal schnell GPX Daten auf einer Google Maps Karte darstellen möchte sollte man sich auf jeden Fall mal den GPXViewer anschauen. Neben der Route auf Google Maps wird auch das Höhenprofil mit Tagesetappen angezeigt.Wirklich gut gemacht.",
                 "categories": "",
                 "date": "2015-06-18 20:26:56 +0200" } '
{"_index":"blog","_type":"posts","_id":"AU4VTna2oGwl_2cZDTqn","_version":1,"created":true}


curl -XPOST 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/blog/posts' -d ' {
                "title": "WeeWX: get archive interval failed",
                "url": "http://127.0.0.1:4000/2015/06/weewx-failed.html",
                "path": "/2015/06/weewx-failed.html",
                "content": "Meine Wetterstation hat die letzten Tage keine Aufzeichnungen dokumentiert. Der Prozess brach kurz nach dem Start ab und im Logfile fand ich folgende Zeilenweewx[]: engine: Record generation will be attempted in 'hardware'weewx[]: fousb: get archive interval failed attempt 1 of 3: could not detach kernel driver from ten verfügbarweewx[]: fousb: get archive interval failed attempt 2 of 3: could not detach kernel driver from ten verfügbarweewx[]: fousb: get archive interval failed attempt 3 of 3: could not detach kernel driver from ten verfügbarweewx[]: engine: Caught WeeWxIOError: Unable to read archive interval after 3 triesweewx[]:     ****  Exiting...An dieser fand ich den Hinweis: Einfach mal die Wetterstation von USB und Strom trennen.Jetzt lüppt es wieder",
                "categories": "",
                "date": "2015-06-17 20:26:56 +0200" } '

So und jetzt die ersten Suchversuche. Der erste Versuch sucht nach einem Begriff der nicht verwendet wird und die zweite nach einem vorhandenen Begriff.

curl -XGET 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/blog/_search?q=GPdX'
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

curl -XGET 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/blog/_search?q=GPX'
{"took":1,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":0.17677669,"hits":[{"_index":"blog","_type":"posts","_id":"AU4VUkPZoGwl_2cZDTxR","_score":0.17677669,"_source": {
                 "title": "GPXViewer: Ein Werkzeug zur Darstellung von GPX Dateien",
                 "url": "http://127.0.0.1:4000/2015/06/gpxviewer.html",
                 "path": "/2015/06/gpxviewer.html",
                 "content": "Wenn man mal schnell GPX Daten auf einer Google Maps Karte darstellen möchte sollte man sich auf jeden Fall mal den GPXViewer anschauen. Neben der Route auf Google Maps wird auch das Höhenprofil mit Tagesetappen angezeigt.Wirklich gut gemacht.",
                 "categories": "",
                 "date": "2015-06-18 20:26:56 +0200"
             }

Falls man einen Index löschen möchte kann man das so machen

curl -XDELETE 'https://username:passwort@try1-yourserver.eu-west-1.bonsai.io/blog'
{"acknowledged":true}

Das fängt ja schon mal gut an. Als nächstes möchte ich herausfinden wie ich einen ganzen Satz von Dokumenten auf einmal indizieren kann und meine Tags und die Jahresangaben als Facetten verwenden kann.

20.6.15
Weitere Beiträge zu: elasticsearch   jekyll  

Dies ist ein privater Blog von Hagen Bauer- berufstätiger Vater, Ehemann, Naturliebhaber, Läufer, Zelter, technikverliebt.


Creative Commons License
This blog is licensed under a Creative Commons License