Créer des requêtes en plusieurs étapes

Compatible avec :

Ce document explique comment les requêtes multi-étapes dans YARA-L vous permettent d'intégrer la sortie d'une étape de requête directement dans l'entrée d'une étape ultérieure. Ce processus vous permet de mieux contrôler la transformation des données qu'une requête monolithique unique.

Intégrer les requêtes en plusieurs étapes aux fonctionnalités existantes

Les requêtes à plusieurs étapes fonctionnent en parallèle avec les fonctionnalités existantes suivantes de Google Security Operations :

  • Règles de détection composite : les requêtes en plusieurs étapes complètent les règles de détection composite en comblant le fossé entre la détection automatisée et l'investigation active. Alors que les règles composites excellent dans l'identification de corrélations complexes et multi-événements sur de longues périodes, les requêtes multi-étapes permettent aux analystes de passer de ces détections à des recherches itératives en temps réel pour valider et délimiter instantanément une menace en cours.

  • Périodes et règles à événements multiples : vous pouvez utiliser des requêtes à plusieurs étapes pour détecter les anomalies en comparant différentes périodes dans vos données. Par exemple, vous pouvez utiliser vos requêtes initiales pour établir une référence sur une période prolongée, puis utiliser des requêtes ultérieures pour évaluer l'activité récente par rapport à cette référence. Vous pouvez également utiliser des règles multi-événements pour créer un type de comparaison similaire.

Les requêtes à plusieurs étapes en YARA-L sont compatibles avec les tableaux de bord et la recherche.

Les jointures permettent de corréler des données provenant de plusieurs sources pour fournir plus de contexte à une enquête. En associant des événements, des entités et d'autres données connexes, vous pouvez examiner des scénarios d'attaque complexes. Pour en savoir plus, consultez Utiliser des jointures dans Search.

Remarques importantes

Lorsque vous configurez une requête à plusieurs étapes, tenez compte des points suivants :

  • Étape de limite : les requêtes à plusieurs étapes doivent contenir entre une et quatre étapes nommées, en plus de l'étape racine.
  • Syntaxe de l'ordre : définissez toujours la syntaxe de l'étape nommée avant de définir la syntaxe de l'étape racine.

Nous vous recommandons de consulter les problèmes connus et les solutions de contournement recommandées ci-dessous lorsque vous implémentez des requêtes à plusieurs étapes :

  • Toutes les requêtes à plusieurs étapes se comportent comme des requêtes de recherche de statistiques (la sortie se compose de statistiques agrégées plutôt que de lignes d'événements ou de tableaux de données non agrégées).

  • Les performances des jointures avec des événements UDM et d'entité d'un côté peuvent être faibles en raison de la taille de cet ensemble de données. Nous vous recommandons vivement de filtrer autant que possible les événements UDM et d'entité du côté de la jointure (par exemple, en filtrant sur le type d'événement).

Pour obtenir des conseils généraux sur les pratiques recommandées, consultez Bonnes pratiques YARA-L 2.0. Pour obtenir des informations spécifiques aux jointures, consultez Bonnes pratiques.

Terminologie clé

Dans le contexte des jointures, une étape avec fenêtre fait référence à une étape avec une section match contenant une fenêtre. En revanche, une étape de table ne génère pas de fenêtres.

Créer une requête YARA-L en plusieurs étapes

Pour créer une requête YARA-L à plusieurs étapes, procédez comme suit.

Structure et syntaxe des étapes

Accédez à Investigation > Recherche. Suivez cette structure lorsque vous définissez les étapes de votre requête :

Syntaxe : utilisez la syntaxe suivante pour nommer chaque étape et la séparer des autres :

stage <stage name> { }

  • Accolades : placez toute la syntaxe de l'étape entre accolades {}.

  • Ordre : définissez la syntaxe pour toutes les étapes nommées avant de définir l'étape racine.

  • Référencement : chaque étape peut faire référence à des étapes définies plus tôt dans la requête.

  • Étape racine : une requête doit comporter une étape racine, qui est traitée après toutes les étapes nommées.

L'étape daily_stats de l'exemple suivant collecte les statistiques réseau quotidiennes :

stage daily_stats {
  metadata.event_type = "NETWORK_CONNECTION"
  $source = principal.hostname
  $target = target.ip
  $source != ""
  $target != ""
  match:
    $source, $target by day
  outcome:
    $exchanged_bytes = sum(network.sent_bytes + network.received_bytes)
}

