יש הבדלים מסוימים בין ההיבטים של הכניסה לזמני הריצה מהדור השני (Java 11 ומעלה) לבין זמני הריצה מהדור הראשון (Java 8). בשונה מהסביבות של זמן הריצה מהדור הראשון, בסביבות של זמן הריצה מהדור השני, יומני האפליקציות לא מקובצים ביומני הבקשות ב-Logs Explorer. בנוסף, בסביבות זמן הריצה מהדור השני, App Engine כותב כל יומן אפליקציה שמשויך לבקשה כרשומה נפרדת ביומן ב-Cloud Logging.
במדריך הזה מוסבר איך להטמיע את אותן שיטות רישום ביומן שבהן השתמשתם באפליקציות של סביבת זמן ריצה מהדור הראשון, ולקבל כמעט את אותן תוצאות של סינון ושל קורלציה של רישום ביומן כשמעבירים את האפליקציה ל-Java 11 ומעלה.
ההבדלים העיקריים
בטבלה הבאה מפורטים ההבדלים ברישום ביומן בין סביבות זמן ריצה מהדור הראשון לבין סביבות זמן ריצה מהדור השני:
| סביבת זמן ריצה מהדור הראשון (Java 8) | זמני ריצה מהדור השני (Java 11 ואילך) | |
|---|---|---|
| יומני בקשות ואפליקציות | App Engine מטמיע את כל יומני האפליקציה ביומן הבקשות. | App Engine לא מטמיע יומני אפליקציות ביומן הבקשות. |
stdout ו-stderr |
יומנים שנכתבו אל stdout
ו-stderr מוטמעים ביומן הבקשות של App Engine. |
App Engine לא מטמיע יומנים שנכתבים אל stdout ו-stderr.
|
| יומנים של פלטפורמת App Engine | App Engine לא פולט יומנים פנימיים של הפלטפורמה. | App Engine פולט יומני פלטפורמה פנימיים במהלך ההפעלה או ההשבתה של מופע עם שם היומן /var/log/google_init.log.
|
| מכסה ל-Cloud Logging API | כל בקשה תואמת לפעולת כתיבה אחת ב-Cloud Logging. | כל רשומה ביומן האפליקציה שמשויכת לבקשה תואמת לפעולת כתיבה אחת ב-Cloud Logging. השימוש ב-Cloud Logging API גדל בסביבות זמן הריצה מהדור השני. |
בקשה ליומנים וליומני אפליקציות
התנהגות הרישום ביומנים בסביבות ריצה מדור ראשון שונה מהתנהגות הרישום ביומנים בסביבות ריצה מדור שני, באופן הבא:
בזמן הריצה של הדור הראשון, App Engine מטמיע את יומני האפליקציה בשדה
protoPayload.lineשל יומני הבקשות. כדי לראות את יומני האפליקציה, מרחיבים בקשה ב-Logs Explorer.התמונה הבאה מציגה יומנים של בקשות ושל אפליקציות עם קורלציה בסביבת זמן הריצה מהדור הראשון:

בזמני הריצה של הדור השני, יומני הבקשות לא מכילים רשומות של יומני האפליקציות כי השדה
protoPayload.lineלא מופיע ביומן הבקשות. במקום זאת, App Engine מתעד כל יומן אפליקציה כרשומה נפרדת. שם היומן תלוי בהגדרות הרישום שלכם. var/log/appמכיל יומנים שהופקו באמצעות מסגרות רישום סטנדרטיות, כמוjava.util.loggingאו Simple Logging Facade for Java (SLF4J). היומניםstderrו-stdoutמכילים יומני אפליקציות שנרשמים באמצעותSystem.err.print()אוSystem.out.print().בתמונה הבאה מוצגים יומני בקשות ויומני אפליקציות נפרדים בסביבות זמן ריצה מהדור השני:

stdout וגם stderr
בזמן הריצה של הדור הראשון, App Engine מתייחס ליומנים שמופקים אל stdout ו-stderr כיומני אפליקציה, ומקבץ באופן אוטומטי את הרשומות האלה של יומני האפליקציה תחת יומן הבקשות המשויך.
בסביבות זמן הריצה מהדור השני, מערכת App Engine לא מבצעת קורלציה בין היומנים שמופקים לבין stdout ו-stderr כברירת מחדל. כדי לקבץ ישויות של יומן האפליקציה עם יומן הבקשות באמצעות stdout ו-stderr, פועלים לפי ההוראות במאמר כתיבת יומנים מובנים אל stdout ו-stderr.
אנחנו לא ממליצים להתחבר ל-stdout ול-stderr כי גם יומנים מסוימים של פלטפורמת App Engine (JVM, Jetty, יומנים של תשתית פנימית) מועברים ל-stderr. יומני אפליקציות ויומני פלטפורמות מופיעים יחד עם שם היומן stderr, מה שגורם לדו-משמעות. ההשפעה הזו מוגזמת בסביבות ריצה מהדור השני, כי ב-App Engine יש נפח גדול יותר של יומני פלטפורמה.
יומנים של פלטפורמת App Engine
בזמן הריצה של הדור הראשון, App Engine לא פולט יומני פלטפורמה.
בזמן ריצה מהדור השני, App Engine פולט יומני פלטפורמה במהלך הפעלה או כיבוי של מופע עם שם היומן /var/log/google_init.log.
אפשר להתעלם מיומני הפלטפורמה. כדי להימנע מהצגת היומנים האלה, מוסיפים מסנן ל-Logs Explorer עם השאילתה logName="/var/log/google_init.log".
התמונה הבאה מציגה יומנים של פלטפורמה בסביבות זמן ריצה מהדור השני:

