מעקב אחרי השימוש בטוקנים של תובנות מנתונים

במאמר הזה מוסבר איך לעקוב אחרי צריכת טוקנים בסריקות של תובנות נתונים ב-Knowledge Catalog (לשעבר Dataplex Universal Catalog) באמצעות Cloud Logging ו-Cloud Monitoring. מעקב אחרי השימוש באסימוני מעקב לכל סריקה ולכל משימה מאפשר לכם להבין את מגמות השימוש במודל ולהעריך את עלויות החיוב בפרויקט.

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

כשמשימת סריקה של תובנות מנתונים (jsonPayload.type="DATA_DOCUMENTATION") מסתיימת במצב SUCCEEDED, Knowledge Catalog כותב רשומה ביומן לתוך היומן dataplex.googleapis.com/data_scan. הרשומה הזו ביומן מכילה בלוק billableTokenUsage בקטע jsonPayload.dataDocumentation, שמתעד את פירוט הטוקנים של המשימה. רשומות אחרות ביומן של העבודה (כמו אירועים של CREATED,‏ STARTED,‏ FAILED או CANCELLED) לא כוללות בלוק של billableTokenUsage.

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

מדד תיאור נוסחה (שימוש בשדות billableTokenUsage)
טוקנים של קלט שלא נשמרו במטמון טוקנים של קלט שלא סופקו משמירת ההקשר במטמון, כולל טוקנים של הנחיות לשימוש בכלים. max(promptTokenCount - cachedContentTokenCount, 0) + toolUsePromptTokenCount
טוקנים של קלט במטמון טוקנים של קלט שסופקו משמירת ההקשר במטמון. הטוקנים במטמון נספרים בנפרד כי המחיר שלהם שונה מהמחיר הרגיל של טוקנים של קלט שלא נשמרו במטמון. cachedContentTokenCount
טוקנים של פלט טוקנים של תשובות שנוצרו וטוקנים של הסקת מסקנות (חשיבה). החיוב על טוקנים של חשיבה הוא כמו על טוקנים של פלט. candidatesTokenCount + thoughtsTokenCount

לפרטים על תמחור טוקנים, ראו תמחור של סוכני Data Cloud.

שדות הטוקן ברשומה ביומן

כל רשומה ביומן dataplex.googleapis.com/data_scan כוללת מזהים סטנדרטיים של משאבים ועבודות, כמו resource.labels.datascan_id, ‏ resource.labels.location, ‏ jsonPayload.jobId ו-jsonPayload.state. בסריקות מוצלחות של תובנות מנתונים, האובייקט jsonPayload.dataDocumentation.billableTokenUsage מכיל את השדות הבאים:

שדה תיאור
promptTokenCount המספר הכולל של טוקנים בהנחיות שנשלחו למודל, כולל טוקנים שנשמרו במטמון.
cachedContentTokenCount חלק מהטוקנים של ההנחיות שסופקו מ<b>שמירת הקשר במטמון</b>.
toolUsePromptTokenCount טוקנים של הנחיה שנוספו על ידי קריאות לכלים (כמו סכימה, פרופיל או הקשר של היסטוריית שאילתות).
candidatesTokenCount טוקנים של תשובות שנוצרו, לא כולל טוקנים של חשיבה.
thoughtsTokenCount טוקנים של חשיבה שהמודל יוצר.

בדוגמה הבאה מוצגת רשומה ביומן dataplex.googleapis.com/data_scan של משימת סריקה מוצלחת של תובנות מנתונים:

{
  "resource": {
    "type": "dataplex.googleapis.com/DataScan",
    "labels": {
      "datascan_id": "my-insights-scan",
      "location": "us-central1",
      "resource_container": "projects/1234567890"
    }
  },
  "jsonPayload": {
    "type": "DATA_DOCUMENTATION",
    "jobId": "8f2b3c4d-1234-5678-9abc-def012345678",
    "state": "SUCCEEDED",
    "dataDocumentation": {
      "billableTokenUsage": {
        "promptTokenCount": "20412",
        "candidatesTokenCount": "7053"
      }
    }
  }
}

בדוגמה הזו, העבודה לא השתמשה בשמירת הקשר במטמון, בטוקנים של חשיבה או בקריאות לכלים. כתוצאה מכך, טוקנים של קלט שלא נשמרו במטמון שווים ל-20,412, טוקנים של קלט שנשמרו במטמון שווים ל-0, וטוקנים של פלט שווים ל-7,053.

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

