Skip to content

Commit 7eac454

Browse files
authored
Support configuration of max document length for command logging (#1072)
JAVA-4841
1 parent e761f17 commit 7eac454

File tree

20 files changed

+297
-47
lines changed

20 files changed

+297
-47
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2008-present MongoDB, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.mongodb;
18+
19+
import com.mongodb.annotations.Immutable;
20+
21+
import java.util.Objects;
22+
23+
import static com.mongodb.assertions.Assertions.notNull;
24+
25+
/**
26+
* An immutable class representing settings for logging.
27+
*
28+
* <p>
29+
* The driver logs using the SLF4J 1.0 API with a root logger of {@code org.mongodb.driver}. See
30+
* <a href="https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/logging">Logging Fundamentals</a>
31+
* for additional information.
32+
* </p>
33+
*
34+
* @since 4.9
35+
*/
36+
@Immutable
37+
public final class LoggerSettings {
38+
private final int maxDocumentLength;
39+
/**
40+
* Gets a builder for an instance of {@code LoggerSettings}.
41+
* @return the builder
42+
*/
43+
public static Builder builder() {
44+
return new Builder();
45+
}
46+
47+
/**
48+
* Creates a builder instance.
49+
*
50+
* @param loggerSettings existing LoggerSettings to default the builder settings on.
51+
* @return a builder
52+
*/
53+
public static Builder builder(final LoggerSettings loggerSettings) {
54+
return builder().applySettings(loggerSettings);
55+
}
56+
57+
/**
58+
* A builder for an instance of {@code LoggerSettings}.
59+
*/
60+
public static final class Builder {
61+
private int maxDocumentLength = 1000;
62+
private Builder() {
63+
}
64+
65+
/**
66+
* Applies the loggerSettings to the builder
67+
*
68+
* <p>Note: Overwrites all existing settings</p>
69+
*
70+
* @param loggerSettings the loggerSettings
71+
* @return this
72+
*/
73+
public Builder applySettings(final LoggerSettings loggerSettings) {
74+
notNull("loggerSettings", loggerSettings);
75+
maxDocumentLength = loggerSettings.maxDocumentLength;
76+
return this;
77+
}
78+
79+
/**
80+
* Sets the max document length.
81+
*
82+
* @param maxDocumentLength the max document length
83+
* @return this
84+
* @see #getMaxDocumentLength()
85+
*/
86+
public Builder maxDocumentLength(final int maxDocumentLength) {
87+
this.maxDocumentLength = maxDocumentLength;
88+
return this;
89+
}
90+
91+
/**
92+
* Build an instance of {@code LoggerSettings}.
93+
* @return the logger settings for this builder
94+
*/
95+
public LoggerSettings build() {
96+
return new LoggerSettings(this);
97+
}
98+
}
99+
100+
/**
101+
* Gets the max length of the extended JSON representation of a BSON document within a log message.
102+
*
103+
* <p>
104+
* For example, when the driver logs a command or its reply via the {@code org.mongodb.driver.protocol.command} SFL4J logger, it
105+
* truncates its JSON representation to the maximum length defined by this setting.
106+
* </p>
107+
*
108+
* <p>
109+
* Defaults to 1000 characters.
110+
* </p>
111+
*
112+
* @return the max document length
113+
*/
114+
public int getMaxDocumentLength() {
115+
return maxDocumentLength;
116+
}
117+
118+
119+
@Override
120+
public boolean equals(final Object o) {
121+
if (this == o) {
122+
return true;
123+
}
124+
if (o == null || getClass() != o.getClass()) {
125+
return false;
126+
}
127+
LoggerSettings that = (LoggerSettings) o;
128+
return maxDocumentLength == that.maxDocumentLength;
129+
}
130+
131+
@Override
132+
public int hashCode() {
133+
return Objects.hash(maxDocumentLength);
134+
}
135+
136+
@Override
137+
public String toString() {
138+
return "LoggerSettings{"
139+
+ "maxDocumentLength=" + maxDocumentLength
140+
+ '}';
141+
}
142+
143+
private LoggerSettings(final Builder builder) {
144+
maxDocumentLength = builder.maxDocumentLength;
145+
}
146+
}

driver-core/src/main/com/mongodb/MongoClientSettings.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public final class MongoClientSettings {
8989
private final StreamFactoryFactory streamFactoryFactory;
9090
private final List<CommandListener> commandListeners;
9191
private final CodecRegistry codecRegistry;
92-
92+
private final LoggerSettings loggerSettings;
9393
private final ClusterSettings clusterSettings;
9494
private final SocketSettings socketSettings;
9595
private final SocketSettings heartbeatSocketSettings;
@@ -173,6 +173,7 @@ public static final class Builder {
173173
private StreamFactoryFactory streamFactoryFactory;
174174
private List<CommandListener> commandListeners = new ArrayList<>();
175175

176+
private final LoggerSettings.Builder loggerSettingsBuilder = LoggerSettings.builder();
176177
private final ClusterSettings.Builder clusterSettingsBuilder = ClusterSettings.builder();
177178
private final SocketSettings.Builder socketSettingsBuilder = SocketSettings.builder();
178179
private final ConnectionPoolSettings.Builder connectionPoolSettingsBuilder = ConnectionPoolSettings.builder();
@@ -211,6 +212,7 @@ private Builder(final MongoClientSettings settings) {
211212
streamFactoryFactory = settings.getStreamFactoryFactory();
212213
autoEncryptionSettings = settings.getAutoEncryptionSettings();
213214
contextProvider = settings.getContextProvider();
215+
loggerSettingsBuilder.applySettings(settings.getLoggerSettings());
214216
clusterSettingsBuilder.applySettings(settings.getClusterSettings());
215217
serverSettingsBuilder.applySettings(settings.getServerSettings());
216218
socketSettingsBuilder.applySettings(settings.getSocketSettings());
@@ -266,6 +268,19 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
266268
return this;
267269
}
268270

271+
/**
272+
* Applies the {@link LoggerSettings.Builder} block and then sets the loggerSettings.
273+
*
274+
* @param block the block to apply to the LoggerSettins.
275+
* @return this
276+
* @see MongoClientSettings#getLoggerSettings()
277+
* @since 4.9
278+
*/
279+
public Builder applyToLoggerSettings(final Block<LoggerSettings.Builder> block) {
280+
notNull("block", block).apply(loggerSettingsBuilder);
281+
return this;
282+
}
283+
269284
/**
270285
* Applies the {@link ClusterSettings.Builder} block and then sets the clusterSettings.
271286
*
@@ -772,6 +787,16 @@ public AutoEncryptionSettings getAutoEncryptionSettings() {
772787
return autoEncryptionSettings;
773788
}
774789

790+
/**
791+
* Gets the logger settings.
792+
*
793+
* @return the logger settings
794+
* @since 4.9
795+
*/
796+
public LoggerSettings getLoggerSettings() {
797+
return loggerSettings;
798+
}
799+
775800
/**
776801
* Gets the cluster settings.
777802
*
@@ -866,6 +891,7 @@ public boolean equals(final Object o) {
866891
&& Objects.equals(streamFactoryFactory, that.streamFactoryFactory)
867892
&& Objects.equals(commandListeners, that.commandListeners)
868893
&& Objects.equals(codecRegistry, that.codecRegistry)
894+
&& Objects.equals(loggerSettings, that.loggerSettings)
869895
&& Objects.equals(clusterSettings, that.clusterSettings)
870896
&& Objects.equals(socketSettings, that.socketSettings)
871897
&& Objects.equals(heartbeatSocketSettings, that.heartbeatSocketSettings)
@@ -883,9 +909,9 @@ public boolean equals(final Object o) {
883909
@Override
884910
public int hashCode() {
885911
return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, readConcern, credential, streamFactoryFactory,
886-
commandListeners, codecRegistry, clusterSettings, socketSettings, heartbeatSocketSettings, connectionPoolSettings,
887-
serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi, autoEncryptionSettings,
888-
heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, contextProvider);
912+
commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings, heartbeatSocketSettings,
913+
connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi,
914+
autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, contextProvider);
889915
}
890916

891917
@Override
@@ -900,6 +926,7 @@ public String toString() {
900926
+ ", streamFactoryFactory=" + streamFactoryFactory
901927
+ ", commandListeners=" + commandListeners
902928
+ ", codecRegistry=" + codecRegistry
929+
+ ", loggerSettings=" + loggerSettings
903930
+ ", clusterSettings=" + clusterSettings
904931
+ ", socketSettings=" + socketSettings
905932
+ ", heartbeatSocketSettings=" + heartbeatSocketSettings
@@ -926,6 +953,7 @@ private MongoClientSettings(final Builder builder) {
926953
codecRegistry = builder.codecRegistry;
927954
commandListeners = builder.commandListeners;
928955
applicationName = builder.applicationName;
956+
loggerSettings = builder.loggerSettingsBuilder.build();
929957
clusterSettings = builder.clusterSettingsBuilder.build();
930958
serverSettings = builder.serverSettingsBuilder.build();
931959
socketSettings = builder.socketSettingsBuilder.build();

driver-core/src/main/com/mongodb/internal/connection/DefaultClusterFactory.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.mongodb.internal.connection;
1818

19+
import com.mongodb.LoggerSettings;
1920
import com.mongodb.MongoCompressor;
2021
import com.mongodb.MongoCredential;
2122
import com.mongodb.MongoDriverInformation;
@@ -54,6 +55,7 @@ public Cluster createCluster(final ClusterSettings originalClusterSettings, fina
5455
final InternalConnectionPoolSettings internalConnectionPoolSettings,
5556
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
5657
@Nullable final MongoCredential credential,
58+
final LoggerSettings loggerSettings,
5759
@Nullable final CommandListener commandListener,
5860
@Nullable final String applicationName,
5961
@Nullable final MongoDriverInformation mongoDriverInformation,
@@ -89,14 +91,14 @@ public Cluster createCluster(final ClusterSettings originalClusterSettings, fina
8991

9092
if (clusterSettings.getMode() == ClusterConnectionMode.LOAD_BALANCED) {
9193
ClusterableServerFactory serverFactory = new LoadBalancedClusterableServerFactory(serverSettings,
92-
connectionPoolSettings, internalConnectionPoolSettings, streamFactory, credential, commandListener, applicationName,
93-
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(), compressorList,
94-
serverApi);
94+
connectionPoolSettings, internalConnectionPoolSettings, streamFactory, credential, loggerSettings, commandListener,
95+
applicationName, mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(),
96+
compressorList, serverApi);
9597
return new LoadBalancedCluster(clusterId, clusterSettings, serverFactory, dnsSrvRecordMonitorFactory);
9698
} else {
9799
ClusterableServerFactory serverFactory = new DefaultClusterableServerFactory(serverSettings,
98100
connectionPoolSettings, internalConnectionPoolSettings,
99-
streamFactory, heartbeatStreamFactory, credential, commandListener, applicationName,
101+
streamFactory, heartbeatStreamFactory, credential, loggerSettings, commandListener, applicationName,
100102
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(), compressorList,
101103
serverApi);
102104

driver-core/src/main/com/mongodb/internal/connection/DefaultClusterableServerFactory.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.mongodb.internal.connection;
1818

19+
import com.mongodb.LoggerSettings;
1920
import com.mongodb.MongoCompressor;
2021
import com.mongodb.MongoCredential;
2122
import com.mongodb.MongoDriverInformation;
@@ -46,6 +47,7 @@ public class DefaultClusterableServerFactory implements ClusterableServerFactory
4647
private final StreamFactory streamFactory;
4748
private final MongoCredentialWithCache credential;
4849
private final StreamFactory heartbeatStreamFactory;
50+
private final LoggerSettings loggerSettings;
4951
private final CommandListener commandListener;
5052
private final String applicationName;
5153
private final MongoDriverInformation mongoDriverInformation;
@@ -57,7 +59,9 @@ public DefaultClusterableServerFactory(
5759
final ServerSettings serverSettings, final ConnectionPoolSettings connectionPoolSettings,
5860
final InternalConnectionPoolSettings internalConnectionPoolSettings,
5961
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
60-
@Nullable final MongoCredential credential, @Nullable final CommandListener commandListener,
62+
@Nullable final MongoCredential credential,
63+
final LoggerSettings loggerSettings,
64+
@Nullable final CommandListener commandListener,
6165
@Nullable final String applicationName, @Nullable final MongoDriverInformation mongoDriverInformation,
6266
final List<MongoCompressor> compressorList, @Nullable final ServerApi serverApi) {
6367
this.serverSettings = serverSettings;
@@ -66,6 +70,7 @@ public DefaultClusterableServerFactory(
6670
this.streamFactory = streamFactory;
6771
this.credential = credential == null ? null : new MongoCredentialWithCache(credential);
6872
this.heartbeatStreamFactory = heartbeatStreamFactory;
73+
this.loggerSettings = loggerSettings;
6974
this.commandListener = commandListener;
7075
this.applicationName = applicationName;
7176
this.mongoDriverInformation = mongoDriverInformation;
@@ -81,11 +86,11 @@ public ClusterableServer create(final Cluster cluster, final ServerAddress serve
8186
ServerMonitor serverMonitor = new DefaultServerMonitor(serverId, serverSettings, cluster.getClock(),
8287
// no credentials, compressor list, or command listener for the server monitor factory
8388
new InternalStreamConnectionFactory(clusterMode, true, heartbeatStreamFactory, null, applicationName,
84-
mongoDriverInformation, emptyList(), null, serverApi),
89+
mongoDriverInformation, emptyList(), loggerSettings, null, serverApi),
8590
clusterMode, serverApi, sdamProvider);
8691
ConnectionPool connectionPool = new DefaultConnectionPool(serverId,
8792
new InternalStreamConnectionFactory(clusterMode, streamFactory, credential, applicationName,
88-
mongoDriverInformation, compressorList, commandListener, serverApi),
93+
mongoDriverInformation, compressorList, loggerSettings, commandListener, serverApi),
8994
connectionPoolSettings, internalConnectionPoolSettings, sdamProvider);
9095
ServerListener serverListener = singleServerListener(serverSettings);
9196
SdamServerDescriptionManager sdam = new DefaultSdamServerDescriptionManager(cluster, serverId, serverListener, serverMonitor,

driver-core/src/main/com/mongodb/internal/connection/InternalStreamConnection.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package com.mongodb.internal.connection;
1818

19+
import com.mongodb.LoggerSettings;
1920
import com.mongodb.MongoClientException;
2021
import com.mongodb.MongoCompressor;
2122
import com.mongodb.MongoException;
@@ -40,6 +41,7 @@
4041
import com.mongodb.connection.Stream;
4142
import com.mongodb.connection.StreamFactory;
4243
import com.mongodb.event.CommandListener;
44+
import com.mongodb.internal.VisibleForTesting;
4345
import com.mongodb.internal.async.SingleResultCallback;
4446
import com.mongodb.internal.diagnostics.logging.Logger;
4547
import com.mongodb.internal.diagnostics.logging.Loggers;
@@ -125,6 +127,7 @@ public class InternalStreamConnection implements InternalConnection {
125127
private final AtomicBoolean opened = new AtomicBoolean();
126128

127129
private final List<MongoCompressor> compressorList;
130+
private final LoggerSettings loggerSettings;
128131
private final CommandListener commandListener;
129132
@Nullable private volatile Compressor sendCompressor;
130133
private final Map<Byte, Compressor> compressorMap;
@@ -142,18 +145,20 @@ static Set<String> getSecuritySensitiveHelloCommands() {
142145
return Collections.unmodifiableSet(SECURITY_SENSITIVE_HELLO_COMMANDS);
143146
}
144147

148+
@VisibleForTesting(otherwise = VisibleForTesting.AccessModifier.PRIVATE)
145149
public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMode, final ServerId serverId,
146150
final ConnectionGenerationSupplier connectionGenerationSupplier,
147151
final StreamFactory streamFactory, final List<MongoCompressor> compressorList,
148152
final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer) {
149-
this(clusterConnectionMode, false, serverId, connectionGenerationSupplier, streamFactory, compressorList, commandListener,
150-
connectionInitializer);
153+
this(clusterConnectionMode, false, serverId, connectionGenerationSupplier, streamFactory, compressorList,
154+
LoggerSettings.builder().build(), commandListener, connectionInitializer);
151155
}
152156

153157
public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMode, final boolean isMonitoringConnection,
154158
final ServerId serverId,
155159
final ConnectionGenerationSupplier connectionGenerationSupplier,
156160
final StreamFactory streamFactory, final List<MongoCompressor> compressorList,
161+
final LoggerSettings loggerSettings,
157162
final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer) {
158163
this.clusterConnectionMode = clusterConnectionMode;
159164
this.isMonitoringConnection = isMonitoringConnection;
@@ -162,6 +167,7 @@ public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMod
162167
this.streamFactory = notNull("streamFactory", streamFactory);
163168
this.compressorList = notNull("compressorList", compressorList);
164169
this.compressorMap = createCompressorMap(compressorList);
170+
this.loggerSettings = loggerSettings;
165171
this.commandListener = commandListener;
166172
this.connectionInitializer = notNull("connectionInitializer", connectionInitializer);
167173
description = new ConnectionDescription(serverId);
@@ -854,7 +860,7 @@ private CommandEventSender createCommandEventSender(final CommandMessage message
854860
final RequestContext requestContext) {
855861
if (!isMonitoringConnection && opened() && (commandListener != null || COMMAND_PROTOCOL_LOGGER.isRequired(DEBUG, getClusterId()))) {
856862
return new LoggingCommandEventSender(SECURITY_SENSITIVE_COMMANDS, SECURITY_SENSITIVE_HELLO_COMMANDS, description,
857-
commandListener, requestContext, message, bsonOutput, COMMAND_PROTOCOL_LOGGER);
863+
commandListener, requestContext, message, bsonOutput, COMMAND_PROTOCOL_LOGGER, loggerSettings);
858864
} else {
859865
return new NoOpCommandEventSender();
860866
}

0 commit comments

Comments
 (0)