当前位置: 首页 > 面试题库 >

如何在GCP Felexible非兼容App Engine中将Java应用日志事件映射到相应的云日志事件级别?

尉迟宪
2023-03-14
问题内容

我是GCP
AppEngine的新手,出于多种原因,我选择了Flexible环境。但是,我震惊地发现灵活环境的非“兼容”运行时似乎不允许我将应用程序的日志记录事件映射到云日志记录中的适当日志记录
级别 。我阅读正确吗?
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 flexible环境中的不兼容运行时。


问题答案:

这是我如何使用SLF4J使云日志记录工作。这适用于不兼容的Java GAE Flex环境。

logback.xml

<configuration debug="true">
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>/var/log/app_engine/custom_logs/app.log.json</file>
        <append>true</append>
        <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout
                class="putyourpackagenamehere.GCPCloudLoggingJSONLayout">
                <pattern>%-4relative [%thread] %-5level %logger{35} - %msg</pattern>
            </layout>
        </encoder>
    </appender>
    <root level="DEBUG">
        <appender-ref ref="FILE" />
    </root>
</configuration>

这是我用来在日志文件中的一行上生成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  
 * 
 *  <br>https://cloud.google.com/appengine/docs/flexible/java/writing-application-logs
 *  
 *  <br>From https://cloud.google.com/appengine/articles/logging
 *  <quote>
 *  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.
 *  </quote>
 *  
 *  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<String, String> getDefaultConverterMap() {
        return PatternLayout.defaultConverterMap;
    }   
}


 类似资料:
  • 我的MBean部署在JBoss上。jboss日志记录级别设置为'info'。现在,当我将我的包的日志级别(java util logger)更改为“fine”(通过设置日志级别以编程方式运行时)时,它不会追加任何logger.fine(“....”)的消息。信息被过滤掉了。 是否有任何方法可以将java util记录器日志级别的更改传播到jboss日志级别?(java util有不同的级别->SE

  • 作为调试的一部分,我需要跟踪pod创建和删除等事件。在我的kubernetes设置中,我使用的是日志记录级别5。

  • 是否有写入此事件日志的方法: 或者至少是其他一些Windows默认日志,在那里我不必注册事件源?

  • 在渗透的过程中,我们难免遇到有删除日志的需求,比如我们做了某些操作是必须要进行日志的删除,同时作为系统管理员也是必须掌握日志的操作与备份等等才能在遇到事件后的第一时间定位攻击和修复方案的提出。我们下面来看看Powershell在Windows事件日志中的表现。 CmdLet Powershell Version 2.0 关于PowershellV2的关于日志的CmdLet有下面的命令,给大家准备了

  • 事件日志相关 API,接口的参数说明请参考Etherscan API 约定, 文档中不单独说明。 [Beta] The Event Log API was designed to provide an alternative to the native eth_getLogs. Below are the list of supported filter parameters: * fromBlo

  • 本文向大家介绍Powershell使用WINDOWS事件日志记录程序日志,包括了Powershell使用WINDOWS事件日志记录程序日志的使用技巧和注意事项,需要的朋友参考一下 通常,人们使用基于文件的日志。这样做没有什么问题,但是使用WINDOWS提供系统内部日志会更加简单。 如果你有管理权限,你可以随时创建一个新的日志: 该命令创造了一个名为Mylog的日志,这个事件源自”JobDUE”,”