jetty / jetty.project

Eclipse Jetty® - Web Container & Clients - supports HTTP/2, HTTP/1.1, HTTP/1.0, websocket, servlets, and more
https://eclipse.dev/jetty
Other
3.83k stars 1.91k forks source link

JETTY 10 logging-logback can't load web's logback config file #10429

Open james-z-repo opened 1 year ago

james-z-repo commented 1 year ago

Jetty version(s)

10.0.15

Jetty Environment

Java version/vendor (use: java -version) openjdk version "11.0.2" 2019-01-15 OpenJDK Runtime Environment 18.9 (build 11.0.2+9) OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)

OS type/version win10

Description

i added module logging-logback resources in start.ini deploy a springboot war used logback to write log, i have a normal logback-spring.xml in WEB-INF\classes dir,

<appender name="FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>E:/TAS_SOFT/jetty-home-10.0.15/logs/${APP_NAME}_stdout.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>E:/SOFT/jetty-home-10.0.15/logs/aaaaa_stdout.%d{yyyy-MM-dd}.log
            </FileNamePattern>
            <maxHistory>20</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] [%-5thread] [%X{request.url}] %logger{20} - %msg%n</pattern>
        </encoder>
    </appender>
<appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>error</level>
        </filter>
        <File>E:/TAS_SOFT/jetty-home-10.0.15/logs/${APP_NAME}_stderr.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>E:/TAS_SOFT/jetty-home-10.0.15/logs/aaaaa_stderr.%d{yyyy-MM-dd}.log
            </FileNamePattern>
            <maxHistory>7</maxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5level] [%-5thread] [%X{request.url}] %logger{20} - %msg%n</pattern>
        </encoder>
    </appender>
<springProfile name="prod">
        <root level="INFO">
            <!-- 如果不输出到控制台,docker logs命令就看不见日志 -->
            <!-- <appender-ref ref="stdout" /> -->
            <appender-ref ref="FILE" />
            <appender-ref ref="FILE-ERROR" />
        </root>
    </springProfile>
....
....

than i started jetty

1、the E:/TAS_SOFT/jetty-home-10.0.15/logs haven't aaaaa_xxxx file, i think jetty's resources\logback.xml works now 2、when i remove resources/logback.xml i got

java.util.ServiceConfigurationError: ch.qos.logback.classic.spi.Configurator: Provider ch.qos.logback.classic.util.DefaultJoranConfigurator not found
        at java.base/java.util.ServiceLoader.fail(ServiceLoader.java:588)
        at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.nextProviderClass(ServiceLoader.java:1211)
        at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNextService(ServiceLoader.java:1220)
        at java.base/java.util.ServiceLoader$LazyClassPathLookupIterator.hasNext(ServiceLoader.java:1264)
        at java.base/java.util.ServiceLoader$2.hasNext(ServiceLoader.java:1299)
        at java.base/java.util.ServiceLoader$3.hasNext(ServiceLoader.java:1384)
        at ch.qos.logback.classic.util.EnvUtil.loadFromServiceLoader(EnvUtil.java:50)
        at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:136)
        at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:84)
        at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
        at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:417)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:362)
        at org.apache.commons.logging.LogAdapter$Slf4jAdapter.createLocationAwareLog(LogAdapter.java:130)
        at org.apache.commons.logging.LogAdapter.createLog(LogAdapter.java:91)
        at org.apache.commons.logging.LogFactoryService.getInstance(LogFactoryService.java:46)
        at org.apache.commons.logging.LogFactoryService.getInstance(LogFactoryService.java:41)
        at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:395)
        at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:96)
        at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
        at org.eclipse.jetty.servlet.ServletContainerInitializerHolder.doStart(ServletContainerInitializerHolder.java:144)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
        at org.eclipse.jetty.servlet.ServletContextHandler$ServletContainerInitializerStarter.doStart(ServletContextHandler.java:1660)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:369)
        at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1304)
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:901)
        at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:306)
        at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:532)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:40)
        at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:183)
        at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:516)
        at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:151)
        at org.eclipse.jetty.deploy.providers.ScanningAppProvider.fileAdded(ScanningAppProvider.java:186)
        at org.eclipse.jetty.deploy.providers.WebAppProvider.fileAdded(WebAppProvider.java:442)
        at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.fileAdded(ScanningAppProvider.java:58)
        at org.eclipse.jetty.util.Scanner$DiscreteListener.pathAdded(Scanner.java:282)
        at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:836)
        at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:802)
        at org.eclipse.jetty.util.Scanner.scan(Scanner.java:709)
        at org.eclipse.jetty.util.Scanner.doStart(Scanner.java:597)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:121)
        at org.eclipse.jetty.deploy.providers.ScanningAppProvider.doStart(ScanningAppProvider.java:158)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.deploy.DeploymentManager.startAppProvider(DeploymentManager.java:605)
        at org.eclipse.jetty.deploy.DeploymentManager.doStart(DeploymentManager.java:246)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
        at org.eclipse.jetty.server.Server.start(Server.java:470)
        at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:121)
        at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
        at org.eclipse.jetty.server.Server.doStart(Server.java:415)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
        at org.eclipse.jetty.xml.XmlConfiguration.main(XmlConfiguration.java:1875)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.eclipse.jetty.start.Main.invokeMain(Main.java:229)
        at org.eclipse.jetty.start.Main.start(Main.java:528)
        at org.eclipse.jetty.start.Main.main(Main.java:76)

