Tous les produits
Search
Centre de documentation

Simple Log Service:Référence générale

Dernière mise à jour :Aug 18, 2026

Présente des références générales pour l'utilisation du langage Structured Process Language (SPL) dans différents scénarios.

Optimisation des instructions SPL

Plusieurs instructions SPL peuvent produire le même résultat de traitement des données. Rédiger des instructions SPL concises et efficaces simplifie la maintenance et améliore les performances. Le tableau suivant propose quelques suggestions.

Suggestion

Avant optimisation

Après optimisation

Combinez les clauses where consécutives en une seule.

*
| where request_method = 'POST'
| where cast(status as integer) >= 500
*
| where request_method = 'POST' and cast(status as integer) >= 500

Combinez les clauses extend consécutives en une seule.

*
| extend k1 = 'v1'
| extend k2 = 'v2'
| extend k3 = 'v3'
*
| extend k1 = 'v1', k2 = 'v2', k3 = 'v3'

Remplacez extend + project-away par project-rename.

*
| extend method = request_method
| project-away request_method
*
| project-rename method = request_method

Modifiez les valeurs des champs sur place au lieu d'utiliser extend pour créer de nouveaux champs, sauf si nécessaire.

*
| extend newContent = json_extract(content, 'abc \d+')
| project-away content
*
| extend content = json_extract(content, 'abc \d+')

Gestion des champs spéciaux

Champs temporels

Lors de l'exécution SPL, le type de données des champs temporels dans les journaux Simple Log Service est toujours INTEGER ou BIGINT. Ces champs incluent le champ d'horodatage des données __time__ et la partie nanoseconde du champ d'horodatage des données __time_ns_part__.

Pour mettre à jour l'horodatage des données, utilisez l'instruction extend et assurez-vous que la nouvelle valeur est un INTEGER ou un BIGINT. Les autres instructions ne peuvent pas agir sur les champs temporels. Leur comportement est le suivant :

  • project, project-away et project-rename : ces instructions conservent les champs temporels par défaut. Vous ne pouvez ni les renommer ni les écraser.

  • parse-regexp et parse-json : si le résultat de l'extraction inclut des champs temporels, ils sont ignorés.

Exemple

Extrayez les valeurs des champs temporels à partir d'une chaîne de temps existante.

  • Instruction SPL

    * 
    | parse-regexp time, '([\d\-\s:]+)\.(\d+)' as ts, ms
    | extend ts=date_parse(ts, '%Y-%m-%d %H:%i:%S')
    | extend __time__=cast(to_unixtime(ts) as INTEGER)
    | extend __time_ns_part__=cast(ms as INTEGER) * 1000000
    | project-away ts, ms
  • Données d'entrée

    time: '2023-11-11 01:23:45.678'
  • Résultat de sortie

    __time__: 1699637025
    __time_ns_part__: 678000000
    time: '2023-11-11 01:23:45.678'

Noms de champs contenant des caractères spéciaux

Si un nom de champ contient des espaces ou d'autres caractères spéciaux, entourez-le de guillemets doubles (") lorsque vous y faites référence. Par exemple, si un champ est nommé A B et contient un espace, référencez-le sous la forme "A B" dans une instruction SPL :

* | where "A B" like '%error%'

Noms de champs insensibles à la casse

Dans les requêtes d'analyse SLS, les noms de champs référencés dans les instructions SPL sont insensibles à la casse. Par exemple, si un journal contient un champ nommé Method, vous pouvez y faire référence sous la forme method ou METHOD dans une instruction SPL.

Important

Cela s'applique à la fonctionnalité de requête d'analyse de Simple Log Service. Pour plus d'informations, consultez Requêtes d'analyse.

Exemple

Utilisez un nom de champ insensible à la casse dans une clause where.

  • Instruction SPL

    * | where METHOD like 'Post%'
  • Données d'entrée

    Method: 'PostLogstoreLogs'
  • Résultat de sortie

    Method: 'PostLogstoreLogs'

Gestion des conflits de noms de champs

Lors du chargement des journaux ou de l'exécution SPL, le traitement sensible à la casse peut provoquer des conflits de noms de champs. Par exemple, un journal brut peut contenir à la fois les champs Method et method. SPL résout ces conflits différemment selon le scénario.

Pour éviter ces situations, standardisez les noms de champs dans vos journaux bruts.

Conflits dans les données d'entrée

Si un journal brut contient des champs dont les noms sont identiques lorsque la casse est ignorée, tels que Status et status, SPL sélectionne aléatoirement un champ pour l'entrée et ignore l'autre. Par exemple :

  • Instruction SPL

    * | extend status_cast = cast(status as bigint)
  • Données d'entrée

    Status: '200'
    status: '404'
  • Résultat du traitement

    • Possibilité 1 : La valeur du champ Status est conservée.

      Status: '200' -- The first column is retained, and the second column is discarded.
      status_cast: '200'
    • Possibilité 2 : La valeur du champ status est conservée.

      status: '404' -- The second column is retained, and the first column is discarded.
      Status_cast: '404'

