-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add collectionName/databaseName
attributes to MongoDB provider
#3322
base: main
Are you sure you want to change the base?
Conversation
…g file instead of just the connectionString
collectionName/databaseName
attributes to MongoDB provider
Thank you for your contribution. While I am not a MongoDB user, the current behavior of using the connection string to infer the name of the database and collection does not make sense to me. Your proposal looks like a valid improvement. According to the MongoDB connection string documentation the connection string has the form:
where
Therefore:
@garydgregory, what do you think? |
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.
This looks like a very valid improvement! 💯
The changes to the MongoDB provider should be documented. Can you:
- Modify database.adoc and add a description of the
databaseName
andcollectionName
configuration attributes. IMHO these attributes should be marked as "required" in the documentation and the description should mention their fallback values (which are kept only for backward compatibility). The fallback values can be marked as deprecated and we might remove them in a future Log4j Core version. - Since IMHO providing the database and collection name explicitly seems like the right thing to do, all the examples and integration tests should be rewritten to use the
databaseName
andcollectionName
attributes.
log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
Outdated
Show resolved
Hide resolved
log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
Outdated
Show resolved
Hide resolved
log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
Outdated
Show resolved
Hide resolved
log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
Outdated
Show resolved
Hide resolved
log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbCollectionNameIT.java
Show resolved
Hide resolved
The integration tests in the
|
I'm not a fan because this creates confusion with the connection string. IMO: It should be that EITHER you provide a connection string OR you provide all the bits and pieces to build a connection string. I don't like the idea of doing it half one way and half the other. IMO, we should follow the KISS principle and only provide connection string support. Just like with JDBC, you just need to know a driver's connection string syntax, which invariably changes from time to time, and I certainly don't want to have to change this code because there is some Mongo driver change in some version that breaks our code. |
These were my initial thoughts too, until I dug deeper into the connection string.
As I mentioned before, I have almost no experience with MongoDB, so these interpretations might not make sense.
For JDBC you also need to provide the name of the table. |
So the real problem is that the Mongo documentation could be better, like in any software. I am concerned this opens the door for more and more options to be added to "override" the connection string components, making maintenance harder. We should only, IMO, offer configuration hooks for behavior that can't be achieved otherwise. Let's review: The database as part of the connection string is documented here (where Google took me):
and fancier:
The collection is specified as "databaseName.collectionName", see our XML configuration files. The classic problem is that we do not want to create support tickets like "My appender connects to A instead of B, why?" where we then have to say "Oh, that's because you specified the foo in both the connection string and in the other thing and this takes precedence over that, blah blah". For these use cases of double configuration, we should throw an exception. Who would port this to |
Agreeing with @garydgregory's sentiment that we should not add more configuration knobs, if the shared use case can be served with just the connection string. I can spare time for this further after the vacation (i.e., 2025-01-02), if not earlier. |
I agree that there is a slippery slope here, but specifying a table name for a db connection in the connection string is very very odd. Allowing the collection name via config instead of connection string puts this in line how the JDBC appender works which required a table name as part of the config. I would actually prefer to make this a config only part and have it override the connection string value. With the way the code currently functions you have to extract the db and collection name from the connection string to pass them to other code blocks anyway. But to preserve backwards compatibility I left it in. |
I looked into the Spring Boot configuration properties for MongoDB:
It seems that Spring Boot interprets the |
I would also point out that spring doesn't have a configuration property for the collection, and that's really the key item here. They assume, appropriately, that you will have various objects being written to various collections inside the app. So you configure the collection for items differently than you do the DB. That's really the pattern I think is needed here. |
So I am working on making the unit test changes but I am finding 2 key challenges.
|
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.
This looks almost done to me, thanks! It is still missing some details:
- can you modify the config files in
log4j-mongodb/src/test/resources
to use thedatabaseName
andcollectionName
attributes? - can you add a changelog entry to
src/changelog/.2.x.x
? Just copy/paste an existing one and modify the data.
log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
Outdated
Show resolved
Hide resolved
log4j-mongodb/src/main/java/org/apache/logging/log4j/mongodb/MongoDbProvider.java
Outdated
Show resolved
Hide resolved
src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc
Outdated
Show resolved
Hide resolved
src/site/antora/modules/ROOT/pages/manual/appenders/database.adoc
Outdated
Show resolved
Hide resolved
log4j-mongodb/src/test/java/org/apache/logging/log4j/mongodb/MongoDbProviderTest.java
Outdated
Show resolved
Hide resolved
…neous dependencies.
Unable to do the changelog entry as this work is done on the main (3.x) branch and that file doesn't exist. I can work to back-port (or recreate these in the 2.x structure and can make those changes to that version as needed. |
Sorry, I meant |
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.
Look good to me
Could you review this PR? |
I will take care of this tomorrow afternoon.
… Message ID: ***@***.***>
|
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.
@jesmith17, thanks so much for the changes! I have requested some changes. But I think we have a more fundamental problem: Your PR targets main
, i.e., Log4j 3, that is yet to be released. Would you mind editing your PR to target the 2.x
branch, please? I will share further remarks once the target is fixed.
@@ -817,6 +817,29 @@ for its format. | |||
|
|||
**Required** | |||
|
|||
| [[MongoDbProvider-attr-databaseName]]databaseName | |||
| 'string' |
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.
| 'string' | |
| `string` |
**Required** | ||
|
||
| [[MongoDbProvider-attr-collectionName]]collectionName | ||
| 'string' |
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.
| 'string' | |
| `string` |
| | ||
It specifies the name of the collection for the appender to use. | ||
For backward compatibility, the collection name can also be specified in the | ||
https://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[Java-specific connection string] |
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.
https://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[Java-specific connection string] | |
https://mongodb.github.io/mongo-java-driver/5.0/apidocs/mongodb-driver-core/com/mongodb/ConnectionString.html[Java-specific connection string]. |
src/site/antora/modules/ROOT/examples/manual/appenders/database/nosql-mongo-keys.json
Show resolved
Hide resolved
<issue id="3321" link="https://github.com/apache/logging-log4j2/discussions/3321"/> | ||
<description format="asciidoc">Update log4j-mongodb to allow collectionName and databaseName to be defined via the config file</description> |
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.
<issue id="3321" link="https://github.com/apache/logging-log4j2/discussions/3321"/> | |
<description format="asciidoc">Update log4j-mongodb to allow collectionName and databaseName to be defined via the config file</description> | |
<issue id="3322" link="https://github.com/apache/logging-log4j2/pull/3322"/> | |
<description format="asciidoc">Add `collectionName` and `databaseName` arguments to the MongoDB appender</description> |
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 see you switched all IT configuration to use the new {database,collection}Name
attributes, don't. This effectively removes the checks verifying that the old style is still working. Could you revert all your resources/*.xml
changes, please? (Keep the new resource files you added for new tests.)
private String validConnectionStringWithoutDatabase = "mongodb://localhost:27017"; | ||
private String validConnectionStringWithDatabase = "mongodb://localhost:27017/logging"; | ||
private String validConnectionStringWithDatabaseAndCollection = "mongodb://localhost:27017/logging.logs"; | ||
|
||
private String collectionName = "logsTest"; | ||
private String databaseName = "loggingTest"; |
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.
Nit: Could you make all these private static final
, please? (I think you can also rename validConnectionStringFoo
to CON_STR_FOO
to save some visual real estate.)
assertNotNull(provider, "Returned provider is null"); | ||
assertEquals( | ||
this.collectionName, | ||
provider.getConnection().getCollection().getNamespace().getCollectionName(), | ||
"Collection names do not match"); | ||
assertEquals( | ||
this.databaseName, | ||
provider.getConnection().getCollection().getNamespace().getDatabaseName(), | ||
"Database names do not match"); |
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.
All checks are pretty self-explanatory. Could you remove all messages (Returned provider is null
, Collection names do not match
, etc.), please?
@@ -151,7 +150,7 @@ | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-surefire-plugin</artifactId> | |||
<configuration> | |||
<skip>true</skip> | |||
<skip>false</skip> |
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.
You can remove the entire <configuration>
, since <skip>false
is the default.
@vy Because the filestrucutres between main and 2.x are different I don't think there is a way to just retarget the code changes. In the 2.x branch the MongoDbProvider class is just a shell that wraps calls to MongoDb4Provider (which is in a different project). I can create a new PR with these changes (and the feedback above) and do that if that makes sense. but trying to port these changes to the 2.x branch ends up being a much bigger change to the core of the appender itself. To your point on the changes to the IT tests to use the new format in all cases, I agree that a test needs to exist for using the old format, but I made those changes at the request of @ppkarwasz on Dec 29th. I don't personally have a strong opinion either way, so if you can both get connected and let me know which way you prefer it, I can make the changes. |
Actually for the IT tests, I just added an additional one that explicitly tests the old format. That's more descriptive and clear anyway. |
Added support for defining the target collectionName and databaseName for the logs to the config file. This allows users to define the values via config instead of only configuring them via the connectionString.