שאילתות SQL לדוגמה ל-Trace

במסמך הזה יש דוגמאות לשאילתות ספציפיות לנתוני מעקב שמאוחסנים בפרויקט שלכם ב- Google Cloud .

תמיכה בשפת SQL

השאילתות שמשמשות בדף Observability Analytics תומכות בפונקציות של GoogleSQL, עם כמה חריגים.

הפקודות הבאות של SQL לא נתמכות בשאילתות SQL שמונפקות באמצעות הדף Observability Analytics:

  • פקודות DDL ו-DML
  • פונקציות בהגדרת המשתמש ב-JavaScript
  • פונקציות של BigQuery ML
  • משתני SQL

התכונות הבאות נתמכות רק כשמריצים שאילתה על מערך נתונים מקושר באמצעות הדפים BigQuery Studio ו-Looker Studio, או באמצעות כלי שורת הפקודה של BigQuery:

  • פונקציות בהגדרת המשתמש ב-JavaScript
  • פונקציות של BigQuery ML
  • משתני SQL

שיטות מומלצות

כדי להגדיר את טווח הזמן של השאילתה, מומלץ להשתמש בבורר טווח הזמן. לדוגמה, כדי לראות את הנתונים של השבוע האחרון, בוחרים באפשרות 7 הימים האחרונים בבורר טווח הזמן. אפשר גם להשתמש בבורר טווח הזמן כדי לציין שעת התחלה ושעת סיום, לציין שעה לצפייה בסביבתה ולשנות אזורי זמן.

אם כוללים שדה start_time בסעיף WHERE, ההגדרה של בורר טווח הזמן לא משמשת. בדוגמה הבאה אפשר לראות איך מסננים לפי חותמת זמן:

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

מידע נוסף על סינון לפי זמן זמין במאמרים בנושא פונקציות זמן ופונקציות של חותמת זמן.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  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. כדי לקבל את ההרשאות שדרושות לטעינת הדף Observability Analytics, לכתיבה, להרצה ולשמירה של שאילתות פרטיות בנתוני המעקב, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים:

    • Observability View Accessor (roles/observability.viewAccessor) בתצוגות הניראות שרוצים לשלוח אליהן שאילתות. התפקיד הזה תומך בתנאי IAM, שמאפשרים להגביל את ההרשאה לתצוגה ספציפית. אם לא מצרפים תנאי להענקת התפקיד, לחשבון המשתמש תהיה גישה לכל תצוגות הנתונים של יכולת התצפית.
    • Observability Analytics User (roles/observability.analyticsUser) on your project. התפקיד הזה כולל את ההרשאות שנדרשות לשמירה ולהרצה של שאילתות פרטיות, ולהרצה של שאילתות משותפות.
    • מציג היומנים (roles/logging.viewer) בפרויקט.

    להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

    יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.

איך משתמשים בשאילתות שבדף הזה

  1. נכנסים לדף Observability Analytics במסוף Google Cloud :

    עוברים אל Observability Analytics

    אם משתמשים בסרגל החיפוש כדי למצוא את הדף הזה, בוחרים בתוצאה שכותרת המשנה שלה היא Logging.

  2. בחלונית Query, לוחצים על  SQL, ואז מעתיקים ומדביקים שאילתה בחלונית של שאילתת ה-SQL.

    הפורמט של FROM cause for querying the _AllSpans view:

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

    הפסקה FROM מכילה את השדות הבאים:

    • PROJECT_ID: מזהה הפרויקט.
    • LOCATION: המיקום של קטגוריית ה-Observability.
    • _Trace הוא שם קטגוריית הנתונים של יכולת התצפית.
    • Spans הוא שם מערך הנתונים.
    • _AllSpans הוא שם התצוגה.

כדי להשתמש בשאילתות שמופיעות במסמך הזה בדף BigQuery Studio או כדי להשתמש בכלי שורת הפקודה של BigQuery, צריך לערוך את סעיף FROM ולהזין את הנתיב למערך הנתונים המקושר. לדוגמה, כדי לשלוח שאילתה לתצוגה _AllSpans במערך הנתונים המקושר שנקרא my_linked_dataset שנמצא בפרויקט myproject, הנתיב הוא `myproject.my_linked_dataset._AllSpans`.

תרחישים נפוצים לדוגמה

בקטע הזה מפורטים כמה תרחישי שימוש נפוצים שיכולים לעזור לכם ליצור שאילתות בהתאמה אישית.

הצגת כל נתוני העקבות

כדי להריץ שאילתה על התצוגה _AllSpans, מריצים את השאילתה הבאה:

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

הצגת מידע נפוץ על טווחים

כדי להציג מידע על טווח משותף, כמו שעת ההתחלה והמשך, מריצים את השאילתה הבאה:

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

מידע נוסף זמין במאמר בנושא ביטויים מותנים.

הצגת האחוזון ה-50 וה-99 של זמן האחזור של הטווח

כדי להציג את האחוזון ה-50 וה-99 של זמן האחזור לכל שירות RPC, מריצים את השאילתה הבאה:

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