Conflits dans les résultats de sortie

Scénario 1 : Conflits de champs de données brutes

Lors de l'exécution SPL, des champs dont les noms sont identiques lorsque la casse est ignorée peuvent être générés. SPL en sélectionne un au hasard pour la sortie. Par exemple, si un champ de journal contient une chaîne JSON, l'utilisation de l'instruction parse-json peut créer des champs avec des noms conflictuels :

  • Instruction SPL

    * | parse-json content
  • Données d'entrée

    content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
  • Résultat de sortie

    • Possibilité 1 : Le champ Method est conservé.

      content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
      Method: 'PostLogs' -- The Method field is retained.
      status: '200'
    • Possibilité 2 : Le champ method est conservé.

      content: '{"Method": "PostLogs", "method": "GetLogs", "status": "200"}'
      method: 'GetLogs' -- The method field is retained.
      status: '200'

Scénario 2 : Conflits avec les champs de données nouvellement générés

Pour éviter toute ambiguïté, SPL conserve la casse des nouveaux noms de champs générés explicitement par les instructions. Cela s'applique aux noms de champs générés par l'instruction extend et aux noms de champs explicitement spécifiés à l'aide de as dans les instructions parse-regexp et parse-csv.

Par exemple, si vous utilisez extend pour créer un nouveau champ Method, le nom du champ résultant reste Method.

  • Instruction SPL

    * | extend Method = 'Post'
  • Données d'entrée

    Status: '200'
  • Résultat de sortie

    Status: '200'
    Method: 'Post'

Gestion des conflits de champs réservés SLS

Important

Cela s'applique aux fonctionnalités de consommation en temps réel et de requête d'analyse de Simple Log Service.

Pour obtenir la liste complète des champs réservés, consultez Champs réservés. SPL lit les données depuis la structure LogGroup en tant qu'entrée. Pour plus d'informations sur la définition de LogGroup, consultez Encodage des données. Si les données brutes écrites dans Simple Log Service ne sont pas encodées au format LogGroup standard, certains champs réservés peuvent apparaître dans LogContent au lieu de leur emplacement standard. SPL gère ces champs réservés comme suit :

  • Pour les champs __source__, __topic__, __time__ et __time_ns_part__, SPL lit leurs valeurs à partir de la structure LogGroup standard et ignore tous les champs portant les mêmes noms dans LogContent.

  • Pour les champs de tag avec le préfixe __tag__: , SPL tente d'abord de lire leurs valeurs à partir de la structure LogGroup standard. Si aucune valeur n'est trouvée, SPL la lit depuis LogContent. Par exemple, pour le champ __tag__:ip, SPL tente d'abord de lire le champ avec la clé ip depuis la liste LogTag. Si le champ n'existe pas, SPL lit ensuite le champ de journal avec la clé __tag__:ip depuis les champs de journal personnalisés dans LogContent.

Le champ __line__ pour la recherche en texte intégral

Important

Cela s'applique à la fonctionnalité de requête d'analyse SLS.

Pour filtrer les journaux bruts dans la console ou en utilisant l'opération d'API GetLogstoreLogs, utilisez le champ __line__.

Exemple

  • Recherchez le mot-clé error dans les journaux.

    * | where __line__ like '%error%'
  • Si un journal contient un champ nommé __line__, entourez le nom du champ de backticks pour y faire référence.

    * | where `__line__` ='20'

Politiques de conservation et d'écrasement des valeurs

Lorsqu'une instruction SPL est exécutée et qu'un champ de sortie porte le même nom qu'un champ d'entrée existant, la valeur du champ est déterminée par la politique suivante :

Important

Ces politiques ne s'appliquent pas à l'instruction extend. Pour extend, en cas de conflit de nom de champ, la nouvelle valeur est toujours utilisée.

Types de données incohérents entre les anciennes et nouvelles valeurs

La valeur d'origine du champ d'entrée est conservée.

Exemple

  • Exemple 1 : Un champ renommé à partir d'une instruction project présente un nom conflictuel.

    • Instruction SPL

      * 
      | extend status=cast(status as BIGINT) -- Convert the type of the status field to BIGINT.
      | project code=status -- The new value's type (BIGINT) differs from the old value's type (VARCHAR), so the old value is kept.
    • Données d'entrée

      status: '200'
      code: 'Success'
    • Résultat de sortie

      code: 'Success'
  • Exemple 2 : Un champ extrait à partir d'une instruction parse-json présente un nom conflictuel.

    • Instruction SPL

      * 
      | extend status=cast(status as BIGINT) -- Convert the type of the status field to BIGINT.
      | parse-json content -- The old type of status is BIGINT and the new type is VARCHAR. The old value is retained.
    • Données d'entrée

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Résultat de sortie

      content: '{"status": "Success", "body": "this is test"}'
      status: 200
      body: 'this is test'

Types de données cohérents entre les anciennes et nouvelles valeurs

Si la valeur d'entrée est nulle, la nouvelle valeur est utilisée. Sinon, le comportement est déterminé par le paramètre mode dans l'instruction, tel que défini dans le tableau suivant.

Important

Si le paramètre mode n'est pas spécifié dans l'instruction, sa valeur par défaut est overwrite.

Mode

Description

overwrite

Écrase l'ancienne valeur avec la nouvelle valeur.

preserve

Conserve l'ancienne valeur et ignore la nouvelle valeur.

Exemple

  • Exemple 1 : Un champ renommé à partir d'une instruction project présente un nom conflictuel et le même type. Le mode par défaut est overwrite.

    • Instruction SPL

    * | project code=status -- The old and new types of code are both VARCHAR. The new value is used based on the overwrite mode.
    • Données d'entrée

      status: '200'
      code: 'Success'
    • Résultat de sortie

      code: '200'
  • Exemple 2 : Un champ extrait à partir d'une instruction parse-json présente un nom conflictuel et le même type. Le mode par défaut est overwrite.

    • Instruction SPL

      * | parse-json content -- The old and new types of status are both VARCHAR. The new value is used based on the overwrite mode.
    • Données d'entrée

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Résultat de sortie

      content: '{"status": "Success", "body": "this is test"}'
      status: 'Success'
      body: 'this is test'
  • Exemple 3 : Un champ extrait à partir d'une instruction parse-json présente un nom conflictuel et le même type. Le mode est défini sur preserve.

    • Instruction SPL

      * | parse-json -mode='preserve' content -- The old and new types of status are both VARCHAR. The old value is retained based on the preserve mode.
    • Données d'entrée

      status: '200'
      content: '{"status": "Success", "body": "this is test"}'
    • Résultat de sortie

      content: '{"status": "Success", "body": "this is test"}'
      status: '200'
      body: 'this is test'

Conversion de type de données

Type initial

Lorsque SPL traite les données, tous les champs d'entrée sont initialement de type VARCHAR, à l'exception des champs de temps des journaux. Si le traitement ultérieur nécessite un type de données différent, vous devez effectuer une conversion de type explicite.

Exemple

Pour filtrer les journaux d'accès avec un code d'état 5xx, convertissez le champ status en type BIGINT avant la comparaison.

* -- The initial type of the status field is VARCHAR.
| where cast(status as BIGINT) >= 500 -- Convert the type of the status field to BIGINT, and then perform the comparison.

Conservation du type

Après avoir utilisé l'instruction extend pour convertir le type de données d'un champ, le traitement ultérieur conserve le type converti.

Exemple

* -- A Logstore is used as input data. Except for time fields, all fields are initially of the VARCHAR type.
| where __source__='127.0.0.1' -- Filter on the __source__ field.
| extend status=cast(status as BIGINT) -- Convert the type of the status field to BIGINT.
| project status, content
| where status>=500 -- The type of the status field remains BIGINT, so it can be directly compared with the number 500.

Gestion des valeurs nulles dans les expressions SPL

Génération de valeurs nulles

Lors du traitement des données SPL, des valeurs nulles sont générées dans les scénarios suivants :

  1. Si un champ utilisé dans une expression SPL n'existe pas dans les données d'entrée, sa valeur est traitée comme nulle lors des calculs.

  2. Si une exception se produit lors du calcul d'une expression SPL, le résultat est nul. Par exemple, une conversion de type cast échoue ou un index de tableau est hors limites.

Exemple

  1. Si un champ n'existe pas, sa valeur est traitée comme nulle dans les calculs.

    • Instruction SPL

      * | extend withoutStatus=(status is null)
    • Données d'entrée

      # Entry 1
      status: '200'
      code: 'Success'
      
      # Entry 2
      code: 'Success'
    • Résultat de sortie

      # Entry 1
      status: '200'
      code: 'Success'
      withoutStatus: false
      
      # Entry 2
      code: 'Success'
      withoutStatus: true
  2. Si une exception se produit lors du calcul, le résultat est nul.

    • Instruction SPL

      *
      | extend code=cast(code as BIGINT) -- Failed to convert the code field to BIGINT.
      | extend values=json_parse(values)
      | extend values=cast(values as ARRAY(BIGINT))
      | extend last=arr[10] -- Array index out of bounds.
    • Données d'entrée

      status: '200'
      code: 'Success'
      values: '[1,2,3]'
    • Résultat de sortie

      status: '200'
      code: null
      values: [1, 2, 3]
      last: null

Élimination des valeurs nulles

