Application de surveillance avec Spring Boot Actuator

View more Tutorials:

1- Qu'est-ce que Spring Boot Actuator ?

Spring Boot Actuator ét un sous projet (sub-project) du projet  Spring Boot. Il est créé pour collecter, superviser les informations de l'application. Vous pouvez l'emblé dans votre application et utiliser ces fonctionnalités. Afin de superviser cette application, vous devez accéder aux  endpoint (des points finaux) qui ont étaient disponibles dans  Spring Boot Actuator. Stimultanément, vous pouvez également créer vos propres  endpoint si vous voulez.
Dans cette publication, je vais vous donner des instructions de l'utilisation de  Spring Boot Actuator dans l'application  Spring Boot version  2.0.0.M7 ou plus récente.
Il est à noter que  Spring Boot Actuator a beaucoup de changements dans la version 2.x so en comparaison avec celle de 1.x, donc, assurez-vous que vous allez travailler avec  Spring Boot version  2.0.0.M7 ou plus récente.

2- Créer le projet Spring Boot

Spring Boot Actuator est un sous projet (un produit complet) dans l'éco-système  Spring, vet vous pouvez l'embler dans votre projet  Spring Boot disponible. Tous les choses que vous devez faire est de déclarer des biblothèques  Spring Boot Actuator et quelques informations de la configuration dans le fichier  application.properties. Dans cette publication,  je vais créerun projet  Spring Boot et embler  Spring Boot Actuator à l'intérieur. Notre but est d'apprendre des fonctionnalités fournies par  Spring Boot Actuator.
OK!, Sur  Eclipse créez un projet  Spring Boot.
Ici, nous allons sélectionner la version  2.0.0.M7 ou celle est plus récente.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.o7planning</groupId>
    <artifactId>SpringBootActuator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringBootActuator</name>
    <description>Spring Boot +Actuator</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

3- Configurer Spring Boot Actuator

Add the configuration to the application.properties file:
application.properties
server.port=8080
management.server.port=8090
management.endpoints.web.exposure.include=*
management.endpoint.shutdown.enabled=true
  • server.port=8080
Votre application va exécuter sur le port 8080 (port 8080), ce port est celui par défaut et vous pouvez le changer si vous voulez.
  • management.server.port=8090
Les  endpoint relatifs à la supervision  Spring Boot Actuator sera mis à jour par un port à part du port 8080 mentionné ci-dessus. Le but de ce fait est d'éviter des erreurs et améliorer la sécurité. Pourtant ceci n'est pas obligatoire.
  • management.endpoints.web.exposure.include=*
Par défaut, tous les Endpoint de Spring Boot Actuator ne sont pas activés. Utilisez * pour activer tous ces Endpoint.
  • management.endpoint.shutdown.enabled=true
shutdown est un  Endpoint spécial de  Spring Boot Actuator. Il vous permet d'éteindre (shutdown) des applications de façon sûre sans l'utilisation des commandes telles que  "Kill process", "end task" du système d'exploitation.

4- Les Endpoint de Spring Boot Actuator

MainController.java
package org.o7planning.sbactuator.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class MainController {

    @ResponseBody
    @RequestMapping(path = "/")
    public String home(HttpServletRequest request) {

        String contextPath = request.getContextPath();
        String host = request.getServerName();

        // Spring Boot >= 2.0.0.M7
        String endpointBasePath = "/actuator";
    
        StringBuilder sb = new StringBuilder();
        
        sb.append("<h2>Sprig Boot Actuator</h2>");
        sb.append("<ul>");

        // http://localhost:8090/actuator
        String url = "http://" + host + ":8090" + contextPath + endpointBasePath;

        sb.append("<li><a href='" + url + "'>" + url + "</a></li>");

        sb.append("</ul>");
        
        return sb.toString();
    }

}
Exécutez votre application et accédez au lien ci-dessous :
Note : Les données fournies par les  endpoint de  Spring Boot Actuator supporte le format  JSON, donc, pour une meilleure visibilité, vous pouvez reformater (reformat) ces données. Par exemple, le site web ci-dessous fournit un outil en ligne pour mettre en forme le JSON :

/actuator

/actuator est un  endpoint (un point final), il fournit une liste d'autres  endpoint de  Spring Boot Actuator que vous pouvez accéder.
/actuator
{
  "_links": {
    "self": {
      "href": "http://localhost:8090/actuator",
      "templated": false
    },
    "auditevents": {
      "href": "http://localhost:8090/actuator/auditevents",
      "templated": false
    },
    "beans": {
      "href": "http://localhost:8090/actuator/beans",
      "templated": false
    },
    "health": {
      "href": "http://localhost:8090/actuator/health",
      "templated": false
    },
    "conditions": {
      "href": "http://localhost:8090/actuator/conditions",
      "templated": false
    },
    "shutdown": {
      "href": "http://localhost:8090/actuator/shutdown",
      "templated": false
    },
    "configprops": {
      "href": "http://localhost:8090/actuator/configprops",
      "templated": false
    },
    "env": {
      "href": "http://localhost:8090/actuator/env",
      "templated": false
    },
    "env-toMatch": {
      "href": "http://localhost:8090/actuator/env/{toMatch}",
      "templated": true
    },
    "info": {
      "href": "http://localhost:8090/actuator/info",
      "templated": false
    },
    "loggers": {
      "href": "http://localhost:8090/actuator/loggers",
      "templated": false
    },
    "loggers-name": {
      "href": "http://localhost:8090/actuator/loggers/{name}",
      "templated": true
    },
    "heapdump": {
      "href": "http://localhost:8090/actuator/heapdump",
      "templated": false
    },
    "threaddump": {
      "href": "http://localhost:8090/actuator/threaddump",
      "templated": false
    },
    "metrics-requiredMetricName": {
      "href": "http://localhost:8090/actuator/metrics/{requiredMetricName}",
      "templated": true
    },
    "metrics": {
      "href": "http://localhost:8090/actuator/metrics",
      "templated": false
    },
    "scheduledtasks": {
      "href": "http://localhost:8090/actuator/scheduledtasks",
      "templated": false
    },
    "trace": {
      "href": "http://localhost:8090/actuator/trace",
      "templated": false
    },
    "mappings": {
      "href": "http://localhost:8090/actuator/mappings",
      "templated": false
    }
  }
}

/actuator/health

/actuator/health vous donne les informations sur la santé de l'application. Le statut vivant (UP) ou mort (DOWN), et d'autres informations sur le disque dur telles que la capacité du disque sur, celle usée et celle disponible.
/actuator/health
{
  "status": "UP",
  "details": {
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 75812040704,
        "free": 8067600384,
        "threshold": 10485760
      }
    }
  }
}

actuator/metrics

Ce  Endpoint vous fournit la liste des  metric (Mesure standard)
actuator/metrics
{
  "names": [
    "jvm.memory.committed",
    "jvm.buffer.memory.used",
    "jvm.buffer.count",
    "logback.events",
    "process.uptime",
    "jvm.memory.max",
    "jvm.memory.used",
    "jvm.buffer.total.capacity",
    "system.cpu.count",
    "process.start.time"
  ]
}
Et vous pouvez également voir les informations d'un certain  metric précis.

actuator/metrics/{requiredMetricName}

/actuator/metrics/jvm.memory.used
{
  "name": "jvm.memory.used",
  "measurements": [
    {
      "statistic": "Value",
      "value": 109937744
    }
  ],
  "availableTags": [
    {
      "tag": "area",
      "values": [
        "heap",
        "nonheap",
        "nonheap",
        "heap",
        "nonheap",
        "nonheap",
        "heap"
      ]
    },
    {
      "tag": "id",
      "values": [
        "G1 Old Gen",
        "Compressed Class Space",
        "CodeHeap 'non-nmethods'",
        "G1 Survivor Space",
        "Metaspace",
        "CodeHeap 'non-profiled nmethods'",
        "G1 Eden Space"
      ]
    }
  ]
}

/actuator/beans

/actuator/beans vous fournit la liste de  Spring BEAN qui est géré dans votre application.
/actuator/beans
{
  "contextId": "application:8080",
  "beans": {
    "endpointCachingOperationInvokerAdvisor": {
      "aliases": [],
      "scope": "singleton",
      "type": "org.springframework.boot.actuate.endpoint.cache.CachingOperationInvokerAdvisor",
      "resource": "class path resource [org/springframework/boot/actuate/autoconfigure/endpoint/EndpointAutoConfiguration.class]",
      "dependencies": [
        "environment"
      ]
    },
    "defaultServletHandlerMapping": {
      "aliases": [],
      "scope": "singleton",
      "type": "org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport$EmptyHandlerMapping",
      "resource": "class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]",
      "dependencies": []
    }
    
      ....
  },
  "parent": null
}

/actuator/env