לפני ששולחים שאילתות ליומני האסימונים של תובנות מנתונים או יוצרים לוח בקרה למעקב, צריך לבצע את הפעולות הבאות.

התפקידים הנדרשים

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

  • צפייה ביומני סריקת הנתונים והרצת שאילתות של Observability Analytics: מציג היומנים (roles/logging.viewer)
  • יצירת לוחות בקרה בהתאמה אישית ב-Monitoring: עריכת Monitoring (roles/monitoring.editor)
  • כדי לראות מרכזי בקרה בהתאמה אישית ב-Monitoring: צפייה ב-Monitoring (roles/monitoring.viewer)

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

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

הפעלת ממשקי ה-API

מפעילים את Dataplex,‏ Logging ו-Monitoring APIs, אם הם עדיין לא מופעלים.

תפקידים שנדרשים להפעלת ממשקי API

כדי להפעיל ממשקי API, צריך את ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק 'שימוש בשירות'' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

הפעלת ממשקי ה-API

אימות ההגדרות של ניתוב היומנים

סריקות של תובנות מנתונים כותבות יומנים בשם היומן dataplex.googleapis.com/data_scan. ההגדרות של מרכז הבקרה במסמך הזה קוראות את היומנים האלה מקטגוריית היומנים _Default של הפרויקט. צריך לוודא שהניתוב של היומנים בפרויקט עומד בתנאים הבאים:

  • הכיור _Default מופעל ומנתב את היומנים לקטגוריית היומנים _Default.
  • לכיור _Default אין מסנן החרגה שמשמיט את היומנים של dataplex.googleapis.com/data_scan או של DATA_DOCUMENTATION.

המסוף

  1. במסוף Google Cloud , נכנסים לדף Logging > Log Router.

    כניסה ל-Log Router

  2. מאתרים את _Default יעד הנתונים ומוודאים שהסטטוס שלו הוא מופעל והיעד שלו הוא _Default מאגר.

  3. לוחצים על תפריט היעד () ובוחרים באפשרות הצגת פרטי היעד. מוודאים שאף מסנן החרגה לא תואם ל-dataplex.googleapis.com/data_scan או ל-DATA_DOCUMENTATION.

gcloud

כדי לבדוק את הסטטוס, היעד ומסנני ההחרגה של אובייקט ה-sink‏ _Default, מריצים את הפקודה:

gcloud logging sinks describe _Default --project=PROJECT_ID

מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud.

מוודאים שהערך של disabled הוא לא true, שהערך של destination מסתיים ב-/buckets/_Default, ושאין רשומה ב-exclusions שתואמת ל-data_scan.

הפעלת Observability Analytics בקטגוריה _Default

כדי להריץ שאילתות SQL על יומני הסריקה של תובנות מנתונים ולהפעיל את לוח הבקרה המותאם אישית של Observability Analytics, צריך לשדרג את קטגוריית היומן _Default של הפרויקט לשימוש ב-Observability Analytics.

לפני שמפעילים את Observability Analytics ב_Default מאגר היומנים, כדאי לעיין בשיקולים הבאים:

  • אי אפשר לבטל את השדרוג של קטגוריה ל-Observability Analytics, ואין עלות נוספת.
  • אין צורך ליצור קבוצת נתונים מקושרת ב-BigQuery.
  • שאילתות SQL של Observability Analytics מחזירות רק יומנים שמגיעים אחרי שהשדרוג מסתיים. יומנים ישנים יותר עדיין זמינים בכלי Logs Explorer, אבל הם לא מופיעים בתוצאות של שאילתות SQL. אחרי שמשדרגים את הקטגוריה, מריצים לפחות סריקה אחת של תובנות מנתונים כדי שיהיו נתונים להצגה בלוח הבקרה.

המסוף

  1. במסוף Google Cloud , נכנסים לדף Logging > Logs Storage.

    כניסה לדף Logs Storage

  2. מאתרים את השורה של הקטגוריה _Default ובודקים את העמודה Observability Analytics available:

    • אם בעמודה מופיע הכיתוב Open, סימן שהתכונה Observability Analytics כבר מופעלת.
    • אם בעמודה מופיע הכיתוב שדרוג, לוחצים על שדרוג ומאשרים את השדרוג.
  3. ממתינים כמה דקות עד שהסטטוס של העמודה משתנה לפתוח.

gcloud

  1. משדרגים את מאגר היומנים _Default כדי להפעיל את Observability Analytics:

    gcloud logging buckets update _Default \
        --location=global --enable-analytics --project=PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud .

  2. אחרי כמה דקות, מוודאים שהשדרוג הושלם:

    gcloud logging buckets describe _Default \
        --location=global --project=PROJECT_ID
    

    מוודאים שהפלט כולל את analyticsEnabled: true.

צפייה בשימוש בטוקנים לכל משימה ב-Logs Explorer

כדי לבדוק את צריכת הטוקנים של משימות סריקת תובנות מנתונים ספציפיות, אפשר להשתמש בכלי Logs Explorer או ב-Google Cloud CLI. כדי לראות נתונים מצטברים ברמת הפרויקט לפי שעה או לפי יום, אתם יכולים ליצור לוח בקרה באמצעות Observability Analytics.

המסוף

  1. במסוף Google Cloud , נכנסים לדף Logging > Logs Explorer.

    כניסה לדף Logs Explorer

  2. אם עורך השאילתות לא מוצג, מפעילים את האפשרות Show query.

  3. מזינים את השאילתה הבאה בעורך השאילתות:

    log_id("dataplex.googleapis.com/data_scan")
    jsonPayload.type="DATA_DOCUMENTATION"
    jsonPayload.dataDocumentation.billableTokenUsage.promptTokenCount:*
    

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

    resource.labels.datascan_id="DATA_SCAN_ID"
    jsonPayload.jobId="JOB_ID"
    

    מחליפים את מה שכתוב בשדות הבאים:

    • ‫DATA_SCAN_ID: המזהה של סריקת התובנות מהנתונים.
    • ‫JOB_ID: המזהה של הרצה ספציפית של משימת סריקה.
  4. בוחרים טווח תאריכים (לדוגמה, 24 השעות האחרונות) ולוחצים על הפעלת השאילתה.

  5. מרחיבים רשומה ביומן ופותחים את jsonPayload > dataDocumentation > billableTokenUsage כדי לבדוק את מספר הטוקנים של המשימה הזו.

gcloud

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

gcloud logging read \
    'log_id("dataplex.googleapis.com/data_scan") AND jsonPayload.type="DATA_DOCUMENTATION" AND jsonPayload.dataDocumentation.billableTokenUsage.promptTokenCount:*' \
    --project=PROJECT_ID --freshness=1d --limit=20 \
    --format='table(timestamp, resource.labels.datascan_id:label=SCAN,
jsonPayload.jobId:label=JOB,
jsonPayload.dataDocumentation.billableTokenUsage.promptTokenCount:label=PROMPT,
jsonPayload.dataDocumentation.billableTokenUsage.cachedContentTokenCount:label=CACHED,
jsonPayload.dataDocumentation.billableTokenUsage.toolUsePromptTokenCount:label=TOOL_USE,
jsonPayload.dataDocumentation.billableTokenUsage.candidatesTokenCount:label=CANDIDATES,
jsonPayload.dataDocumentation.billableTokenUsage.thoughtsTokenCount:label=THOUGHTS)'

מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud.

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

שליחת שאילתות לגבי השימוש באסימונים באמצעות Observability Analytics

אפשר גם להריץ או להתאים אישית את שאילתות ה-SQL של הווידג'ט ישירות בדף Log Analytics במסוףGoogle Cloud .

התרשימים היומי והשעתי משתמשים באותה שאילתת תרשים, שמחזירה שורה אחת לכל עבודת סריקה. כל ווידג'ט של תרשים מקבץ ומסכם את השורות לפי יום (timeBinSize: 86400s) או לפי שעה (timeBinSize: 3600s). אם אתם עורכים שאילתה של תרשים ומדביקים אותה בחזרה בווידג'ט של מרכז הבקרה, חשוב לשמור על הכינויים של העמודות timestamp,‏ total_non_cached_input_tokens,‏ total_cached_input_tokens ו-total_output_tokens.

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

AND JSON_VALUE(resource.labels, '$.datascan_id') = 'DATA_SCAN_ID'

מחליפים את DATA_SCAN_ID במזהה של סריקת התובנות מהנתונים.

שאילתה לדוגמה ליצירת תרשים (תרשימים יומיים ושעתיים)

SELECT
  timestamp,
  GREATEST(
    IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') AS INT64), 0)
    - IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0),
    0)
  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.toolUsePromptTokenCount') AS INT64), 0)
    AS total_non_cached_input_tokens,
  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0)
    AS total_cached_input_tokens,
  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.candidatesTokenCount') AS INT64), 0)
  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.thoughtsTokenCount') AS INT64), 0)
    AS total_output_tokens
FROM `PROJECT_ID.global._Default._Default`
WHERE
  log_id = 'dataplex.googleapis.com/data_scan'
  AND JSON_VALUE(json_payload, '$.type') = 'DATA_DOCUMENTATION'
  AND JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') IS NOT NULL

מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud.

שאילתה לדוגמה לכל משימת סריקה

SELECT
  timestamp,
  JSON_VALUE(resource.labels, '$.datascan_id') AS data_scan_id,
  JSON_VALUE(resource.labels, '$.location') AS location,
  JSON_VALUE(json_payload, '$.jobId') AS job_id,
  JSON_VALUE(json_payload, '$.state') AS state,
  GREATEST(
    IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') AS INT64), 0)
    - IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0),
    0)
  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.toolUsePromptTokenCount') AS INT64), 0)
    AS non_cached_input_tokens,
  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0)
    AS cached_input_tokens,
  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.candidatesTokenCount') AS INT64), 0)
  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.thoughtsTokenCount') AS INT64), 0)
    AS output_tokens
FROM `PROJECT_ID.global._Default._Default`
WHERE
  log_id = 'dataplex.googleapis.com/data_scan'
  AND JSON_VALUE(json_payload, '$.type') = 'DATA_DOCUMENTATION'
  AND JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') IS NOT NULL
ORDER BY timestamp DESC
LIMIT 500

מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud.

יצירת מרכז בקרה באמצעות Observability Analytics

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

בגישה הזו, מריצים שאילתות SQL ישירות על יומני הסריקה של תובנות הנתונים בקטגוריית היומנים _Default. יש לה כמה יתרונות:

  • דיוק: השאילתות מחשבות את מספר הטוקנים המדויק ישירות ממטעני הייעודי (payload) של JSON ברשומת היומן, ולא מהערכות של מדדים נצברים.
  • היסטוריית משימות מפורטת: בנוסף לתרשימים המצטברים, אתם יכולים לבדוק משימות סריקה ספציפיות בתצוגת טבלה.
  • ללא עלות נוספת: שדרוג של קטגוריית היומנים _Default ל-Observability Analytics לא כרוך בחיובים נוספים.

באפשרות הזו נוצר לוח בקרה של Monitoring עם שלושה ווידג'טים שמריצים שאילתות SQL ביומנים:

  • שימוש יומי בטוקנים (תרשים עמודות אופקי מוערם)
  • שימוש שעתי בטוקנים (תרשים קו)
  • השימוש בטוקנים לכל משימת סריקה (טבלה שבה מוצגות 500 המשימות האחרונות)

ההגדרה הבאה של מרכז הבקרה ב-JSON משתמשת במשתנה המובנה @__project_id (@__project_id.global._Default._Default), שמבצע באופן אוטומטי שאילתה בפרויקט שבו פותחים את מרכז הבקרה. לא צריך לערוך את הפלייסהולדרים של הפרויקט בקובץ ה-JSON לפני הייבוא.

המסוף

  1. במסוף Google Cloud , נכנסים לדף Monitoring > Dashboards.

    מעבר אל Dashboards

  2. לוחצים על יצירת מרכז בקרה.

  3. בסרגל הכלים, לוחצים על Settings, בוחרים באפשרות JSON ואז באפשרות JSON Editor.

  4. מחליפים את התוכן הקיים של העורך בהגדרת ה-JSON של מרכז הבקרה שמפורטת בקטע הבא.

  5. לוחצים על החלת שינויים. כשהשמירה האוטומטית מופעלת, לוח הבקרה נשמר ב-Monitoring בשם Data Insights - Token Usage.

  6. בפעם הראשונה שפותחים את לוח הבקרה, כל ווידג'ט מבקש לאשר את הרצת שאילתת ה-SQL במנוע BigQuery של הפרויקט. מוודאים שהפרויקט מופיע בהודעה, ולוחצים על Continue execution בכל ווידג'ט.

  7. בוחרים טווח תאריכים בסרגל הכלים של לוח הבקרה (לדוגמה, 7 הימים האחרונים).