מידע נוסף על הספירה מופיע במאמר בנושא OpenTelemetry: SpanKind.

כדי לראות את התוצאות בגרף, אפשר ליצור תרשים עם המאפיין rpc_service_method. לדוגמה, אפשר להוסיף שני מדדים: אחד לממוצע של הערך duration_nano_p50 והשני לממוצע של השדה duration_nano_p99.

סינון רשומות של מעקב

כדי להחיל מסנן על השאילתה, מוסיפים פסקה WHERE. התחביר שבו משתמשים בסעיף הזה תלוי בסוג הנתונים של השדה. בקטע הזה תמצאו כמה דוגמאות לסוגי נתונים שונים.

סינון לפי סוגי נתונים של מחרוזות

השדה name מאוחסן כ-String.

  • כדי לנתח רק את טווחי הזמן שבהם מצוין name, משתמשים בסעיף הבא:

    -- Matches spans that have a name field.
    WHERE name IS NOT NULL
    
  • כדי לנתח רק את הטווחים שבהם name מקבל את הערך "POST", משתמשים בסעיף הבא:

    -- Matches spans whose name is POST.
    WHERE STRPOS(name, "POST") > 0
    
  • כדי לנתח רק את הטווחים שבהם name מכיל את הערך "POST", משתמשים באופרטור LIKE עם תווים כלליים:

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

סינון לפי סוגי נתונים של מספרים שלמים

השדה kind הוא מספר שלם, שיכול לקבל ערכים בין אפס לחמש:

  • כדי לנתח רק את הטווחים שבהם מצוין kind, משתמשים בפסקה הבאה:

    -- Matches spans that have field named kind.
    WHERE kind IS NOT NULL
    
  • כדי לנתח טווחים שבהם הערך של kind הוא אחד או שניים, משתמשים בפסקה הבאה:

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

סינון לפי סוגי נתונים של רשומות

לחלק מהשדות בסכמת העקבות יש סוג נתונים של RECORD. בשדות האלה אפשר לאחסן מבנה נתונים אחד או יותר, או רשומות חוזרות של אותו מבנה נתונים.

סינון לפי סטטוס או קוד סטטוס

השדה status הוא דוגמה לשדה שסוג הנתונים שלו הוא RECORD. בשדה הזה מאוחסן מבנה נתונים אחד, עם חברים שמסומנים בתוויות code ו-message.

  • כדי לנתח רק טווחי זמן כשהשדה status.code מכיל את הערך 1, מוסיפים את הסעיף הבא:

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

    השדה status.code מאוחסן כמספר שלם.

  • כדי לנתח טווחי זמן שבהם השדה status לא EMPTY, מוסיפים את הפסקה הבאה:

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

השדות events ו-links מאוחסנים עם סוג נתונים RECORD, אבל אלה שדות חוזרים.

  • כדי להתאים טווחי זמן שכוללים לפחות אירוע אחד, משתמשים בסעיף הבא:

    -- 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
    
  • כדי להתאים ליחידות לוגיות למעקב שיש להן אירוע שבו השדה name מכיל את הערך message, משתמשים בפסוקית הבאה:

    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'
      )
    

סינון לפי סוגי נתונים ב-JSON

השדה attributes הוא מסוג JSON. כל מאפיין בנפרד הוא צמד מפתח/ערך.

  • כדי לנתח רק את טווחי הזמן שבהם מצוין attributes, משתמשים בסעיף הבא:

    -- Matches spans where at least one attribute is specified.
    WHERE attributes IS NOT NULL
    
  • כדי לנתח רק את הטווחים שבהם למפתח המאפיין שנקרא component יש ערך של "proxy", משתמשים בפסקה הבאה:

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

    אפשר גם להשתמש בהצהרת LIKE יחד עם תווים כלליים לחיפוש כדי לבצע בדיקת הכלה:

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

קיבוץ וצבירה של נתוני מעקב

בקטע הזה מוסבר איך לקבץ ולצבור טווחי זמן. אם לא מציינים קיבוץ אבל מציינים צבירה, תוצאה אחת מודפסת כי SQL מתייחס לכל הרשומות שמקיימות את התנאי של פסוקית WHERE כקבוצה אחת.

כל ביטוי SELECT צריך להיכלל בשדות הקבוצה או להיות מצטבר.

קיבוץ טווחי זמן לפי שעת התחלה

כדי לקבץ נתונים לפי שעת התחלה, משתמשים בפונקציה TIMESTAMP_TRUNC, שמקצרת חותמת זמן לגרנולריות שצוינה כמו HOUR:

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

מידע נוסף זמין בTIMESTAMP_TRUNCמאמרי העזרה ובקטע פונקציות של תאריך ושעה.

ספירת טווחי זמן לפי קוד סטטוס

כדי להציג את מספר ה-spans עם קוד סטטוס ספציפי, מריצים את השאילתה הבאה:

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

אם מחליפים את status.code ב-kind, בדוח של השאילתה הקודמת יופיע מספר המרווחים לכל ערך של המנייה kind. באופן דומה, אם מחליפים את status.code ב-name, תוצאות השאילתה יציגו את מספר הרשומות של כל שם של טווח.

חישוב משך הזמן הממוצע של כל הטווחים

כדי להציג את משך הזמן הממוצע, אחרי שמקבצים את נתוני הטווח לפי שם הטווח, מריצים את השאילתה הבאה:

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

חישוב משך הזמן הממוצע ואחוזונים לכל שם שירות

השאילתה הבאה מחשבת את מספר הטווחים ונתונים סטטיסטיים שונים לכל שירות:

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

בקטע הזה מתוארות שתי גישות שבהן אפשר להשתמש כדי לחפש בכמה עמודות בתצוגה ששולחים לגביה שאילתה:

  • חיפושים מבוססי-טוקן: מציינים את מיקום החיפוש, שאילתת חיפוש ואז משתמשים בפונקציה SEARCH. לפונקציה SEARCH יש כללים ספציפיים לגבי אופן החיפוש של הנתונים, ולכן מומלץ לקרוא את התיעוד של SEARCH.

  • חיפושים שמבוססים על מחרוזת משנה: מציינים את מיקום החיפוש, מחרוזת מילולית, ואז משתמשים בפונקציה CONTAINS_SUBSTR. המערכת מבצעת בדיקה לא תלוית-רישיות כדי לקבוע אם המחרוזת המילולית קיימת בביטוי. הפונקציה CONTAINS_SUBSTR מחזירה TRUE אם ליטרל המחרוזת קיים, ומחזירה FALSE אם לא. ערך החיפוש חייב להיות ערך מילולי STRING, אבל לא הערך המילולי NULL.

הרצת שאילתות על כמה תצוגות

הוראות שאילתה סורקות טבלה אחת או יותר או ביטויים ומחזירות את שורות התוצאות המחושבות. לדוגמה, אפשר להשתמש בהצהרות שאילתה כדי למזג את התוצאות של הצהרות SELECT בטבלאות או במערכי נתונים שונים במגוון דרכים, ואז לבחור את העמודות מהנתונים המשולבים.

ההגבלות הבאות חלות על הצטרפות לתצוגות:

  1. המיקומים של התצוגות עומדים באחד מהתנאים הבאים:

    • לכל התצוגות יש את אותו המיקום.
    • כל התצוגות נמצאות במיקום global או us.
  2. כשמשאבי אחסון משתמשים במפתחות הצפנה בניהול הלקוח (CMEK), אחד מהתנאים הבאים מתקיים:

    • משאבי אחסון שמשתמשים ב-CMEK משתמשים באותו מפתח Cloud KMS.
    • למשאבי אחסון שמשתמשים ב-CMEK יש אב משותף, ובאב הזה מוגדר מפתח Cloud KMS שמוגדר כברירת מחדל ונמצא באותו מיקום כמו משאבי האחסון.

    כשמשתמשים ב-CMEK במשאב אחסון אחד או יותר, המערכת מצפינה את הנתונים הזמניים שנוצרים על ידי הצטרפות למפתח Cloud KMS המשותף או למפתח Cloud KMS שמוגדר כברירת מחדל של משאב האב.

לדוגמה, נניח שיש לכם שתי תצוגות שנמצאות באותו מיקום. אחר כך תוכלו להצטרף לתצוגות האלה אם מתקיים אחד מהתנאים הבאים:

  • משאבי האחסון לא משתמשים ב-CMEK.
  • משאב אחסון אחד משתמש ב-CMEK והשני לא.
  • שני משאבי האחסון משתמשים ב-CMEK ובאותו מפתח Cloud KMS.
  • שני משאבי האחסון משתמשים ב-CMEK, אבל במפתחות שונים. עם זאת, המשאבים חולקים ישות אב שמציינת מפתח ברירת מחדל של Cloud KMS שנמצא באותו מיקום כמו משאבי האחסון.

    לדוגמה, נניח שהיררכיית המשאבים של קטגוריית יומנים וקטגוריית נתונים לצפייה כוללת את אותו ארגון. אתם יכולים לצרף תצוגות לקטגוריות האלה אם הגדרתם בארגון את הגדרות ברירת המחדל של המשאבים ב-Cloud Logging ואת קטגוריות הנתונים של יכולת התצפית עם אותו מפתח ברירת מחדל של Cloud KMS למיקום האחסון.

איחוד נתונים של מעקב ויומנים באמצעות מזהה המעקב

השאילתה הבאה מצטרפת לנתוני יומן ולנתוני מעקב באמצעות מזהי הטווח והמעקב:

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

בתשובה לשאילתה מופיעים מזהה יומן המעקב ומזהה היחידה הלוגית למעקב, שאפשר להשתמש בהם כדי לשלוח שאילתה לגבי כל אחד מהם בנפרד ולאסוף מידע נוסף. בנוסף, ברשימת התוצאות מופיעים חומרת רשומת היומן ומטען ה-JSON.

המאמרים הבאים

למאמרי עזרה בנושא SQL או לדוגמאות נוספות, אפשר לעיין במסמכים הבאים: