10 nov. 2021 15:07:27 Thomas Dumont avatar

Générer des statistiques avec Elastic Search et Kibana

Le plugin ElasticData

Le plugin ElasticData permet de créer des index et d'y ajouter des données horodatées dans un serveur Elastic Search de manière à produire des tableaux de bord Kibana.

Le principe de ce plugin est de manipuler des DataSources et de faire correspondre à chacune d'elles un index dans ElasticSearch.

Le plugin gère deux types d'objets :

  • les datasources : les sources de données
  • les dataobjects : les objets d'un datasource

Les attributs d'une DataSource sont :

  • son identifiant (alphanumérique)
  • son nom
  • le nom de l'index correspondant dans ElasticSearch
  • le type des objets dans l'index

Une DataSource doit fournir la liste de tous ses dataobjects.

Un DataObject doit simplement renvoyer un timestamp.

Voici l'interface du Back Office qui permet de lancer la création des index :

Interface Back Office

Création d'un module ElasticData

Voici un exemple de code pour le dataObject

/**
 * My DataObject
 */
public class MyDataObject implements DataObject
{
    // fields
    private String _strAttribute1;
    ...
    private String _strAttributeN;

    // getters and setters : all those attributes will be created in the index 
    public String getAttribute1()  { ... }
    public void setAttribute1( ... ) { ... } 
    ...

    // implementation of the DataObject interface
    /**
     * {@inheritDoc}
     */
    @Override
    public String getTimestamp( )
    {
        // time in milliseconds
        ...
    }
}

Voici un exemple de DataSource

/**
 * My DataSource
 */
public class MyDataSource extends AbstractDataSource implements DataSource
{
    @Override
    public Collection<DataObject> getDataObjects( )
    {
        MyObjectDAO dao = new MyObjectDAO(); 
        return dao.selectAll();
    }
}

avec son DAO

/**
  * MyObjectDAO 
  */
public class MyObjectDAO 
{
    private static final String SQL_QUERY_SELECTALL = "SELECT ... FROM ... ";

    /**
     * Load the data of all the objects and returns them as a list
     *
     * @return The list which contains the data of all the objects
     */
    public Collection<DataObject> selectAll()
    {
        Collection<DataObject> listObjects= new ArrayList<>();
        DAOUtil daoUtil = new DAOUtil( SQL_QUERY_SELECTALL );
        daoUtil.executeQuery();

        while( daoUtil.next() )
        {
            MyDataObject object= new MyDataObject ();

            object.setAttribute1( daoUtil.getString( 1 ) );
            object.setAttribute2( daoUtil.getString( 2 ) );
            ...

            listObjects.add( object );
        }

        daoUtil.free();
        return listObjects;
    }
}

La DataSource doit être déclarée dans le fichier de context Spring du module pour être trouvée par le plugin ElasticData. Voici un exemple de déclaration :

<!-- My datasource -->
<bean id="elasticdata-mymodule.dataSource" class="fr.paris.lutece.plugins.elasticdata.business.mymodule.MyDataSource" >
    <property name="id" value="MyDataSource" />
    <property name="name" value="My Data Source" />
    <property name="targetIndexName" value="datasource" />
    <property name="dataType" value="mydataobject" />
</bean>

Vous pouvez également différer l'indexation de vos documents en sauvegardant les identifiants des ressources à traiter. Le daemon incrémental se chargera de les indexer.

/**
     * {@inheritDoc}
     */
    @Override
    public void addedResource( ResourceEvent event )
    {
        new Thread( ( ) -> {
            DataSourceIncrementalService.addTask( _formsDataSource.getId( ), event.getIdResource( ), IndexerAction.TASK_CREATE);
        } ).start( );
    }

Le plugin Kibana

Voici un exemple de tableau de bord présenté par le plugin Kibana :

Plugin Kibana