SQL-Beispielabfragen

Dieses Dokument enthält Beispielabfragen, mit denen Sie Ihre Log- und Tracedaten abfragen können.

Unterstützung von SQL-Sprachen

Für Abfragen auf der Seite Loganalysen werden GoogleSQL-Funktionen mit einigen Ausnahmen unterstützt.

Die folgenden SQL-Befehle werden für SQL-Abfragen, die über die Seite Loganalysen ausgegeben werden, nicht unterstützt:

  • DDL- und DML-Befehle
  • Benutzerdefinierte JavaScript-Funktionen
  • BigQuery ML-Funktionen
  • SQL-Variablen

Die folgenden Elemente werden nur unterstützt, wenn Sie ein verknüpftes Dataset über die Seiten BigQuery Studio und Looker Studio oder über das bq-Befehlszeilentool abfragen:

  • Benutzerdefinierte JavaScript-Funktionen
  • BigQuery ML-Funktionen
  • SQL-Variablen

Best Practices

Wir empfehlen, den Zeitraum der Abfrage über die Zeitraumauswahl festzulegen. Wenn Sie beispielsweise die Daten der letzten Woche aufrufen möchten, wählen Sie in der Zeitraumauswahl Letzte 7 Tage aus. Sie können auch die Zeitraumauswahl verwenden, um eine Start- und Endzeit festzulegen, eine Uhrzeit anzugeben, um die herum Sie sich die Daten ansehen möchten, und Zeitzonen zu ändern.

Logdaten

Wenn Sie ein timestamp-Feld in die WHERE-Klausel einfügen, wird die Einstellung für die Zeitbereichsauswahl nicht verwendet. Das folgende Beispiel zeigt, wie nach Zeitstempel gefiltert wird:

-- Matches log entries whose timestamp is within the most recent 1 hour.
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Trace-Daten

Wenn Sie ein start_time-Feld in die WHERE-Klausel einfügen, wird die Einstellung für die Zeitbereichsauswahl nicht verwendet. Das folgende Beispiel zeigt, wie nach Zeitstempel gefiltert wird:

-- Matches trace spans whose start_time is within the most recent 1 hour.
WHERE start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Weitere Informationen zum Filtern nach Zeit finden Sie unter Zeitfunktionen und Zeitstempelfunktionen.

Hinweis

  1. Melden Sie sich in Ihrem Google Cloud -Konto an. Wenn Sie mit Google Cloudnoch nicht vertraut sind, erstellen Sie ein Konto, um die Leistungsfähigkeit unserer Produkte in der Praxis sehen und bewerten zu können. Neukunden erhalten außerdem ein Guthaben von 300 $, um Arbeitslasten auszuführen, zu testen und bereitzustellen.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Aktivieren Sie die Observability API.

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    API aktivieren

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Aktivieren Sie die Observability API.

    Rollen, die zum Aktivieren von APIs erforderlich sind

    Zum Aktivieren von APIs benötigen Sie die IAM-Rolle „Service Usage-Administrator“ (roles/serviceusage.serviceUsageAdmin), die die Berechtigung serviceusage.services.enable enthält. Weitere Informationen zum Zuweisen von Rollen

    API aktivieren

  8. Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Laden der Seite Log Analytics, zum Schreiben, Ausführen und Speichern privater Abfragen für Ihre Tracedaten benötigen:

    • Observability View Accessor (roles/observability.viewAccessor) für die Observability-Ansichten, die Sie abfragen möchten. Diese Rolle unterstützt IAM-Bedingungen, mit denen Sie die Zuweisung auf eine bestimmte Ansicht beschränken können. Wenn Sie der Rollenzuweisung keine Bedingung hinzufügen, kann das Hauptkonto auf alle Ansichten für die Beobachtbarkeit zugreifen. Ansichten für die Beobachtbarkeit sind in der öffentlichen Vorschau verfügbar.
    • Observability Analytics User (roles/observability.analyticsUser) für Ihr Projekt. Diese Rolle enthält die Berechtigungen, die zum Speichern und Ausführen privater Abfragen sowie zum Ausführen freigegebener Abfragen erforderlich sind.
    • Loganzeige (roles/logging.viewer) für Ihr Projekt.
    • Zugriffsberechtigter für Logbetrachtung (roles/logging.viewAccessor) für das Projekt, in dem die Logansichten gespeichert sind, die Sie abfragen möchten.

    Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

    Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Abfragen auf dieser Seite verwenden

  1. Rufen Sie in der Google Cloud -Console die Seite Loganalysen auf.

    Zu Loganalysen

    Wenn Sie diese Seite über die Suchleiste suchen, wählen Sie das Ergebnis mit der Zwischenüberschrift Logging aus.

  2. Klicken Sie im Bereich Abfrage auf  SQL und kopieren und fügen Sie dann eine Abfrage in den Bereich „SQL-Abfrage“ ein.

    Logdaten

    Bevor Sie eine Abfrage kopieren, ersetzen Sie in der FROM-Klausel die folgenden Felder:

    • PROJECT_ID: Die Kennung des Projekts.
    • LOCATION: Der Speicherort der Logansicht oder der Analyseansicht.
    • BUCKET_ID: Der Name oder die ID des Log-Buckets.
    • LOG_VIEW_ID: Die Kennung der Logansicht. Sie ist auf 100 Zeichen begrenzt und darf nur Buchstaben, Ziffern, Unterstriche und Bindestriche enthalten.

    Im Folgenden sehen Sie das Format der FROM-Klausel für eine Logansicht:

    FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
    

    In den Logbeispielen auf dieser Seite wird eine Logansicht abgefragt. Wenn Sie eine Analyseansicht abfragen möchten, verwenden Sie das folgende Pfadformat: `analytics_view.PROJECT_ID.LOCATION.ANALYTICS_VIEW_ID`. Im vorherigen Ausdruck ist PROJECT_ID die ID Ihres Projekts und LOCATION und ANALYTICS_VIEW_ID sind der Standort und der Name Ihrer Analyseansicht.

    Trace-Daten

    Im Folgenden sehen Sie das Format der FROM-Ursache für die Abfrage der _AllSpans-Ansicht:

    FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
    

    Die FROM-Klausel enthält die folgenden Felder:

    • PROJECT_ID: Die Kennung des Projekts.
    • LOCATION: Der Speicherort des Observability-Buckets.
    • _Trace ist der Name des Observability-Buckets.
    • Spans ist der Name des Datasets.
    • _AllSpans ist der Name der Ansicht.

