Explorer les logs avancés sur Google BigQuery (GBQ)
Vue d’ensemble
Il est important de savoir que vous avez en permanence accès à des logs plus complets hors de l’application Addingwell, et plus particulièrement au détail des requêtes qui échouent en sortie du serveur.
Les données sont accessibles via GBQ, où votre conteneur server-side envoie son activité brute dans un dataset dédié (appelé <your-dataset> ci-dessous).
Le dataset expose les tables suivantes ; l’essentiel de votre travail utilisera le premier groupe :
Tables utiles pour vos investigations :
| Table | Contenu |
|---|---|
tagging_outgoing_requests | Une ligne par appel HTTP sortant du conteneur vers les vendors (Google Analytics, Meta, Snapchat, …) avec l’URL complète, les headers, le body et la réponse. |
tagging_requests | Une ligne par hit reçu par le conteneur SST, avec l’URL complète, les headers, le body et la réponse renvoyée au navigateur. Alimentée uniquement après activation des logs avancés. |
gtm_monitoring | Monitoring par événement des déclenchements de balises : quelles balises se sont exécutées pour un événement, leur statut, leur temps d’exécution, la décision de consentement par vendor, et les données brutes de l’événement. |
gtm_tags | Catalogue des définitions de balises GTM versionné dans le temps (id, nom, template, état de pause). |
Tables internes et de référence (données partielles ou de référence interne, rarement nécessaires) :
| Table | Contenu |
|---|---|
incoming_requests | Table technique : une ligne par hit reçu par le conteneur SST, avec identifiants hashés et métadonnées uniquement (vérification origin/host, détection d’adblocker), sans headers ni body. |
didomi_vendor_registry | Table de référence associant un vendor_id Didomi à son vendor_name lisible. |
Par défaut, l’export GBQ ne contient que les requêtes sortantes en échec. Si vous avez besoin du détail des requêtes sortantes réussies ou des requêtes entrantes complètes (tagging_requests), contactez notre équipe à [email protected] pour demander l’activation des logs avancés. L’activation n’est pas rétroactive ; seuls les événements postérieurs à l’activation seront disponibles.
Si vous n’avez besoin que d’une vue de plus haut niveau de ce qui se passe côté serveur, le monitoring intégré à l’application couvre la plupart des cas ; voir Monitoring des performances server-side.
Prérequis
Pour exécuter des requêtes sur le dataset GBQ, il vous faut :
- Un compte associé à GCP (les adresses Gmail le sont nativement ; les autres, par ex. Outlook, doivent d’abord être liées à un compte Google) qui est aussi membre du conteneur Addingwell.
- Un projet GBQ associé à ce compte, pour pouvoir exécuter des requêtes sur le dataset.
- L’accès GBQ accordé depuis Addingwell (voir la section suivante).
Donner l’accès GBQ
Vous devez avoir le rôle Admin ou Owner sur le conteneur pour accorder ou retirer l’accès GBQ, à vous-même ou à un autre utilisateur.
- Dans Addingwell, ouvrez la section Team dans la navigation en bas à gauche.
- Cliquez sur le menu à trois points à droite de l’utilisateur(ice) à qui vous voulez donner l’accès.
- Sélectionnez Grant BigQuery Access.
- Une icône violette de loupe apparaît, indiquant que l’utilisateur(ice) a désormais les droits d’accès aux logs.

Pour retirer l’accès, suivez les mêmes étapes : l’option Grant BigQuery Access est remplacée par Remove BigQuery Access.
- Cliquez sur l’icône violette pour être redirigé(e) vers les tables GBQ.
Exécuter une requête nécessite aussi qu’un projet Google Cloud soit sélectionné dans GBQ. N’importe quel projet de votre propre compte convient (il ne sert qu’à exécuter la requête, pas à stocker les logs) ; si vous n’en avez pas, créez-en un dans la console Google Cloud au préalable.
Où exécuter les requêtes
Une fois sur GBQ, ouvrez votre dataset, cliquez sur + Compose new query (ou le + à côté des onglets existants), collez une requête ci-dessous, puis cliquez sur Run.

- Nouvelle requête : cliquez sur le + pour ouvrir un nouvel onglet de requête, puis collez votre requête dans l’éditeur.
- Run : exécute la requête ; le quota de traitement à la demande utilisé s’affiche juste sous l’éditeur.
- Results : la vue par défaut des lignes retournées, une colonne par champ.
- Visualization : transforme le jeu de résultats en graphique rapide sans quitter GBQ, ce qui peut être utile pour certaines requêtes (voir par exemple le #4 de la section suivante).
<your-dataset> dans les exemples est un placeholder pour votre projet et dataset : remplacez-le par ce que l’explorateur GBQ affiche une fois arrivé(e) via l’icône violette, suivant un motif du type prod_environment.clientname_raw (une référence complète de table s’écrit donc prod_environment.clientname_raw.tagging_outgoing_requests).
La plupart des tables sont partitionnées sur leur colonne de timestamp : nous recommandons une clause WHERE sur request_at / event_timestamp dans chaque requête pour la garder rapide et peu coûteuse.
Cas d’usage courants
Cette section rassemble quelques cas d’usage courants qui pourraient vous être utiles. Ces requêtes sont volontairement simples : pour des cas spécifiques, vous pourriez avoir besoin de filtres supplémentaires (par événement, sous-requêtes imbriquées, etc.).
Dépliez une requête ci-dessous pour en voir le détail.
1. Afficher vos requêtes sortantes en échec
Par défaut, l’export ne contient déjà que les requêtes sortantes en échec : c’est donc le moyen le plus rapide de voir les requêtes en erreur.
SELECT *
FROM `<your-dataset>.tagging_outgoing_requests`
WHERE TIMESTAMP_TRUNC(request_at, DAY) = TIMESTAMP("2026-04-20") -- replace with the date you want
AND response_status_code >= 400
LIMIT 1000;2. Inspecter le payload en échec d’un vendor
Quand un vendor rejette un appel, le détail utile se trouve dans request_body. Cette requête extrait les champs clés directement d’un payload Meta (CAPI) pour repérer celui qui est mal formé. Les chemins JSON sont spécifiques à Meta ; adaptez-les pour d’autres vendors.
SELECT
request_at,
JSON_VALUE(request_body, "$.data[0].event_name") AS event_name,
JSON_VALUE(request_body, "$.data[0].event_source_url") AS event_source_url,
JSON_VALUE(request_body, "$.data[0].custom_data.currency") AS currency,
JSON_VALUE(request_body, "$.data[0].custom_data.value") AS value
FROM `<your-dataset>.tagging_outgoing_requests`
WHERE host LIKE "%facebook%" -- replace with the vendor you investigate
AND TIMESTAMP_TRUNC(request_at, DAY) = TIMESTAMP("2026-04-20") -- replace with the date you want
AND response_status_code >= 400
LIMIT 1000;3. Suivre le taux de succès vs erreurs par jour pour un vendor
Utile pour confirmer si une erreur est un pic isolé ou un problème durable. Remplacez host par le vendor que vous investiguez. Des filtres supplémentaires (par exemple sur un événement ou un endpoint spécifique) peuvent vous aider à affiner l’investigation.
SELECT
TIMESTAMP_TRUNC(request_at, DAY) AS time_bucket,
COUNTIF(response_status_code = 200) AS success_count,
COUNTIF(response_status_code >= 400) AS error_count,
SAFE_DIVIDE(COUNTIF(response_status_code >= 400), COUNT(*)) * 100 AS error_rate_pct
FROM `<your-dataset>.tagging_outgoing_requests`
WHERE request_at >= "2026-04-20" -- replace with your start date
AND host LIKE "%facebook%" -- replace with the vendor you investigate
GROUP BY time_bucket
ORDER BY time_bucket ASC;4. Répartition Consent Mode par jour
Compte les événements par état de Google Consent Mode et par jour, avec la part de chacun. G111 = tout accordé, G100 = tout refusé ; G110 / G101 sont des états partiels, et vide/undefined signifie qu’aucun signal n’a été enregistré.
SELECT
TIMESTAMP_TRUNC(event_timestamp, DAY) AS day,
SUM(IF(consent_settings LIKE '%G111%', 1, 0)) AS consent_G111,
SUM(IF(consent_settings LIKE '%G110%', 1, 0)) AS consent_G110,
SUM(IF(consent_settings LIKE '%G101%', 1, 0)) AS consent_G101,
SUM(IF(consent_settings LIKE '%G100%', 1, 0)) AS consent_G100,
SUM(IF(consent_settings = "" OR consent_settings IS NULL, 1, 0)) AS consent_undefined,
ROUND(SUM(IF(consent_settings LIKE '%G111%', 1, 0)) / COUNT(*) * 100, 2) AS rate_G111,
ROUND(SUM(IF(consent_settings LIKE '%G100%', 1, 0)) / COUNT(*) * 100, 2) AS rate_G100
-- add rate columns for G110 / G101 / undefined the same way if needed
FROM `<your-dataset>.gtm_monitoring`
WHERE TIMESTAMP_TRUNC(event_timestamp, DAY) BETWEEN TIMESTAMP('2026-04-01') AND TIMESTAMP('2026-04-30') -- replace with your period
AND event_name = "purchase" -- replace with the event you want
GROUP BY day
ORDER BY day;Pour un total unique sur toute la période au lieu d’un détail par jour, retirez la colonne day et le GROUP BY.
5. Détecter les bots par user-agent et IP
Regroupe les hits entrants par user-agent et IP transmise. Un agent ou une IP responsable d’une part énorme des hits est généralement un bot. Cette requête lit les requêtes entrantes complètes : elle nécessite donc tagging_requests (logs avancés) actif.
-- Requires the full incoming request logs (tagging_requests); ask support to activate them.
SELECT
JSON_VALUE(request_headers, "$.user-agent") AS user_agent,
JSON_VALUE(request_headers, "$.x-forwarded-for") AS x_forwarded_for,
MIN(request_at) AS first_seen,
MAX(request_at) AS last_seen,
COUNT(*) AS hits
FROM `<your-dataset>.tagging_requests`
WHERE TIMESTAMP_TRUNC(request_at, DAY) BETWEEN TIMESTAMP("2026-04-01") AND TIMESTAMP("2026-04-30") -- replace with your period
GROUP BY user_agent, x_forwarded_for
ORDER BY hits DESC;6. Retrouver l’id d’une balise à partir de son nom
gtm_monitoring ne stocke que les ids de balises. Pour retrouver l’id à partir du nom (ex. « Meta CAPI Purchase »), requêtez la dernière version de gtm_tags :
SELECT tag_id, name, is_paused, template_name
FROM `<your-dataset>.gtm_tags`
WHERE CAST(version_id AS INT64) = (
SELECT MAX(CAST(version_id AS INT64))
FROM `<your-dataset>.gtm_tags`
)
AND name LIKE "%Meta%CAPI%" -- replace with (part of) your tag name
ORDER BY name;7. Inspecter un événement GA4 entrant (ex. purchase)
Suivez un événement GA4 de bout en bout : cette requête lit les hits purchase entrants et en extrait les paramètres GA4 clés (measurement id, transaction id, valeur, devise, état de consentement) pour vérifier ce qui est réellement arrivé. Fonctionne sur les hits GET et POST (request_body ou query).
-- Requires the full incoming request logs (tagging_requests); ask support to activate them.
SELECT
request_at,
REGEXP_EXTRACT(query, r'(?:^|&)tid=([^&]+)') AS tid,
REGEXP_EXTRACT(IF(request_body > "", request_body, query), r'(?:^|&)en=([^&]+)') AS event_name,
REGEXP_EXTRACT(IF(request_body > "", request_body, query), r'(?:^|&)ep\.transaction_id=([^&]+)') AS transaction_id,
REGEXP_EXTRACT(IF(request_body > "", request_body, query), r'(?:^|&)epn\.value=([^&]+)') AS value,
REGEXP_EXTRACT(query, r'(?:^|&)cu=([^&]+)') AS currency,
REGEXP_EXTRACT(query, r'(?:^|&)gcs=([^&]+)') AS gcs
FROM `<your-dataset>.tagging_requests`
WHERE TIMESTAMP_TRUNC(request_at, DAY) = TIMESTAMP("2026-04-20") -- replace with the date you want
AND (request_body LIKE "%en=purchase%" OR query LIKE "%en=purchase%") -- replace purchase with your event
ORDER BY request_at;8. Expressions régulières utiles
Petits snippets pour extraire une valeur de request_body ou query :
-- Extract a transaction_id from the body
REGEXP_EXTRACT(request_body, r'ep\.transaction_id=([^&]+)') AS transaction_id
-- Extract a header from the request_headers JSON column
JSON_VALUE(request_headers, "$.user-agent") AS user_agent
JSON_VALUE(request_headers, "$.x-forwarded-for") AS x_forwarded_forRéférence des tables
Tables utiles pour vos investigations
tagging_outgoing_requests
Chaque appel HTTP sortant du conteneur SST vers un endpoint vendor (Google, Meta, TikTok, Snapchat, …). C’est la table que vous utiliserez le plus pour debugger les erreurs de balises.
| Colonne | Type | Description |
|---|---|---|
request_at | TIMESTAMP | Date de la requête sortante (clé de partition). |
response_at | TIMESTAMP | Date de la réponse. |
host | STRING | Host de la requête (ex. graph.facebook.com). |
method | STRING | Méthode HTTP. |
url | STRING | URL complète. |
query | STRING | Query string de la requête. |
request_headers | JSON | Headers de la requête. |
request_body | STRING | Body de la requête (souvent JSON ou URL-encoded). |
response_status_code | INT64 | Code de statut HTTP retourné par le vendor. |
response_headers | JSON | Headers de la réponse. |
response_body | STRING | Body de la réponse. |
Tables internes et de référence
Ces tables alimentent des fonctionnalités Addingwell et contiennent des données partielles ou de référence interne ; vous en aurez rarement besoin au quotidien. Elles sont documentées ici par souci d’exhaustivité.
incoming_requests
Table technique : chaque hit reçu par le conteneur server-side, avant tout traitement de balise, métadonnées uniquement. Les identifiants sont hashés en FarmHash : aucune PII n’est stockée en clair.
| Colonne | Type | Description |
|---|---|---|
request_at | TIMESTAMP | Date de la requête (clé de partition). |
client_id_hashed | INT64 | ClientId hashé en FarmHash. |
master_id_hashed | INT64 | MasterID hashé en FarmHash. |
user_agent_hashed | INT64 | Header User-Agent hashé en FarmHash. |
fingerprint | INT64 | Fingerprint hashé en FarmHash. |
origin_domain | STRING | Origin de la requête. |
host_domain | STRING | Host de la requête. |
same_domain | BOOL | true quand origin_domain = host_domain. |
is_client_id_restored | BOOL | Indique si le client id a dû être restauré sur cette requête. |
adblocker_detected | BOOL | Indique si un adblocker a été détecté. |
Cette table ne contient pas le body, la query string ni les headers ; c’est une table technique. Pour le détail complet des requêtes entrantes, voir tagging_requests, disponible une fois les logs avancés activés.
Si vous avez une question, contactez-nous à [email protected], nous serons ravis de vous aider !