SQL-Beispielabfragen für Trace

Dieses Dokument enthält Beispielabfragen, die speziell für das Abfragen von Tracedaten in Ihrem Google Cloud Projekt entwickelt wurden.

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.

Wenn Sie ein start_time-Feld in die WHERE-Klausel einfügen, wird die Einstellung für die Zeitraumauswahl nicht verwendet. Im folgenden Beispiel werden die Daten mit der Funktion TIMESTAMP_SUB gefiltert, mit der Sie ein Rückblickintervall ab der aktuellen Zeit angeben können:

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 noch kein Konto haben Google Cloud, erstellen Sie ein Konto, um die Leistung 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. Enable the Observability API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  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. Enable the Observability API.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the API

  8. Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Laden der Seite Loganalysen und 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 der Prinzipal auf alle Observability-Ansichten zugreifen.
    • 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.

    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.

    Im Folgenden sehen Sie das Format der FROM-Klausel zum Abfragen der Ansicht _AllSpans:

    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 BigQuery Studio-Seite verwenden oder das bq-Befehlszeilentool nutzen möchten, bearbeiten Sie die FROM-Klausel und geben Sie den Pfad zum verknüpften Dataset ein. Wenn Sie beispielsweise die _AllSpans Ansicht 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.

Alle Tracedaten 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

Allgemeine Spanneninformationen anzeigen

Führen Sie die folgende Abfrage aus, um allgemeine Spanneninformationen wie Startzeit und Dauer anzuzeigen:

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 unter SpanKind.

Wenn Sie die Ergebnisse grafisch darstellen möchten, können Sie ein Diagramm erstellen, bei dem die Dimension auf rpc_service_method festgelegt ist. Sie können zwei Messwerte hinzufügen, einen für den Durchschnitt des Werts duration_nano_p50 und den anderen für den Durchschnitt des Felds duration_nano_p99.

Traceeinträ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 Spannen analysieren möchten, bei denen name angegeben ist, verwenden Sie die folgende Klausel:

    -- Matches spans that have a name field.
    WHERE name IS NOT NULL
    
  • Wenn Sie nur Spannen analysieren möchten, bei 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 Spannen analysieren möchten, bei 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 Ganzzahl-Datentypen filtern

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

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

    -- Matches spans that have field named kind.
    WHERE kind IS NOT NULL
    
  • Wenn Sie Spannen analysieren möchten, deren kind-Wert entweder 1 oder 2 ist, verwenden Sie die folgende Klausel:

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

Nach RECORD-Datentypen filtern

Einige Felder im Trace-Schema 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 Spannen analysieren möchten, bei 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 Spannen analysieren möchten, bei 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, aber es handelt sich um wiederholte Felder.

  • Wenn Sie Spannen abgleichen möchten, die mindestens ein Ereignis haben, verwenden Sie die folgende Klausel:

    -- 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
    
  • Wenn Sie Spannen abgleichen möchten, die ein Ereignis haben, dessen Feld name den Wert message hat, verwenden Sie die folgende Klausel:

    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 Spannen analysieren möchten, bei 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 Spannen analysieren möchten, bei denen der Attributschlüssel 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 Test auf „enthält“ 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%'
    

Tracedaten gruppieren und aggregieren

In diesem Abschnitt wird veranschaulicht, wie Sie Spannen 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.

Spannen 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 TIMESTAMP_TRUNC Dokumentation und unter Datums- und Zeitfunktionen.

Spannen nach Statuscode zählen

Führen Sie die folgende Abfrage aus, um die Anzahl der Spannen mit einem bestimmten Statuscode anzuzeigen:

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, gibt die vorherige Abfrage die Anzahl der Spannen für jeden Wert der Aufzählung kind zurück. Wenn Sie status.code durch name ersetzen, werden in den Abfrageergebnissen die Anzahl der Einträge für jeden Spannennamen aufgeführt.

Durchschnittliche Dauer aller Spannen berechnen

Wenn Sie die durchschnittliche Dauer anzeigen möchten, nachdem Sie die Spannendaten nach Spannennamen gruppiert haben, führen Sie die folgende Abfrage aus:

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

Die folgende Abfrage berechnet die Anzahl der Spannen und verschiedene Statistiken für jeden Dienst:

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.

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 Speicherorte der Ansichten erfüllen eine der folgenden Bedingungen:

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

    • Für Speicherressourcen, die CMEK verwenden, wird derselbe Cloud KMS-Schlüssel verwendet.
    • Speicherressourcen, die CMEK verwenden, haben einen gemeinsamen Vorfahren und dieser Vorfahre gibt einen Standard- Cloud KMS-Schlüssel an, der sich am selben Speicherort wie die Speicherressourcen befindet.

    Wenn für eine oder mehrere Speicherressourcen CMEK verwendet wird, verschlüsselt das System temporäre Daten, die durch die Zusammenführung generiert werden, entweder mit dem gemeinsamen Cloud KMS-Schlüssel oder dem Standard-Cloud KMS-Schlüssel des Vorfahren.

Angenommen, Sie haben zwei Ansichten, die sich am selben Speicherort befinden. Dann können Sie diese Ansichten zusammenführen, wenn eine der folgenden Bedingungen erfüllt ist:

  • Für die Speicherressourcen wird kein CMEK verwendet.
  • Für eine Speicherressource wird CMEK verwendet, für die andere nicht.
  • Für beide Speicherressourcen wird CMEK verwendet und beide verwenden denselben Cloud KMS-Schlüssel.
  • Für beide Speicherressourcen wird CMEK verwendet, aber sie verwenden unterschiedliche Schlüssel. Die Ressourcen haben jedoch einen gemeinsamen Vorfahren, der einen Standard-Cloud KMS-Schlüssel angibt, der sich am selben Speicherort 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 zusammenführen, wenn Sie für diese Organisation, die Standardressourceneinstellungen für Cloud Logging und für Observability-Buckets mit demselben Standard-Cloud KMS-Schlüssel für den Speicherort konfiguriert haben.

Trace- und Logdaten mit der Trace-ID zusammenführen

Die folgende Abfrage führt Log- und Tracedaten mit den Spannen- und Trace-IDs zusammen:

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

Die Antwort der Abfrage enthält die Trace- und Spannen-ID, mit denen Sie sie einzeln abfragen können, um weitere Informationen zu erhalten. Außerdem werden in den Ergebnissen die Schwere des Logeintrags und die JSON-Nutzlast aufgeführt.

Nächste Schritte

SQL-Referenzdokumentation oder andere Beispiele finden Sie in den folgenden Dokumenten: