【问题标题】:Make Logback write to the console locally, but to log file on server使 Logback 在本地写入控制台,但在服务器上记录文件
【发布时间】:2014-03-10 16:47:09
【问题描述】:

在使用 Maven 3 构建的 Web 应用程序中,是否有办法让 Logback 使用 ConsoleAppenderRollingFileAppender,具体取决于应用程序的运行位置/方式?

在生产中,.war 文件部署在 Tomcat 7 上。我在本地运行 Jetty Maven 插件以在开发期间进行测试。

我想要这样的日志记录工作:

  • 当我在本地运行mvn jetty:run 时:使用ConsoleAppender
  • *.war 文件部署到生产环境(Tomcat 7)时:使用RollingFileAppender

在本地开发期间,在控制台上显示所有日志输出似乎很舒服。在生产中,我宁愿登录到一个文件:CATALINA_BASE/logs/myApp.log

显然,您可以在logback.xml 中同时使用ConsoleAppenderRollingFileAppender。但对我来说,将生产中的所有日志输出写入STDOUT 并写入日志文件似乎是不必要的多余。此外,从 Tomcat 文档看来,在生产环境中登录到 STDOUT 通常是一种不好的做法。

我在网上找不到任何好的解决方案。有没有好的解决方案?

这是我当前的 logback.xml,它始终记录到 STDOUT 和所需的日志文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${catalina.base}/logs/myApp.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${catalina.base}/logs/myApp.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.myDomain.myApp" level="DEBUG" />

    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

【问题讨论】:

    标签: maven logging log4j logback


    【解决方案1】:

    您可以使用配置文件在环境之间切换。假设您有两个不同的 logback.xml 文件用于本地和产品。在资源目录中创建一个 logback 目录。在资源目录中,创建一个特定于环境的目录。目录名称和 envName 内部属性应该匹配。这是一个例子。

    <profiles>
            <profile>
                <id>local</id>
                <activation>
                    <activeByDefault>true</activeByDefault>
                </activation>
                <properties>
                    <envName>local</envName>
                </properties>
            </profile>
            <profile>
                <id>prod</id>
                <properties>
                    <envName>prod</envName>
                </properties>
            </profile>
    </profiles>
    
    <build>
        <finalName>kp-prj</finalName>
        <outputDirectory>${project.build.directory}/classes</outputDirectory>
        <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
        <resources>
            <resource>
                <directory>${basedir}/src/main/java</directory>
                <includes>
                    <include>**/*.class</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources/logback/${envName}</directory>
            </resource>
        </resources>
    </build>
    

    并且在使用运行 maven 命令时指定配置文件。

    mvn run -Plocal
    

    【讨论】:

      【解决方案2】:

      我也有同样的需求,结果证明在 spring boot“ifulness”和 logback 的条件支持的帮助下非常容易。以下是我提出的一个模板,它可以用于任何应用程序,因为它使用 spring.applcation.name(如果可用)创建日志文件,您可以在 bootstrap.properties 中定义:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE project>
      <configuration>
          <if condition='isDefined("logging.path")'>
              <then>
                  <!--  get application name from external properties file -->
                  <property resource="bootstrap.properties" />
      
                  <!--  set local properties here for better visibility -->
                  <!--  TODO: make these profile conditional based on profiles -->
                  <property name="logging.maxfilesize" value="1GB" />
                  <property name="logging.maxdays" value="180" />
      
                  <!-- Assume file strategy for appender if logging path given -->
                  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
                      <!-- Use application.log if s.a.n not defined in bootstrap.properties -->
                      <file>${logging.path}/${spring.application.name:-application}.log</file>
                      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                          <!-- daily rollover -->
                          <fileNamePattern>${logging.path}/${spring.application.name:-application}.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
                          <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                              <!-- or whenever the file size reaches maxFileSize -->
                              <maxFileSize>${logging.maxfilesize}</maxFileSize>
                          </timeBasedFileNamingAndTriggeringPolicy>
                          <!-- keep max days' worth of history -->
                          <maxHistory>${logging.maxdays}</maxHistory>
                      </rollingPolicy>
                      <encoder>
                          <pattern>%date [%thread] %-5level %logger{36} - %msg%n</pattern>
                      </encoder>
                  </appender>
                  <root>
                      <appender-ref ref="FILE" />
                  </root>
              </then>
              <else>
                  <!-- The logging path not specified so assume console output -->
                  <!-- Note: In this case we don't care about the full date just the hour minutes seconds -->
                  <appender name="CON" class="ch.qos.logback.core.ConsoleAppender">
                      <encoder>
                          <pattern>%d{HH:mm:ss.SSS} %-5level %logger{35} - %msg %n</pattern>
                      </encoder>
                  </appender>
                  <root>
                      <appender-ref ref="CON" />
                  </root>
              </else>
          </if>
      
          <!-- in-house loggers -->
      
      
          <!-- 3rdparty Loggers -->
      
          <logger name="org.springframework">
              <level value="WARN" />
          </logger>
      
          <!-- default root level for everything else -->
      
          <root>
              <level value="INFO" />
          </root>
      
      </configuration>
      

      如果 spring boot app 带有 starter parent,你只需要在你的 pom.xml 中添加以下内容:

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-logging</artifactId>
      </dependency>
      <!-- Needed for conditional logback.xml statement support - very cool stuff -->
      <dependency>
          <groupId>org.codehaus.janino</groupId>
          <artifactId>janino</artifactId>
      </dependency>
      

      【讨论】:

        【解决方案3】:

        您可以配置您的 logback 并在其中添加配置文件信息。无需更改 POM

         <springProfile name="local">
            <root level="DEBUG">
        <!-- no appenders -->
                <appender-ref ref="stdout"/>
            </root>
        </springProfile>
        <springProfile name="prod">
            <root level="INFO">
                <appender-ref ref="FILE_APPENDER"/>
            </root>
        </springProfile>
        

        您可能还需要包含以下 spring 文件

        <include resource="org/springframework/boot/logging/logback/defaults.xml" />
        <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
        

        欲了解更多信息,请查看logback

        【讨论】:

          【解决方案4】:

          我过去使用 log4j 所做的一件事是将 log4j.xml 配置文件添加到 web 应用程序的 src/test/resources 目录。然后,我将 Jetty 配置为包含测试类目录 (&lt;useTestScope&gt;true&lt;/useTestScope&gt;)。

          对于您的示例,带有 ConsoleLogger 的 logback.xml 将位于 src/test/resources,而带有 RollingFileAppender 的 logback.xml 将位于 src/main/resources

          这在所有情况下都不是一个很好的解决方案,但对我来说它很简单而且效果很好。

          【讨论】:

          • 这似乎真的用很少的配置就可以解决问题。但是使用测试范围在本地运行 Jetty 也感觉有点脏 ;-)
          猜你喜欢
          • 1970-01-01
          • 2018-01-12
          • 2018-01-02
          • 2015-03-24
          • 1970-01-01
          • 2017-10-15
          • 2017-08-27
          • 2018-05-21
          • 1970-01-01
          相关资源
          最近更新 更多