gcloud

  1. שומרים את הגדרת ה-JSON של מרכז הבקרה בקובץ מקומי בשם dashboard.json.
  2. יוצרים את לוח הבקרה ב-Monitoring:

    gcloud monitoring dashboards create \
        --project=PROJECT_ID \
        --config-from-file=dashboard.json
    

    מחליפים את PROJECT_ID במזהה הפרויקט ב-Google Cloud .

  3. פותחים את הדף Dashboards במסוף Google Cloud , בוחרים באפשרות Insights Scan - Token Usage ולוחצים על Continue execution בכל ווידג'ט כדי לאשר את הרצת שאילתת ה-SQL.

הגדרת JSON של לוח הבקרה

כדי ליצור את מרכז הבקרה, מרחיבים את הקטע הבא ומעתיקים את הגדרת ה-JSON:

הגדרה של JSON

{
  "displayName": "Data Insights - Token Usage",
  "mosaicLayout": {
    "columns": 48,
    "tiles": [
      {
        "xPos": 0,
        "yPos": 0,
        "width": 24,
        "height": 16,
        "widget": {
          "title": "Daily token usage",
          "xyChart": {
            "chartOptions": {
              "mode": "COLOR",
              "displayHorizontal": false
            },
            "dataSets": [
              {
                "plotType": "STACKED_BAR",
                "targetAxis": "Y1",
                "breakdowns": [],
                "dimensions": [
                  {
                    "column": "timestamp",
                    "columnType": "TIMESTAMP",
                    "sortColumn": "timestamp",
                    "sortOrder": "SORT_ORDER_ASCENDING",
                    "timeBinSize": "86400s"
                  }
                ],
                "measures": [
                  {
                    "column": "total_non_cached_input_tokens",
                    "aggregationFunction": {
                      "type": "sum",
                      "parameters": []
                    }
                  },
                  {
                    "column": "total_cached_input_tokens",
                    "aggregationFunction": {
                      "type": "sum",
                      "parameters": []
                    }
                  },
                  {
                    "column": "total_output_tokens",
                    "aggregationFunction": {
                      "type": "sum",
                      "parameters": []
                    }
                  }
                ],
                "timeSeriesQuery": {
                  "opsAnalyticsQuery": {
                    "sql": "SELECT\n  timestamp,\n  GREATEST(\n    IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') AS INT64), 0)\n    - IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0),\n    0)\n  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.toolUsePromptTokenCount') AS INT64), 0)\n    AS total_non_cached_input_tokens,\n  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0)\n    AS total_cached_input_tokens,\n  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.candidatesTokenCount') AS INT64), 0)\n  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.thoughtsTokenCount') AS INT64), 0)\n    AS total_output_tokens\nFROM `@__project_id.global._Default._Default`\nWHERE\n  log_id = 'dataplex.googleapis.com/data_scan'\n  AND JSON_VALUE(json_payload, '$.type') = 'DATA_DOCUMENTATION'\n  AND JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') IS NOT NULL"
                  }
                }
              }
            ],
            "yAxis": {
              "label": "tokens",
              "scale": "LINEAR"
            }
          }
        }
      },
      {
        "xPos": 24,
        "yPos": 0,
        "width": 24,
        "height": 16,
        "widget": {
          "title": "Hourly token usage",
          "xyChart": {
            "chartOptions": {
              "mode": "COLOR",
              "displayHorizontal": false
            },
            "dataSets": [
              {
                "plotType": "LINE",
                "targetAxis": "Y1",
                "breakdowns": [],
                "dimensions": [
                  {
                    "column": "timestamp",
                    "columnType": "TIMESTAMP",
                    "sortColumn": "timestamp",
                    "sortOrder": "SORT_ORDER_ASCENDING",
                    "timeBinSize": "3600s"
                  }
                ],
                "measures": [
                  {
                    "column": "total_non_cached_input_tokens",
                    "aggregationFunction": {
                      "type": "sum",
                      "parameters": []
                    }
                  },
                  {
                    "column": "total_cached_input_tokens",
                    "aggregationFunction": {
                      "type": "sum",
                      "parameters": []
                    }
                  },
                  {
                    "column": "total_output_tokens",
                    "aggregationFunction": {
                      "type": "sum",
                      "parameters": []
                    }
                  }
                ],
                "timeSeriesQuery": {
                  "opsAnalyticsQuery": {
                    "sql": "SELECT\n  timestamp,\n  GREATEST(\n    IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') AS INT64), 0)\n    - IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0),\n    0)\n  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.toolUsePromptTokenCount') AS INT64), 0)\n    AS total_non_cached_input_tokens,\n  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0)\n    AS total_cached_input_tokens,\n  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.candidatesTokenCount') AS INT64), 0)\n  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.thoughtsTokenCount') AS INT64), 0)\n    AS total_output_tokens\nFROM `@__project_id.global._Default._Default`\nWHERE\n  log_id = 'dataplex.googleapis.com/data_scan'\n  AND JSON_VALUE(json_payload, '$.type') = 'DATA_DOCUMENTATION'\n  AND JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') IS NOT NULL"
                  }
                }
              }
            ],
            "yAxis": {
              "label": "tokens",
              "scale": "LINEAR"
            }
          }
        }
      },
      {
        "xPos": 0,
        "yPos": 16,
        "width": 48,
        "height": 20,
        "widget": {
          "title": "Token usage per scan job (latest 500)",
          "timeSeriesTable": {
            "columnSettings": [],
            "dataSets": [
              {
                "tableTemplate": "",
                "timeSeriesQuery": {
                  "opsAnalyticsQuery": {
                    "sql": "SELECT\n  timestamp,\n  JSON_VALUE(resource.labels, '$.datascan_id') AS data_scan_id,\n  JSON_VALUE(resource.labels, '$.location') AS location,\n  JSON_VALUE(json_payload, '$.jobId') AS job_id,\n  JSON_VALUE(json_payload, '$.state') AS state,\n  GREATEST(\n    IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') AS INT64), 0)\n    - IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0),\n    0)\n  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.toolUsePromptTokenCount') AS INT64), 0)\n    AS non_cached_input_tokens,\n  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.cachedContentTokenCount') AS INT64), 0)\n    AS cached_input_tokens,\n  IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.candidatesTokenCount') AS INT64), 0)\n  + IFNULL(SAFE_CAST(JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.thoughtsTokenCount') AS INT64), 0)\n    AS output_tokens\nFROM `@__project_id.global._Default._Default`\nWHERE\n  log_id = 'dataplex.googleapis.com/data_scan'\n  AND JSON_VALUE(json_payload, '$.type') = 'DATA_DOCUMENTATION'\n  AND JSON_VALUE(json_payload, '$.dataDocumentation.billableTokenUsage.promptTokenCount') IS NOT NULL\nORDER BY timestamp DESC\nLIMIT 500"
                  }
                }
              }
            ],
            "metricVisualization": "NUMBER"
          }
        }
      }
    ]
  }
}

מגבלות

  • מדדי הטוקנים מלאים רק אם היומנים של dataplex.googleapis.com/data_scan לא מוחרגים או מנותבים מחוץ למאגר היומנים של _Default.
  • נספרות רק משימות שהסתיימו בהצלחה עם מטא-נתונים של טוקנים. רשומות ביומן בלי בלוק billableTokenUsage לא נכללות בשאילתות ובמדדים.
  • לוחות הבקרה האלה נועדו למעקב אחרי מגמות השימוש ולהערכת עלויות, ולא להשוואה לחשבונית רשמית של חיוב ב-Cloud.
  • לכל Google Cloud פרויקט צריך להגדיר לוח בקרה משלו.
  • שאילתות SQL לא מחזירות רשומות ביומן שנכתבו לפני שהפעלתם את Observability Analytics בקטגוריה _Default.
  • בווידג'ט הטבלה של כל משימה מוצגות עד 500 המשימות האחרונות בטווח התאריכים שנבחר. כדי לבדוק משימות ישנות יותר, אפשר לשלוח שאילתה ל-Logs Explorer.

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