Wenn Sie die in diesem Dokument gezeigten Abfragen auf der Seite BigQuery Studio verwenden oder das bq-Befehlszeilentool nutzen möchten, bearbeiten Sie die FROM-Klausel und geben Sie den Pfad zum verknüpften Dataset ein.

Logdaten

Wenn Sie beispielsweise die Ansicht _AllLogs für das verknüpfte Dataset mit dem Namen mydataset im Projekt myproject abfragen möchten, lautet der Pfad myproject.mydataset._AllLogs.

Trace-Daten

Wenn Sie beispielsweise die Ansicht _AllSpans für das verknüpfte Dataset mit dem Namen my_linked_dataset im Projekt myproject abfragen möchten, lautet der Pfad `myproject.my_linked_dataset._AllSpans`.

Gängige Anwendungsfälle

In diesem Abschnitt werden einige gängige Anwendungsfälle aufgeführt, die Ihnen bei der Erstellung Ihrer benutzerdefinierten Abfragen helfen können.

Logeinträge im Standard-Log-Bucket anzeigen

Führen Sie die folgende Abfrage aus, um den _Default-Bucket abzufragen:

SELECT
  timestamp, severity, resource.type, log_name, text_payload, proto_payload, json_payload
FROM
  `PROJECT_ID.LOCATION._Default._AllLogs`
-- Limit to 1000 entries
LIMIT 1000

Feldwert mit regulärem Ausdruck extrahieren

Wenn Sie einen Wert aus einem String mithilfe eines regulären Ausdrucks extrahieren möchten, verwenden Sie die Funktion REGEXP_EXTRACT:

SELECT
  -- Display the timestamp, and the part of the name that begins with test.
  timestamp, REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Get the value of jobName, which is a subfield in a JSON structure.
  JSON_VALUE(json_payload.jobName) IS NOT NULL
ORDER BY timestamp DESC
LIMIT 20

Weitere Informationen finden Sie in der Dokumentation zu REGEXP_EXTRACT.

Bei Teilstring-Übereinstimmungen wie in der vorherigen Abfrage führt die Verwendung der Funktion CONTAINS_SUBSTR zu einer effizienteren Abfrage.

Alle Trace-Daten anzeigen

Führen Sie die folgende Abfrage aus, um die Ansicht _AllSpans abzufragen:

-- Display all data.
SELECT *
FROM `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
-- Limit to 10 entries.
LIMIT 10

Gemeinsame Spanneninformationen anzeigen

Führen Sie die folgende Abfrage aus, um allgemeine Informationen zum Zeitraum wie Startzeit und Dauer abzurufen:

SELECT
  start_time,
  -- Set the value of service name based on the first non-null value in the list.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,
  name AS span_name,
  duration_nano,
  status.code AS status,
  trace_id,
  span_id
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
LIMIT 10

Weitere Informationen finden Sie unter Bedingte Ausdrücke.

50. und 99. Perzentil der Spannenlatenz anzeigen

Führen Sie die folgende Abfrage aus, um das 50. und 99. Perzentil der Latenz für jeden RPC-Dienst anzuzeigen:

SELECT
  -- Compute 50th and 99th percentiles for each service
  STRING(attributes['rpc.service']) || '/' || STRING(attributes['rpc.method']) AS rpc_service_method,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS duration_nano_p50,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS duration_nano_p99
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans whose kind field has a value of 2 (SPAN_KIND_SERVER).
  kind = 2
GROUP BY rpc_service_method

Weitere Informationen zur Aufzählung finden Sie in der OpenTelemetry-Dokumentation zu SpanKind.

Um die Ergebnisse grafisch darzustellen, können Sie ein Diagramm erstellen, in dem die Dimension auf rpc_service_method festgelegt ist. Sie können beispielsweise zwei Messwerte hinzufügen, einen für den Durchschnitt des duration_nano_p50-Werts und einen für den Durchschnitt des Felds duration_nano_p99.

Log-Einträge filtern

Wenn Sie einen Filter auf Ihre Abfrage anwenden möchten, fügen Sie eine WHERE-Klausel hinzu. Die Syntax, die Sie in dieser Klausel verwenden, hängt vom Datentyp des Felds ab. Dieser Abschnitt enthält mehrere Beispiele für verschiedene Datentypen.

Logeinträge nach Nutzlasttyp filtern

Logeinträge können einen von drei Nutzlasttypen haben. Verwenden Sie eine der folgenden Klauseln, um Logeinträge nach dem Nutzlasttyp zu filtern:

  • Textnutzlasten

    -- Matches log entries that have a text payload.
    WHERE text_payload IS NOT NULL
    
  • JSON-Nutzlasten

    -- Matches log entries that have a JSON payload.
    WHERE json_payload IS NOT NULL
    
  • Proto-Nutzlasten

    -- Matches log entries that have a proto payload.
    -- Because proto_payload has a data type of RECORD, this statement tests
    -- whether a mandatory subfield exits.
    WHERE proto_payload.type IS NOT NULL
    

In den Abfrageergebnissen werden sowohl die Felder json_payload als auch proto_payload in JSON gerendert, die Sie sich anschauen können.

Logdaten nach Zeitstempel filtern

Wenn Sie Logeinträge nach ihrem Zeitstempel filtern möchten, empfehlen wir die Verwendung der Zeitbereichsauswahl. Sie können timestamp aber auch in der WHERE-Klausel angeben:

-- Matches log entries whose timestamp is within the most recent hour
WHERE timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR)

Weitere Informationen zum Filtern nach Zeit finden Sie unter Zeitfunktionen und Zeitstempelfunktionen.

Nach Ressource filtern

Wenn Sie Ihre Log- und Tracedaten nach Ressource filtern möchten, fügen Sie der WHERE-Klausel eine resource.type-Anweisung hinzu:

-- Matches log entries whose resource type is gce_instance
WHERE resource.type = "gce_instance"

Nach Schweregrad filtern

Wenn Sie Ihre Logdaten nach einem Schweregrad filtern möchten, fügen Sie der WHERE-Klausel eine severity-Anweisung hinzu:

-- Matches log entries whose severity is INFO or ERROR
WHERE severity IS NOT NULL AND severity IN ('INFO', 'ERROR')

Sie können Ihre Logeinträge auch nach severity_number filtern, einer Ganzzahl. Die folgende Klausel entspricht beispielsweise allen Logeinträgen, deren Schweregrad mindestens NOTICE ist:

-- Matches log entries whose severity level is at least NOTICE
WHERE severity_number IS NOT NULL AND severity_number > 200

Informationen zu den aufgezählten Werten finden Sie unter LogSeverity.

Nach Logname filtern

Wenn Sie Ihre Logdaten nach einem Lognamen filtern möchten, fügen Sie der WHERE-Klausel eine log_name- oder log_id-Anweisung hinzu:

  • Der Logname gibt den Ressourcenpfad an:

    -- Matches log entries that have the following log ID.
    WHERE log_name="projects/cloud-logs-test-project/logs/cloudaudit.googleapis.com%2Factivity"
    
  • Die Log-ID lässt den Ressourcenpfad aus:

    -- Matches log entries that have the following log id.
    WHERE log_id = "cloudaudit.googleapis.com/data_access"
    

Logeinträge nach Ressourcenlabel filtern

Ressourcenlabels werden als JSON-Struktur gespeichert. Wenn Sie nach dem Wert eines Felds in einer JSON-Struktur filtern möchten, verwenden Sie die Funktion JSON_VALUE:

SELECT
  timestamp, JSON_VALUE(resource.labels.zone) AS zone, json_payload, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries whose resource type is gce_instance and whose zone is
  -- us-central1-f. Because resource has data type JSON, you must use JSON_VALUE
  -- to get the value for subfields, like zone.
  resource.type = "gce_instance" AND
  JSON_VALUE(resource.labels.zone) = "us-central1-f"
ORDER BY timestamp ASC

Die vorherige Abfrage basiert auf dem Format von Ressourcenlabels, wie sie in einem Logeintrag gespeichert sind. Hier ein Beispiel für das Ressourcenfeld:

{
   type: "gce_instance"
   labels: {
      instance_id: "1234512345123451"
      project_id: "my-project"
      zone: "us-central1-f"
   }
}

Informationen zu allen Funktionen, mit denen JSON-Daten abgerufen und transformiert werden können, finden Sie unter JSON-Funktionen.

Nach HTTP-Anfrage filtern

Wenn Sie nur Logeinträge abfragen möchten, die ein HTTP-Anfragefeld haben, verwenden Sie die folgende Klausel:

-- Matches log entries that have a HTTP request_method field.
-- Don't compare http_request to NULL. This field has a data type of RECORD.
WHERE http_request.request_method IS NOT NULL

Sie können auch die IN-Anweisung verwenden:

-- Matches log entries whose HTTP request_method is GET or POST.
WHERE http_request.request_method IN ('GET', 'POST')

Nach HTTP-Status filtern

Wenn Sie nur Logeinträge mit einem HTTP-Status abfragen möchten, verwenden Sie die folgende Klausel:

-- Matches log entries that have an http_request.status field.
WHERE http_request.status IS NOT NULL

Nach einem Feld in einem JSON-Datentyp filtern

Wenn Sie nur Logeinträge abfragen möchten, in denen das Unterfeld eines Felds mit einem JSON-Datentyp einen bestimmten Wert hat, extrahieren Sie den Wert mit der Funktion JSON_VALUE:

-- Compare the value of the status field to NULL.
WHERE JSON_VALUE(json_payload.status) IS NOT NULL

Die vorherige Klausel unterscheidet sich geringfügig von der folgenden Klausel:

-- Compare the status field to NULL.
WHERE json_payload.status IS NOT NULL

In der ersten Klausel wird geprüft, ob der Wert des Statusfelds NULL ist. In der zweiten Klausel wird geprüft, ob das Statusfeld vorhanden ist. Angenommen, eine Logansicht enthält zwei Logeinträge. Für einen Logeintrag hat das Feld json_payload das folgende Format:

{
    status: {
        measureTime: "1661517845"
    }
}

Für den anderen Logeintrag hat das Feld json_payload eine andere Struktur:

{
    @type: "type.googleapis.com/google.cloud.scheduler.logging.AttemptFinished"
    jobName: "projects/my-project/locations/us-central1/jobs/test1"
    relativeUrl: "/food=cake"
    status: "NOT_FOUND"
    targetType: "APP_ENGINE_HTTP"
}

Die Klausel WHERE json_payload.status IS NOT NULL stimmt mit beiden Logeinträgen überein. Die Klausel WHERE JSON_VALUE(json_payload.status) IS NOT NULL stimmt jedoch nur mit dem zweiten Logeintrag überein.

Trace-Einträge filtern

Wenn Sie einen Filter auf Ihre Abfrage anwenden möchten, fügen Sie eine WHERE-Klausel hinzu. Die Syntax, die Sie in dieser Klausel verwenden, hängt vom Datentyp des Felds ab. Dieser Abschnitt enthält mehrere Beispiele für verschiedene Datentypen.

Nach String-Datentypen filtern

Das Feld name wird als String gespeichert.

  • Wenn Sie nur die Spannen analysieren möchten, in denen name angegeben ist, verwenden Sie die folgende Klausel:

    -- Matches spans that have a name field.
    WHERE name IS NOT NULL
    
  • Wenn Sie nur die Zeiträume analysieren möchten, in denen name den Wert "POST" hat, verwenden Sie die folgende Klausel:

    -- Matches spans whose name is POST.
    WHERE STRPOS(name, "POST") > 0
    
  • Wenn Sie nur die Spannen analysieren möchten, in denen name den Wert "POST" enthält, verwenden Sie den Operator LIKE zusammen mit Platzhaltern:

    -- Matches spans whose name contains POST.
    WHERE name LIKE "%POST%"
    

Nach Ganzzahldatentypen filtern

Das Feld kind ist eine Ganzzahl, die Werte zwischen 0 und 5 annehmen kann:

  • Wenn Sie nur Spans analysieren möchten, in denen kind angegeben ist, verwenden Sie die folgende Klausel:

    -- Matches spans that have field named kind.
    WHERE kind IS NOT NULL
    
  • Verwenden Sie die folgende Klausel, um Zeiträume zu analysieren, deren kind-Wert entweder 1 oder 2 ist:

    -- Matches spans whose kind value is 1 or 2.
    WHERE kind IN (1, 2)
    

Nach RECORD-Datentypen filtern

Einige Felder im Traceschema haben den Datentyp RECORD. In diesen Feldern können entweder eine oder mehrere Datenstrukturen oder wiederholte Einträge derselben Datenstruktur gespeichert werden.

Nach Status oder Statuscode filtern

Das Feld status ist ein Beispiel für ein Feld mit dem Datentyp RECORD. In diesem Feld wird eine Datenstruktur mit den Mitgliedern code und message gespeichert.

  • Wenn Sie nur Zeiträume analysieren möchten, in denen das Feld status.code den Wert 1 hat, fügen Sie die folgende Klausel hinzu:

    -- Matches spans that have a status.code field that has a value of 1.
    WHERE status.code = 1
    

    Das Feld status.code wird als Ganzzahl gespeichert.

  • Wenn Sie Zeiträume analysieren möchten, in denen das Feld status nicht EMPTY ist, fügen Sie die folgende Klausel hinzu:

    -- Matches spans that have status field. When the status field exists, it
    -- must contain a subfield named code.
    -- Don't compare status to NULL, because this field has a data type of RECORD.
    WHERE status.code IS NOT NULL
    

Die Felder events und links werden mit dem Datentyp RECORD gespeichert, sind aber wiederkehrende Felder.

  • Verwenden Sie die folgende Klausel, um Spannen abzugleichen, die mindestens ein Ereignis enthalten:

    -- Matches spans that have at least one event. Don't compare events to NULL.
    -- The events field has data type of RECORD and contains a repeated fields.
    WHERE ARRAY_LENGTH(events) > 0
    
  • Verwenden Sie die folgende Klausel, um Spannen abzugleichen, die ein Ereignis enthalten, dessen Feld name den Wert message hat:

    WHERE
      -- Exists is true when any event in the array has a name field with the
      -- value of message.
      EXISTS(
        SELECT 1
        FROM UNNEST(events) AS ev
        WHERE ev.name = 'message'
      )
    

Nach JSON-Datentypen filtern

Das Feld attributes hat den Typ JSON. Jedes einzelne Attribut ist ein Schlüssel/Wert-Paar.

  • Wenn Sie nur die Spannen analysieren möchten, in denen attributes angegeben ist, verwenden Sie die folgende Klausel:

    -- Matches spans where at least one attribute is specified.
    WHERE attributes IS NOT NULL
    
  • Wenn Sie nur die Spannen analysieren möchten, in denen der Attributschlüssel mit dem Namen component den Wert "proxy" hat, verwenden Sie die folgende Klausel:

    -- Matches spans that have an attribute named component with a value of proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') = 'proxy'
    

    Sie können auch eine LIKE-Anweisung zusammen mit Platzhaltern verwenden, um einen „contains“-Test durchzuführen:

    -- Matches spans that have an attribute named component whose value contains proxy.
    WHERE attributes IS NOT NULL
          AND JSON_VALUE(attributes, '$.component') LIKE '%proxy%'
    

Logeinträge gruppieren und aggregieren

In diesem Abschnitt wird auf den vorherigen Beispielen aufgebaut und veranschaulicht, wie Sie Logeinträge gruppieren und aggregieren können. Wenn Sie keine Gruppierung, aber eine Aggregation angeben, wird ein Ergebnis ausgegeben, da in SQL alle Zeilen, die die WHERE-Klausel erfüllen, als eine Gruppe behandelt werden.

Jeder SELECT-Ausdruck muss in den Gruppenfeldern enthalten oder aggregiert werden.

Logeinträge nach Zeitstempel gruppieren

Wenn Sie Daten nach Zeitstempel gruppieren möchten, verwenden Sie die Funktion TIMESTAMP_TRUNC, mit der ein Zeitstempel auf eine bestimmte Granularität wie HOUR gekürzt wird:

SELECT
  -- Truncate the timestamp by hour.
  TIMESTAMP_TRUNC(timestamp, HOUR) AS hour,
  JSON_VALUE(json_payload.status) AS status,
  -- Count the number log entries in each group.
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries that have a status field whose value isn't NULL.
  json_payload IS NOT NULL AND JSON_VALUE(json_payload.status) IS NOT NULL
GROUP BY
  -- Group by hour and status
  hour,status
ORDER BY hour ASC

Weitere Informationen finden Sie in der Dokumentation zu TIMESTAMP_TRUNC und unter Datums- und Zeitfunktionen.

Logeinträge nach Ressource gruppieren

In der folgenden Abfrage wird gezeigt, wie Sie Logeinträge nach Ressourcentyp gruppieren und dann die Anzahl der Logeinträge in jeder Gruppe zählen:

SELECT
   -- Count the number of log entries for each resource type
   resource.type, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY resource.type
LIMIT 100

Logeinträge nach Schweregrad gruppieren

In der folgenden Abfrage wird gezeigt, wie Logeinträge nach Schweregrad gruppiert und dann die Anzahl der Logeinträge in jeder Gruppe gezählt wird:

SELECT
  -- Count the number of log entries for each severity.
  severity, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  severity IS NOT NULL
GROUP BY severity
ORDER BY severity
LIMIT 100

Logeinträge nach log_id gruppieren

In der folgenden Abfrage wird gezeigt, wie Logeinträge nach der Log-ID gruppiert und dann die Anzahl der Logeinträge in jeder Gruppe gezählt wird:

SELECT
  -- Count the number of log entries for each log ID.
  log_id, COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
GROUP BY log_id
ORDER BY count DESC
LIMIT 100

Durchschnittliche Latenz von HTTP-Anfragen pro URL berechnen

In der folgenden Abfrage wird veranschaulicht, wie Logeinträge nach der HTTP-Anfrage-URL und dem Standort gruppiert und dann die Anzahl der Logeinträge in jeder Gruppe gezählt wird:

SELECT
  -- Compute the average latency for each group. Because the labels field has a
  -- data type of JSON, use JSON_VALUE to get the value of checker_location.
  JSON_VALUE(labels.checker_location) AS location,
  AVG(http_request.latency.seconds) AS secs, http_request.request_url
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  -- Matches log entries when the request_method field is GET.
  http_request IS NOT NULL AND http_request.request_method IN ('GET')
GROUP BY
  -- Group by request URL and location
  http_request.request_url, location
ORDER BY location
LIMIT 100

Durchschnittliche Anzahl der gesendeten Byte für einen Subnetzwerktest berechnen

In der folgenden Abfrage wird gezeigt, wie Logeinträge nach dem in den Ressourcenlabels angegebenen Standort gruppiert und dann die Anzahl der Logeinträge in jeder Gruppe berechnet wird:

SELECT
  -- Compute the average number of bytes sent per location. Because labels has
  -- a data type of JSON, use JSON_VALUE to get the value of the location field.
  -- bytes_sent is a string. Must cast to a FLOAT64 before computing average.
  JSON_VALUE(resource.labels.location) AS location,
  AVG(CAST(JSON_VALUE(json_payload.bytes_sent) AS FLOAT64)) AS bytes
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  resource.type = "gce_subnetwork" AND json_payload IS NOT NULL
GROUP BY
  -- Group by location
  location
LIMIT 100

Weitere Informationen finden Sie unter JSON-Funktionen und Konversionsfunktionen.

Logeinträge mit einem Feld zählen, das einem Muster entspricht

Wenn Sie den Teilstring zurückgeben möchten, der mit einem regulären Ausdruck übereinstimmt, verwenden Sie die Funktion REGEXP_EXTRACT:

SELECT
  -- Extract the value that begins with test.
  -- Count the number of log entries for each name.
  REGEXP_EXTRACT(JSON_VALUE(json_payload.jobName), r".*(test.*)$") AS name,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID`
