Modifier les paramètres de sonde
Vous pouvez modifier ou désactiver les paramètres de sonde par défaut, ou activer une sonde personnalisée pour surveiller des classes supplémentaires.
Les tâches de test suivantes sont traitées dans cette rubrique :
Modifier ou désactiver les paramètres de sonde par défaut
Vous pouvez modifier ou désactiver les paramètres de sonde par défaut à l'aide du fichier ProbeConfig.acml
.
Après que vous avez provisionné un agent Java APM, le fichier ProbeConfig.acml
est disponible sous le répertoire oracle-apm-agent/config
. Pour plus d'informations sur l'accès au fichier ProbeConfig.acml
, voir Provisionner l'agent Java APM.
Le fichier ProbeConfig.acml
vous permet d'effectuer les opérations suivantes :
- Activez ou désactivez des sondes particulières.
- Désactiver la surveillance de modèles spécifiques de traces/espaces en fonction d'informations telles que l'URL, l'extension de fichier, etc.
- Activer la capture de balises/dimensions supplémentaires. Par exemple, capturer des en-têtes et des paramètres spécifiques pour la sonde SERVLET.
- Manipulez le nom de l'étendue. Par exemple, la manipulation de l'URL pour les sondes SERVLET ou HTTP_CLIENT.
- Saisir les énoncés d'interrogation SQL DB d'une longueur supérieure à 1 000 caractères sous forme de journal d'intervalle.
Pour activer ou désactiver la journalisation de l'ensemble des énoncés d'interrogation SQL dans le journal d'intervalle JDBC, utilisez le paramètre
enable_complete_sql_span_log_jdbc
. Cette fonction est utile lorsque la requête SQL longue est tronquée à 1 000 caractères. Par exemple, utilisez :enable_complete_sql_span_log_jdbc: true
pour l'activer. - Saisissez le nom d'utilisateur connecté.
Les noms d'utilisateur hachés sont capturés pour les sessions authentifiées dans le but de permettre de signaler le nombre d'utilisateurs uniques, sans exposer d'informations personnelles identifiables (PII). Cependant, il peut être nécessaire de signaler le nom d'utilisateur au format texte brut. Dans ce cas, allez à la section générale et définissez
track_plain_username: true
. - Saisir les données utiles.
Les données utiles incluent le contenu de la demande HTTP et de la réponse.
Vous pouvez suivre le flux complet des demandes d'application et envoyer les données collectées à l'explorateur de trace pour analyse en activant les données utiles.
La prise en charge de la capture des données utiles inclut Servlet, JAX-RS Server, OSB Proxy Service et OSB Business Service.
À partir de la version 1.16 de l'agent Java APM, les clients HTTP Apache (4.x et 5.x), le client HTTP JDK 11+, le client HTTP de la trousse SDK OCI (2.x et 3.x), le client Web Spring 5.x et les clients 2.x et 3.x OkHttp sont également pris en charge.
Activer les données utiles : Pour activer les données utiles de demande et de réponse HTTP, définissez les paramètres :
capture_request_payload
etcapture_response_payload
dans le fichierProbeConfig.acml
.- Pour capturer un sous-ensemble des données utiles, les expressions xpath/jsonpath/regex peuvent être appliquées en fonction du nom de l'opération.
- Après l'avoir activée, les données utiles saisies sont disponibles en tant que dimensions :
RequestPayload
etResponsePayload
respectivement. La longueur maximale par défaut est de 1000 caractères. - Plusieurs dimensions des mêmes données utiles peuvent être saisies en spécifiant tag_name avec l'expression.
- Modifiez la modélisation des appels asynchrones HttpClient.
À partir de la version 1.16 de l'agent Java APM, un seul intervalle représente la demande sortante, le temps d'attente et le rappel.
Pour conserver le comportement précédent des versions d'agent antérieures (un intervalle pour l'appel sortant et un second pour le rappel), modifiez le paramètrehttpclient_async_one_span
sous la section HTTP_CLIENT du fichierProbeConfig.acml
et réglez-le àfalse
.#Enables capturing async client invocations as a single span. No separate callback spans will be reported httpclient_async_one_span: false
Le comportement des paramètres de sonde par défaut peut être mis à jour à l'aide du fichier ProbeConfig.acml
de l'agent Java APM.
Pour modifier les paramètres de sonde par défaut, suivez les instructions disponibles dans le fichier ProbeConfig.acml
.
Les modifications au fichier ProbeConfig.acml
peuvent être effectuées lorsque le serveur d'applications est en cours d'exécution et qu'il n'est pas nécessaire de redémarrer ce dernier pour que les modifications entrent en vigueur.
À partir de la version 1.12 de l'agent Java APM, la convention d'attribution de nom pour les sondes Servlet, HttpClient et OSB est améliorée et simplifiée. Par conséquent, la règle replace_all_patterns
pour la suppression de l'ID hexadécimal et des nombres n'est plus incluse par défaut dans le fichier ProbeConfig.acml
. Cela s'applique aux sections SERVLET, HTTP_CLIENT et OSB.
# Hex ID and numbers
-
pattern: "([a-fA-F\._\:-]*[0-9]+){2,}[a-fA-F_\:-]*([/\.])?"
replacement: "*$2"
Configurer une sonde personnalisée
Vous pouvez configurer une sonde personnalisée pour surveiller des classes supplémentaires et obtenir des détails propres à l'application.
La sonde personnalisée est utile si le jeu intégré de sondes qui est disponible dans le fichier ProbeConfig.acml
ne répond pas aux exigences de surveillance. Par exemple, si vous souhaitez surveiller une unité d'exécution d'arrière-plan qui n'est pas surveillée à l'aide des sondes par défaut, vous pouvez configurer une sonde personnalisée pour la surveiller.
Pour configurer une sonde personnalisée, procédez comme suit :
- Configurez un fichier
DirectivesConfig.acml
pour spécifier les élémentsclasses
,methods
ouannotations
à surveiller. Pour plus d'informations, voir Configuration de fichiers DirectivesConfig.acml. - Ajoutez le fichier
DirectivesConfig.acml
au répertoireoracle-apm-agent/config
.Il est maintenant obsolète de spécifier le fichierSupprimez l'argument ci-dessus du script de démarrage de votre application si vous avez précédemment spécifié le fichierDirectivesConfig.acml
à l'aide des éléments suivants du script de démarrage de votre serveur d'applications :-Dcom.oracle.apm.agent.customDirectivesFile=<Path_to_DirectivesConfig.acml_file>
DirectivesConfig.acml
de cette manière. - Redémarrez le serveur d'applications si un nouveau fichier
DirectivesConfig.acml
est spécifié.Les modifications apportées au fichier
DirectivesConfig.acml
prennent effet après le redémarrage du serveur d'applications.Le redémarrage du serveur d'applications est requis lors de la spécification d'un nouveau fichier
DirectivesConfig.acml
ou de la suppression du fichier.Le redémarrage du serveur d'applications n'est pas nécessaire si vous effectuez l'une des opérations suivantes :- Modifiez
span_name
. - Ajoutez, modifiez ou supprimez
tags
,logs
ou Variables avancées dans un fichierDirectivesConfig.acml
existant déjà en vigueur.
- Modifiez
Configuration des fichiers DirectivesConfig.acml
Pour configurer le fichier DirectivesConfig.acml
, vérifiez les éléments suivants :
Paramètres DirectivesConfig.acml
Voici des informations sur les paramètres que vous pouvez spécifier dans le fichier DirectivesConfig.acml
.
Au moins un des paramètres DOIT suivants est spécifié dans le fichier DirectivesConfig.acml
:
class_name
class_name_regex
class_annotation
method_annotation
class_annotation_regex
method_annotation_regex
Paramètre | Description | Exemple |
---|---|---|
label |
Étiquette unique pour la directive. Il s'agit d'un paramètre obligatoire. |
|
class_name |
Nom de la classe à surveiller. Vous devez indiquer le nom complet de la classe, y compris le paquetage. |
|
class_name_regex |
Modèle d'expression rationnelle (regex) permettant de surveiller toute classe qui y correspond. Pour le modèle d'expression rationnelle, au lieu d'utiliser "." pour le paquetage, utilisez "/". Par exemple, pour surveiller une classe nommée Si |
|
method_name |
Nom de la méthode à surveiller. Cela n'inclut pas les paramètres de méthode. Si |
|
method_name_regex |
Modèle d'expression rationnelle permettant de surveiller toute méthode qui y correspond. Si Si |
|
class_annotation |
Nom complet de la classe de l'annotation à surveiller. Tout élément |
|
method_annotation |
Nom complet de la classe de l'annotation à surveiller. Tout élément |
|
class_annotation_regex |
Modèle d'expression rationnelle permettant de surveiller toute annotation de classe qui y correspond. Pour le modèle d'expression rationnelle, au lieu d'utiliser "." pour le paquetage, utilisez "/". De plus, la valeur doit commencer par "L" et se terminer par ";". Par exemple, pour surveiller une annotation nommée Si |
|
method_annotation_regex |
Modèle d'expression rationnelle permettant de surveiller toute annotation de méthode qui y correspond. Pour le modèle d'expression rationnelle, au lieu d'utiliser "." pour le paquetage, utilisez "/". De plus, la valeur doit commencer par "L" et se terminer par ";". Par exemple, pour surveiller une annotation nommée Si |
|
include_sub_classes |
Indiquez si les sous-classes de la classe cible doivent être surveillées. Par défaut, cette option est réglée à |
|
span_name |
Nom de l'intervalle créé lors de la surveillance. Si aucune valeur n'est indiquée pour Notez que vous pouvez spécifier un nom pour l'intervalle, comme dans l'exemple Lorsque vous spécifiez le paramètre |
|
tags |
Les marqueurs (noms et valeurs) à inclure dans l'intervalle. Comme dans le cas du paramètre Notez que les marqueurs ( Pour les valeurs de marqueur, un type facultatif peut être spécifié. Vous pouvez spécifier la valeur du marqueur comme étant de type String, Boolean, Integer, Long, Float ou Double à l'aide de la syntaxe et du mot clé appropriés (comme illustré dans l'exemple). Le type de valeur de marqueur par défaut est Chaîne. Elle sera utilisée si aucun type ou type incompatible n'est spécifié. Si un type incompatible est spécifié pour une valeur de balise, le type rétablit la valeur String par défaut et un message de journal indique l'incompatibilité. La valeur de dimension d'intervalle peut être confirmée au moyen d'interrogations avec des agrégations qui tirent parti de valeurs numériques (le cas échéant) dans l'explorateur de trace. |
|
logs <! [CDATA[ ]]> |
Journaux (noms et valeurs) à inclure dans l'intervalle. Comme dans le cas des paramètres Notez que les |
|
span_name, marqueurs et variables de journaux
Lors de la spécification des paramètres span_name
, tags
et logs
, les variables suivantes permettent d'obtenir des informations supplémentaires :
class_name
: Nom de la classe surveillée, y compris le paquetage.short_class_name
: Nom de la classe surveillée, à l'exclusion du paquetage.method_name
: Nom de la méthode surveillée.method_descriptor
: Format de descripteur de la signature de la méthode surveillée.param#
: Paramètres de la méthode surveillée, oùparam1
indique le premier paramètre,param2
le deuxième paramètre, etc.this
: Objet surveillé. Notez que si la méthode (method
) surveillée eststatic
, la variablethis
ne sera pas disponible.return
: Valeur retournée pour la méthode surveillée.Note
La variablereturn
ne peut être utilisée que pour le paramètretags
et non pourspan_name
.
Exemple de fichier DirectivesConfig.acml
Voici un exemple du fichier DirectivesConfig.acml
:
Test:
class_name: "com.oracle.apm.samples.servlet.OutboundTestServlet"
method_name: "performHttpURLConnectionCall"
include_sub_classes: true
span_name: "${short_class_name}.${method_name}"
tags:
targetURL: "${param2}"
port: "${param1}"
Selon l'exemple ci-dessus :
com.oracle.apm.samples.servlet.OutboundTestServlet.performHttpURLConnectionCall
sera surveillé, ainsi que ses sous-classes.- Le nom de l'intervalle affiché dans l'explorateur de trace sera
OutboundTestServlet.performHttpURLConnectionCall
. - Les marqueurs
targetURL
etport
seront ajoutés à l'intervalle et utiliseront les valeurs des premier et deuxième paramètres de la méthodeperformHttpURLConnectionCall
.
Les captures d'écran suivantes sont un exemple de la page de sonde personnalisée :
Variables avancées pour la probabilité personnalisée
Lorsque vous utilisez une sonde personnalisée, vous pouvez configurer la syntaxe de commande avancée pour construire dynamiquement des variables à l'aide de la méthode de chaînage et de la manipulation de chaîne au moyen d'expressions rationnelles. Ces variables avancées peuvent être référencées dans les sections span_name
, tags
et logs
, comme les autres variables mentionnées ci-dessus.
- Voyez comment configurer une sonde personnalisée. Voir Configurer une sonde personnalisée.
- Examinez la syntaxe de la chaîne de commande. Voir Syntaxe de la chaîne de commande.
- Consultez les exemples. Voir Exemples de variables avancées.
Syntaxe de la chaîne de commande
Le symbole de tuyau "|" est utilisé pour signifier la tuyauterie de l'objet de départ vers la première commande de chaîne et l'objet de sortie de tuyauterie d'une commande de chaîne à la suivante.
Durée d'exécution
Les chaînes de commandes sont exécutées avant ou après l'appel de la méthode surveillée de la sonde personnalisée. Cette valeur est définie par la durée dexécution, qui apparaît avant larchitecture SOI.
<execution time> ::= [before || after]
Toutes les chaînes de commande ne sont pas compatibles avec les deux temps d'exécution : Lorsque return
est utilisé en tant qu'interface de ligne de commande ou en tant que paramètre dans une commande de méthode, le temps d'exécution suivant doit être utilisé. En effet, l'objet de retour n'est disponible qu'après l'appel de la méthode surveillée. Lorsque d'autres variables sont utilisées comme SOI ou paramètres dans des commandes de méthode, les temps d'exécution dépendent des chaînes référencées.
Par exemple, définissez chain1
et chain2
, où chain2
utilise chain1
comme SOI ou paramètre pour une commande de méthode. Notez que chain1
doit être défini avant chain2
si les deux chaînes utilisent la même durée d'exécution. Sinon, chain1
doit avoir un temps d'exécution avant et chain2
doit avoir un temps d'exécution après.
Pour plus d'informations sur l'utilisation des interfaces SOI et des commandes de méthode, reportez-vous à la section ci-dessous Démarrage de l'identificateur d'objet.
Identificateur de l'objet de départ
Un identificateur d'objet de départ (SOI) peut être un objet associé à :
-
Mots-clés prédéfinis :
this
,return
etparam#
. -
Sortie d'une chaîne identifiée par sa clé.
Les temps d'exécution peuvent être associés à la syntaxe SOI.
SOI | Description | Durée d'exécution possible | Syntaxe | Exemple |
---|---|---|---|---|
ThisSOI | La chaîne est exécutée sur l'objet spécifié par class_name dans le fichier DirectivesConfig.acml.
|
before ou after |
<this SOI> ::= [before || after] this |
thisSOIchain: before this | method (public getAddress ()) |
ParamSOI | La chaîne est exécutée sur l'objet spécifié par param# dans le fichier DirectivesConfig.acml.
Il s'agit de paramètres de la méthode à surveiller. |
before or after |
<param_SOI> ::= [before || after] param# |
paramSOIchain: before param1 | method (public getAddress ())
|
ReturnSOI | La chaîne est exécutée sur l'objet spécifié par return dans le fichier DirectivesConfig.acml.
Il s'agit de la valeur de retour de la méthode surveillée. |
after |
<return_SOI> ::= [after] return |
returnSOIchain: after return | method (public getAddress ()) |
StaticSOI | La chaîne n'est démarrée avec aucun objet. | before or after |
<static SOI> ::= [before || after] static |
staticSOIchain: before static | static method((com.test.beans.Employee)(public getLevel())) |
VariableSOI | La chaîne est exécutée sur l'objet spécifié par l'une des variables ci-dessus définies dans le fichier DirectivesConfig.acml. | before or after |
<variable_SOI> ::= [before || after] variable-key |
var1: this | method (public setNewAddress (string "Variable Street", string "Redwood City", string "California", int 94065, string "US"))
|
Séquence de commande de chaîne
Une séquence de commandes de chaîne consiste en une ou plusieurs commandes de chaîne.
Syntaxe : <chain_command_sequence> ::= <chain_command> || <chain_command> | <chain_command_sequence>
Types de commande de chaîne
Syntaxe : <chain_command> ::= <method_command> || <field_command> || <regex_command>
Commande de méthode
Une commande de méthode est utilisée pour appeler une méthode. La sortie d'une commande de méthode est l'objet de retour de cette méthode spécifique.
Une commande de méthode se compose de la visibilité de la méthode, du nom de la méthode et de la séquence de paramètres. Ceci imite la signature de la méthode.
La syntaxe doit se présenter comme suit :
<method_command> ::= method(<visibility> <java_identifier> (<parameter_sequence>))
<visibility> ::= private || public || protected || package
La valeur package
est utilisée pour spécifier une méthode de visibilité ou un champ privé (sans modificateur).
<scalar_parameter_type> ::= int || double || float || String
<parameter> ::=<scalar_parameter_type> value || this || return || param<index> || variable-key
<parameter_sequence> ::= <parameter> || <parameter> , <parameter_sequence>
Exemples de commandes de méthode
-
Cette chaîne affiche
this
en tant qu'objet utilisateur. Cette chaîne appelle la méthodegetAddress
publique dans la classe Utilisateur. La sortie de cette chaîne sera la représentation de chaîne de l'adresse de cet utilisateur.addresschain: this | method (public getAddress ())
-
Cette chaîne appelle la méthode
public setName
sur l'utilisateur et définit le nom sur "John Smith". Puisque cette méthode set n'a pas de valeur de retour, la sortie de cette chaîne sera nulle. Cette chaîne explique comment utiliser des paramètres scalaires dans les commandes de méthode.testSetupVar: this | method(public setName(String "John", String "Smith"))
-
Cette chaîne utilise
param1
(le premier paramètre de la méthode surveillée) en tant que paramètre de la méthode que nous appelons.testParamAsParam: this | method(public incUserId(param1))
-
Cette chaîne utilise une autre variable, en l'occurrence
testParamAsParam
, comme paramètre de la méthode.testVarAsParam: this | method(public incUserId(testParamAsParam))
-
Cette chaîne appelle explicitement la super méthode.
invokeUsingSuper: this | method(private super.overloadPrivate(String "string3", int 2222))
Commande de champ
Une commande de champ est utilisée pour inspecter les valeurs de champ. La sortie d'une commande de champ est l'objet de ce champ spécifique.
Une commande de méthode consiste en la visibilité des champs et le nom des champs.
Syntaxe : <field_command> ::= field (<visibility> <java_identifier>)
Exemples de commandes de champ
this
est un objet utilisateur. Ici, nous accédons aux champs de différentes visibilité dans la classe User. La sortie de chaque chaîne est la valeur du champ respectif.
fieldPublic: this | field(public firstName)
fieldProtected: this | field (protected lastName)
fieldPackagePrivate: this | field (package middleName)
fieldPrivate: this | field (private maidenName)
Commande de méthode statique
Une commande de méthode statique est utilisée pour appeler une méthode statique. La sortie d'une commande de méthode statique est l'objet de retour de cette méthode spécifique.
Une commande de méthode consiste en une classe de début, une visibilité de méthode, un nom de méthode et une séquence de paramètres. Cela imite la signature de la méthode.
<static_method_command> ::= static method((<starting_class>)(<visibility> <java_identifier> (<parameter_sequence>)))
La classe de départ est la classe dans laquelle la méthode statique est trouvée.
- Cette chaîne ne commence par aucun objet. Cette chaîne appelle la méthode
getlevel
publique dans la classe Employé. La sortie de cette chaîne sera la représentation de chaîne du niveau de cet employé. staticMethodPublic: static | static method((com.test.beans.Employee)(public getLevel()))
- L'utilisation d'autres visibilités et différents types de paramètres de méthode sont les mêmes que dans les exemples pour Method Command.
Commande de champ statique
Une commande de champ statique est utilisée pour inspecter les valeurs de champ statique. La sortie d'une commande de champ statique est l'objet dans ce champ spécifique.
Une commande de méthode consiste en une classe de début, une visibilité de champ et un nom de champ.
Syntaxe :
<static_field_command> ::= static field ((<starting_class>)(<visibility> <java_identifier>))
Exemples de commandes de champ statique :
L'exemple ci-dessous suppose que this
est un objet utilisateur. Ici, nous accédons à des champs de visibilité différente dans la classe Utilisateur. La sortie de chaque chaîne est la valeur du champ respectif.
staticFieldPublic: static field((com.test.beans.Employee)(public role))
L'utilisation d'autres visibilités est la même que dans les exemples pour Field Command.
Commande Regex
Une commande regex est utilisée pour rechercher et/ou remplacer des chaînes résultant du SOI, des valeurs renvoyées des commandes de méthode ou des valeurs de champ. La sortie d'une commande regex est une chaîne.
Une commande regex est constituée de la chaîne regex. Facultativement, il peut également s'agir d'une chaîne de remplacement, ainsi que d'une première ou de toutes les occurrences à remplacer.
Syntaxe : <regex_command> ::=regex (string [,<replace-string> [, first || all]])
Exemples de commandes Regex
- Après avoir reçu l'adresse "100 Oracle Pkway, Redwood City, CA 94065", remplacez le premier "Pk" par "This" pour obtenir "100 Oracle Thatway, Redwood City, CA 94065
replaceFirstChain : this | method (public getStreet()) | regex(Pk, This, first)
- Après avoir reçu l'adresse "100 Oracle Pkway, Redwood City, CA 94065", remplacez toutes les "0" par "1" pour obtenir "111 Oracle Pkway, Redwood City, CA 94165"
replaceAllChain: this | method (public getStreet()) | regex(0, 1, all)
Exemples de variables avancées
Voici un exemple de chaîne de commandes dans le fichier DirectivesConfig.acml
.
test: class_name: "com.test.beans.User"
method_name: "incAge"
span_name: "${short_class_name}.${method_name}"
tags:
t: "${this}"
params: "${param1}"
r: "${return}"
exampleVarTag: "${exampleVar}"
variables:
exampleVar: before this | method (public getAddress ()) | field(private street) | regex(Pk,This, all) | regex(This, That, first)
Vérification de l'exécution de la chaîne de variables exampleVar
:
exampleVar
commence par l'objet User qui est spécifié dans "class_name". XX
-
La première commande de chaîne est une commande de méthode qui renvoie un objet Address. Par exemple : "100 Oracle Pkway, Redwood City, CA 94065."
-
La deuxième commande de chaîne est une commande de champ qui obtient la rue de l'adresse de la commande de champ précédente. Ce sera "Oracle Pkway".
-
La troisième commande de chaîne est une commande regex qui remplace toutes les instances de "Pk" par "This" et retourne "Oracle Thisway".
-
La dernière commande de chaîne est une commande regex qui remplace la première instance de "This" par "That", retournant "OracleThatway".
Résultat final : Lorsque vous examinez les dimensions de cet intervalle, vous voyez une balise nommée exampleVarTag avec la valeur "OracleThatway". Notez que la spécification de exampleVarTag: "${exampleVar}"
dans la section Marqueurs était nécessaire pour voir cette dimension d'intervalle.
Utiliser ACMLValidate pour vérifier la syntaxe du fichier
Lorsque vous utilisez des fichiers de type acml
, vous pouvez utiliser l'utilitaire ACMLValidate pour vérifier la syntaxe des fichiers acml
.
acml
suivants :
- ProbeConfig.acml
- DirectivesConfig.acml
- CircuitBreaker.acml
L'utilitaire ACMLValidate
valide la syntaxe, mais il ne valide pas les valeurs. Il est disponible à partir de la version 1.16 de l'agent Java APM.
Conditions requises :
JDK disponible dans PATH
ou définissez la variable d'environnement JAVA_HOME
.
Emplacement :
L'utilitaire ACMLValidate
se trouve sous le répertoire oracle-apm-agent/bin
.
Exécutez ACMLValidate :
ACMLValidate
, utilisez les éléments suivants :
-
Pour Windows :
ACMLValidate.bat
-
Pour Linux :
ACMLValidate.sh
ACMLValidate.[bat|sh] <path to the acml file>
oracle-apm-agent/bin % sh ACMLvalidate.sh ../config/1.16.0.560/ProbeConfig.acml
===============================================================================
Testing file: ../config/1.16.0.560/ProbeConfig.acml
ACML Validation Result: PASSED
===============================================================================
oracle-apm-agent/bin % sh ACMLvalidate.sh ../config/1.16.0.560/ProbeConfig.acml
===========================================================================
Testing file: ../config/1.16.0.560/ProbeConfig.acml
ACML Validation Result: FAILED
Exception: Failed to parse line [5][ SERVLET: true]
Caused by: Tab detected in the following line. Please replace '\t' with spaces: [ \tSERVLET: true]
===========================================================================