Pour éliminer les valeurs nulles lors des calculs, utilisez l'expression COALESCE. Elle renvoie la première valeur non nulle d'une liste d'expressions. Vous pouvez également spécifier une valeur par défaut à utiliser si toutes les expressions sont évaluées à nul.

Exemple

Lisez le dernier élément d'un tableau. Si le tableau est vide, la valeur par défaut est 0.

  • Instruction SPL

    *
    | extend values=json_parse(values)
    | extend values=cast(values as ARRAY(BIGINT))
    | extend last=COALESCE(values[3], values[2], values[1], 0)
  • Données d'entrée

    # Entry 1
    values: '[1, 2, 3]'
    
    # Entry 2
    values: '[]'
  • Résultat de sortie

    # Entry 1
    values: [1, 2, 3]
    last: 3
    
    # Entry 2
    values: []
    last: 0

Échappement des caractères

Guillemets simples

Les guillemets simples sont utilisés pour entourer un littéral de chaîne. Si le littéral de chaîne contient un guillemet simple, vous devez utiliser un guillemet simple supplémentaire pour l'échapper.

Exemple

  • Instruction SPL

    *
    | extend user = 'Alice'
    | extend phone = 'Alice''s Phone'
  • Résultat de sortie

    user: Alice
    phone: Alice's Phone

Guillemets doubles

Les guillemets doubles sont utilisés pour entourer un nom de champ. Si le nom de champ contient un guillemet double, vous devez utiliser un guillemet double supplémentaire pour l'échapper.

Exemple

  • Instruction SPL

    *
    | extend user_name = 'Alice'
    | extend "user name" = 'Alice'
    | extend "user""name" = 'Alice'
  • Résultat de sortie

    user_name: Alice
    user name: Alice
    user"name: Alice

Autres caractères spéciaux

Exemple 1

Dans SPL, la barre oblique inverse (\) n'est pas un caractère d'échappement et est donc conservée telle quelle.

  • Instruction SPL

    *
    | extend a = 'foo\tbar'
    | extend b = 'foo\nbar'
  • Résultat de sortie

    a: foo\tbar
    b: foo\nbar

Exemple 2

Si une chaîne doit inclure des caractères spéciaux, tels qu'un caractère de tabulation ou un saut de ligne, vous pouvez utiliser la fonction chr pour concaténer des chaînes.

  • Instruction SPL

    *
    | extend a = concat('foo', chr(9), 'bar')
    | extend b = concat('foo', chr(10), 'bar')
  • Résultat de sortie

    a: foo	bar
    b: foo
    bar

Gestion des erreurs

Erreur de syntaxe

Des erreurs de syntaxe se produisent lorsqu'une instruction SPL est mal formée, par exemple un nom d'instruction incorrect, une erreur de référence de mot-clé ou une erreur de spécification de type. Lorsqu'une erreur de syntaxe se produit, SPL ne traite aucune donnée. Corrigez l'instruction en fonction du message d'erreur.

Erreur de données

Une erreur de données se produit lorsqu'une fonction ou une conversion échoue lors de l'exécution SPL. SPL définit le champ résultant sur null. Comme des erreurs de données peuvent se produire sur n'importe quelle ligne, SPL échantillonne aléatoirement et ne renvoie que certains messages d'erreur. Vous pouvez ignorer ces erreurs ou modifier l'instruction SPL en fonction du contenu des données.

Les erreurs de données n'arrêtent pas l'ensemble du processus d'exécution. L'instruction SPL renvoie toujours des résultats, mais le champ où l'erreur s'est produite est défini sur null.

Délai d'exécution dépassé

Une instruction SPL contient diverses instructions, et leur temps d'exécution varie en fonction du scénario de données. Si le temps d'exécution total dépasse la période de délai d'attente par défaut, l'exécution s'arrête et une erreur de délai d'attente est renvoyée avec un résultat vide. La période de délai d'attente par défaut varie pour les requêtes d'analyse, la consommation en temps réel et la collecte Logtail.

Pour résoudre cette erreur, simplifiez votre instruction SPL afin de réduire sa complexité, par exemple en optimisant les expressions régulières complexes ou en réduisant le nombre de pipelines.

Limite de mémoire dépassée

Une instruction SPL contient diverses instructions, et leur consommation de mémoire varie en fonction du scénario de données. L'exécution SPL est limitée à un quota de mémoire spécifique. Si ce quota est dépassé, l'exécution échoue et une erreur de limite de mémoire dépassée est renvoyée avec un résultat vide. Le quota de mémoire par défaut varie pour les requêtes d'analyse, la consommation en temps réel et la collecte Logtail.

Pour résoudre cette erreur, simplifiez votre instruction SPL afin de réduire sa complexité, réduisez le nombre de pipelines ou vérifiez si la taille des données brutes est trop importante.