/actuator/env vous donne tous les informations sur l'environnement où exécute votre application, par exemple : le nom du système d'exploitation, classpath, la version de  Java,...
/actuator/env
{
  "activeProfiles": [],
  "propertySources": [
    {
      "name": "server.ports",
      "properties": {
        "local.management.port": {
          "value": 8090
        },
        "local.server.port": {
          "value": 8080
        }
      }
    },
    {
      "name": "servletContextInitParams",
      "properties": {}
    },
    {
      "name": "systemProperties",
      "properties": {
        "sun.desktop": {
          "value": "windows"
        },
        "awt.toolkit": {
          "value": "sun.awt.windows.WToolkit"
        },
        "java.specification.version": {
          "value": "9"
        },
        "file.encoding.pkg": {
          "value": "sun.io"
        },
        "sun.cpu.isalist": {
          "value": "amd64"
        },
        "sun.jnu.encoding": {
          "value": "Cp1252"
        },
        "java.class.path": {
          "value": "C:\\Users\\tran\\.m2\\repository\\org\\springframework\\spring-jcl\\5.0.2.RELEASE\\spring-jcl-5.0.2.RELEASE.jar;...."
        },
        "com.sun.management.jmxremote.authenticate": {
          "value": "false"
        },
        "java.vm.vendor": {
          "value": "Oracle Corporation"
        },
        "sun.arch.data.model": {
          "value": "64"
        },
        "user.variant": {
          "value": ""
        },
        "java.vendor.url": {
          "value": "http://java.oracle.com/"
        },
        "catalina.useNaming": {
          "value": "false"
        },
        "user.timezone": {
          "value": "Asia/Bangkok"
        },
        "os.name": {
          "value": "Windows 8.1"
        },
        "java.vm.specification.version": {
          "value": "9"
        },
        "sun.java.launcher": {
          "value": "SUN_STANDARD"
        },
        "user.country": {
          "value": "US"
        },
        "sun.boot.library.path": {
          "value": "C:\\DevPrograms\\Java\\jre-9.0.1\\bin"
        },
        "com.sun.management.jmxremote.ssl": {
          "value": "false"
        },
        "spring.application.admin.enabled": {
          "value": "true"
        },
        "sun.java.command": {
          "value": "org.o7planning.sbactuator.SpringBootActuatorApplication"
        },
        "com.sun.management.jmxremote": {
          "value": ""
        },
        "jdk.debug": {
          "value": "release"
        },
        "sun.cpu.endian": {
          "value": "little"
        },
        "user.home": {
          "value": "C:\\Users\\tran"
        },
        "user.language": {
          "value": "en"
        },
        "java.specification.vendor": {
          "value": "Oracle Corporation"
        },
        "java.home": {
          "value": "C:\\DevPrograms\\Java\\jre-9.0.1"
        },
        "file.separator": {
          "value": "\\"
        },
        "java.vm.compressedOopsMode": {
          "value": "Zero based"
        },
        "line.separator": {
          "value": "\r\n"
        },
        "java.specification.name": {
          "value": "Java Platform API Specification"
        },
        "java.vm.specification.vendor": {
          "value": "Oracle Corporation"
        },
        "java.awt.graphicsenv": {
          "value": "sun.awt.Win32GraphicsEnvironment"
        },
        "java.awt.headless": {
          "value": "true"
        },
        "user.script": {
          "value": ""
        },
        "sun.management.compiler": {
          "value": "HotSpot 64-Bit Tiered Compilers"
        },
        "java.runtime.version": {
          "value": "9.0.1+11"
        },
        "user.name": {
          "value": "tran"
        },
        "path.separator": {
          "value": ";"
        },
        "os.version": {
          "value": "6.3"
        },
        "java.runtime.name": {
          "value": "Java(TM) SE Runtime Environment"
        },
        "file.encoding": {
          "value": "UTF-8"
        },
        "spring.beaninfo.ignore": {
          "value": "true"
        },
        "java.vm.name": {
          "value": "Java HotSpot(TM) 64-Bit Server VM"
        },
        "java.vendor.url.bug": {
          "value": "http://bugreport.java.com/bugreport/"
        },
        "java.io.tmpdir": {
          "value": "C:\\Users\\tran\\AppData\\Local\\Temp\\"
        },
        "catalina.home": {
          "value": "C:\\Users\\tran\\AppData\\Local\\Temp\\tomcat.16949807720416048110.8080"
        },
        "java.version": {
          "value": "9.0.1"
        },
        "com.sun.management.jmxremote.port": {
          "value": "54408"
        },
        "user.dir": {
          "value": "E:\\ECLIPSE_TUTORIAL\\JAVA_SPRING_BOOT\\SpringBootActuator"
        },
        "os.arch": {
          "value": "amd64"
        },
        "java.vm.specification.name": {
          "value": "Java Virtual Machine Specification"
        },
        "PID": {
          "value": "5372"
        },
        "java.awt.printerjob": {
          "value": "sun.awt.windows.WPrinterJob"
        },
        "sun.os.patch.level": {
          "value": ""
        },
        "catalina.base": {
          "value": "C:\\Users\\tran\\AppData\\Local\\Temp\\tomcat.8934969984130443549.8090"
        },
        "java.library.path": {
          "value": "C:\\DevPrograms\\Java\\jre-9.0.1\\bin;...;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files\\EmEditor;."
        },
        "java.vm.info": {
          "value": "mixed mode"
        },
        "java.vendor": {
          "value": "Oracle Corporation"
        },
        "java.vm.version": {
          "value": "9.0.1+11"
        },
        "java.rmi.server.hostname": {
          "value": "localhost"
        },
        "java.rmi.server.randomIDs": {
          "value": "true"
        },
        "sun.io.unicode.encoding": {
          "value": "UnicodeLittle"
        },
        "java.class.version": {
          "value": "53.0"
        }
      }
    },
    {
      "name": "systemEnvironment",
      "properties": {
        "USERDOMAIN_ROAMINGPROFILE": {
          "value": "tran-pc",
          "origin": "System Environment Property \"USERDOMAIN_ROAMINGPROFILE\""
        },
        "LOCALAPPDATA": {
          "value": "C:\\Users\\tran\\AppData\\Local",
          "origin": "System Environment Property \"LOCALAPPDATA\""
        },
        "PROCESSOR_LEVEL": {
          "value": "6",
          "origin": "System Environment Property \"PROCESSOR_LEVEL\""
        },
        "FP_NO_HOST_CHECK": {
          "value": "NO",
          "origin": "System Environment Property \"FP_NO_HOST_CHECK\""
        },
        "USERDOMAIN": {
          "value": "tran-pc",
          "origin": "System Environment Property \"USERDOMAIN\""
        },
        "LOGONSERVER": {
          "value": "\\\\TRAN-PC",
          "origin": "System Environment Property \"LOGONSERVER\""
        },
        "SESSIONNAME": {
          "value": "Console",
          "origin": "System Environment Property \"SESSIONNAME\""
        },
        "ALLUSERSPROFILE": {
          "value": "C:\\ProgramData",
          "origin": "System Environment Property \"ALLUSERSPROFILE\""
        },
        "PROCESSOR_ARCHITECTURE": {
          "value": "AMD64",
          "origin": "System Environment Property \"PROCESSOR_ARCHITECTURE\""
        },
        "PSModulePath": {
          "value": "C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\",
          "origin": "System Environment Property \"PSModulePath\""
        },
        "SystemDrive": {
          "value": "C:",
          "origin": "System Environment Property \"SystemDrive\""
        },
        "APPDATA": {
          "value": "C:\\Users\\tran\\AppData\\Roaming",
          "origin": "System Environment Property \"APPDATA\""
        },
        "USERNAME": {
          "value": "tran",
          "origin": "System Environment Property \"USERNAME\""
        },
        "ProgramFiles(x86)": {
          "value": "C:\\Program Files (x86)",
          "origin": "System Environment Property \"ProgramFiles(x86)\""
        },
        "CommonProgramFiles": {
          "value": "C:\\Program Files\\Common Files",
          "origin": "System Environment Property \"CommonProgramFiles\""
        },
        "Path": {
          "value": "D:\\DEV_PROGRAMS\\Oracle12c\\product\\12.2.0\\dbhome_1\\bin;...;C:\\Program Files\\EmEditor",
          "origin": "System Environment Property \"Path\""
        },
        "PATHEXT": {
          "value": ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC",
          "origin": "System Environment Property \"PATHEXT\""
        },
        "OS": {
          "value": "Windows_NT",
          "origin": "System Environment Property \"OS\""
        },
        "COMPUTERNAME": {
          "value": "TRAN-PC",
          "origin": "System Environment Property \"COMPUTERNAME\""
        },
        "PROCESSOR_REVISION": {
          "value": "3c03",
          "origin": "System Environment Property \"PROCESSOR_REVISION\""
        },
        "CommonProgramW6432": {
          "value": "C:\\Program Files\\Common Files",
          "origin": "System Environment Property \"CommonProgramW6432\""
        },
        "ComSpec": {
          "value": "C:\\Windows\\system32\\cmd.exe",
          "origin": "System Environment Property \"ComSpec\""
        },
        "ProgramData": {
          "value": "C:\\ProgramData",
          "origin": "System Environment Property \"ProgramData\""
        },
        "ProgramW6432": {
          "value": "C:\\Program Files",
          "origin": "System Environment Property \"ProgramW6432\""
        },
        "HOMEPATH": {
          "value": "\\Users\\tran",
          "origin": "System Environment Property \"HOMEPATH\""
        },
        "SystemRoot": {
          "value": "C:\\Windows",
          "origin": "System Environment Property \"SystemRoot\""
        },
        "TEMP": {
          "value": "C:\\Users\\tran\\AppData\\Local\\Temp",
          "origin": "System Environment Property \"TEMP\""
        },
        "HOMEDRIVE": {
          "value": "C:",
          "origin": "System Environment Property \"HOMEDRIVE\""
        },
        "PROCESSOR_IDENTIFIER": {
          "value": "Intel64 Family 6 Model 60 Stepping 3, GenuineIntel",
          "origin": "System Environment Property \"PROCESSOR_IDENTIFIER\""
        },
        "USERPROFILE": {
          "value": "C:\\Users\\tran",
          "origin": "System Environment Property \"USERPROFILE\""
        },
        "TMP": {
          "value": "C:\\Users\\tran\\AppData\\Local\\Temp",
          "origin": "System Environment Property \"TMP\""
        },
        "CommonProgramFiles(x86)": {
          "value": "C:\\Program Files (x86)\\Common Files",
          "origin": "System Environment Property \"CommonProgramFiles(x86)\""
        },
        "ProgramFiles": {
          "value": "C:\\Program Files",
          "origin": "System Environment Property \"ProgramFiles\""
        },
        "PUBLIC": {
          "value": "C:\\Users\\Public",
          "origin": "System Environment Property \"PUBLIC\""
        },
        "NUMBER_OF_PROCESSORS": {
          "value": "8",
          "origin": "System Environment Property \"NUMBER_OF_PROCESSORS\""
        },
        "windir": {
          "value": "C:\\Windows",
          "origin": "System Environment Property \"windir\""
        }
      }
    },
    {
      "name": "applicationConfig: [classpath:/application.properties]",
      "properties": {
        "server.port": {
          "value": "8080",
          "origin": "class path resource [application.properties]:1:13"
        },
        "management.server.port": {
          "value": "8090",
          "origin": "class path resource [application.properties]:2:24"
        },
        "management.endpoints.web.expose": {
          "value": "*",
          "origin": "class path resource [application.properties]:3:33"
        },
        "management.endpoint.shutdown.enabled": {
          "value": "true",
          "origin": "class path resource [application.properties]:4:38"
        }
      }
    }
  ]
}

