רישום ביומן וצפייה ביומנים ב-Cloud Run

בדף הזה מוסבר על היומנים שזמינים כשמשתמשים ב-Cloud Run, ואיך צופים ביומנים וכותבים אותם.

ב-Cloud Run יש כמה סוגים של יומנים, והם נשלחים אוטומטית אל Cloud Logging:

  • יומני בקשות (שירותים בלבד): יומנים של בקשות שנשלחו לשירותי Cloud Run. היומנים האלה נוצרים באופן אוטומטי.
  • יומני קונטיינרים (שירותים, משימות ומאגרי עובדים): יומנים שנוצרים מהמופעים, בדרך כלל מהקוד שלכם, ונכתבים במיקומים נתמכים כפי שמתואר במאמר כתיבת יומני קונטיינרים.
  • יומני מערכת (שירותים, משימות ומאגרי עובדים): יומנים שנוצרו על ידי הפלטפורמה ומכילים מידע על עומסי העבודה שלכם. היומנים האלה נכתבים ב-varlog/system.

צפייה ביומנים

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

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

צפייה ביומנים ב-Cloud Run

אפשר לצפות ביומנים בדף Cloud Run עבור המשאבים הבאים:

צפייה ביומנים של שירות

כדי לראות את יומני השירות בדף Cloud Run:

  1. כניסה ל-Cloud Run

  2. לוחצים על השירות ברשימה שמוצגת.

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

צפייה ביומנים של משימה

כדי לראות את יומני העבודות בדף Cloud Run:

  1. כניסה ל-Cloud Run

  2. מאתרים את המשרה ברשימת המשרות ולוחצים עליה.

  3. לוחצים על הכרטיסייה LOGS (יומנים) כדי לראות את יומני הקונטיינר של כל ההרצות של העבודה הזו. אפשר לסנן לפי רמת החומרה של היומן.

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

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

כדי לראות את היומנים של מאגר העובדים בדף Cloud Run:

  1. כניסה ל-Cloud Run

  2. לוחצים על מאגר העובדים ברשימה שמוצגת.

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

צפייה ביומני שירות באמצעות Google Cloud CLI

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

כדי להציג את סוף הקובץ של יומנים, צריך להתקין את הרכיב log-streaming ב-Google Cloud CLI. אם הרכיב לא מותקן, תתבקשו להתקין אותו כשיהיה צורך בכך.

צפייה ביומנים בשורת הפקודה

בשביל שירות ב-Cloud Run, אפשר לעקוב אחרי יומנים בזמן אמת משירות Cloud Run ישירות בשורת הפקודה:

gcloud beta run services logs tail SERVICE --project PROJECT-ID

מחליפים את:

  • SERVICE מחליפים בשם של שירות Cloud Run.
  • PROJECT-ID במזהה הפרויקט. Google Cloud כדי לראות את מזהה הפרויקט, מריצים את הפקודה gcloud config get-value project.

קריאת יומנים בשורת הפקודה

בשביל שירות של Cloud Run, אפשר לקרוא יומנים קיימים באחת משתי דרכים:

  • בפורמט שעבר אופטימיזציה לקונסולה:
    gcloud run services logs read SERVICE --limit=10 --project PROJECT-ID
  • ישירות מ-Cloud Logging:
    gcloud logging read "resource.type=cloud_run_revision AND resource.labels.service_name=SERVICE" --project PROJECT-ID --limit 10

מחליפים את:

  • SERVICE מחליפים בשם של שירות Cloud Run.
  • PROJECT-ID במזהה הפרויקט. Google Cloud כדי לראות את מזהה הפרויקט, מריצים את הפקודה gcloud config get-value project.

צפייה ביומנים ב-Cloud Logging