WHERE
  json_payload.jobName IS NOT NULL
GROUP BY name
ORDER BY count
LIMIT 20

Weitere Beispiele finden Sie in der Dokumentation zu REGEXP_EXTRACT.

Trace-Daten gruppieren und aggregieren

In diesem Abschnitt wird veranschaulicht, wie Sie Spans gruppieren und aggregieren können. Wenn Sie keine Gruppierung, aber eine Aggregation angeben, wird ein Ergebnis ausgegeben, da in SQL alle Einträge, die die WHERE-Klausel erfüllen, als eine Gruppe behandelt werden.

Jeder SELECT-Ausdruck muss in den Gruppenfeldern enthalten oder aggregiert werden.

Zeiträume nach Startzeit gruppieren

Wenn Sie Daten nach Startzeit gruppieren möchten, verwenden Sie die Funktion TIMESTAMP_TRUNC, mit der ein Zeitstempel auf eine bestimmte Granularität wie HOUR gekürzt wird:

SELECT
  -- Truncate the start time to the hour. Count the number of spans per group.
  TIMESTAMP_TRUNC(start_time, HOUR) AS hour,
  status.code AS code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE
  -- Matches spans shows start time is within the previous 12 hours.
  start_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 12 HOUR)
GROUP BY
  -- Group by hour and status code.
  hour, code
ORDER BY hour DESC

Weitere Informationen finden Sie in der Dokumentation zu TIMESTAMP_TRUNC und unter Datums- und Zeitfunktionen.

Spannen nach Statuscode zählen

Wenn Sie die Anzahl der Spans mit einem bestimmten Statuscode anzeigen möchten, führen Sie die folgende Abfrage aus:

SELECT
  -- Count the number of spans for each status code.
  status.code,
  COUNT(*) AS count
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
WHERE status.code IS NOT NULL
GROUP BY status.code

Wenn Sie status.code durch kind ersetzen, wird in der vorherigen Abfrage die Anzahl der Spannen für jeden Wert der kind-Aufzählung ausgegeben. Wenn Sie status.code durch name ersetzen, wird in den Abfrageergebnissen die Anzahl der Einträge für jeden Spannenname aufgeführt.

Durchschnittliche Dauer aller Zeiträume berechnen

Führen Sie die folgende Abfrage aus, um die durchschnittliche Dauer nach der Gruppierung von Spannen-Daten nach Spannenname anzuzeigen:

SELECT
  -- Group by name, and then compute the average duration for each group.
  name,
  AVG(duration_nano) AS nanosecs,
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY name
ORDER BY nanosecs DESC

Durchschnittliche Dauer und Perzentile pro Dienstname berechnen

