יש הבדלים מסוימים בין ההיבטים של הכניסה לזמני הריצה מהדור השני (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, פועלים לפי השלבים הבאים:
כדי להתקין את כלי ה-appender לרישום ב-Logback, מוסיפים את כלי ה-appender
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:<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 באמצעות השדה של מזהה המעקב בכל רשומה ביומן. כדי לראות יומנים עם קורלציה ב-Logs Explorer:
בחלונית הניווט של מסוף Google Cloud , בוחרים באפשרות Logging ואז באפשרות Logs Explorer:
בקטע Resource Type, בוחרים באפשרות GAE Application.
כדי להציג יומני בקשות ולבצע ביניהם קורלציה, בוחרים באפשרות request_log בשם היומן. לחלופין, כדי לבצע קורלציה לפי יומני בקשות, לוחצים על Correlate by (ביצוע קורלציה לפי) ובוחרים באפשרות request_log (יומן בקשות):

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