i have see etc/logging-logback.mod has the line

jetty.webapp.addServerClasses+=,ch.qos.logback.

but jetty9 logback-impl is:

jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/logback/

so' i change jetty10 like this:

#jetty.webapp.addServerClasses+=,ch.qos.logback.
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/logging/logback-classic-${logback.version}.jar
jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/logging/logback-core-${logback.version}.jar

then, jetty can load the logback-spring.xml and logs dir has the log file I don't understand why the class path should be used here, not the directory. The class path will work for all applications within JETTY

How to reproduce?

janbartel commented 1 year ago

If I understand correctly, what you have tried to do is:

By enabling the logging-logback module, you're saying you want jetty server to use logback to log its events. Therefore, it needs to be able to access a logback configuration file that is on the server classpath, which is why we add the resources/logging-logback.xml. The module hides the logback classes from the webapp, presumably to allow webapps to provide their own, different logging setup for logs produced by your webapp.

BTW we moved away from configuring server and system classes using explicit jar locations because that's both pretty fragile and too broad - better to be precise about exactly which packages should be excluded from visibility for the webapp.

@joakime any other advice you can give here?

james-z-repo commented 1 year ago

no content

james-z-repo commented 1 year ago

If I understand correctly, what you have tried to do is:

  • enable logback logging for the jetty server (by enabling the logging-logback module)
  • provide a logback configuration file that is inside your webapp

By enabling the logging-logback module, you're saying you want jetty server to use logback to log its events. Therefore, it needs to be able to access a logback configuration file that is on the server classpath, which is why we add the resources/logging-logback.xml. The module hides the logback classes from the webapp, presumably to allow webapps to provide their own, different logging setup for logs produced by your webapp.

BTW we moved away from configuring server and system classes using explicit jar locations because that's both pretty fragile and too broad - better to be precise about exactly which packages should be excluded from visibility for the webapp.

@joakime any other advice you can give here?

I think I understand what you mean, LOGBACK + Resource/logback.xml is used to override the application's log configuration. But I'm still confused. After I deleted resource/logback.xml, it would be better to load the application configuration instead of the application failing to start.

janbartel commented 1 year ago

I think I understand what you mean, LOGBACK + Resource/logback.xml is used to override the application's log configuration.

No, there's a subtlety you're missing. It's not overriding the applications log configuration, the server literally can't see it. You're configuring the server's logging behaviour, not your webapp's logging behaviour.

But I'm still confused. After I deleted resource/logback.xml, it would be better to load the application configuration instead of the application failing to start.

After you deleted resource/logback.xml, I think you'll find jetty started fine, but your application did not start correctly. If you look at your stacktrace, you can see the exception is in the spring SpringBootServletInitializer which is looking for logging. It is not finding the ch.qos.logback classes from the server's classpath because they are hidden from the webapp (by the serverClasses statement in the logging-logback module). You'd need to provide your own copy of logback inside your webapp, along with you applications logback.xml config file. Alternatively, if you're trying to have both jetty and your webapp share a common logback setup, have a read of the jetty-9 documentation here: https://eclipse.dev/jetty/documentation/jetty-9/index.html#example-logging-logback-centralized

james-z-repo commented 1 year ago

我想我明白你的意思,LOGBACK + Resource/logback.xml 用于覆盖应用程序的日志配置。 不,你忽略了一个微妙之处。它不会_覆盖_应用程序日志配置,服务器实际上看不到它。您正在配置服务器的日志记录行为,而不是您的网络应用程序的日志记录行为。

但我还是很困惑。我删除resource/logback.xml后,最好加载应用程序配置而不是应用程序无法启动。 删除后resource/logback.xml,我想您会发现 jetty 启动正常,但您的应用程序未正确启动。如果您查看堆栈跟踪,您可以看到异常发生在SpringBootServletInitializer正在寻找日志记录的 spring 中。它没有ch.qos.logback从服务器的类路径中找到类,因为它们对 web 应用程序是隐藏的(通过模块serverClasses中的语句logging-logback)。您需要在 Web 应用程序中提供您自己的 logback 副本以及应用程序 logback.xml 配置文件。或者,如果您想同时拥有码头_和_您的 web 应用程序共享一个通用的 logback 设置,请在此处阅读 jetty-9 文档: https ://eclipse.dev/jetty/documentation/jetty-9/index.html#example-logging-logback-centralized

There is a logback-spring.xml file in my application. According to the logback configuration loading order, it will first search for logback.xml. If this file does not exist, it will load the logback-spring.xml file, because at this time jetty’s addServerClasses leads to I can't load the logback-spring.xml of the application itself as a configuration file, I think this has modified the configuration loading order of logback

github-actions[bot] commented 2 weeks ago

This issue has been automatically marked as stale because it has been a full year without activity. It will be closed if no further activity occurs. Thank you for your contributions.