> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Requêtes de journaux

Recherchez des lignes de journal avec l'[API publique (V2)](/api/v2/overview).
C'est la manière d'interroger les journaux de manière programmatique, y compris
les données de journal structurées (JSON). L'API GraphQL n'expose pas les
lignes de journal.

<Tip>
  Si vous créez un agent ou un assistant IA, [AppSignal MCP](/mcp-server)
  expose directement la recherche de journaux et d'autres données de
  surveillance aux agents, sans avoir besoin d'appeler cette API vous-même.
</Tip>

## Trouver vos IDs de site et de source

Une recherche de journaux nécessite un `site_id` et un ou plusieurs
`source_ids`. Les deux apparaissent dans l'URL d'une source de journal dans
AppSignal. Ouvrez une source de journal et lisez-les à partir du chemin :

<CodeGroup>
  ```text URL theme={null}
  https://appsignal.com/<organization>/sites/<SITE_ID>/logs/sources/<SOURCE_ID>
  ```
</CodeGroup>

## Rechercher des lignes de journal

<CodeGroup>
  ```shell Endpoint theme={null}
  POST /api/v2/logs/lines
  ```
</CodeGroup>

### Corps de la requête

| Champ             | Type              | Obligatoire | Description                                                                                     |
| ----------------- | ----------------- | ----------- | ----------------------------------------------------------------------------------------------- |
| `site_id`         | chaîne            | Oui         | Site à interroger.                                                                              |
| `source_ids`      | chaîne\[]         | Oui         | IDs des sources de journal à rechercher. Au moins un est requis.                                |
| `query`           | chaîne            | Oui         | Chaîne de requête qui filtre les lignes de journal. Voir [langage de requête](#query-language). |
| `use_expressions` | booléen           | Non         | Lorsque `true`, analyse `query` avec le langage de requête basé sur des expressions.            |
| `from`            | chaîne (ISO 8601) | Non         | Début de la plage temporelle. Par défaut, la limite inférieure de rétention.                    |
| `to`              | chaîne (ISO 8601) | Non         | Fin de la plage temporelle. Par défaut, l'heure actuelle.                                       |
| `pagination`      | objet             | Oui         | Curseur et direction de pagination (voir la section suivante).                                  |

Définissez `use_expressions` sur `true` pour utiliser le langage de requête
basé sur les expressions documenté sur cette page.

`pagination` prend `per_page` (nombre), `order` (`ASC` ou `DESC`), et un
`cursor` avec un champ `time` (un horodatage ISO 8601, ou `null` pour la
première page). Pour récupérer la page suivante, envoyez l'horodatage de la
dernière ligne que vous avez reçue comme `cursor.time` de la requête suivante.

### Exemple de requête

<CodeGroup>
  ```shell cURL theme={null}
  curl --request POST \
    --url "https://appsignal.com/api/v2/logs/lines" \
    --header "Authorization: Bearer YOUR-PERSONAL-API-TOKEN" \
    --header "Content-Type: application/json" \
    --data @body.json
  ```
</CodeGroup>

<CodeGroup>
  ```json body.json theme={null}
  {
    "site_id": "YOUR-SITE-ID",
    "source_ids": ["YOUR-LOG-SOURCE-ID"],
    "query": "severity=error status_code=401",
    "use_expressions": true,
    "from": "2026-06-22T00:00:00Z",
    "to": "2026-06-22T23:59:59Z",
    "pagination": {
      "per_page": 100,
      "order": "DESC",
      "cursor": { "time": null }
    }
  }
  ```
</CodeGroup>

### Réponse

Le point de terminaison renvoie un tableau de lignes de journal. Chaque ligne
inclut ces champs :

| Champ        | Type              | Description                                                                                |
| ------------ | ----------------- | ------------------------------------------------------------------------------------------ |
| `id`         | chaîne            | Identifiant de la ligne de journal.                                                        |
| `timestamp`  | chaîne (ISO 8601) | Quand la ligne de journal a été enregistrée.                                               |
| `source_id`  | chaîne            | Source de journal à laquelle appartient la ligne.                                          |
| `severity`   | chaîne            | Niveau de gravité, tel que `info` ou `error`.                                              |
| `message`    | chaîne            | Le corps du message de journal.                                                            |
| `hostname`   | chaîne            | Hôte qui a produit la ligne.                                                               |
| `group`      | chaîne            | Groupe de journal.                                                                         |
| `json`       | chaîne            | Le corps brut structuré (JSON) de la ligne de journal, lorsqu'il est disponible.           |
| `attributes` | objet             | Attributs clé-valeur typés hérités. En cours de suppression progressive — préférez `json`. |

<Note>
  Les champs structurés tels que `status_code`, `path` ou `detail` se trouvent
  dans le champ `json`, et non dans `attributes`. Interrogez-les par leur clé
  exacte telle qu'elle apparaît dans le JSON de votre journal (par exemple,
  `status_code=401` ou `detail.message:"required"`).
