עיצוב רשומה ביומן כדי לדווח על אירועי שגיאה

במאמר הזה מוסבר איך לעצב את הרשומה ביומן כשרוצים להשתמש ב-Cloud Logging כדי לדווח על אירועי שגיאה.

כדי לדווח על אירועי שגיאה לפרויקט ב- Google Cloud , מריצים את השיטה write של Cloud Logging API או את השיטה report של Error Reporting API. כשמדווחים על אירועי שגיאה באמצעות Cloud Logging API, גוף הבקשה מכיל אובייקט LogEntry שחייב לכלול דוח קריסות או אובייקט ReportedErrorEvent.

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

  • פועלים לפי הוראות ההגדרה לשפה ולפלטפורמה שלכם.

  • אם אתם צריכים אימות שמבוסס על מפתח API, אתם צריכים להשתמש ב-Error Reporting API. כדי לדווח על אירוע שגיאה באמצעות Error Reporting API, מריצים את השיטה report ומעצבים את גוף הבקשה של השיטה כאובייקט ReportedErrorEvent.

    כשמשתמשים ב-Error Reporting API, רשומות ביומן עם הודעות שגיאה בפורמט תקין נוצרות באופן אוטומטי ונכתבות ב-Cloud Logging. רשומות היומן האלה נכתבות ביומן ששם הקובץ שלו מעוצב באופן הבא:logName

    projects/PROJECT_ID/clouderrorreporting.googleapis.com%2Freported_errors
    

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

    אם אתם מדווחים על אירועי שגיאה באמצעות Error Reporting API, שאר המידע במאמר הזה לא רלוונטי.

הדרישות בנוגע לפורמט LogEntry

בקטע הזה מוסבר איך לעצב LogEntry כדי ש-Error Reporting יתעד את אירוע השגיאה שמופיע ברשומת היומן.

רישום דוח קריסות

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

  • textPayload עם כמה שורות.
  • jsonPayload שכולל את השדה message, stack_trace או exception.

    אפשר לציין יותר מאחד מהשדות האלה. אם מציינים יותר משדה אחד מאלה, סדר הבדיקה הוא: stack_trace, אחר כך exception ואז message.

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

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

  • jsonPayload שלא כולל את השדות message, stack_trace או exception, אבל כן כולל דוח קריסות.

    Error Reporting מחפש בכל השדות ב-jsonPayload כדי למצוא דוחות קריסות. אם נמצא יותר מ-stack trace אחד, המערכת בוחרת אחד מהם. אלגוריתם הבחירה מבטיח בחירה עקבית.

תיעוד של הודעת טקסט

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

    "jsonPayload": {
      "@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent",
      "message": "Text message"
    },

כשמגדירים את השדה @type לערך שצוין, Error Reporting תמיד מעריכה את רשומת היומן כאילו כל שדות החובה קיימים. כתוצאה מכך, Error Reporting מתעד את אירוע השגיאה.

אם מגדירים ערך אחר בשדה @type או לא מגדירים אותו, Cloud Logging מחפש את השדה עם התווית serviceContext כדי לקבוע אם מטען הייעודי (payload) הוא אובייקט ReportedErrorEvent.

אין צורך להגדיר את השדה @type אם השדות message, stack_trace או exception של jsonPayload מכילים דוח קריסות. במקרים כאלה, הכלי Error Reporting מתעד באופן אוטומטי את אירוע השגיאה.

משאבים נתמכים במעקב

מגדירים את השדה resource של אובייקט LogEntry לאחד מסוגי המשאבים המפוקחים הנתמכים הבאים:

  • app_script_function
  • aws_ec2_instance
  • cloud_function
  • cloud_run_jobs
  • cloud_run_revision
  • consumed_api
  • container
  • dataflow_step
  • gae_app
  • gce_instance
  • k8s_container
  • k8s_pod
  • ml_job1
  • workflows.googleapis.com/Workflow
  • global1

1 textPayload לא נתמך

דוגמאות

בקטע הזה מוסבר איך לוודא ש-Error Reporting מעבד רשומה ביומן כשהיא מכילה הודעת טקסט או דוח קריסות.

רישום ביומן של אירוע שגיאה שהוא הודעת טקסט

בדוגמה הבאה מוצג פורמט של אובייקט LogEntry כשרוצים לרשום ביומן אירוע שגיאה שהוא הודעת טקסט. משתמשים במבנה ה-JSON הבא בשדה jsonPayload של LogEntry:

{...
  {
    "jsonPayload": {
      "@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent",
      "message": "A simple text message"
    },
    "logName": "projects/test-project/logs/reported-error",
    "resource": {
      "labels": {
        "project_id": "test-project"
      },
      "type": "global"
    },
    "severity": "ERROR",
    "timestamp": "2019-06-27T13:43:26.375834551Z"
  }
}

כפי שמוצג בדוגמה, צריך להגדיר את השדה @type לערך שמכריח את Error Reporting לקבץ את רשומת היומן: למידע נוסף, אפשר לעיין במאמר בנושא רישום הודעת טקסט ביומן.

אם השדה message מכיל דוח קריסות, רשומה ביומן מקובצת באופן אוטומטי, כך שלא צריך לציין את השדה @type.

רישום שגיאה ביומן בפורמט של אובייקט ReportedErrorEvent

אם אירוע השגיאה מאוחסן באובייקט ReportedErrorEvent, צריך להשתמש במבנה ה-JSON הבא בשדה jsonPayload של LogEntry:

{
  "eventTime": string,
  "serviceContext": {
    "service": string,     // Required.
    "version": string
  },
  "message": string,       // Required. This field contains the main error content to report.
  "@type": string          // Optional. For information about this field, see Log a text message.
  "context": {
    "httpRequest": {
      "method": string,
      "url": string,
      "userAgent": string,
      "referrer": string,
      "responseStatusCode": number,
      "remoteIp": string
    },
    "user": string,
    "reportLocation": {    // Required if no stack trace is provided.
      "filePath": string,
      "lineNumber": number,
      "functionName": string
    }
  }
}

חשוב לוודא שאתם ממלאים את השדה message בפרטי השגיאה. מידע נוסף על אחסון של מעקב אחר מחסנית בשדה message של אובייקט ReportedErrorEvent מופיע בדף העזר של השיטה report.

בדוגמה הבאה אפשר לראות איך להגדיר את השדה jsonPayload של LogEntry כך שיוצג כנתוני אובייקט ReportedErrorEvent. כי השדה message מכיל מעקב אחר מחסנית, אירוע השגיאה מקוּבץ על ידי דיווח השגיאות:

{...
   "jsonPayload": {
      "serviceContext": {
        "service": "frontend",
        "version": "bf6b5b09b9d3da92c7bf964ab1664fe751104517"
      },
      "message": "com.example.shop.Template$CartDiv retrieveCart: Error\njava.lang.IndexOutOfBoundsException: Index: 4, Size: 4\n\tat java.util.ArrayList.rangeCheck(ArrayList.java:635)\n\tat java.util.ArrayList.get(ArrayList.java:411)\n\tat com.example.shop.Cart.retrieve(Cart.java:76)\n\tat com.example.shop.Cart.generate(Cart.java:55)\n\tat com.example.shop.Template$CartDiv.retrieveCart(Template.java:113)\n\tat com.example.shop.Template.generate(Template.java:22)\n\tat com.example.shop.CartServlet.doGet(CartServlet.java:115)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:717)\n",
      "context":
        "httpRequest": {
          "method": "GET",
          "url": "http://example.com/shop/cart",
          "responseStatusCode": 500
        },
        "user": "9f32f587135aa6774e78ed30fbaabcce3ec5528f"
      }
   },
   "logName": "projects/test-project/logs/reported-error",
   "resource": {
      "labels": {
        "project_id": "test-project"
      },
      "type": "global"
   },
   "severity": "ERROR",
   "timestamp": "2019-06-27T13:43:26.375834551Z"
}

רישום ביומן של אירוע שגיאה באמצעות השדה textPayload

אפשר להקליט אירוע שגיאה באמצעות השדה textPayload של LogEntry כדי לאחסן את הודעת השגיאה, למשל דוח קריסות. לדוגמה, הפקודה הבאה של Google Cloud CLI יוצרת רשומה ביומן שרמת החומרה שלה היא ERROR והשדה textPayload שלה מכיל אירוע שגיאה:

gcloud logging write test-log --severity=ERROR --payload-type=text 'RuntimeException: Oops! Something bad happened.
at com.example.MyClass.method(MyClass.java:123)
at com.example.OtherClass.doStuff(Unknown Source)
at com.example.Sys.create(Native Method)'

התוצאה של הפקודה הקודמת היא רשומה ביומן שמקובצת לפי Error Reporting:

{...
    logName: "projects/PROJECT_ID/logs/test-log"
    severity: "ERROR"
    textPayload: "RuntimeException: Oops! Something bad happened.
                  at com.example.MyClass.method(MyClass.java:123)
                  at com.example.OtherClass.doStuff(Unknown Source)
                  at com.example.Sys.create(Native Method)"
    ...
}