Recherchez des lignes de journal avec l’API publique (V2).
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.
Si vous créez un agent ou un assistant IA, AppSignal MCP
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.
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 :
https://appsignal.com/<organization>/sites/<SITE_ID>/logs/sources/<SOURCE_ID>
Rechercher des lignes de journal
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. |
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
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
{
"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 }
}
}
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. |
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").
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 :
{
"message": "API request completed",
"severity": "info",
"duration": 156.7,
"status_code": 200,
"user": {
"id": 12345,
"roles": ["admin", "developer"],
"location.country": "US"
}
}
- 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 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.
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 :
message:"API request" attributes.user_id_int=12345 severity=[info, warn]
Une requête qui utilise encore la syntaxe héritée renvoie un 422 avec le
slug d’erreur legacy_log_query_syntax.