Accéder à la sortie de l'étape

La sortie d'une étape nommée est accessible aux étapes suivantes à l'aide des champs d'étape. Les champs d'étape correspondent aux variables match et outcome de l'étape. Ils peuvent être utilisés de la même manière que les champs du modèle de données unifié (UDM).

Utilisez la syntaxe suivante pour accéder à un champ d'étape :

$<stage name>.<variable name>

Facultatif : Accéder aux codes temporels des fenêtres

Si une étape nommée utilise une fenêtre glissante, de saut ou de tumbling, accédez au début et à la fin de la fenêtre pour chaque ligne de sortie à l'aide de ces champs réservés :

  • $<stage name>.window_start

  • $<stage name>.window_end

window_start et window_end sont des champs entiers exprimés en secondes depuis l'epoch Unix. La taille des fenêtres peut varier selon l'étape.

Exemples de requêtes en plusieurs étapes

Les exemples de cette section vous aideront à illustrer la façon dont vous pouvez créer une requête YARA-L complète en plusieurs étapes.

Exemple : Rechercher les connexions réseau inhabituellement actives (heures)

Cet exemple YARA-L en plusieurs étapes identifie les paires d'adresses IP présentant une activité réseau supérieure à la normale, en ciblant les paires qui maintiennent une activité élevée pendant plus de trois heures. La requête inclut deux composants obligatoires : l'étape nommée hourly_stats et l'étape root.

L'étape hourly_stats recherche les paires principal.ip et target.ip avec des niveaux d'activité réseau élevés.

Cette étape renvoie une seule valeur horaire pour les champs suivants :

  • Statistiques pour l'adresse IP source (chaîne) : $hourly_stats.src_ip

  • Statistiques pour l'adresse IP de destination (chaîne) : $hourly_stats.dst_ip

  • Statistiques sur le nombre d'événements (entier) : $hourly_stats.count

  • Écart-type des octets reçus (float) : $hourly_stats.std_recd_bytes

  • Nombre moyen d'octets reçus (float) : $hourly_stats.avg_recd_bytes

  • Heure de début du bucket horaire en secondes depuis l'epoch Unix (nombre entier) : $hourly_stats.window_start

  • Heure de fin du bucket horaire en secondes depuis l'epoch Unix (nombre entier) : $hourly_stats.window_end

L'étape racine traite la sortie de l'étape hourly_stats. Il calcule les statistiques pour les paires principal.ip et target.ip dont l'activité dépasse le seuil spécifié par $hourly_stats. Il filtre ensuite les paires ayant enregistré plus de trois heures d'activité élevée.


stage hourly_stats {
  metadata.event_type = "NETWORK_CONNECTION"
  $src_ip = principal.ip
  $dst_ip = target.ip
  $src_ip != ""
  $dst_ip != ""

  match:
    $src_ip, $dst_ip by hour

  outcome:
    $count = count(metadata.id)
    $avg_recd_bytes = avg(network.received_bytes)
    $std_recd_bytes = stddev(network.received_bytes)

  condition:
    $avg_recd_bytes > 100 and $std_recd_bytes > 50
}

$src_ip = $hourly_stats.src_ip
$dst_ip = $hourly_stats.dst_ip
$time_bucket_count = strings.concat(timestamp.get_timestamp($hourly_stats.window_start), "|", $hourly_stats.count)

match:
 $src_ip, $dst_ip

outcome:
 $list = array_distinct($time_bucket_count)
 $count = count_distinct($hourly_stats.window_start)

condition:
 $count > 3

Si vous modifiez la condition de correspondance dans l'étape racine comme suit, vous pouvez introduire une agrégation par jour pour la requête à plusieurs étapes.

match:
 $src_ip, $dst_ip by day