Mit der folgenden Abfrage werden die Anzahl der Spannen und verschiedene Statistiken für jeden Dienst berechnet:

SELECT
  -- Set the service name by the first non-null value.
  COALESCE(
    JSON_VALUE(resource.attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."service.name"'),
    JSON_VALUE(attributes, '$."g.co/gae/app/module"')) AS service_name,

  -- Count the number spans for each service name. Also compute statistics.
  COUNT(*) AS span_count,
  AVG(duration_nano) AS avg_duration_nano,
  MIN(duration_nano) AS min_duration_nano,
  MAX(duration_nano) AS max_duration_nano,

  -- Calculate percentiles for duration
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(50)] AS p50_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(95)] AS p95_duration_nano,
  APPROX_QUANTILES(duration_nano, 100)[OFFSET(99)] AS p99_duration_nano,

  -- Count the number of unique trace IDs. Also, collect up to 5 unique
  -- span names and status codes.
  COUNT(DISTINCT trace_id) AS distinct_trace_count,
  ARRAY_AGG(DISTINCT name IGNORE NULLS LIMIT 5) AS sample_span_names,
  ARRAY_AGG(DISTINCT status.code IGNORE NULLS LIMIT 5) AS sample_status_codes
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans`
GROUP BY service_name
ORDER BY span_count DESC

In diesem Abschnitt werden zwei Ansätze beschrieben, mit denen Sie mehrere Spalten der Ansicht durchsuchen können, die Sie abfragen:

  • Tokenbasierte Suche: Sie geben den Suchort und eine Suchanfrage an und verwenden dann die Funktion SEARCH. Da für die Funktion SEARCH bestimmte Regeln für die Suche in den Daten gelten, empfehlen wir Ihnen, die SEARCH-Dokumentation zu lesen.

  • Auf Teilstrings basierende Suchvorgänge: Sie geben den Suchort und ein String-Literal an und verwenden dann die Funktion CONTAINS_SUBSTR. Das System führt einen Test durch, bei dem die Groß-/Kleinschreibung nicht berücksichtigt wird, um festzustellen, ob das String-Literal in einem Ausdruck vorhanden ist. Die Funktion CONTAINS_SUBSTR gibt TRUE zurück, wenn das String-Literal vorhanden ist, und andernfalls FALSE. Der Suchwert muss ein STRING-Literal sein, aber nicht das Literal NULL.

Mit der folgenden Abfrage werden nur die Zeilen beibehalten, die ein Feld enthalten, das genau mit „35.193.12.15“ übereinstimmt:

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- The use of backticks prevents the string from being tokenized.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  SEARCH(t,"`35.193.12.15`")
ORDER BY timestamp ASC
LIMIT 20

Wenn im Abfragestring keine Backticks verwendet werden, wird er anhand der in der SEARCH-Dokumentation definierten Regeln aufgeteilt. Wenn beispielsweise die folgende Anweisung ausgeführt wird, wird der Abfragestring in vier Tokens aufgeteilt: „35“, „193“, „12“ und „15“:

  SEARCH(t,"35.193.12.15")

Die vorherige SEARCH-Anweisung stimmt mit einer Zeile überein, wenn ein einzelnes Feld mit allen vier Tokens übereinstimmt. Die Reihenfolge der Tokens spielt keine Rolle.

Eine Abfrage kann mehrere SEARCH-Anweisungen enthalten. In der vorherigen Abfrage könnten Sie beispielsweise den Filter für die Log-ID durch eine Anweisung wie die folgende ersetzen:

  SEARCH(t,"`cloudaudit.googleapis.com/data_access`")

Mit der vorherigen Anweisung wird jedes Feld der Logeinträge in der Logansicht durchsucht, während mit der ursprünglichen Anweisung nur das Feld log_id der Logeinträge durchsucht wird.

Wenn Sie mehrere Suchvorgänge für mehrere Felder ausführen möchten, trennen Sie die einzelnen Strings durch ein Leerzeichen. Mit der folgenden Anweisung werden beispielsweise Zeilen abgeglichen, in denen ein Feld „Hello World“, „happy“ und „days“ enthält:

  SEARCH(t,"`Hello World` happy days")

Außerdem können Sie bestimmte Felder durchsuchen, anstatt eine ganze Tabelle. Mit der folgenden Anweisung werden beispielsweise nur die Spalten mit den Namen text_payload und json_payload durchsucht:

   SEARCH((text_payload, json_payload) ,"`35.222.132.245`")

Informationen zur Verarbeitung der Parameter der SEARCH-Funktion finden Sie auf der BigQuery-Referenzseite Suchfunktionen.

Mit der folgenden Abfrage werden beispielsweise alle Audit-Logeinträge zum Datenzugriff mit einer bestimmten IP-Adresse abgerufen, deren Zeitstempel in einem bestimmten Zeitraum liegen. Schließlich werden die Ergebnisse sortiert und die 20 ältesten Ergebnisse angezeigt:

SELECT
  timestamp, log_id, proto_payload, severity, resource.type, resource, labels
FROM
  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_ID` AS t
WHERE
  -- Search data access audit logs for the IP address that matches 35.193.12.15.
  -- CONTAINS_SUBSTR performs a contains-test.
  proto_payload IS NOT NULL AND
  log_id = "cloudaudit.googleapis.com/data_access" AND
  CONTAINS_SUBSTR(t,"35.193.12.15")
ORDER BY timestamp ASC
LIMIT 20

Mehrere Ansichten abfragen

Abfrageanweisungen prüfen eine oder mehrere Tabellen oder Ausdrücke und geben die berechneten Ergebniszeilen zurück. Sie können beispielsweise mit Abfrageanweisungen die Ergebnisse von SELECT-Anweisungen für verschiedene Tabellen oder Datasets auf unterschiedliche Weise zusammenführen und dann die Spalten aus den kombinierten Daten auswählen.

Für das Zusammenführen von Ansichten gelten die folgenden Einschränkungen:

  1. Die Positionen der Ansichten erfüllen eine der folgenden Bedingungen:

    • Alle Ansichten haben denselben Standort.
    • Alle Ansichten befinden sich entweder am Standort global oder us.
  2. Wenn für Speicherressourcen kundenverwaltete Verschlüsselungsschlüssel (Customer Managed Encryption Keys, CMEK) verwendet werden, gilt eine der folgenden Bedingungen:

    • Für Speicherressourcen, die CMEK verwenden, wird derselbe Cloud KMS-Schlüssel verwendet.
    • Speicherressourcen, die CMEK verwenden, haben einen gemeinsamen Vorfahren, in dem ein standardmäßiger Cloud KMS-Schlüssel angegeben ist, der sich am selben Standort wie die Speicherressourcen befindet.

    Wenn für eine oder mehrere Speicherressourcen CMEK verwendet wird, verschlüsselt das System temporäre Daten, die durch den Join generiert werden, entweder mit dem gemeinsamen Cloud KMS-Schlüssel oder mit dem standardmäßigen Cloud KMS-Schlüssel des übergeordneten Elements.

