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
GEODE-6964: Move geode log4j core classes to geode-log4j #4003
GEODE-6964: Move geode log4j core classes to geode-log4j #4003
Conversation
This pull request fixes 4 alerts when merging 1db6b9d into 7f2b986 - view on LGTM.com fixed alerts:
|
1db6b9d
to
022e3c8
Compare
This pull request fixes 4 alerts when merging 022e3c8 into 245f285 - view on LGTM.com fixed alerts:
|
022e3c8
to
82c52ae
Compare
This pull request fixes 4 alerts when merging 82c52ae into 383bc54 - view on LGTM.com fixed alerts:
|
Thanks for pointing out the overlap between this pull request and the one for GEODE-7177 @aaronlindsey. I think we'll probably want to look at how to reconcile the two. The goal of GEODE-7177 is to move dependencies on logging-related classes used by the |
The goal of this PR is to remove geode-core's dependency on log4j-core, so that users may use a different logging backend (such as logback) more easily. See Hopefully, that clarifies things a bit. To answer the question, I don't think it would be appropriate to move all of the logging code that membership depends on into geode-log4j. |
3de8a32
to
25b980a
Compare
This pull request fixes 4 alerts when merging 25b980a into 1a1d221 - view on LGTM.com fixed alerts:
|
25b980a
to
9a75e39
Compare
Introduce new Logging and Alerting SPIs. Extract all log4j-core code to geode-log4j module. The geode-core module no longer contains log4j2.xml and no longer has a dependency on log4j-core. All code that uses log4j-core has moved to the new module geode-log4j. The log4j2.xml for Geode now lives in geode-log4j as well. These changes ensure that users have better control over logging including which backend to use. This should improve user experience when using Spring Boot. Co-authored-by: Mark Hanson <mhanson@pivotal.io>
AlertAppender uses a ThreadLocal to prevent recursive calls from actually doing anything. However, a recent upgrade to our log4j dependencies seems to have changed the behavior such that log4j refuses to invoke doAppend if the thread is currently handling a sendAlert initiated from doAppend. To fix this bug, sendAlert must be async.
9a75e39
to
55da942
Compare
This pull request fixes 4 alerts when merging 55da942 into 97e1d19 - view on LGTM.com fixed alerts:
|
Thanks for the picture @aaronlindsey! I think we are on the same page regarding the end result. Currently in the GEODE-7177 PR we have moved select classes which depend on log4j into geode-logging, but now that seems a bit odd since those should really be in geode-log4j (as they are in this PR). I think we should get this PR merged in, then take another pass at getting the membership logging dependencies into geode-logging without moving any log4j related stuff. |
StringBuilder sb = new StringBuilder(); | ||
sb.append("Unable to run modify_war script, command: ").append(builder.command()); | ||
sb.append(lineSeparator()); | ||
sb.append("log file: "); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is intentional but you lost the word "check" in this refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not intentional. Pushing a fix to restore the lost word. Those \n make it too easy to delete a word when you get rid of \n.
implementation('org.apache.logging.log4j:log4j-core') { | ||
ext.optional = true | ||
} | ||
api('org.apache.logging.log4j:log4j-api') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used implementation
here before which would have hidden the log4j API from consumers of geode-core. Is that not what we want in this new model, since we are now using api
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LogService is an internal API used by modules other than geode-core. In a follow-up PR, I will need to move LogService to a User API package. It returns log4j-api Logger and is an API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In a follow-up PR, I will need to move LogService to a User API package
Could you elaborate on this some more? Why are we exposing LogService as User API? Do we want users of geode to be able to write to geode logs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've discussed this previously with @pivotal-jbarrett and others. I currently feel strongly that we should NOT export internal APIs between modules. I also feel strongly against defining SPIs within internal packages. I know that @upthewaterspout prefers internal SPIs and internal APIs, but I haven't heard any arguments for this that have swayed me yet.
To summarize: If all geode-* modules are going to get Loggers from LogService then I want LogService to live in org.apache.geode.logging
package instead of an internal package. I believe this is more correct and within this PR, the class only exposes two public methods:
public static Logger getLogger();
public static Logger getLogger(String name);
I defined geode-core as having api
dependency on log4j-api because LogService currently lives in geode-core and is returning Loggers from log4j-api. This portion of the PR was done while pairing with @rhoughton-pivot who helped me understand how to use api
vs implementation
in gradle.
I have no problem moving LogService to geode-logging instead of geode-core.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kirklund - I do prefer internal APIs for things that we only want to be used internally. I think that is the case for LogService - we don't intend for users to ever call this class, so it should not be public.
By making log4j2 an API dependency we make life worse for our users because we are pollute their compile time classpath with log4j2. How we do logging inside geode really shouldn't leak out to our users. Adding public API that depends on log4j2-api would commit us into to providing a log4j2 API to our users in the future, even if we switched over to using logback or something else internally.
...-core/src/distributedTest/java/org/apache/geode/alerting/AlertingServiceDistributedTest.java
Outdated
Show resolved
Hide resolved
...ibutedTest/java/org/apache/geode/alerting/AlertingServiceWithoutListenerDistributedTest.java
Outdated
Show resolved
Hide resolved
...c/integrationTest/java/org/apache/geode/internal/cache/PartitionedRegionIntegrationTest.java
Show resolved
Hide resolved
...integrationTest/java/org/apache/geode/logging/internal/ConfigurationInfoIntegrationTest.java
Outdated
Show resolved
Hide resolved
...rg/apache/geode/distributed/LocatorLauncherRemoteWithCustomLoggingIntegrationTest_log4j2.xml
Show resolved
Hide resolved
geode-core/src/main/java/org/apache/geode/internal/logging/SortLogFile.java
Outdated
Show resolved
Hide resolved
geode-core/src/main/java/org/apache/geode/logging/spi/SessionContext.java
Outdated
Show resolved
Hide resolved
This pull request fixes 4 alerts when merging 1ecae44 into cc17bea - view on LGTM.com fixed alerts:
|
Looks like we have a few lingering test failures, but otherwise I think we can get this in and iterate on it to address membership's dependencies on logging related classes in geode-core. |
This pull request fixes 4 alerts when merging 8c9b4ce into cc17bea - view on LGTM.com fixed alerts:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I submitted a review without reading the comments already posted on this PR. I'm retracting my review until I've had time to read everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should move all of these internal classes to the public API. Is this really an API we want to expose to our users?
Here's a partial list of classes that were moved to the public API that I see in this PR.
AlertingService, AlertLevel, AlertingAction, EntriesCollection, LogConfig, LogConfigListener, LogConfigSupplier, LogFile, LogFileDetails, LogLevelUpdateOccurs, LogLevelUpdateScope, LogWriterLevel, LoggingProvider, LoggingSessionListener, StatisticsConfig, AlertAppender, AppenderContext, GeodeConsoleAppender, HexThreadIdPatternConverter, Log4jLoggingProvider, LogWriterAppender, MemberNamePatternConverter, MemberNameSupplier, NullLogWriter, PausableAppender, GemFireParameterizedMessage, GemFireParameterizedMessageFactory
@@ -367,10 +350,11 @@ dependencies { | |||
integrationTestCompile(project(':geode-dunit')) { | |||
exclude module: 'geode-core' | |||
} | |||
integrationTestImplementation(project(':geode-log4j')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better if geode-core tests did not depend on geode-log4j. If we always test geode-core with geode-log4j, we will never know if there are parts of the system which will just fail without geode-log4j.
Could we instead just add plain old log4j-core here as a test dependency instead, or whatever we expect users to use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too many of the integration tests are end-to-end server or locator requiring logging and/or alerting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: I'm still very committed to having geode-log4j in the classpath for integrationTests which do spin up servers/locators, perform logging and alerting, etc. These tests are not debuggable without logs. We would also have to find a new home for all integrationTests which have validation involving logging and alerting, and that's not something I want to tackle in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would adding log4j itself as a dependency not solve the issue of getting logs in the tests? It would just mean that geode-core would be tested without whatever special functionality geode-log4j adds.
I'm still concerned that we need to test geode-core without geode-log4j, if we are going to claim that geode-log4j is optional.
I think being forced to move tests of alerting, etc. to geode-log4j would be valuable, because it would show us what functionality doesn't work without geode-log4j.
@upthewaterspout I'm committed to properly exposing SPI classes as non-internal. I also intend to finish up my geode-logback repo which implements a logback provider with a corresponding blog article. I've discussed this (having non-internal SPIs) with other Geode committers and most developers approve of using non-internal SPIs. My opinion is that we should not have ANY internal APIs that are exported for other modules or for SPI usage. Please note that I feel very strongly about this and do not want to be involved in crafting internal SPIs or exporting internal APIs. |
@kirklund - Regarding the public APIs - If you feel strongly about adding these new public API classes, I think it would be helpful to start a discussion on the dev list about them. This seems like a lot of new public API to be hidden in a PR that many people will not notice. |
@upthewaterspout @jxblum @pivotal-jbarrett @mcmellawatt @nvpivot @metatype @demery-pivotal: One of the main areas that Geode has not done well in is integration and fostering non-Pivotal contributions. I believe our continued use and preference of "internal" APIs as integration points with a lack of real SPIs is the main reason behind this. I think it's vital that we steer our project away from having to use ambiguous or hazy internal APIs between modules or as integration points. It should be very clear which APIs can or cannot change without breaking integration points and without having to describe some bizarre policy that's more complicated than "internal" vs "external". We need clear, distinct "external" APIs between modules as well as integration points. I believe this promotes non-Pivotal employees becoming involved in Geode, contributing their own SPI provider implementations and helping to integrate Geode with more environments and 3rd party libraries of various sorts. Every time we double down on "internal" APIs we end up breaking Spring Data Geode or other non-open-source integration. Ultimately, these "internal" APIs promote tribal knowledge in our project and prevent us from clearly knowing what can or cannot change in our code base. I feel very strongly against using "internal" APIs as integration points between modules and I feel even more strongly against discouraging Geode users and non-committers from extending Geode and trying to write their own implementation providers. I'm not interested in making it difficult for others to do the same thing we are doing. I want to improve Geode code quality and make integration with it clear and easy instead of difficult or esoteric. Just imaging an open-source world in which we have non-Pivotal employees write and contribute a module such |
This pull request fixes 4 alerts when merging 85f676a into 165648b - view on LGTM.com fixed alerts:
|
In the previous PR (#3914), we discussed marking the classes we need to change later as |
There is a lot going on here. I will preface that I haven't read the entire PR. I would prefer to have seen an RFC that described the intent of this PR. I believe the intent is to move all the Log4J specific code into its own module. This module is expected to be an SPI implementation of the Geode logging service, such that another implementation could be dropped in without changes to any code. Based on this assumption here is what I would expect:
|
Closing this PR. |
Move all log4j-core code from geode-core to geode-log4j.
Move Geode's log4j2.xml from geode-core to geode-log4j.
Make geode-log4j an implementation dependency for geode-dunit.
Co-authored-by: Mark Hanson mhanson@pivotal.io
Co-authored-by: Aaron Lindsey alindsey@pivotal.io
Co-authored-by: Dale Emery demery@pivotal.io
Previous PR: #3914