Exemple : Rechercher les connexions réseau inhabituellement actives (à l'aide du score Z)

Cette requête en plusieurs étapes compare l'activité réseau moyenne quotidienne à l'activité du jour à l'aide d'un calcul de score Z (qui mesure le nombre d'écarts-types par rapport à la moyenne). Cette requête recherche efficacement une activité réseau anormalement élevée entre les ressources internes et les systèmes externes.

Prérequis : La période de la requête doit être supérieure ou égale à deux jours et inclure le jour actuel pour que le score Z calculé soit efficace.

Cette requête à plusieurs étapes inclut les étapes daily_stats et root, qui fonctionnent ensemble pour calculer le score Z de l'activité réseau :

  • L'étape daily_stats effectue l'agrégation quotidienne initiale. Il calcule le nombre total d'octets échangés chaque jour pour chaque paire d'adresses IP (source et target), puis renvoie les champs d'étape suivants (correspondant aux colonnes des lignes de sortie) :

    • $daily_stats.source : singulier, chaîne
    • $daily_stats.target : singulier, chaîne
    • $daily_stats.exchanged_bytes : singulier, entier
    • $daily_stats.window_start : singulier, entier
    • $daily_stats.window_end : singulier, entier
  • L'étape racine agrège la sortie de l'étape daily_stats pour chaque paire d'adresses IP. Il calcule la moyenne et l'écart-type des octets échangés quotidiennement sur l'ensemble de la plage de recherche, ainsi que les octets échangés aujourd'hui. Il utilise ces trois valeurs calculées pour déterminer le score Z.

  • Le résultat liste les scores Z de toutes les paires d'adresses IP du jour, triées par ordre décroissant.

// Calculate the total bytes exchanged per day by source and target

stage daily_stats {
  metadata.event_type = "NETWORK_CONNECTION"
  $source = principal.hostname
  $target = target.ip
  $source != ""
  $target != ""

  match:
    $source, $target by day

  outcome:
    $exchanged_bytes = sum(network.sent_bytes + network.received_bytes)
}

// Calculate the average per day over the time window and compare with the bytes exchanged today

$source = $daily_stats.source
$target = $daily_stats.target
$date = timestamp.get_date($daily_stats.window_start)

match:
  $source, $target

outcome:
  $today_bytes = sum(if($date = timestamp.get_date(timestamp.current_seconds()), cast.as_int($daily_stats.exchanged_bytes), 0))
  $average_bytes = window.avg($daily_stats.exchanged_bytes)
  $stddev_bytes = window.stddev($daily_stats.exchanged_bytes)
  $zscore = ($today_bytes - $average_bytes) / $stddev_bytes

order:
  $zscore desc

Exporter des variables non agrégées à partir d'étapes

Dans une requête à plusieurs étapes typique, les données sont souvent transmises entre les étapes par le biais d'un processus d'agrégation, qui peut "réduire" plusieurs événements en un seul récapitulatif. Toutefois, dans certains cas, vous devez conserver les détails spécifiques de chaque événement, comme un ID de processus unique ou une ligne de commande spécifique, sans perdre cette précision. Pour ce faire, vous pouvez exporter directement les variables sans fonction de regroupement.

Les étapes nommées peuvent inclure une section outcome non agrégée. Cela signifie que les variables définies dans cette section outcome sont générées directement à partir de l'étape, ce qui permet aux étapes suivantes d'y accéder en tant que champs d'étape sans nécessiter d'agrégation groupée.

Cette information est utile, car elle permet de :

  • Fidélité des données préservée : vous pouvez transmettre les attributs exacts d'un événement (par exemple, un chemin d'accès spécifique à un fichier) à l'étape suivante sans avoir à utiliser une agrégation de "valeur de substitution" artificielle comme max() ou array_distinct().
  • Réduit la complexité des requêtes : simplifie votre logique YARA-L en supprimant la nécessité d'une section match ou d'instructions de regroupement juste pour transporter une valeur de l'étape 1 à l'étape 2.
  • Optimisation des performances : en contournant le moteur d'agrégation, le système peut diffuser des données entre les étapes de manière plus efficace, ce qui permet de réduire les temps d'exécution pour les recherches complexes et à volume élevé.

Exemple : Exporter une variable non agrégée

Cet exemple montre comment exporter des variables non agrégées. Notez la logique suivante :

  • L'étape top_5_bytes_sent recherche les cinq événements présentant la plus forte activité réseau.

  • L'étape top_5_bytes_sent génère les champs d'étape suivants correspondant aux colonnes des lignes de sortie :

    • $top_5_bytes_sent.bytes_sent : singulier, entier
    • $top_5_bytes_sent.timestamp_seconds : singulier, entier
  • L'étape root calcule les codes temporels les plus récents et les plus anciens pour les cinq événements ayant la plus forte activité réseau.

stage top_5_bytes_sent {
  metadata.event_type = "NETWORK_CONNECTION"
  network.sent_bytes > 0

  outcome:
    $bytes_sent = network.sent_bytes
    $timestamp_seconds = metadata.event_timestamp.seconds

  order:
    $bytes_sent desc

  limit:
    5
}

outcome:
  $latest_timestamp = timestamp.get_timestamp(max($top_5_bytes_sent.timestamp_seconds))
  $earliest_timestamp = timestamp.get_timestamp(min($top_5_bytes_sent.timestamp_seconds))

Implémenter le fenêtrage dans les requêtes à plusieurs étapes

Dans les détections en plusieurs étapes, le fenêtrage vous permet de définir des limites temporelles spécifiques pour la corrélation des événements au sein d'une étape. En partitionnant les données dans des buckets temporels distincts, comme une fenêtre glissante de cinq minutes ou une fenêtre basculante d'une heure, vous pouvez identifier des schémas tels que les attaques par force brute ou les comportements de balise qui ne deviennent visibles que lorsqu'ils sont analysés en tant que séquence limitée dans le temps.

Les requêtes à plusieurs étapes sont compatibles avec tous les types de fenêtrage (par saut, glissant et cumulatif) dans les étapes nommées. Cela vous permet de transmettre des données contextualisées dans le temps entre les étapes. Par exemple, vous pouvez utiliser l'étape 1 pour identifier une fenêtre d'événement à haute fréquence et l'étape 2 pour corréler cette fenêtre spécifique avec les actions administratives ultérieures.

Si une étape nommée inclut une fenêtre, le début et la fin de la fenêtre pour chaque ligne de sortie sont accessibles à l'aide des champs réservés suivants :

  • $stage_window_start : code temporel Unix marquant le début de la période.
  • $stage_window_end : horodatage Unix marquant la fin de la période.

Pour en savoir plus sur le fenêtrage, consultez Logique de fenêtrage YARA-L 2.0.

Cas d'utilisation courants

  • Détection séquentielle : une fois le délai spécifique d'un pic de tentatives de connexion ayant échoué détecté, une deuxième étape recherche une connexion réussie peu de temps après.
  • Analyse de la durée : calcul du "temps de compromission" en comparant le $stage_window_start d'une étape d'exploitation initiale aux codes temporels des événements d'une étape ultérieure.
  • Définition de référence historique : utilisation de fenêtres pour comparer le nombre d'événements actuels aux variables de sortie d'une fenêtre précédente.

Exemple : fenêtre de saut

L'exemple suivant montre comment utiliser des fenêtres de saut dans une requête à plusieurs étapes :

  • L'étape hourly_stats recherche les paires d'adresses IP qui présentent une activité réseau élevée au cours de la même heure.

  • hourly_stats génère les champs d'étape suivants correspondant aux colonnes des lignes de sortie :

    • $hourly_stats.src_ip : singulier, chaîne
    • $hourly_stats.dst_ip : singulier, chaîne
    • $hourly_stats.count : singulier, entier
    • $hourly_stats.std_recd_bytes : singulier, float
    • $hourly_stats.avg_recd_bytes : singulier, float
    • $hourly_stats.window_start : singulier, entier
    • $hourly_stats.window_end : singulier, entier
  • L'étape racine filtre les paires d'adresses IP présentant plus de trois heures d'activité élevée. Les heures peuvent se chevaucher en raison de l'utilisation d'une fenêtre récurrente dans l'étape hourly_stats.

stage hourly_stats {
  metadata.event_type = "NETWORK_CONNECTION"
  $src_ip = principal.ip
  $dst_ip = target.ip
  $src_ip != ""
  $dst_ip != ""

  match:
    $src_ip, $dst_ip over 1h

  outcome:
    $count = count(metadata.id)
    $avg_recd_bytes = avg(network.received_bytes)
    $std_recd_bytes = stddev(network.received_bytes)

  condition:
    $avg_recd_bytes > 100 and $std_recd_bytes > 50
}

$src_ip = $hourly_stats.src_ip
$dst_ip = $hourly_stats.dst_ip
$time_bucket_count = strings.concat(timestamp.get_timestamp($hourly_stats.window_start), "|", $hourly_stats.count)

match:
 $src_ip, $dst_ip

outcome:
 $list = array_distinct($time_bucket_count)
 $count = count_distinct($hourly_stats.window_start)

condition:
 $count > 3

Jointures internes dans les requêtes en plusieurs étapes

Les jointures internes vous permettent de corréler des données entre différentes étapes ou types de sources, ce qui crée des workflows analytiques complexes, comme la comparaison d'événements en temps réel avec des références statistiques précalculées. En associant des étapes, vous pouvez enrichir la télémétrie brute avec des données avec état (comme des médianes ou des tables de référence) pour identifier les valeurs aberrantes ou les menaces multivecteurs qu'un filtre d'événements à une seule étape manquerait.

Les jointures internes sont acceptées dans les étapes des requêtes à plusieurs étapes et entre elles. La fonctionnalité de jointure interne est compatible avec les types suivants :

  • UDM et UDM : corréler deux ensembles différents d'événements de sécurité (par exemple, faire correspondre un événement de connexion avec un accès à un fichier ultérieur).
  • UDM et ECG : fusion des données d'événement avec les informations du graphique de contexte des entités pour l'enrichissement des identités ou des ressources.
  • UDM et tableau de données : joindre des événements en direct à des listes de référence statiques ou importées (par exemple, une liste d'assets à forte valeur ou de plages d'adresses IP spécifiques à un service).

L'exemple suivant montre comment configurer une jointure sans correspondance (une jointure effectuée dans la section outcome ou events plutôt que dans la section match) entre des événements UDM et une étape de table calculée. Ce modèle vous permet d'effectuer une détection statistique des anomalies, comme le montre le calcul suivant de la déviation absolue moyenne (MAD) :

  • Étape median : calcule la médiane des octets envoyés pour chaque paire hôte source/adresse IP cible.
    • $median.host : singulier, chaîne
    • $median.target : singulier, chaîne
    • $median.median : singulier, float
  • Étape absolute_deviations : joint chaque événement UDM à la ligne correspondante de l'étape médiane. Cela vous permet de calculer l'écart absolu des octets envoyés pour chaque événement individuel par rapport à son groupe de pairs.
    • $absolute_deviations.host : singulier, chaîne
    • $absolute_deviations.target : singulier, chaîne
    • $absolute_deviations.absolute_deviation : singulier, float
  • Étape racine : calcule la moyenne de ces écarts absolus pour tous les événements UDM afin d'établir un seuil d'anomalie.

Exemple : Configurer une jointure sans correspondance

stage median {
  metadata.event_type = "NETWORK_CONNECTION"
  $host = principal.hostname
  $target = target.ip

  match:
    $host, $target

  outcome:
    $median = window.median(network.sent_bytes, true)
}

stage absolute_deviations {
  metadata.event_type = "NETWORK_CONNECTION"
  $join_host = principal.hostname
  $join_host = $median.host
  $join_target = target.ip[0]
  $join_target = $median.target

  outcome:
    $host = $join_host
    $target = $join_target
    $absolute_deviation = math.abs(network.sent_bytes - $median.median)
}

$host = $absolute_deviations.host
$target = $absolute_deviations.target

match:
  $host, $target

outcome:
  $mean_absolute_deviation = avg($absolute_deviations.absolute_deviation)

Exemple : Jointure sans correspondance entre une étape de fenêtre et une étape de table

L'exemple suivant montre comment configurer une jointure sans correspondance entre une étape de fenêtre et une étape de table dans une requête à plusieurs étapes.

  • L'étape hourly_stats calcule le nombre total d'octets envoyés pour chaque paire d'hôtes source et de destination, et pour chaque tranche horaire.
  • L'étape hourly_stats génère les champs d'étape suivants correspondant aux colonnes des lignes de sortie :
    • $hourly_stats.source_host : singulier, chaîne
    • $hourly_stats.dst_host : singulier, chaîne
    • $hourly_stats.total_bytes_sent : singulier, float
    • $hourly_stats.window_start : singulier, entier
    • $hourly_stats.window_end : singulier, entier
  • L'étape agg_stats calcule la moyenne et l'écart-type des octets par heure pour chaque paire d'hôtes source et cible.
  • agg_stats génère les champs d'étape suivants correspondant aux colonnes des lignes de sortie :

    • $agg_stats.source_host : singulier, chaîne
    • $agg_stats.dst_host : singulier, chaîne
    • $agg_stats.avg_bytes_sent : singulier, float
    • $agg_stats.stddev_bytes_sent : singulier, float
  • L'étape racine joint chaque ligne de hourly_stats à la ligne de agg_stats pour la même paire d'hôtes source et cible. Pour chaque paire d'hôtes source et cible, il calcule le score Z à l'aide du nombre total d'octets envoyés pour le bucket de cette paire d'hôtes et des statistiques globales.

stage hourly_stats {
 $source_host = principal.hostname
 $dst_host = target.hostname
 principal.hostname != ""
 target.hostname != ""
 match:
   $source_host, $dst_host by hour
 outcome:
   $total_bytes_sent = sum(network.sent_bytes)
}

stage agg_stats {
  $source_host = $hourly_stats.source_host
  $dst_host = $hourly_stats.dst_host
  match:
    $source_host, $dst_host
  outcome:
   $avg_bytes_sent = avg($hourly_stats.total_bytes_sent)
   $stddev_bytes_sent = stddev($hourly_stats.total_bytes_sent)
}

$source_host = $agg_stats.source_host
$source_host = $hourly_stats.source_host

$dst_host = $agg_stats.dst_host
$dst_host = $hourly_stats.dst_host

outcome:
  $hour_bucket = timestamp.get_timestamp($hourly_stats.window_start)
  $z_score = ($hourly_stats.total_bytes_sent - $agg_stats.avg_bytes_sent)/$agg_stats.stddev_bytes_sent

Jointures croisées dans les requêtes en plusieurs étapes

Lorsque vous utilisez la recherche ou les tableaux de bord Google SecOps, les jointures croisées dans les requêtes à plusieurs étapes vous permettent de comparer des données d'événements UDM individuelles à des statistiques agrégées calculées dans d'autres étapes YARA-L.

Dans YARA-L, le mot clé cross join fonctionne avec une étape qui ne renvoie qu'une seule ligne.

Lorsqu'une jointure croisée est utilisée entre une étape avec une limite de 1 et un autre ensemble de données (par exemple, des événements UDM), la ligne unique générée par l'étape est ajoutée à chaque ligne de l'autre ensemble de données. Cela enrichit les données d'événement avec les statistiques globales.

Exemple : Trouver une activité de connexion inhabituelle

L'exemple suivant identifie les utilisateurs qui se connectent plus souvent que la normale. Pour ce faire, elle compare le nombre de connexions de chaque utilisateur (à l'aide de l'étape user_login_counts) au nombre moyen de connexions de tous les utilisateurs (à l'aide de l'étape total_users). Les utilisateurs qui se connectent un nombre inhabituel de fois peuvent être triés dans les résultats de recherche.

Vous utilisez ensuite le mot clé "jointure croisée" pour associer les résultats de l'étape total_users à ceux de l'étape user_login_counts.

stage user_login_counts {
    $user = principal.user.userid
    metadata.event_type = "USER_LOGIN"
    security_result.action = "ALLOW"

    match:
        $user

    outcome:
        $login_count = count(metadata.id)
}

stage total_users {
    outcome:
        $count = count($user_login_counts.user)
    limit:
        1
}

cross join $total_users, $user_login_counts

$login_count = $user_login_counts.login_count
$user = $user_login_counts.user
$tot_users = $total_users.count

// all users who logged in the same number of times are grouped together.
match:
    $login_count
outcome:
    $num_users = count($user)
    $frequency_percent = (count($user) / max($tot_users) ) * 100

Limites

Les requêtes à plusieurs étapes présentent les contraintes fonctionnelles et structurelles suivantes :

Exigences structurelles

Vous devez respecter les exigences structurelles suivantes lorsque vous créez vos requêtes :

  • Étape racine : une seule étape racine est autorisée par requête.
  • Étapes nommées : vous pouvez utiliser jusqu'à quatre étapes nommées.
  • Référence aux étapes : une étape ne peut faire référence qu'à des étapes définies logiquement avant elle dans la même requête.
  • Jointures croisées : une jointure croisée ne peut faire référence qu'à une étape qui renvoie une seule ligne. Pour répondre à cette exigence, vous devez inclure une limite (1) dans l'étape référencée. Cela est utile, car cela vous permet d'ajouter une seule statistique globale (comme un maximum ou une moyenne) à chaque ligne d'événement individuel à des fins de comparaison.
  • Jointures : un maximum de quatre jointures non liées à des tables de données est autorisé pour toutes les étapes.
  • Exigence de résultat : chaque étape nommée (à l'exception de l'étape racine) doit inclure une section match ou une section outcome, où la section outcome ne nécessite pas d'agrégation.

Limites de fenêtre et de compatibilité

Les restrictions suivantes s'appliquent à l'utilisation des fenêtres et à l'exécution des requêtes :

  • Fonctionnalités compatibles : les requêtes à plusieurs étapes fonctionnent dans la recherche et les tableaux de bord, mais cette fonctionnalité n'est pas compatible avec les règles.
  • Types de fenêtres : évitez de mélanger différents types de fenêtres dans une même requête.
  • Dépendance de fenêtre : une étape utilisant une fenêtre glissante ou un saut ne peut pas dépendre d'une autre étape qui utilise également une fenêtre glissante ou un saut.
  • Taille de la fenêtre bascule : la taille des fenêtres bascule peut varier d'une étape à l'autre, mais la différence de taille doit être inférieure à 720x.

Exemple : Différence d'agrégation des étapes (non valide)

La configuration suivante n'est pas valide, car un mois contient 44 640 minutes (44 640 / 1 > 720) :

Étape : monthly_stats { ... match: by month }

Racine : match: by minute

Exemple : Différence d'agrégation des étapes (valide)

Pour résoudre ce problème, assurez-vous que le ratio entre les étapes est plus petit. Par exemple, agrégez les données horaires dans un rapport quotidien :

Étape : daily_stats { ... match: by day }

Racine : match: by hour

Comme 24 (heures dans une journée) est inférieur à 720, le système peut mapper efficacement les données de l'étape à l'étape racine.

Limites concernant les étapes et les requêtes

Chaque étape d'une requête à plusieurs étapes est soumise à des contraintes spécifiques. La plupart des limites qui s'appliquent à une requête à une seule étape s'appliquent également à chaque étape individuelle :

  • Exigence de sortie : chaque étape doit générer au moins une variable de correspondance ou de résultat (champ d'étape).
  • Période de la requête :

    • Requêtes standards : la durée maximale est de 30 jours.
    • Requêtes à plusieurs étapes avec jointures sans correspondance : la durée maximale est de 14 jours.
  • Limites de taille de fenêtre : la taille de fenêtre maximale (hop, glissante ou tumbling) dépend de la présence ou non d'une jointure dans votre requête :

    • Avec des jointures : la taille maximale de la fenêtre pour tout type (hop, glissante ou tumbling) est de deux jours. Pour en savoir plus, consultez Limites des jointures de recherche.

    • Sans jointures (événement unique) :

    • Fenêtres glissantes et avec chevauchement : la durée maximale est de deux jours.

    • Fenêtres glissantes : la durée maximale passe à 30 jours.

  • Nombre maximal de variables de résultat :

    • 20 par défaut
    • 50 pour les clients ayant opté pour la limite supérieure
    • Limites des tableaux : une variable de résultat de type tableau ne peut pas contenir plus de 10 000 éléments.
  • Contraintes d'événement par requête :

    • Deux événements UDM maximum
    • Un événement ECG maximum
    • Maximum de deux tableaux de données

Limites de service et de performances

Les requêtes à plusieurs étapes sont soumises aux mêmes limites que les requêtes statistiques :

  • Requêtes statistiques : 120 QPH (API et UI).
  • Vues de recherche : 100 vues par minute.
  • Compatibilité des API : le système Google SecOps et l'API EventService.UDMSearch sont compatibles avec les jointures à plusieurs étapes, mais pas l'API SearchService.UDMSearch. Le système vous permet également d'exécuter des requêtes en plusieurs étapes sans jointures.

Limites d'événement et globales

Vous devez respecter les limites suivantes pour les événements et l'ensemble de la plate-forme :

Nombre maximal d'événements

Les requêtes à plusieurs étapes limitent strictement le nombre d'événements qu'elles peuvent traiter simultanément :

  • Événements UDM : vous ne pouvez pas ajouter plus de deux événements UDM.
  • Événements du graphique du contexte d'entité (ECG) : un seul événement ECG est autorisé.

Limites des requêtes globales

Ces contraintes à l'échelle de la plate-forme contrôlent la période et la quantité de données renvoyées par une requête à plusieurs étapes :

  • Période de la requête : la période maximale pour une requête standard est de 30 jours.
  • Ensemble de résultats total : la taille maximale de l'ensemble de résultats total est de 10 000 résultats.

Vous avez encore besoin d'aide ? Obtenez des réponses de membres de la communauté et de professionnels Google SecOps.