במאמר הזה נסביר על הקונספט של רישום ביומן במבנה מוגדר ועל השיטות להוספת מבנה לשדות של מטען ייעודי (payload) של רשומות ביומן. כשמטען ייעודי של יומן מעוצב כאובייקט JSON והאובייקט הזה מאוחסן בשדה jsonPayload, רשומת היומן נקראת יומן מובנה. ביומנים האלה אפשר ליצור שאילתות שמחפשות נתיבי JSON ספציפיים, ולבצע אינדוקס של שדות ספציפיים במטען הייעודי (payload) של היומן. לעומת זאת, אם מטען הייעודי (payload) של היומן מעוצב כמחרוזת ומאוחסן בשדה textPayload, רשומת היומן היא לא מובנית.
אפשר לחפש בשדה הטקסט, אבל אי אפשר ליצור אינדקס של התוכן שלו.
כדי ליצור רשומות יומן מובנות, אפשר לבצע אחת מהפעולות הבאות:
- קוראים לשיטת ה-API
entries.writeומספקיםLogEntryבפורמט מלא. - משתמשים בפקודה
gcloud logging write.
- שימוש בספריית לקוח של Cloud Logging שכותבת יומנים מובנים.
- משתמשים בשירות BindPlane.
שימוש בסוכן לכתיבת יומנים:
חלק מה Google Cloud שירותים מכילים סוכן רישום ביומן משולב ששולח את הנתונים שנכתבו ב-
stdoutאו ב-stderrכיומנים ל-Cloud Logging. אפשר להשתמש בגישה הזו בשירותים כמו Google Kubernetes Engine, הסביבה הגמישה של App Engine ופונקציות Cloud Run. Google Cloudבמכונות וירטואליות (VM) של Compute Engine, אפשר להתקין ולהגדיר את סוכן תפעול או את סוכן ה-Logging מדור קודם, ואז להשתמש בסוכן שהותקן כדי לשלוח יומנים ל-Cloud Logging.
בסעיפים הבאים יש מידע נוסף על הגישות האלה.
כתיבת יומנים באמצעות ספריות לקוח או ה-API
אפשר לכתוב נתוני יומנים באמצעות ספריות הלקוח של Cloud Logging, שקוראות ל-Cloud Logging API, או באמצעות קריאה ישירה ל-Cloud Logging API.
ספריות לקוח יכולות לפשט את האכלוס של שדות ה-JSON המיוחדים על ידי תיעוד אוטומטי של חלק מהמידע ועל ידי מתן ממשקים לאכלוס השדות בצורה מתאימה. עם זאת, כדי לקבל שליטה מלאה במבנה של נתוני ה-payload, צריך להפעיל ישירות את Cloud Logging API ולהעביר את המבנה המלא של LogEntry אל Cloud Logging API.
מידע נוסף זמין במאמר בנושא entries.write.
דוגמאות קוד מופיעות במאמר בנושא כתיבת יומנים מובְנים.
כתיבת יומנים באמצעות ה-CLI של gcloud
אפשר לכתוב נתוני יומן באמצעות ה-CLI של gcloud. הממשק תומך ביומנים לא מובנים וביומנים מובנים. כשרוצים לכתוב יומן מובנה, צריך לספק לפקודה אובייקט JSON שעבר סריאליזציה.
מדריך למתחילים: כתיבה של רשומות ביומן וביצוע שאילתות לגביהן באמצעות Google Cloud CLI
דוגמאות קוד מופיעות במאמר בנושא gcloud logging write.
כתיבת יומנים באמצעות BindPlane
אפשר להשתמש בשירות BindPlane כדי לשלוח יומנים אל Logging. במקרה של יומנים כאלה, המטען הייעודי (payload) הוא בפורמט JSON ומובנה בהתאם למערכת המקור. למידע על איתור וצפייה ביומנים שנקלטים באמצעות BindPlane, אפשר לעיין במדריך למתחילים של BindPlane.
כתיבת יומנים באמצעות סוכן
כדי לקבל יומנים מהמכונות של Compute Engine, אפשר להשתמש בסוכן התפעול או בסוכן Cloud Logging מדור קודם. שני הסוכנים יכולים לאסוף מדדים מאפליקציות של צד שלישי, ושניהם תומכים ברישום ביומן במבנה:
Ops Agent הוא הסוכן המומלץ לאיסוף טלמטריה ממכונות Compute Engine. הסוכן הזה משלב רישום ביומן ומדדים בסוכן יחיד, מספק הגדרה מבוססת-YAML וכולל רישום ביומן עם תפוקה גבוהה.
במאמר הגדרת סוכן תפעול מוסבר איך מגדירים את סוכן תפעול כך שיתמוך ברישום ביומן במבנה או בהתאמה אישית של מבנה היומן.
סוכן Logging מדור קודם של Cloud אוסף יומנים. הסוכן הזה לא אוסף סוגים אחרים של טלמטריה.
החלק שנותר בקטע הזה מתייחס ספציפית לסוכן Logging מדור קודם.
סוכן Logging: שדות JSON מיוחדים
חלק מהשדות באובייקט JSON מזוהים כשדות מיוחדים על ידי סוכן Logging מדור קודם, והם מחולצים למבנה LogEntry. אפשר להשתמש בשדות ה-JSON המיוחדים האלה כדי להגדיר את השדות הבאים ב-LogEntry:
severityspanIdlabelsבהגדרת משתמשhttpRequest
מכיוון ש-JSON מדויק ורב-תכליתי יותר משורות טקסט, אפשר להשתמש באובייקטים של JSON כדי לכתוב הודעות מרובות שורות ולהוסיף מטא-נתונים.
כדי ליצור רשומות יומן מובנות לאפליקציות שלכם באמצעות הפורמט הפשוט, אפשר לעיין בטבלה הבאה שבה מפורטים השדות והערכים שלהם ב-JSON:
| שדה ביומן JSON |
LogEntry
שדה
|
פונקציית הסוכן של Cloud Logging | ערך לדוגמה |
|---|---|---|---|
severity
|
severity
|
הסוכן של Logging מנסה להתאים מגוון של מחרוזות נפוצות של חומרת הבעיה, כולל הרשימה של מחרוזות LogSeverity שמזוהות על ידי Logging API. | "severity":"ERROR"
|
message
|
textPayload
(או חלק מ-
jsonPayload)
|
ההודעה שמופיעה בשורת רשומה ביומן בכלי Logs Explorer. | "message":"There was an error in the application." הערה: הערך message נשמר כ-textPayload אם זה השדה היחיד שנשאר אחרי שהסוכן Logging מעביר את שאר השדות המיוחדים ו
detect_json לא הופעל. אחרת, הערך message נשאר ב-jsonPayload. detect_json לא רלוונטי לסביבות ניהול רישום ביומן כמו Google Kubernetes Engine. אם רשומת היומן מכילה מעקב אחר מחסנית חריגים, צריך להגדיר את המעקב אחר מחסנית החריגים בשדה היומן message בפורמט JSON, כדי שאפשר יהיה לנתח את המעקב אחר מחסנית החריגים ולשמור אותו ב-Error Reporting. |
log
(legacy
Google Kubernetes Engine
only) |
textPayload
|
ההגדרה הזו רלוונטית רק לגרסה הקודמת של Google Kubernetes Engine:
אם אחרי העברת שדות מיוחדים נשאר רק שדה log, השדה הזה יישמר בתור textPayload. |
|
httpRequest
|
httpRequest
|
רשומה מובנית בפורמט של השדה LogEntry
HttpRequest. |
"httpRequest":{"requestMethod":"GET"}
|
| שדות שקשורים לזמן | timestamp
|
מידע נוסף זמין במאמר בנושא שדות שקשורים לזמן. | "time":"2020-10-12T07:20:50.52Z"
|
logging.googleapis.com/insertId
|
insertId
|
מידע נוסף זמין במאמר insertId בדף LogEntry. |
"logging.googleapis.com/insertId":"42"
|
logging.googleapis.com/labels
|
labels
|
הערך בשדה הזה חייב להיות רשומה מובנית.
מידע נוסף זמין במאמר labels בדף LogEntry. |
"logging.googleapis.com/labels":
{"user_label_1":"value_1","user_label_2":"value_2"}
|
logging.googleapis.com/operation
|
operation
|
הערך של השדה הזה משמש גם את הכלי Logs Explorer לקיבוץ רשומות יומן שקשורות זו לזו.
מידע נוסף זמין במאמר בנושא operation בדף LogEntry. |
"logging.googleapis.com/operation":
{"id":"get_data","producer":"github.com/MyProject/MyApplication",
"first":"true"}
|
logging.googleapis.com/sourceLocation
|
sourceLocation
|
מידע על מיקום קוד המקור שמשויך לרשומה ביומן, אם יש.
מידע נוסף זמין במאמר LogEntrySourceLocation בדף LogEntry. |
"logging.googleapis.com/sourceLocation":
{"file":"get_data.py","line":"142","function":"getData"}
|
logging.googleapis.com/spanId
|
spanId
|
מזהה הטווח בתוך המעקב שמשויך לרשומה ביומן.
מידע נוסף זמין במאמר spanId בדף LogEntry. |
"logging.googleapis.com/spanId":"000000000000004a"
|
logging.googleapis.com/trace
|
trace
|
שם המשאב של ה-trace שמשויך לרשומה ביומן, אם יש כזה.
מידע נוסף זמין במאמר trace בדף LogEntry.
|
"logging.googleapis.com/trace":"projects/my-projectid/traces/0679686673a" הערה: אם לא כותבים ל- stdout או ל-stderr, הערך של השדה הזה צריך להיות בפורמט projects/[PROJECT-ID]/traces/[TRACE-ID], כדי ש-Logs Explorer ומציג העקבות יוכלו להשתמש בו כדי לקבץ רשומות ביומן ולהציג אותן בשורה עם העקבות.
אם autoformat_stackdriver_trace הוא true ו-[V] תואם לפורמט של ResourceTrace
traceId הערך בשדה LogEntry trace הוא projects/[PROJECT-ID]/traces/[V]. |
logging.googleapis.com/trace_sampled
|
traceSampled
|
הערך בשדה הזה חייב להיות true או false.
מידע נוסף זמין במאמר traceSampled בדף LogEntry. |
"logging.googleapis.com/trace_sampled": false
|
כדי ליצור רשומות ביומן בפורמט הפשוט, יוצרים ייצוג JSON של הרשומה באמצעות השדות. כל השדות הם אופציונליים.
הדוגמה הבאה היא של רשומה פשוטה ביומן בפורמט JSON:
{ "severity":"ERROR", "message":"There was an error in the application.", "httpRequest":{ "requestMethod":"GET" }, "time":"2020-10-12T07:20:50.52Z", "logging.googleapis.com/insertId":"42", "logging.googleapis.com/labels":{ "user_label_1":"value_1", "user_label_2":"value_2" }, "logging.googleapis.com/operation":{ "id":"get_data", "producer":"github.com/MyProject/MyApplication", "first":"true" }, "logging.googleapis.com/sourceLocation":{ "file":"get_data.py", "line":"142", "function":"getData" }, "logging.googleapis.com/spanId":"000000000000004a", "logging.googleapis.com/trace":"projects/my-projectid/traces/06796866738c859f2f19b7cfb3214824", "logging.googleapis.com/trace_sampled":false }
דוגמה לרשומה ביומן שמתקבלת:
{ "insertId": "42", "jsonPayload": { "message": "There was an error in the application", "time": "2020-10-12T07:20:50.52Z" }, "httpRequest": { "requestMethod": "GET" }, "resource": { "type": "k8s_container", "labels": { "container_name": "hello-app", "pod_name": "helloworld-gke-6cfd6f4599-9wff8", "project_id": "stackdriver-sandbox-92334288", "namespace_name": "default", "location": "us-west4", "cluster_name": "helloworld-gke" } }, "timestamp": "2020-10-12T07:20:50.52Z", "severity": "ERROR", "labels": { "user_label_2": "value_2", "user_label_1": "value_1" }, "logName": "projects/stackdriver-sandbox-92334288/logs/stdout", "operation": { "id": "get_data", "producer": "github.com/MyProject/MyApplication", "first": true }, "trace": "projects/my-projectid/traces/06796866738c859f2f19b7cfb3214824", "sourceLocation": { "file": "get_data.py", "line": "142", "function": "getData" }, "receiveTimestamp": "2020-10-12T07:20:57.52Z", "spanId": "000000000000004a" }
סוכן Logging: הגדרה
סוכן Logging מדור קודם, google-fluentd, הוא חבילה ספציפית ל-Cloud Logging של כלי לאיסוף נתוני יומן Fluentd.
הסוכן Logging מגיע עם הגדרת ברירת המחדל של Fluentd, והוא משתמש בפלאגינים של Fluentd input כדי לשלוף יומני אירועים ממקורות חיצוניים, כמו קבצים בדיסק, או כדי לנתח רשומות יומן נכנסות.
ב-Fluentd יש רשימה של מנתחי נתונים נתמכים שמחלצים יומנים וממירים אותם למטענים ייעודיים (payloads) מובנים (JSON).
אם מגדירים מקור יומן עם format [PARSER_NAME], אפשר להשתמש במנתחי הנתונים המובנים ש-Fluentd מספקת. מידע על הגדרת סוכן Logging מדור קודם זמין במאמר הגדרת סוכן Logging.
בדוגמאות הקוד הבאות מוצגת ההגדרה של Fluentd, רשומת יומן הקלט ומטען הייעודי המובנה של הפלט, שהוא חלק מרשומה ביומן של Cloud Logging:
הגדרת Fluentd:
<source> @type tail format syslog # This uses a predefined log format regex named # `syslog`. See details at https://docs.fluentd.org/parser/syslog. path /var/log/syslog pos_file /var/lib/google-fluentd/pos/syslog.pos read_from_head true tag syslog </source>רשומה ביומן (קלט):
<6>Feb 28 12:00:00 192.168.0.1 fluentd[11111]: [error] Syslog testמטען ייעודי (פלט) מובנה:
jsonPayload: { "pri": "6", "host": "192.168.0.1", "ident": "fluentd", "pid": "11111", "message": "[error] Syslog test" }
מידע נוסף על אופן הפעולה של מנתח ה-syslog זמין במסמכי התיעוד המפורטים של Fluentd.
סוכן Logging: מנתחי נתונים רגילים מופעלים כברירת מחדל
הטבלה הבאה כוללת את מנתחי הנתונים הרגילים שנכללים בסוכן אם מפעילים רישום מובנה ביומן:
| שם מנתח | קובץ תצורה |
|---|---|
syslog |
/etc/google-fluentd/config.d/syslog.conf |
nginx |
/etc/google-fluentd/config.d/nginx.conf |
apache2 |
/etc/google-fluentd/config.d/apache.conf |
apache_error |
/etc/google-fluentd/config.d/apache.conf |
הוראות להפעלת רישום מובנה ביומן במהלך ההתקנה של סוכן Logging מדור קודם מופיעות בקטע התקנה.
סוכן Logging: התקנה
כדי להפעיל רישום ביומן מובנה, צריך לשנות את הגדרת ברירת המחדל של סוכן Logging מדור קודם כשמתקינים או מתקינים מחדש את הסוכן. הפעלת רישום מובנה מחליפה את קובצי ההגדרות שצוינו קודם, אבל לא משנה את הפעולה של הסוכן עצמו.
כשמפעילים רישום מובנה ביומן, היומנים שמופיעים ברשימה מומרים לרשומות ביומן בפורמטים שונים מאלה שהיו להם לפני שהפעלתם רישום מובנה ביומן. אם היומנים מנותבים ליעדים מחוץ ל'רישום ביומן', השינוי עשוי להשפיע על כל אפליקציות העיבוד שלאחר מכן. לדוגמה, אם מעבירים יומנים ל-BigQuery, המערכת דוחה את רשומות היומן החדשות למשך שארית היום כי יש להן סכימה שגויה.
הוראות להתקנת סוכן Logging מדור קודם ולהפעלת רישום ביומן מובנה מופיעות במאמר התקנת סוכן Logging.
אפשר למצוא את קובצי התצורה של סוכן Logging במיקום /etc/google-fluentd/config.d/, שצריכים לכלול עכשיו את הנתחים הרגילים שמופעלים כברירת מחדל.
סוכן Logging: הגדרת פורמט של יומן גישה של Apache
כברירת מחדל, סוכן Logging מדור קודם שומר נתוני יומן גישה של Apache בשדה jsonPayload. לדוגמה:
{
"logName": ...,
"resource": ...,
"httpRequest": ...,
"jsonPayload": {
"user" : "some-user",
"method" : "GET",
"code" : 200,
"size" : 777,
"host" : "192.168.0.1",
"path" : "/some-path",
"referer": "some-referer",
"agent" : "Opera/12.0"
},
...
}
לחלופין, אפשר להגדיר את סוכן Logging מדור קודם כדי לחלץ שדות מסוימים לשדה httpRequest. לדוגמה:
{
"logName": ...,
"resource": ...,
"httpRequest": {
"requestMethod": "GET",
"requestUrl": "/some-path",
"requestSize": "777",
"status": "200",
"userAgent": "Opera/12.0",
"serverIp": "192.168.0.1",
"referrer":"some-referrer",
},
"jsonPayload": {
"user":"some-user"
},
...
}
הגדרת השדה httpRequest, כמו בדוגמה הקודמת, עוזרת במעקב: במסוף Google Cloud מוצגים כל היומנים של בקשת HTTP נתונה בהיררכיה של הורה-צאצא.
כדי להגדיר את החילוץ הזה, מוסיפים את הקוד הבא לסוף התג /etc/google-fluentd/config.d/apache.conf:
<filter apache-access>
@type record_transformer
enable_ruby true
<record>
httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "serverIp" => record['host'],
"referer" => record['referer']} }
</record>
remove_keys method, path, size, code, agent, host, referer
</filter>
פרטים נוספים על הגדרת הרשומות ביומן זמינים במאמר שינוי רשומות ביומן.
סוכן Logging: הגדרת פורמט של יומן גישה ל-nginx
כברירת מחדל, סוכן Logging מדור קודם שומר את נתוני יומן הגישה של nginx בשדה jsonPayload. לדוגמה:
{
"logName": ...,
"resource": ...,
"httpRequest": ...,
"jsonPayload": {
"remote":"127.0.0.1",
"host":"192.168.0.1",
"user":"some-user",
"method":"GET",
"path":"/some-path",
"code":"200",
"size":"777",
"referrer":"some-referrer",
"agent":"Opera/12.0",
"http_x_forwarded_for":"192.168.3.3"
},
...
}
לחלופין, אפשר להגדיר את סוכן Logging מדור קודם כדי לחלץ שדות מסוימים לשדה httpRequest. לדוגמה:
{
"logName": ...,
"resource": ...,
"httpRequest": {
"requestMethod": "GET",
"requestUrl": "/some-path",
"requestSize": "777",
"status": "200",
"userAgent": "Opera/12.0",
"remoteIp": "127.0.0.1",
"serverIp": "192.168.0.1",
"referrer":"some-referrer",
},
"jsonPayload": {
"user":"some-user",
"http_x_forwarded_for":"192.168.3.3"
},
...
}
הגדרת השדה httpRequest, כמו בדוגמה הקודמת, עוזרת במעקב: במסוף Google Cloud מוצגים כל הרישומים של בקשת HTTP נתונה בהיררכיה של הורה-צאצא.
כדי להגדיר את החילוץ הזה, מוסיפים את הקוד הבא לסוף התג /etc/google-fluentd/config.d/nginx.conf:
<filter nginx-access>
@type record_transformer
enable_ruby true
<record>
httpRequest ${ {"requestMethod" => record['method'], "requestUrl" => record['path'], "requestSize" => record['size'], "status" => record['code'], "userAgent" => record['agent'], "remoteIp" => record['remote'], "serverIp" => record['host'], "referer" => record['referer']} }
</record>
remove_keys method, path, size, code, agent, remote, host, referer
</filter>
פרטים נוספים על הגדרת הרשומות ביומן זמינים במאמר שינוי רשומות ביומן.
כתיבת מנתח משלכם
אם הקבצים שלכם לא נתמכים על ידי מנתחי הנתונים הרגילים, אתם יכולים לכתוב מנתח נתונים משלכם. מנתחי הנתונים מורכבים מביטוי רגולרי שמשמש להתאמה של רשומות ביומן ולהוספת תוויות לחלקים.
בדוגמאות הקוד הבאות מוצגת שורה ביומן ברשומה ביומן, הגדרה עם ביטוי רגולרי שמציין את הפורמט של השורה ביומן והרשומה ביומן שמאוחסנת:
שורה ביומן ברשומה ביומן:
REPAIR CAR $500הגדרה עם ביטוי רגולרי שמציין את הפורמט של שורת היומן:
$ sudo vim /etc/google-fluentd/config.d/test-structured-log.conf $ cat /etc/google-fluentd/config.d/test-structured-log.conf <source> @type tail # Format indicates the log should be translated from text to # structured (JSON) with three fields, "action", "thing" and "cost", # using the following regex: format /(?<action>\w+) (?<thing>\w+) \$(?<cost>\d+)/ # The path of the log file. path /tmp/test-structured-log.log # The path of the position file that records where in the log file # we have processed already. This is useful when the agent # restarts. pos_file /var/lib/google-fluentd/pos/test-structured-log.pos read_from_head true # The log tag for this log input. tag structured-log </source>רשומה ביומן שמתקבלת:
{ insertId: "eps2n7g1hq99qp" jsonPayload: { "action": "REPAIR" "thing": "CAR" "cost": "500" } labels: { compute.googleapis.com/resource_name: "add-structured-log-resource" } logName: "projects/my-sample-project-12345/logs/structured-log" receiveTimestamp: "2023-03-21T01:47:11.475065313Z" resource: { labels: { instance_id: "3914079432219560274" project_id: "my-sample-project-12345" zone: "us-central1-c" } type: "gce_instance" } timestamp: "2023-03-21T01:47:05.051902169Z" }
פתרון בעיות
כדי לפתור בעיות נפוצות שקשורות להתקנה או לאינטראקציה עם סוכן Logging מדור קודם, אפשר לעיין במאמר פתרון בעיות בסוכן.
המאמרים הבאים
כדי לשלוח שאילתות ולצפות ברשומות ביומן, ראו צפייה ביומנים באמצעות Logs Explorer.
כדי לקרוא רשומות ביומן באמצעות Google Cloud CLI, אפשר לעיין במאמר בנושא קריאת רשומות ביומן.
כדי לקרוא רשומות ביומן באמצעות Logging API, אפשר לעיין בשיטה
entries.list.