/actuator/info

/actuator/info vous donne vos informations personnalisées. Par défaut, elle est une information vide donc vous devez créer un  Spring BEAN pour recevoir ces informations.
BuildInfoContributor.java
package org.o7planning.sbactuator.monitoring;

import java.util.HashMap;
import java.util.Map;

import org.springframework.boot.actuate.info.Info;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.stereotype.Component;

 

@Component
public class BuildInfoContributor implements InfoContributor {
    
    @Override
    public void contribute(Info.Builder builder) {
        Map<String,String> data= new HashMap<String,String>();
        data.put("build.version", "2.0.0.M7");
        builder.withDetail("buildInfo", data);
    }
    
}

5- /actuator/shutdown

Ceci est un  endpoint qui vous aide d'éteindre (shutdown) l'application. Vous devez l'appeler par la méthode  POST, si vous êtes réussi, vous obtiendrez un message  "Shutting down, bye...".
ShutdownController.java
package org.o7planning.sbactuator.controller;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

@Controller
public class ShutdownController {

    @ResponseBody
    @RequestMapping(path = "/shutdown")
    public String callActuatorShutdown() {

        // Actuator Shutdown Endpoint:
        String url = "http://localhost:8090/actuator/shutdown";

        // Http Headers
        HttpHeaders headers = new HttpHeaders();
        headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
        headers.setContentType(MediaType.APPLICATION_JSON);

        RestTemplate restTemplate = new RestTemplate();

        // Data attached to the request.
        HttpEntity<String> requestBody = new HttpEntity<>("", headers);

        // Send request with POST method.
        String e = restTemplate.postForObject(url, requestBody, String.class);

        return "Result: " + e;
    }

}

6- Créer des Endpoint personnalisés

Spring Boot Actuator est un produit complet, il vous fournit des  endpoint pour superviser l'application. Pourtant, en certains cas où vous voulez créer vos propres  endpoint, vous devez suivre les instructions dans le lien ci-dessous :
  • TODO Link!

View more Tutorials: