Tous les produits
Search
Centre de documentation

Simple Log Service:FAQ about querying and analyzing JSON logs

Dernière mise à jour :Aug 21, 2026

Questions fréquentes et solutions pour l'interrogation et l'analyse des journaux au format JSON dans Simple Log Service, incluant la configuration des index, les fonctions JSON et la gestion des tableaux JSON.

Exemple de journal

Les exemples de cette rubrique utilisent des journaux JSON issus d'un système de traitement des commandes.

{
    "request":{
        "clientIp":"20xxx30",
        "http.path":"/order/buy",
        "param":{
            "userId": "186453",
            "orders":[
                {
                    "commodity":["bread","milk","meat"],
                    "payment":132
                },
                {
                    "commodity":["milk","beer"],
                    "payment":49
                }
            ]
        }
    },
    "response":"{\"errcode\":400,\"msg\":\"insufficient\"}"
}
  • Le champ request/@parmname contient les informations de demande de commande au format JSON. Une demande peut inclure plusieurs commandes pour un utilisateur, chacune avec les produits achetés et le montant total payé.

  • Le champ response/@parmname contient le résultat du traitement de la commande.

    • En cas de succès, la valeur du champ response/@parmname est SUCCESS.

    • En cas d'échec, la valeur du champ response/@parmname est un objet JSON contenant errcode et msg.

Utilisez Logtail pour Collecter des journaux en mode JSON dans Simple Log Service afin de les interroger et de les analyser.

Comment configurer un index

Configurez un index avant d'interroger ou d'analyser les données de journal. Gardez à l'esprit les points suivants lors de la configuration des index pour les journaux JSON.

How to select an index type

Simple Log Service prend en charge les index en texte intégral et les index de champ. Choisissez en fonction de votre cas d'utilisation. Créer un index.

  • Pour interroger tous les champs, créez un index en texte intégral. Pour interroger uniquement des champs spécifiques, créez des index de champ pour ces champs afin de réduire les coûts.

  • Pour exécuter une analyse SQL sur un champ, créez un index de champ pour celui-ci et activez les statistiques.

Remarque

Lorsqu'un index en texte intégral et des index de champ sont tous deux configurés, l'index de champ est prioritaire pour les champs qui en possèdent un.

Par exemple, pour analyser les champs request/@parmname et response/@parmname, créez des index de champ pour ceux-ci et activez les statistiques.

How to select a data type for a field in the index configuration

Lors de la configuration d'un index, définissez le type de données d'un champ comme text, long, double ou JSON. Types de données.

Gardez les éléments suivants à l'esprit lors de la définition d'un type de données pour un champ JSON.

  • Si la valeur d'un champ n'est pas au format JSON standard mais contient du contenu JSON, définissez le type de données sur text. Si la valeur est au format JSON standard, définissez-la sur JSON.

    Remarque

    Pour les journaux JSON qui ne sont pas entièrement valides, Simple Log Service peut analyser les parties valides.

  • Après avoir défini le type de données sur JSON, créez un index pour un nœud feuille au sein de l'objet JSON pour accélérer les requêtes. Cela entraîne des frais d'indexation supplémentaires.

  • Simple Log Service prend en charge les index pour les nœuds feuilles dans les objets JSON, mais pas pour les nœuds enfants qui contiennent des nœuds feuilles.

  • Simple Log Service ne prend pas en charge les index pour les champs dont les valeurs sont des tableaux JSON, ni pour les champs au sein d'un tableau JSON. Pour de tels champs, utilisez des fonctions JSON pour l'analyse en temps réel.

Sur la base du journal exemple, créez les index suivants.

  • Champ request/@parmname

    • request/@parmname : La valeur est au format JSON. Définissez le type de données sur JSON et activez les statistiques.

    • request.clientIp/@parmname : Fréquemment analysé. Créez un index séparé, définissez le type de données sur text et activez les statistiques.

    • request.http.path/@parmname : Rarement analysé. Ignorez l'index séparé — analysez-le à la demande à l'aide de fonctions JSON.

    • request.param/@parmname : Un nœud enfant qui contient des nœuds feuilles. L'indexation n'est pas prise en charge.

    • request.param.userId/@parmname : Fréquemment analysé. Créez un index séparé, définissez le type de données sur text et activez les statistiques.

    • request.param.orders/@parmname : La valeur est un tableau JSON. L'indexation n'est pas prise en charge.

  • Champ response/@parmname

    La valeur du champ response/@parmname n'est pas toujours au format JSON. Définissez son type de données sur text et activez les statistiques.

Après la création de l'index, les journaux nouvellement collectés s'affichent selon la configuration de l'index.

How to set an alias

Pour les chemins longs de nœuds feuilles JSON, définissez un alias. Alias de colonne.

