ELK Magento

By | 21 octobre 2014

elk

Dans cet article je vais vous montrer comment exploiter la pile ELK (elasticsearch, logstash et kibana) pour monitorer les performances de magento sans trop d’effort.

Je ne vais pas m’étendre sur les détails de ces 3 logiciels, mais simplement vous décrire en quelques mots leur principal rôle.

ELK:

    • Elasticsearch: base de données NoSQL, orientée document
    • Logstash: gestionnaire d’évennements et de log (~ ETL)
    • Kibana: interface graphique d’elasticsearch

Si vous n’avez jamais installé elasticsearch, je vous laisse vous référer au site officiel www.elasticsearch.org, ces trois logiciels s’installent très simplement via des paquets debian ou rpm.

Module Magento

La première chose que nous allons devoir faire, est la mise en place d’un observer qui aura en charge d’écouter les events provenant de magento, et d’écrire des logs contenant les temps de réponse, la consommation mémoire, l’action exécutée …

Les 2 événements qui vont nous permettre d’obtenir ces informations sont predispatch et postdispatch. Nous commençons donc par déclarer notre observeur à magento via le fichier de configuration de notre module.

app/code/local/Devart/ElkMagento/etc/config.xml

<?xml version="1.0" encoding="UTF-8"?>
<config>

    <modules>
        <Devart_ElkMagento>
            <version>0.0.1</version>
        </Devart_ElkMagento>
    </modules>

    <global>
        <models>
            <devart_elkmagento>
                <class>Devart_ElkMagento_Model</class>
            </devart_elkmagento>

        </models>
        <events>
            <controller_action_predispatch>
                <observers>
                    <devart_elkmagento>
                        <class>devart_elkmagento/observer</class>
                        <method>predispatch</method>
                        <type>singleton</type>
                    </devart_elkmagento>
                </observers>
            </controller_action_predispatch>
            <controller_action_postdispatch>
                <observers>
                    <devart_elkmagento>
                        <class>devart_elkmagento/observer</class>
                        <method>postdispatch</method>
                        <type>singleton</type>
                    </devart_elkmagento>
                </observers>
            </controller_action_postdispatch>
        </events>
    </global>

</config>

Le second et dernier fichier à éditer est notre observer. Une méthode qui va déclencher les compteurs (time + memory) et la seconde qui va écrire les logs.

<?php

class Devart_ElkMagento_Model_Observer
{
    
    const LOG_FILE = 'elk-magento.log';
   
    protected $startTime;
    protected $startMemory;

    public function preDispatch()
    {
        $this->startTime   = microtime(true);
        $this->startMemory = memory_get_usage(true);
    }

    public function postDispatch(Varien_Event_Observer $observer)
    {
        $event = $observer->getEvent();

        $action = $event->getControllerAction()->getFullActionName();
        $time   = round(microtime(true) - $this->startTime, 2);
        $memory = memory_get_usage(true) - $this->startMemory;

        $message = Mage::getDesign()->getArea() . ' | ' . $action . ' | ' . $time . ' | ' . $memory;

        Mage::log($message, null, self::LOG_FILE);
    }
}

Exemples de log générés:

2014-10-21T16:31:55+00:00 DEBUG (7): adminhtml | adminhtml_dashboard_index | 1.1 | 7864320
2014-10-21T16:31:58+00:00 DEBUG (7): frontend | catalog_category_view | 1 | 9961472

Le module ELK-magento sur github: https://github.com/GuillaumeDievart/ELK-magento

Logstash

Maintenant que nos logs sont correctement générés, nous allons devoir mettre en place la configuration logstash.

Logstash se configure en 3 temps, la source des logs (input), l’extraction des données (filter) et la destination (output).

input

La source correspond à l’emplacement de nos fichiers de logs.

file: plugin d’ input utilisé pour la récupération des données

type: utilisé par elasticsearch comme collection.
path: chemin du fichier de log.

input {
    file {
        type => "magento-perf"
        path => "/opt/hosting/elk-magento/www/var/log/elk-magento.log"
    }
}

filter

La section filter, nous permet d’extraire les valeurs qui nous intéressent des logs. Il existe une panoplie de plugins permettant d’effectuer cette tâche, pour ma part j’utilise principalement grok.

Nous allons extraire les valeurs via une expression régulière, Logstash fournit plus d’une centaine de pattern qui répondront à la plupart de vos besoins, et utilisable avec grok (logstash pattern).

Chaque champ est composé de cette façon: %{pattern:nom_du_champ[:type_elasticsearch]}. Il est important de définir le type correctement, sinon vous ne pourrez pas effectuer de calcul sur les champs numérique.

Pour vous faciliter l’écriture de vos expression grok vous pouvez utiliser ce site https://grokdebug.herokuapp.com.

filter {

    if [type] == "magento-perf" {
        grok {
            match => [ "message", "%{TIMESTAMP_ISO8601:date} %{GREEDYDATA:log_level} \([0-9]+\): %{DATA:area} \| %{DATA:action} \| %{DATA:request_time:float} \| %{INT:memory:int}" ]
        }
    }

}

output

Les données extraites seront chargées dans elasticsearch.

output {
    elasticsearch {
        protocol => "http"
        host => "localhost"
        port => 9200
    }
}

Le fichier de configuration logstash: /etc/logstash/conf.d/elk-magento.conf

kibana

Une fois les log correctement indexés dans elasticsearch, il ne reste plus qu’à les exploiter avec kibana. L’idée est donc de réussir à mettre en avant les informations qui nous intéressent à travers des graphiques et/ou tableau de stats.

Dans l’exemple ci-dessous j’ai créé 2 requêtes  pour séparer les logs front et back (bleu et rouge). J’ai séparé le dashboard en 3 parties principales. La première correspond aux hits effectués avec le détail des actions, la seconde partie concerne les temps de réponse, et la troisième et dernière partie la consommation mémoire.

Ci-dessous un exemple de dashboard fait à partir des logs:
elk-magento

Configuration du dashboard: https://gist.github.com/GuillaumeDievart/987992d397d6dc03764e

 vm du blog post

Si vous souhaitez jouer avec cette configuration, j’ai mis à disposition la box sur vagrantCloud (disponible à partir du 2014-10-24).

$ vagrant init gdievart/elk-magento
$ vagrant up

Les accès:

  • kibana: http://{ip_vm}:9200/_plugin/kibana/#/dashboard/elasticsearch/Magento performance
  • magento: http://{ip_vm}:80
  • magento backoffice: http://{ip_vm}:80/admin (demo2kibana / demo2kibana)

Un conseil avant de terminer cet article, si votre application génère beaucoup de log je vous conseille d’utiliser logstash-forwader en tant qu’agent sur votre serveur de production, car son empreinte mémoire est plus faible que celle de logstash.