mai
2014
Pour analyser des logs de production, la solution basée sur Logstash est particulièrement adaptée. Nous ne rentrerons pas ici trop dans les détails, voir cet article du blog de Xebia pour une bonne porte d’entrée sur le sujet.
Nous nous placerons ici dans la perspective d’une architecture classique avec une instance de Logstash chargée de récupérer les logs de la manière choisie et de les parser et insérer dans Elasticsearch, un serveur Elasticsearch déployé à part, et une interface graphique Kibana déployée statiquement sur un serveur Apache.
Une fois que tout à l’air de fonctionner, un petit coup d’oeil aux logs ne fait pas de mal, et là on observe de multiples exceptions du type:
org.elasticsearch.search.SearchParseException: [kibana-int][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{"facets":{"0":{"date_histogram":{"field":"@timestamp","interval":"10m"},"global":true,"facet_filter":{"fquery":{"query":{"filtered":{"query":{"query_string":{"query":"msg:*enregistrer*"}},"filter":{"bool":{"must":[{"range":{"@timestamp":{"from":1400403418362,"to":"now"}}}]}}}}}}}},"size":0}]]
at org.elasticsearch.search.SearchService.parseSource(SearchService.java:595)
at org.elasticsearch.search.SearchService.createContext(SearchService.java:498)
at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:472)
at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:244)
at org.elasticsearch.search.action.SearchServiceTransportAction.sendExecuteQuery(SearchServiceTransportAction.java:202)
at org.elasticsearch.action.search.type.TransportSearchCountAction$AsyncAction.sendExecuteFirstPhase(TransportSearchCountAction.java:70)
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.performFirstPhase(TransportSearchTypeAction.java:216)
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction.performFirstPhase(TransportSearchTypeAction.java:203)
at org.elasticsearch.action.search.type.TransportSearchTypeAction$BaseAsyncAction$2.run(TransportSearchTypeAction.java:186)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.elasticsearch.search.facet.FacetPhaseExecutionException: Facet [0]: (key) field [@timestamp] not found
at org.elasticsearch.search.facet.datehistogram.DateHistogramFacetParser.parse(DateHistogramFacetParser.java:160)
at org.elasticsearch.search.facet.FacetParseElement.parse(FacetParseElement.java:93)
at org.elasticsearch.search.SearchService.parseSource(SearchService.java:583)
... 11 more
Ce qui caractérise l’erreur ici est donc le message « (key) field [@timestamp] not found. » Après un petit contrôle de routine dans la configuration de l’indexer logstash, il est vite apparu que celui-ci ne pouvait pas être coupable: tout ce qu’il insère dans Elasticsearch possède un timestamp.
La solution, je l’ai trouvée ici: En fait lorsqu’on commence à personnaliser Kibana, toute la configuration est stockée dans un indice dédié d’Elasticsearch, vous pouvez vous en rendre compte facilement en vous visualisant vos indices actuels, par exemple en local sur l’url http://localhost:9200/_status?pretty=true et en recherchant « kibana », vous verrez que vous avez un indice dédié. C’est cet indice qui pose problème car il ne contient pas de timestamp. La solution consiste donc à aller dans les préférences de l’interface « Configure Dashboard -> Dashboard Settings -> Index -> Default Index » et de remplacer « _all » par « logstash* », afin de spécifier à l’interface de ne rechercher que parmi les index Logstash.