Dans la configuration de l'index, vous pouvez définir des alias pour les nœuds feuilles des champs de type JSON. Par exemple, définissez l'alias de request.clientIp sur ip, et l'alias de request.param.userId sur id.

Remarque
  • Les noms de champ et les alias doivent être uniques pour tous les champs d'une configuration d'index.

  • Pour les champs de type JSON, l'unicité est déterminée par le chemin complet du nœud feuille. Par exemple, définir l'alias du champ response/@parmname sur clientIp/@parmname n'entre pas en conflit avec le nom de champ request.clientIp/@parmname.

Comment interroger et analyser un champ JSON indexé

Une instruction d'interrogation et d'analyse suit le format query statement|analytic statement. Dans une instruction d'analyse, entourez les noms de champ de guillemets doubles ("") et les chaînes de caractères de guillemets simples (''). Spécifiez le chemin complet pour les champs imbriqués — par exemple, Key1.Key2.Key3, request.clientIp, ou request.param.userId. Interroger et analyser des journaux JSON.

Par exemple, pour trouver les adresses IP des clients pour l'utilisateur 186499 :

*
and request.param.userId: 186499 |
SELECT
  distinct("request.clientIp")

Quand utiliser les fonctions JSON

Pour les grands ensembles de données avec des structures JSON complexes mais fixes où les performances de requête sont importantes, créez des index de champ pour les nœuds feuilles JSON. Pour les ensembles de données plus petits ou les analyses ponctuelles, utilisez des fonctions JSON sans index de champ pour économiser des coûts. Les fonctions JSON permettent le traitement et l'analyse dynamiques du contenu JSON. Dans certains cas, elles constituent la seule option.

  • La valeur du champ n'est pas toujours au format JSON ou nécessite un prétraitement.

    Par exemple, le champ response/@parmname contient un JSON avec un champ errcode/@parmname uniquement lorsqu'une demande échoue. Pour analyser la distribution de errcode/@parmname, filtrez les demandes ayant échoué et extrayez errcode/@parmname avec une fonction JSON.

    *  not response :SUCCESS |
    SELECT
      json_extract_scalar(response, '$.errcode') AS errcode

    JSON log

  • Le champ ne peut pas être indexé. Pour les nœuds JSON qui ne prennent pas en charge l'indexation — tels que request.param/@parmname et request.param.orders/@parmname — les fonctions JSON sont le seul moyen d'exécuter une analyse en temps réel.

Comment choisir entre json_extract et json_extract_scalar

Les fonctions json_extract et json_extract_scalar extraient toutes deux du contenu à partir d'objets ou de tableaux JSON. La différence principale réside dans le type de retour.

  • json_extract renvoie un type JSON ; json_extract_scalar renvoie un type varchar.

    Remarque

    Cela fait référence aux types de données SQL (varchar, bigint, boolean, JSON, array, date), qui diffèrent des types de données d'index SLS. Utilisez la fonction typeof pour vérifier le type de données d'un objet SQL. Fonction typeof.

  • json_extract peut analyser n'importe quelle sous-structure d'un objet JSON. json_extract_scalar analyse uniquement les nœuds feuilles scalaires (chaîne, booléen ou nombre) et renvoie la chaîne correspondante.

Les deux fonctions peuvent extraire le champ clientIp/@parmname du champ request/@parmname.

  • Utilisation de json_extract :

    * |
    SELECT
      json_extract(request, '$.clientIp')

    Dans les résultats de l'interrogation et de l'analyse, puisqu'aucun alias n'est défini, le nom de la colonne affiche par défaut _col0, contenant la valeur clientIp extraite par json_extract.

  • Utilisation de json_extract_scalar :

    * | SELECT json_extract_scalar(request, '$.clientIp')

    Après l'exécution de l'instruction de requête ci-dessus, le résultat de la requête affiche la valeur du champ extrait dans une seule colonne _col0.

Pour extraire le premier octet de la valeur clientIp/@parmname, utilisez json_extract_scalar pour extraire clientIp/@parmname, puis utilisez split_part pour extraire le premier nombre. json_extract ne fonctionne pas ici car split_part nécessite une entrée varchar.

* |
SELECT
  split_part(
    json_extract_scalar(request, '$.clientIp'),
    '.',
    1
  ) AS segment

JSON log

Dans la plupart des cas, utilisez json_extract_scalar — son type de retour varchar se compose naturellement avec d'autres fonctions SQL. Utilisez json_extract lorsque vous devez travailler avec la structure JSON elle-même. Par exemple, pour compter les commandes dans une demande (la longueur du tableau request.param.orders/@parmname) :

* |
SELECT
  json_array_length((json_extract(request, '$.param.orders')))

Dans les résultats de l'interrogation et de l'analyse, la colonne _col0 renvoie la longueur du tableau JSON (c'est-à-dire le nombre de commandes) dans chaque demande, avec des valeurs d'exemple étant 2.

Important

json_extract_scalar renvoie un type varchar. Par exemple, le nombre 2 dans le résultat précédent est de type varchar. Pour effectuer des calculs tels qu'une somme, convertissez-le d'abord en bigint en utilisant cast. Fonctions de conversion de type.

Comment définir un chemin JSON

Lors de l'utilisation de fonctions telles que json_extract, spécifiez un chemin JSON pour cibler la partie de l'objet JSON à extraire. Le format est $.a.b, où $ est le nœud racine et les points (.) référencent les nœuds enfants.

Pour les noms de champ JSON qui contiennent des caractères spéciaux — tels que http.path/@parmname, http path/@parmname, ou http-path/@parmname — utilisez des crochets [] au lieu d'un point et entourez le nom du champ de guillemets doubles. Exemple : * |SELECT json_extract_scalar(request, '$["http.path"]').

Remarque

Lors de l'interrogation via un SDK, échappez les guillemets doubles. Exemple : * | select json_extract_scalar(request, '$[\"http.path\"]').

Pour extraire un élément d'un tableau JSON, utilisez des crochets [] avec un index basé sur zéro.

  • Affichez le paiement pour la première commande de l'utilisateur :

    * |
    SELECT
      json_extract_scalar(request, '$.param.orders[0].payment')

    Le tableau des résultats de la requête montre deux lignes dans la colonne _col0, toutes deux avec une valeur de 132.

  • Affichez le deuxième produit acheté dans la première commande de l'utilisateur :

    * |
    SELECT
      json_extract_scalar(request, '$.param.orders[0].commodity[1]')

    La colonne _col0 renvoie deux enregistrements, tous deux avec une valeur de milk.

Comment analyser un tableau JSON

Pour analyser un tableau JSON, combinez cast avec la clause UNNEST pour développer le tableau, puis agrégez les résultats.

Example 1

Pour calculer le paiement total pour toutes les commandes réussies :

  1. Filtrez les demandes réussies et extrayez le champ orders/@parmname en utilisant json_extract.

    *
    and response: SUCCESS |
    SELECT
      json_extract(request, '$.param.orders')
    _col0
    [{"commodity":["bread","milk","meat"],"payment":132},{"commodity":["milk","beer","rice"],"payment":49}]
    [{"commodity":["bread","milk","meat"],"payment":132},{"commodity":["milk","beer","rice"],"payment":49}]
  2. Convertissez le tableau JSON en un type array.

    *
    and response: SUCCESS |
    SELECT
      cast(
        json_extract(request, '$.param.orders') AS array(json)
      )
    _col0
    ["{"commodity":["bread","milk","meat"],"payment":132}","{"commodity":["milk","beer","rice"],"payment":49}"]
    ["{"commodity":["bread","milk","meat"],"payment":132}","{"commodity":["milk","beer","rice"],"payment":49}"]
  3. Utilisez UNNEST pour développer le tableau en lignes individuelles.

    *
    and response: SUCCESS |
    SELECT
      orderinfo
    FROM  log,
      unnest(
        cast(
          json_extract(request, '$.param.orders') AS array(json)
        )
      ) AS t(orderinfo)

    Résultats de l'interrogation et de l'analyse :

    orderinfo
    {"commodity":["milk","beer","rice"],"payment":49}
    {"commodity":["milk","beer","rice"],"payment":49}
  4. Extrayez la valeur payment/@parmname en utilisant json_extract_scalar, convertissez en bigint et faites la somme.

    *
    and response: SUCCESS |
    SELECT
      sum(
        cast(
          json_extract_scalar(orderinfo, '$.payment') AS bigint
        )
      )
    FROM  log,
      unnest(
        cast(
          json_extract(request, '$.param.orders') AS array(json)
        )
      ) AS t(orderinfo)

    Le résultat renvoyé est 10860.

Example 2

Pour compter la quantité de chaque produit pour toutes les demandes réussies : extrayez le champ orders/@parmname, convertissez en array(json), et développez avec UNNEST — chaque ligne représente une commande. Extrayez le champ commodity/@parmname, convertissez et développez à nouveau — chaque ligne représente un produit. Groupez et comptez.

*
and response: SUCCESS |
SELECT
  item,
  count(1) AS cnt
FROM  (
    SELECT
      orderinfo
    FROM      log,
      unnest(
        cast(
          json_extract(request, '$.param.orders') AS array(json)
        )
      ) AS t(orderinfo)
  ),
  unnest(
    cast(
      json_extract(orderinfo, '$.commodity') AS array(json)
    )
  ) AS t(item)
GROUP  BY
  item
ORDER BY
  cnt DESC

Les résultats de la requête contiennent deux colonnes : item et cnt. Les statistiques de quantité achetée pour chaque produit sont :

  • "milk" : 120

  • "bread" : 60

  • "rice" : 60

  • "beer" : 60

  • "meat" : 60