Angenommen, Sie haben zwei Ansichten, die sich am selben Speicherort befinden. Anschließend können Sie diese Ansichten zusammenführen, wenn eine der folgenden Bedingungen zutrifft:

  • Für die Speicherressourcen wird kein CMEK verwendet.
  • Eine Speicherressource verwendet CMEK, die andere nicht.
  • Beide Speicherressourcen verwenden CMEK und denselben Cloud KMS-Schlüssel.
  • Für beide Speicherressourcen wird CMEK verwendet, aber mit unterschiedlichen Schlüsseln. Die Ressourcen haben jedoch einen gemeinsamen Vorfahren, der einen standardmäßigen Cloud KMS-Schlüssel angibt, der sich am selben Ort wie die Speicherressourcen befindet.

    Angenommen, die Ressourcenhierarchie für einen Log-Bucket und einen Observability-Bucket umfasst dieselbe Organisation. Sie können Ansichten für diese Buckets verknüpfen, wenn Sie für diese Organisation die Standardressourceneinstellungen für Cloud Logging und für Observability-Buckets mit demselben standardmäßigen Cloud KMS-Schlüssel für den Speicherort konfiguriert haben.

Zwei Logansichten über die Trace-ID zusammenführen

Wenn Sie Informationen aus zwei Tabellen kombinieren möchten, verwenden Sie einen der Join-Operatoren:

SELECT
  -- Do an inner join on two tables by using the span ID and trace ID.
  -- Don't join only by span ID, as this field isn't globally unique.
  -- From the first view, show the timestamp, severity, and JSON payload.
  -- From the second view, show the JSON payload.
  a.timestamp, a.severity, a.json_payload, b.json_payload, a.span_id, a.trace
FROM  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1` a
JOIN  `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2` b
ON
  a.span_id = b.span_id AND
  a.trace = b.trace
LIMIT 100

Zwei Logansichten mit einer UNION-Anweisung abfragen

Wenn Sie die Ergebnisse von zwei oder mehr SELECT-Anweisungen kombinieren und doppelte Zeilen verwerfen möchten, verwenden Sie den Operator UNION. Wenn Sie doppelte Zeilen beibehalten möchten, verwenden Sie den Operator UNION ALL:

SELECT
  timestamp, log_name, severity, json_payload, resource, labels
-- Create a union of two log views
FROM(
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_1`
  UNION ALL
  SELECT * FROM `PROJECT_ID.LOCATION.BUCKET_ID.LOG_VIEW_2`
)
-- Sort the union by timestamp.
ORDER BY timestamp ASC
LIMIT 100

Trace- und Logdaten über die Trace-ID zusammenführen

In der folgenden Abfrage werden Log- und Trace-Daten mithilfe der Span- und Trace-IDs verknüpft:

SELECT
  T.trace_id,
  T.span_id,
  T.name,
  T.start_time,
  T.duration_nano,
  L.log_name,
  L.severity,
  L.json_payload
FROM
  `PROJECT_ID.LOCATION._Trace.Spans._AllSpans` AS T
JOIN
  `PROJECT_ID.LOCATION._Default._AllLogs` AS L
ON
  -- Join log and trace data by both the span ID and trace ID.
  -- Don't join only on span ID, this field isn't globally unique.
  T.span_id = L.span_id
  -- A regular expression is required because the storage format of the trace ID
  -- differs between a log view and a trace view.
  AND T.trace_id = REGEXP_EXTRACT(L.trace, r'/([^/]+)$')
WHERE T.duration_nano > 1000000
LIMIT 10

In der Antwort auf die Abfrage werden die Trace- und Span-ID aufgeführt. Sie können sie einzeln abfragen, um weitere Informationen zu erhalten. Außerdem werden in den Ergebnissen der Schweregrad des Logeintrags und die JSON-Nutzlast aufgeführt.

Doppelte Logeinträge entfernen

In Loganalysen werden doppelte Logeinträge nicht entfernt, bevor eine Abfrage ausgeführt wird. Dieses Verhalten unterscheidet sich von der Abfrage von Logeinträgen mit dem Log-Explorer. Dort werden doppelte Einträge durch Vergleichen der Felder „Lognamen“, „Zeitstempel“ und „Einfüge-ID“ entfernt.

Mit der Validierung auf Zeilenebene lassen sich doppelte Logeinträge entfernen.

Weitere Informationen finden Sie unter Fehlerbehebung: In meinen Loganalyse-Ergebnissen sind doppelte Logeinträge vorhanden.

Nächste Schritte

SQL-Referenzdokumentation und weitere Beispiele finden Sie in den folgenden Dokumenten: