Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide compatibility or replace the need for the Log4j-Spring-Boot Module #28909

Closed
rgoers opened this issue Dec 6, 2021 · 8 comments
Closed
Assignees
Labels
status: superseded An issue that has been superseded by another

Comments

@rgoers
Copy link
Contributor

rgoers commented Dec 6, 2021

Spring Boot 2.6.0 added support for Log4j2 Composite Configurations. Log4j's log4j-spring-boot module also provides support for this but in a different manner since prior to 2.6.0 Spring Boot only allowed a single property to identify the logging configuration files. But log4j-spring-boot also allows these files to be stored in a Spring Cloud Configuration server instance with access via HTTP(S) even if the access is password protected. Spring Boot does not so anyone looking for that support will have to forego Spring Boot's support and use log4j-spring-boot instead. Log4j also allows SSL configuration to be provided although this is probably not very important in a Spring Boot environment where the SSL/TLS configuration for the JVM is probably OK.

log4j-spring-boot also provides

Spring Lookup

The Spring Lookup allows configuration files to reference properties defined in Spring configuration files from a Log4j configuration file. For example:

<property name="applicationName">${spring:spring.application.name}</property>
would set the Log4j applicationName property to the value of spring.application.name set in the Spring configuration. Users can then do things like:

<Appenders>
   <RollingFile name="log4j" fileName="${LOG_DIR}/${applicationName}.log" filePattern="${LOG_DIR}/archive/${applicationName}.log.%d{yyyyMMdd_HH}-%i">
     <PatternLayout pattern="${log4jPattern}"/>
     <Policies>
       <SizeBasedTriggeringPolicy size="30 MB"/>
     </Policies>
     <!-- A max of 20 will allow 20 files per second with the date pattern specified on the RollingFile declaration.
         Hopefully that is a ridiculous value -->
     <DefaultRolloverStrategy min="1" max="20">
       <Delete basePath="${LOG_DIR}/archive">
         <!-- Nested conditions: the inner condition is only evaluated on files for which the outer conditions are true. -->
         <IfFileName glob="${applicationName}.log.*">
           <!-- Only allow 500 MB of files to accumulate -->
           <IfAccumulatedFileSize exceeds="500 MB"/>
         </IfFileName>
       </Delete>
     </DefaultRolloverStrategy>
   </RollingFile>
 </Appenders>  

Spring Property Source

Log4j uses property sources when resolving properties it uses internally. This support allows most of Log4j’s System Properties to be specified in the Spring Configuration. However, some properties that are only referenced during the first Log4j initialization, such as the property Log4j uses to allow the default Log4j implementation to be chosen, would not be available.

Spring Profile Arbiter

New with Log4j 2.15.0 are "Arbiters" which are conditionals that can cause a portion of the Log4j configuration to be included or excluded. log4j-spring-boot provides an Arbiter that allows a Spring profile value to be used for this purpose. Below is an example:

<Configuration name="ConfigTest" status="ERROR" monitorInterval="5">
  <Appenders>

    <SpringProfile name="dev | staging">
      <Console name="Out">
        <PatternLayout pattern="%m%n"/>
      </Console>
    </SpringProfile>
    <SpringProfile name="prod">
      <List name="Out">
      </List>
    </SpringProfile>

  </Appenders>
  <Loggers>
    <Logger name="org.apache.test" level="trace" additivity="false">
      <AppenderRef ref="Out"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Out"/>
    </Root>
  </Loggers>
</Configuration>

To implement these features Log4j had to extend Spring's Log4j2LoggingSystem. This is unfortunate as it means Log4j may need to be modified to support new versions that add new methods or features as 2.6.0 did. Log4j will now need to override the new loadConfiguration method that accepts a list of override names so that authentication support can be added to the new way of specifying override files.

Finally, it is confusing to users to have to use log4j-spring-boot to get features that enhance Spring Boot's integration with Log4j.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Dec 6, 2021
@quaff
Copy link
Contributor

quaff commented Dec 6, 2021

I‘m expecting Spring Lookup.

@philwebb philwebb added the for: team-meeting An issue we'd like to discuss as a team to make progress label Dec 10, 2021
@philwebb
Copy link
Member

See also the discussion in #22149 (comment)

@ppkarwasz
Copy link
Contributor

ppkarwasz commented Feb 27, 2022

@rgoers and @wilkinsona: I would like to add my two cents on how to solve this issue and the recursive dependency mentioned in #22149.

The log4j-spring-boot module only requires a spring-core dependency (more exactly the Environment and Profiles classes). The component that boosts the dependency requirements is Log4j2CloudConfigLoggingSystem, which performs two tasks: it allows the retrieval of Spring Cloud configuration and registers the Spring Environment with the LoggerContext.

Therefore without loosing backward compatibility one might:

  1. Modify the Log4j2LoggingSystem to register a "SpringEnvironment" key with the LoggerContext. I prepared the PR Adds support for Log4j SpringLookup #30004 for this purpose. This does not add any dependency to Spring Boot, the log4j-spring-boot artifact is only used in tests with a disabled Log4j2CloudConfigLoggingSystem.
  2. Once this is done, the Log4j2CloudConfigLoggingSystem can be moved to log4j-spring-cloud-config-client and the dependencies of the log4j-spring-boot module can be cut down to spring-core. Alternatively (if naming has importance) the module can be renamed to log4j-spring, leaving log4j-spring-boot as empty module with a dependency upon spring-boot and log4j-spring.
  3. Spring Boot can add the new version of log4j-spring-boot to spring-boot-starter-log4j2.

@ppkarwasz
Copy link
Contributor

Log4j2's PR #777 could be used to easily disable Log4j2CloudConfigLoggingSystem. Right now this can be only achieved by removing the log4j2.system.properties file in the log4j-spring-boot artifact.

@wilkinsona
Copy link
Member

Thanks for the suggestions, @ppkarwasz. Unfortunately, they won't really address my concerns about circular dependencies as we prefer not to have any dependency cycles, even when it's only in test code. Even if we addressed the test code, we'd still be left with Spring Framework's spring-jcl module having a dependency on Log4j 2's API. I'd rather get us into a position where Spring Boot itself offers functionality that's equivalent to things like SpringLookup, eventually superseding log4j-spring-boot.

@wilkinsona wilkinsona removed the for: team-meeting An issue we'd like to discuss as a team to make progress label Apr 6, 2022
@w-ronin
Copy link

w-ronin commented Dec 15, 2023

Hi all.
Offers Spring Boot already SpringLookup funktionality?
With spring-jcl ignores Spring Boot 2.7.17 log levels (is always DEBUG) from log4j2-spring.xml on Websphere Traditional 9.0.5.14.

@ppkarwasz
Copy link
Contributor

@w-ronin,

The Spring lookup was integrated into Spring Boot 3.x. For Spring Boot 2.x you need to add log4j-spring-boot as a dependency.

@rgoers
Copy link
Contributor Author

rgoers commented Dec 15, 2023

I am going to close this as my PR was integrated into Spring Boot 3.

@rgoers rgoers closed this as completed Dec 15, 2023
@philwebb philwebb added status: superseded An issue that has been superseded by another and removed status: waiting-for-triage An issue we've not yet triaged labels Dec 17, 2023
@wilkinsona wilkinsona closed this as not planned Won't fix, can't repro, duplicate, stale Dec 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: superseded An issue that has been superseded by another
Projects
None yet
Development

No branches or pull requests

7 participants