כדי לראות את היומנים של Cloud Run ב-Logs Explorer של Cloud Logging:

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

    כניסה לדף Logs Explorer

  2. בוחרים פרויקט קיים Google Cloud בחלק העליון של הדף או יוצרים פרויקט חדש.

  3. בתפריטים הנפתחים, בוחרים את המשאב:

    • גרסת Cloud Run של שירות
    • משימה ב-Cloud Run למשימה
    • מאגר עובדים של Cloud Run בשביל מאגר עובדים

מידע נוסף זמין במאמר שימוש ב-Logs Explorer.

הצגת יומני שירות ב-Cloud Code

כדי לראות את היומנים ב-Cloud Code, אפשר לקרוא את המדריכים ל-IntelliJ ול-Visual Studio Code.

קריאת יומנים באופן פרוגרמטי

אם רוצים לקרוא את הרישומים באופן פרוגרמטי, אפשר להשתמש באחת מהשיטות הבאות:

פורמט ותוכן של יומני שינוי גודל המופע

כשמופעלים מופעים חדשים בשירות Cloud Run, ‏ Cloud Logging כולל רשומות ביומן בשם היומן varlog/system שמסבירות למה כל מופע נוצר. הרשומה ביומן מופיעה בפורמט הבא:

Starting new instance. Reason: REASON - DESCRIPTION

בטבלה הבאה מפורטים תיאורי המופעים:

סיבה תיאור
MANUAL_OR_CUSTOMER_MIN_INSTANCE המופע הופעל בגלל מופעים מינימליים שהוגדרו על ידי הלקוח או בגלל שינוי גודל ידני.
AUTOSCALING המופע הופעל בגלל גורמי קנה מידה שהוגדרו (כמו ניצול CPU, נפח בקשות וכו') או בגלל שלא היה מספיק קיבולת קיימת לתעבורה הנוכחית.
DEPLOYMENT_ROLLOUT המופע הופעל בגלל העברת תנועה בין עדכונים בעקבות פריסה, התאמה של פיצול התנועה או בדיקת תקינות של הפריסה.

כתיבת יומני קונטיינרים

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

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

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

הרישום המשולב מאזן בין מהימנות לבין שימוש במשאבים, והוא אמור לפעול ברוב האפליקציות. כתיבת רשומות ביומן באמצעות רישום משולב לא צורכת מכסה של מספר הבקשות entries.write לדקה של Cloud Logging API.

אם יש לאפליקציה שלכם דרישות לגבי נפח או אמינות גבוהים יותר, מומלץ להשתמש ישירות ב-Cloud Logging API, או כספרייה בתוך האפליקציה או כקובץ sidecar נפרד.

שימוש בטקסט פשוט לעומת JSON מובנה ביומנים

כשכותבים יומנים, אפשר לשלוח מחרוזת טקסט פשוטה או שורה אחת של JSON שעבר סריאליזציה, שנקרא גם נתונים 'מובנים'. הנתונים האלה נאספים ומנותחים על ידי Cloud Logging, ומוצבים ב-jsonPayload. לעומת זאת, הודעת הטקסט הפשוטה ממוקמת ב-textPayload.

כתיבה של יומנים מובְנים

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

Node.js


// Uncomment and populate this variable in your code:
// const project = 'The project ID of your function or Cloud Run service';

// Build structured log messages as an object.
const globalLogFields = {};

// Add log correlation to nest all log messages beneath request log in Log Viewer.
// (This only works for HTTP-based invocations where `req` is defined.)
if (typeof req !== 'undefined') {
  const traceHeader = req.header('X-Cloud-Trace-Context');
  if (traceHeader && project) {
    const [trace] = traceHeader.split('/');
    globalLogFields['logging.googleapis.com/trace'] =
      `projects/${project}/traces/${trace}`;
  }
}

// Complete a structured log entry.
const entry = Object.assign(
  {
    severity: 'NOTICE',
    message: 'This is the default display field.',
    // Log viewer accesses 'component' as 'jsonPayload.component'.
    component: 'arbitrary-property',
  },
  globalLogFields
);

// Serialize to a JSON string and output.
console.log(JSON.stringify(entry));

Python

# Uncomment and populate this variable in your code:
# PROJECT = 'The project ID of your Cloud Run service';

# Build structured log messages as an object.
global_log_fields = {}

# Add log correlation to nest all log messages.
# This is only relevant in HTTP-based contexts, and is ignored elsewhere.
# (In particular, non-HTTP-based Cloud Functions.)
request_is_defined = "request" in globals() or "request" in locals()
if request_is_defined and request:
    trace_header = request.headers.get("X-Cloud-Trace-Context")

    if trace_header and PROJECT:
        trace = trace_header.split("/")
        global_log_fields[
            "logging.googleapis.com/trace"
        ] = f"projects/{PROJECT}/traces/{trace[0]}"

# Complete a structured log entry.
entry = dict(
    severity="NOTICE",
    message="This is the default display field.",
    # Log viewer accesses 'component' as jsonPayload.component'.
    component="arbitrary-property",
    **global_log_fields,
)

print(json.dumps(entry))

Go

המבנה של כל רשומה ביומן מסופק על ידי סוג Entry:


// Entry defines a log entry.
type Entry struct {
	Message  string `json:"message"`
	Severity string `json:"severity,omitempty"`
	Trace    string `json:"logging.googleapis.com/trace,omitempty"`

	// Logs Explorer allows filtering and display of this as `jsonPayload.component`.
	Component string `json:"component,omitempty"`
}

// String renders an entry structure to the JSON format expected by Cloud Logging.
func (e Entry) String() string {
	if e.Severity == "" {
		e.Severity = "INFO"
	}
	out, err := json.Marshal(e)
	if err != nil {
		log.Printf("json.Marshal: %v", err)
	}
	return string(out)
}

כשמבצעים רישום ביומן של מבנה Entry, מתבצעת קריאה לשיטה String כדי להמיר אותו לפורמט JSON שצפוי ב-Cloud Logging:


func init() {
	// Disable log prefixes such as the default timestamp.
	// Prefix text prevents the message from being parsed as JSON.
	// A timestamp is added when shipping logs to Cloud Logging.
	log.SetFlags(0)
}

func indexHandler(w http.ResponseWriter, r *http.Request) {
	// Uncomment and populate this variable in your code:
	// projectID = "The project ID of your Cloud Run service"

	// Derive the traceID associated with the current request.
	var trace string
	if projectID != "" {
		traceHeader := r.Header.Get("X-Cloud-Trace-Context")
		traceParts := strings.Split(traceHeader, "/")
		if len(traceParts) > 0 && len(traceParts[0]) > 0 {
			trace = fmt.Sprintf("projects/%s/traces/%s", projectID, traceParts[0])
		}
	}

	log.Println(Entry{
		Severity:  "NOTICE",
		Message:   "This is the default display field.",
		Component: "arbitrary-property",
		Trace:     trace,
	})

	fmt.Fprintln(w, "Hello Logger!")
}

Java

כדי להפעיל רישום בפורמט JSON באמצעות Logback ו-SLF4J, צריך להפעיל את Logstash JSON Encoder בהגדרות של logback.xml.

// Build structured log messages as an object.
Object globalLogFields = null;

// Add log correlation to nest all log messages beneath request log in Log Viewer.
// TODO(developer): delete this code if you're creating a Cloud
//                  Function and it is *NOT* triggered by HTTP.
String traceHeader = req.headers("x-cloud-trace-context");
if (traceHeader != null && project != null) {
  String trace = traceHeader.split("/")[0];
  globalLogFields =
      kv(
          "logging.googleapis.com/trace",
          String.format("projects/%s/traces/%s", project, trace));
}
// -- End log correlation code --

// Create a structured log entry using key value pairs.
// For instantiating the "logger" variable, see
// https://cloud.google.com/run/docs/logging#run_manual_logging-java
logger.error(
    "This is the default display field.",
    kv("component", "arbitrary-property"),
    kv("severity", "NOTICE"),
    globalLogFields);

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

<configuration>
  <appender name="jsonConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <!-- Ignore default logging fields -->
      <fieldNames>
        <timestamp>[ignore]</timestamp>
        <version>[ignore]</version>
        <logger>[ignore]</logger>
        <thread>[ignore]</thread>
        <level>[ignore]</level>
        <levelValue>[ignore]</levelValue>
      </fieldNames>
    </encoder>
  </appender>
  <root level="INFO">
    <appender-ref ref="jsonConsoleAppender"/>
  </root>
</configuration>

שדות JSON מיוחדים בהודעות

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

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

התאמה בין יומני הקונטיינר לבין יומן בקשות (שירותים בלבד)

בכלי Logs Explorer, יומנים שמשויכים לאותו trace מוצגים בפורמט 'הורה-צאצא': כשלוחצים על סמל המשולש מימין לרשומה ביומן הבקשות, יומני המאגר שקשורים לבקשה הזו מוצגים כרשומות משנה ביומן הבקשות.

יומני קונטיינרים לא משויכים אוטומטית ליומני בקשות, אלא אם משתמשים בספריית לקוח של Cloud Logging. כדי לבצע קורלציה בין יומני קונטיינרים לבין יומני בקשות בלי להשתמש בספריית לקוח, אפשר להשתמש בשורת יומן JSON מובנית שמכילה שדה logging.googleapis.com/trace עם מזהה המעקב שחולץ מהכותרת X-Cloud-Trace-Context, כמו בדוגמה שלמעלה לרישום מובנה ביומן.

שליטה בשימוש במשאבים ביומן הבקשות (שירותים בלבד)

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

הערה לגבי רישום נציגים ביומן

אם השתמשתם ב-Cloud Logging עם מוצרים מסוימים, כמו Compute Engine, יכול להיות שהשתמשתם בסוכני רישום ב-Cloud Logging. Google Cloud ב-Cloud Run לא משתמשים בסוכני רישום ביומן כי יש תמיכה מובנית באיסוף יומנים.

שמות המשאבים של Logging

שמות המשאבים של Cloud Run ב-Cloud Logging הם:

משאבי רישום ביומן

כשלוחצים על רשומה ביומן ב-Logs Explorer, נפתחת רשומה ביומן בפורמט JSON, כך שאפשר להגיע לפרטים הרצויים.

כל השדות ברשומה ביומן, כמו חותמות זמן, חומרה וhttpRequest, הם סטנדרטיים ומתוארים במסמכים של רשומה ביומן.

‫Cloud Run מוסיף מטא-נתונים נוספים, כך שאפשר לזהות את המקור של יומן. זה כולל את (התוויות שהגדרתם בשירות Cloud Run) ואת תוויות המשאבים שספציפיות ל-Cloud Run.

שדות של רשומות ביומן עבור שירות

הרשימה הבאה כוללת שדות שאפשר למצוא ברשומת היומן של שירות Cloud Run:

שדה ערכים והערות
LogEntry.labels.instanceId המופע שטיפל בבקשה.
LogEntry.labels.run.googleapis.com/base_image_versions גרסת תמונת הבסיס שבה השירות משתמש. האפשרות הזו מופיעה רק בשירותים שנפרסו ממקור, ורק אם האפשרות עדכוני אבטחה אוטומטיים מופעלת.
LogEntry.labels.run.googleapis.com/cloud_event_id המזהה של CloudEvent. האפשרות הזו מופיעה רק בשירותים שמקבלים אירועים מ-Eventarc.
LogEntry.labels.run.googleapis.com/cloud_event_source המקור של CloudEvent. האפשרות הזו מופיעה רק בשירותים שמקבלים אירועים מ-Eventarc.
LogEntry.labels.mylabel,
LogEntry.labels.mysecondlabel
התוויות שהגדרתם בשירות.
LogEntry.logName מזהה את היומן, לדוגמה, יומן בקשות, שגיאה רגילה, פלט רגיל וכו'.
LogEntry.resource.labels.location מזהה את המיקום של השירות ב-Google Cloud.
LogEntry.resource.labels.project_id הפרויקט שבו השירות נפרס.
LogEntry.resource.labels.revision_name הגרסה ששימשה להצגת הבקשה.
LogEntry.resource.labels.service_name השירות שטיפל בבקשה.
LogEntry.resource.type cloud_run_revision. סוג המשאב Cloud Run.

דוגמה לרשומה ביומן הבקשות של שירות Cloud Run:

{
 httpRequest: {}
 insertId:  "5c82b3d1000ece0000000000"
 labels: {
  instanceId:  "00bf4bf00000fb59c906a00000c9e29c2c4e06dce91500000000056008d2b6460f163c0057b97b2345f2725fb2423ee5f0bafd36df887fdb1122371563cf1ff453717282afe000001"
  mylabel: "mylabelvalue"
  mysecondlabel: "mysecondlabelvalue"
 }
 logName:  "projects/my-project/logs/run.googleapis.com%2Frequests"
 receiveTimestamp:  "2019-03-08T18:26:25.981686167Z"
 resource: {
  labels: {
   configuration_name:  "myservice"
   location:  "europe-west1"
   project_id:  "my-project"
   revision_name:  "myservice-00002"
   service_name:  "myservice"
  }
  type:  "cloud_run_revision"
 }
 severity:  "INFO"
 timestamp:  "2019-03-08T18:26:25.970397Z"
}

שדות של רשומות ביומן למשרות

זו רשימה של השדות שמופיעים ברשומה ביומן של משימת Cloud Run:

שדה ערכים והערות
LogEntry.labels.instanceId המופע.
LogEntry.labels.mylabel,

LogEntry.labels.mysecondlabel

התוויות שהגדרתם למשרה.
LogEntry.logName מזהה את היומן, למשל, שגיאה רגילה, פלט רגיל וכו'.
LogEntry.resource.labels.location מזהה את Google Cloud מיקום העבודה.
LogEntry.resource.labels.project_id הפרויקט שבו העבודה נפרסת.
LogEntry.resource.labels.job_name שם המשרה.
LogEntry.labels.execution_name השם של הרצת העבודה.
LogEntry.labels.task_index האינדקס של המשימה.
LogEntry.labels.task_attempt כמה פעמים נעשה ניסיון לבצע את המשימה הזו.
LogEntry.resource.type cloud_run_job. סוג המשאב Cloud Run.

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

זו רשימה של שדות שאפשר למצוא ברשומה ביומן של מאגר עובדים ב-Cloud Run:

שדה ערכים והערות
LogEntry.labels.instanceId המופע.
LogEntry.labels.mylabel,

LogEntry.labels.mysecondlabel

התוויות שהגדרתם במאגר העובדים.
LogEntry.logName מזהה את היומן, למשל, שגיאה רגילה, פלט רגיל וכו'.
LogEntry.resource.labels.location Google Cloud המיקום של מאגר העובדים.
LogEntry.resource.labels.project_id הפרויקט שבו נפרס מאגר העובדים.
LogEntry.resource.labels.workerpool_name השם של מאגר העובדים.
LogEntry.resource.type cloud_run_workerpool. סוג המשאב Cloud Run.

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

  • אתם יכולים להשתמש ב-Gemini Cloud Assist Investigations כדי לאבחן בעיות, לקבל תובנות פרקטיות ולפתור בעיות. מידע נוסף על דרכים שונות להתחלת חקירה באמצעות Logs Explorer מופיע במאמר פתרון בעיות באמצעות Gemini Cloud Assist Investigations במסמכי Gemini.