</Note>

## Langage de requête

Lorsque `use_expressions` est `true`, la chaîne `query` prend en charge la
logique booléenne sur les champs des lignes de journal et le corps structuré
`json`.

### Opérateurs

| Opérateur | Nom               | Comportement                       |
| --------- | ----------------- | ---------------------------------- |
| `=`       | Égal              | Correspondance exacte.             |
| `!=`      | Différent         | Non-correspondance exacte.         |
| `:`       | Contient          | Correspondance de sous-chaîne.     |
| `!:`      | Ne contient pas   | Non-correspondance de sous-chaîne. |
| `>`       | Supérieur à       | Comparaison numérique.             |
| `>=`      | Supérieur ou égal | Comparaison numérique.             |
| `<`       | Inférieur à       | Comparaison numérique.             |
| `<=`      | Inférieur ou égal | Comparaison numérique.             |

Les opérateurs de chaîne (`=`, `!=`, `:`, `!:`) comparent les deux côtés comme
des chaînes. Les opérateurs numériques (`>`, `>=`, `<`, `<=`) convertissent
les deux côtés en nombres ; si une valeur ne peut pas être analysée comme un
nombre, cette ligne de journal est ignorée.

### Combiner des expressions

* **AND / OR :** `severity=error AND hostname:web`, ou `severity=info OR severity=warn`.
* **AND implicite :** un espace entre les expressions signifie AND. `severity=error hostname:web` est identique à `severity=error AND hostname:web`.
* **Imbrication avec des parenthèses :** `message:"API request" AND (severity=info OR severity=warn)`.
* **Précédence :** AND a une priorité plus élevée que OR.

Tout opérateur peut être utilisé à l'intérieur d'un groupe `OR`, pas
uniquement l'égalité — par exemple, `message:"API request" AND (user.id>1000
OR user.email:"example.com")`.

### Champs

Étant donné une ligne de journal avec ce corps JSON :

<CodeGroup>
  ```json Example log theme={null}
  {
    "message": "API request completed",
    "severity": "info",
    "duration": 156.7,
    "status_code": 200,
    "user": {
      "id": 12345,
      "roles": ["admin", "developer"],
      "location.country": "US"
    }
  }
  ```
</CodeGroup>

* **Champs de base :** `message`, `severity`, `hostname` et `group` correspondent aux champs de premier niveau de la ligne de journal.
* **JSON imbriqué :** utilisez la notation par point pour accéder au corps `json`, comme `status_code=200` ou `user.id=12345`.
* **Tableaux JSON :** indexez les éléments du tableau, comme `user.roles.0=admin`.
* **Points échappés :** pour faire correspondre un point littéral dans un nom de clé, échappez-le. `user.location\.country=US` correspond à la clé `location.country` à l'intérieur de `user`, plutôt qu'à un objet `country` imbriqué.
* **Champ par défaut :** un terme isolé sans champ correspond à `message` avec l'opérateur `contains`. `timeout` équivaut à `message:timeout`.

Vous n'avez pas besoin de préfixer `attributes.` ou d'ajouter un suffixe de
type pour interroger un champ — référencez-le directement par son nom. Voir
[syntaxe de requête héritée](#legacy-query-syntax) si vous avez des requêtes
plus anciennes.

### Mise entre guillemets des valeurs

Encadrez les valeurs contenant des espaces ou des parenthèses avec des
guillemets doubles. Sinon, l'espace divise la valeur en expressions distinctes
jointes par un AND implicite.

```text theme={null}
message:"hello world"           matches message containing "hello world"
message:hello world             parsed as message:hello AND message:world
severity=error message:"oh no"  severity equals error AND message contains "oh no"
```

Seuls les guillemets doubles sont reconnus. À l'intérieur d'une valeur entre
guillemets, échappez un guillemet avec `\"` et une barre oblique inverse avec
`\\`. Par exemple, `message:"value with \"quotes\""` correspond au texte
`value with "quotes"`.

### Syntaxe de requête héritée

Les requêtes plus anciennes stockaient les attributs comme des champs typés,
elles devaient donc préfixer `attributes.`, ajouter un suffixe de type
(`_string`, `_int`) et utiliser une liste `[ ]` pour plusieurs valeurs. Le
langage de requête actuel supprime ces trois éléments — référencez les champs
directement et utilisez `OR` au lieu d'une liste :

<CodeGroup>
  ```text Old query theme={null}
  message:"API request" attributes.user_id_int=12345 severity=[info, warn]
  ```

  ```text New query theme={null}
  message:"API request" user.id=12345 (severity=info OR severity=warn)
  ```
</CodeGroup>

Une requête qui utilise encore la syntaxe héritée renvoie un `422` avec le
slug d'erreur `legacy_log_query_syntax`.