מכסת Cloud Logging API
בזמן הריצה מהדור הראשון, App Engine מטמיע את כל יומני האפליקציה שנוצרו במהלך בקשה ביומן בקשות יחיד, ושולח את הבקשה המוטמעת אל Cloud Logging. כל בקשה תואמת לפעולת כתיבה אחת ב-Cloud Logging.
בסביבות זמן הריצה מהדור השני, App Engine שולח כל יומן אפליקציה ל-Cloud Logging ברשומות נפרדות ביומן, מה שגורם לעלייה במספר הכולל של פעולות הכתיבה ב-Cloud Logging לכל בקשה.
Google Cloud Cloud Logging קובע את החיוב על סמך נפח האחסון הכולל שבו הוא משתמש. גם אם נפח האחסון הכולל שנדרש ליומנים לא גדל באופן משמעותי, מספר הפעולות של כתיבה בדקה גדל, בהתאם למספר יומני האפליקציות ש-App Engine כותב לכל בקשה. אם האפליקציה חורגת ממכסת הכתיבה של Cloud Logging, אפשר לבקש להגדיל את מכסת השימוש.
מידע נוסף זמין במאמר בנושא תמחור של Cloud Logging.
סקירה כללית של תהליך המיגרציה
גם אם יומני האפליקציות לא מוטמעים ביומני הבקשות בסביבות זמן הריצה מהדור השני, אפשר לשמור על חוויית הצפייה ביומנים כמו באפליקציות מהדור הראשון.
אפשר לבחור אחת מהאפשרויות הבאות להגדרת רישום ביומן בסביבות זמן ריצה מהדור השני:
שימוש בחבילת
java.util.logging(JUL): ל-App Engine יש תמיכה מובנית בהתאמה בין בקשות לבין יומני אפליקציות באמצעות מזהה מעקב. אם מזהה העקבות מופיע ביומני האפליקציה, ב-Logs Explorer מוצגים יומני האפליקציה שמקובצים ביומן הבקשות.שימוש ב-Simple Logging Facade for Java (SLF4J): צריך לשנות את קוד המקור כדי להוסיף את מזהה העקבות בהתאם לחלק האחורי של רישום הנתונים ביומן שבו האפליקציה משתמשת:
שימוש בחבילה java.util.logging (JUL)
אם האפליקציות שלכם שמשתמשות בסביבת זמן ריצה מהדור הראשון מטמיעות את java.util.logging החבילה לכל דרישות הרישום ביומן, לא תצטרכו לבצע שינויים בקוד כדי לבצע מיגרציה לסביבות זמן ריצה מהדור השני.
בדוגמה הבאה אפשר לראות איך משתמשים בחבילה java.util.logging בזמני ריצה מהדור השני לרישום ביומן:
package com.example.appengine.my_app;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.util.logging.Logger;
@WebServlet(name = "HelloAppEngine", value = "/")
public class HelloAppEngine extends HttpServlet {
// Use the java.util.logging.Logger to log messages
private static final Logger logger = Logger.getLogger(HelloAppEngine.class.getName());
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// Sample log messages
logger.info("Info message");
logger.warning("Warning message");
logger.severe("Severe message");
response.setContentType("text/plain");
response.getWriter().println("Hello App Engine");
}
}
קיבוץ יומני אפליקציות עם יומן הבקשות
בזמני הריצה מהדור השני, השדה protoPayload.line ביומן הבקשות לא מכיל יומני אפליקציות. ב-Logs Explorer נעשה שימוש בשדה trace כדי לקבץ יומני בקשות ויומני אפליקציות. החבילה java.util.logging מוסיפה באופן אוטומטי את מזהה המעקב לכל הבקשות ולכל יומני האפליקציות. כדי להציג יומנים עם קורלציה ב-Logs Explorer, ראו הצגת יומנים עם קורלציה.
שימוש ב-Simple Logging Facade for Java (SLF4J)
SLF4J הוא ממשק הרישום הפופולרי ביותר שמשמש באפליקציות Java. ממשק SLF4J הוא חזית, ולכן הוא לא תלוי בפלטפורמה של בק-אנד הרישום ביומן שלו, כך שאתם יכולים לבחור כל בק-אנד שמתאים לאפליקציות שלכם.
בתמונה הבאה מוצגות אפשרויות שילוב לשני עורפי SLF4J, כולל ספריית java.util.logging וה-appender של Logback:

SLF4J עם חבילת java.util.logging
SLF4J מאפשר לכם לשלב את האפליקציה עם Cloud Logging כשאתם משתמשים ב-SLF4J עם java.util.logging כקצה העורפי של רישום היומן. כברירת מחדל, App Engine מוסיף מזהה מעקב לכל הבקשות וליומני האפליקציות. המנגנון הזה מאפשר לקבץ את היומנים של הבקשות והאפליקציות ב-Logs Explorer.
כדי להטמיע את SLF4J עם java.util.logging, פועלים לפי השלבים הבאים:
מוסיפים את התלות
slf4j-jdk14.jarלקובץpom.xml. קובץslf4j-jdk14.jarמספק את שילוב ה-Backend לספרייהjava.util.logging:<!-- SLF4J interface --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.4</version> </dependency> <!-- JUL implementation for SLF4J --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>2.0.9</version> </dependency>יוצרים קובץ
WEB-INF/logging.propertiesכדי להוסיף הגדרות בהתאמה אישית:com.example.appengine.java8.HelloAppEngine.level = INFOמעדכנים את הקובץ
appengine-web.xmlומוסיפים את הערך<property>בשבילWEB-INF/logging.properties:<system-properties> <property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/> </system-properties>
בתמונה הבאה אפשר לראות איך SLF4J עם java.util.logging מוסיף באופן אוטומטי את מזהה המעקב ליומן של האפליקציה:

כדי לשנות את התצוגה ב-Logs Explorer לתצוגה ממוקדת בבקשות כמו בדור הראשון של זמן הריצה, אפשר לעיין במאמר הצגת יומנים מקושרים.
שימוש ב-SLF4J עם Logback appender
אם אפליקציות זמן הריצה מהדור הראשון משתמשות בהטמעה המובנית של SLF4J עם Logback, צריך לעדכן את קוד המקור ולבצע שלבים נוספים כדי לקבץ את בקשות היומן ואת יומני האפליקציה.
כדי לשלב את האפליקציה עם Cloud Logging, פועלים לפי השלבים הבאים:
כדי להתקין את תוסף הרישום של Logback, מוסיפים את התוסף
google-cloud-logging-logbackלקובץpom.xml:<!-- SLF4J interface --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.4</version> </dependency> <!-- Logback JARs --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.3.6</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.3.5</version> </dependency> <!-- Google Cloud logging appender for Logback --> <dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-logging-logback</artifactId> </dependency>יוצרים כלי לשיפור הרישום ביומן כדי להוסיף מזהה מעקב לכל שדה
LogEntry. המחלקות הבאותTraceIdLoggingEnhancerמשתמשות ב-ApiProxy API כדי לאחזר את מזהה המעקב שמשויך לבקשה:import com.google.appengine.api.utils.SystemProperty; import com.google.cloud.logging.LogEntry; import com.google.cloud.logging.LoggingEnhancer; import com.google.apphosting.api.ApiProxy; import com.google.apphosting.api.ApiProxy.Environment; // Add trace ID to the log entry public class TraceIdLoggingEnhancer implements LoggingEnhancer { @Override public void enhanceLogEntry(LogEntry.Builder logEntry) { final String PROJECT_ID = SystemProperty.applicationId.get(); Environment environment = ApiProxy.getCurrentEnvironment(); if (environment instanceof ApiProxy.EnvironmentWithTrace) { ApiProxy.EnvironmentWithTrace environmentWithTrace = (ApiProxy.EnvironmentWithTrace) environment; environmentWithTrace .getTraceId() .ifPresent( id -> logEntry.setTrace(String.format("projects/%s/traces/%s", PROJECT_ID, id))); } } } // [END logging_enhancer]מוסיפים את ההגדרה של Cloud Logging appender בקובץ
logback.xmlכדי להגדיר את Logback. הגדרות מנוהלות באמצעות קובץlogback.xmlב-WEB-INF/classesבמסגרת Logback:<configuration> <appender name="CLOUD" class="com.google.cloud.logging.logback.LoggingAppender"> <!-- This should be set to the new Logging Enhancer in the app code. --> <enhancer>com.example.appengine.my_app.enhancers.TraceIdLoggingEnhancer</enhancer> <resourceType>gae_app</resourceType> </appender> <root level="info"> <appender-ref ref="CLOUD" /> </root> </configuration>בתמונה הבאה מוצג המבנה הסופי של תיקיית האפליקציה:

צפייה ביומנים עם קורלציה
אפשר לראות יומנים עם קורלציה ב-Logs Explorer באמצעות השדה trace ID בכל רשומה ביומן. כדי להציג יומנים עם קורלציה ב-Logs Explorer:
בחלונית הניווט של מסוף Google Cloud , בוחרים באפשרות Logging ואז באפשרות Logs Explorer:
בקטע Resource Type, בוחרים באפשרות GAE Application.
כדי להציג יומני בקשות ולבצע ביניהם קורלציה, בוחרים באפשרות request_log בשם היומן. לחלופין, כדי לבצע קורלציה לפי יומני בקשות, לוחצים על Correlate by (קורלציה לפי) ובוחרים באפשרות request_log (יומן בקשות):

בחלונית Query results, כדי להרחיב רשומה ביומן, לוחצים על Expand. כשמרחיבים את היומן, מוצגים יומני האפליקציה שמשויכים לכל בקשה.