如何将我的Java应用程序日志记录事件映射到GCP中的相应云记录事件级别Felastic非compat App Engine?

我是GCP AppEngine的新手,我选择灵活的环境有几个原因。 但是,我很震惊地发现灵活环境的非“兼容”运行时似乎不允许我将应用程序的日志记录事件映射到云日志记录中的相应日志级别 。 我读得对吗? https://cloud.google.com/appengine/docs/flexible/java/writing-application-logs#writing_application_logs_1

这个页面真是无益。 https://cloud.google.com/java/getting-started/logging-application-events

这是经过几个小时的阅读GAE日志记录困境并尝试确定哪些应用于标准环境与灵活。 我可以说,在标准环境中可以进行事件级映射。

但是,要在Cloud Platform Console中更精细地控制日志级别显示,日志记录框架必须使用java.util.logging适配器。 https://cloud.google.com/appengine/docs/java/how-requests-are-handled#Java_Logging

好。 这是一个模糊的参考,但我想我在其他地方看到了更清楚的东西。

无论如何,在“灵活”环境中这不应该更容易吗? 谁不想通过记录级别轻松过滤事件?

更新:我澄清了问题,表明我在询问GAE灵活环境中的不兼容运行时。

以下是我使用SLF4J进行云日志记录的方法。 这适用于不兼容的Java GAE Flex环境。

logback.xml

  /var/log/app_engine/custom_logs/app.log.json true    %-4relative [%thread] %-5level %logger{35} - %msg        

这是我用来在日志文件中的单行上生成JSON的PatternLayout类。

 import static ch.qos.logback.classic.Level.DEBUG_INT; import static ch.qos.logback.classic.Level.ERROR_INT; import static ch.qos.logback.classic.Level.INFO_INT; import static ch.qos.logback.classic.Level.TRACE_INT; import static ch.qos.logback.classic.Level.WARN_INT; import java.util.Map; import org.json.JSONObject; import com.homedepot.ta.wh.common.logging.GCPCloudLoggingJSONLayout.GCPCloudLoggingEvent.GCPCloudLoggingTimestamp; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.PatternLayout; import ch.qos.logback.classic.spi.ILoggingEvent; /** * Format a LoggingEvent as a single line JSON object * * 
https://cloud.google.com/appengine/docs/flexible/java/writing-application-logs * *
From https://cloud.google.com/appengine/articles/logging * * Applications using the flexible environment should write custom log files to the VM's log directory at * /var/log/app_engine/custom_logs. These files are automatically collected and made available in the Logs Viewer. * Custom log files must have the suffix .log or .log.json. If the suffix is .log.json, the logs must be in JSON * format with one JSON object per line. If the suffix is .log, log entries are treated as plain text. * * * Nathan: I can't find a reference to this format on the google pages but I do remember getting the format from some * GO code that a googler on the community slack channel referred me to. */ public class GCPCloudLoggingJSONLayout extends PatternLayout { @Override public String doLayout(ILoggingEvent event) { String formattedMessage = super.doLayout(event); return doLayout_internal(formattedMessage, event); } /* for testing without having to deal wth the complexity of super.doLayout() * Uses formattedMessage instead of event.getMessage() */ String doLayout_internal(String formattedMessage, ILoggingEvent event) { GCPCloudLoggingEvent gcpLogEvent = new GCPCloudLoggingEvent(formattedMessage , convertTimestampToGCPLogTimestamp(event.getTimeStamp()) , mapLevelToGCPLevel(event.getLevel()) , null); JSONObject jsonObj = new JSONObject(gcpLogEvent); /* Add a newline so that each JSON log entry is on its own line. * Note that it is also important that the JSON log entry does not span multiple lines. */ return jsonObj.toString() + "\n"; } static GCPCloudLoggingTimestamp convertTimestampToGCPLogTimestamp(long millisSinceEpoch) { int nanos = ((int) (millisSinceEpoch % 1000)) * 1_000_000; // strip out just the milliseconds and convert to nanoseconds long seconds = millisSinceEpoch / 1000L; // remove the milliseconds return new GCPCloudLoggingTimestamp(seconds, nanos); } static String mapLevelToGCPLevel(Level level) { switch (level.toInt()) { case TRACE_INT: return "TRACE"; case DEBUG_INT: return "DEBUG"; case INFO_INT: return "INFO"; case WARN_INT: return "WARN"; case ERROR_INT: return "ERROR"; default: return null; /* This should map to no level in GCP Cloud Logging */ } } /* Must be public for JSON marshalling logic */ public static class GCPCloudLoggingEvent { private String message; private GCPCloudLoggingTimestamp timestamp; private String traceId; private String severity; public GCPCloudLoggingEvent(String message, GCPCloudLoggingTimestamp timestamp, String severity, String traceId) { super(); this.message = message; this.timestamp = timestamp; this.traceId = traceId; this.severity = severity; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public GCPCloudLoggingTimestamp getTimestamp() { return timestamp; } public void setTimestamp(GCPCloudLoggingTimestamp timestamp) { this.timestamp = timestamp; } public String getTraceId() { return traceId; } public void setTraceId(String traceId) { this.traceId = traceId; } public String getSeverity() { return severity; } public void setSeverity(String severity) { this.severity = severity; } /* Must be public for JSON marshalling logic */ public static class GCPCloudLoggingTimestamp { private long seconds; private int nanos; public GCPCloudLoggingTimestamp(long seconds, int nanos) { super(); this.seconds = seconds; this.nanos = nanos; } public long getSeconds() { return seconds; } public void setSeconds(long seconds) { this.seconds = seconds; } public int getNanos() { return nanos; } public void setNanos(int nanos) { this.nanos = nanos; } } } @Override public Map getDefaultConverterMap() { return PatternLayout.defaultConverterMap; } }

java.util.logging提供的日志级别将映射到Cloud Logging中的相应日志级别。 登录灵活运行时基本上与在Standard上运行相同。

编辑 :似乎“ 编写应用程序日志 ”页面的基本原理是Cloud Logging映射不适用于所有运行时。 但是,它们似乎目前至少适用于’-compat’运行时和Java自定义运行时。 其他人的解决方法在文档的其他地方提供(见下文):

建议在Java应用程序中登录的默认方法是使用java.util.logging (对于Python,它是’logging’模块,对于Go它是’log’包,所有这些都提供映射到Cloud Logging级别的日志级别)。 我会要求这些页面得到更新。

您链接的其他文档提供有关Java日志记录的准确信息。 关于您引用的部分, 从中提取的完整段落提供了上下文。 它说任何写入stderr或stdout的日志记录框架都可以工作,但是如果你想要除“INFO”或“WARNING”之外的更细粒度的日志级别,它需要使用’java.util.logging’。 使用’java.util.logging’的完整代码示例直接在引用部分下面提供,其他文档在您提到的另一个文档’ 使用Java记录应用程序事件 ‘中提供。

更新 :“入门”指南包含有关如何为每个运行时配置日志记录的特定详细信息:

Java的
https://cloud.google.com/java/getting-started/logging-application-events#understanding_the_code

python
https://cloud.google.com/python/getting-started/logging-application-events#understanding_the_code


https://cloud.google.com/go/getting-started/logging-application-events

的NodeJS
https://cloud.google.com/nodejs/getting-started/logging-application-events#understanding_the_code

ruby
https://cloud.google.com/ruby/getting-started/logging-application-events#application_structure

PHP
https://cloud.google.com/php/getting-started/logging-application-events