Skip to content

Commit b9cb96f

Browse files
committed
Support configuration of max document length for command logging
JAVA-4841
1 parent 54a72fe commit b9cb96f

File tree

20 files changed

+294
-47
lines changed

20 files changed

+294
-47
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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 SLF4J 1.0 API with a root logger of {@code org.mongodb.driver}.
30+
* </p>
31+
*
32+
* @since 4.9
33+
*/
34+
@Immutable
35+
public final class LoggerSettings {
36+
private final int maxCommandLoggingDocumentLength;
37+
/**
38+
* Gets a builder for an instance of {@code LoggerSettings}.
39+
* @return the builder
40+
*/
41+
public static Builder builder() {
42+
return new Builder();
43+
}
44+
45+
/**
46+
* Creates a builder instance.
47+
*
48+
* @param loggerSettings existing LoggerSettings to default the builder settings on.
49+
* @return a builder
50+
*/
51+
public static Builder builder(final LoggerSettings loggerSettings) {
52+
return builder().applySettings(loggerSettings);
53+
}
54+
55+
/**
56+
* A builder for an instance of {@code LoggerSettings}.
57+
*/
58+
public static final class Builder {
59+
private int maxCommandLoggingDocumentLength = 1000;
60+
private Builder() {
61+
}
62+
63+
/**
64+
* Applies the loggerSettings to the builder
65+
*
66+
* <p>Note: Overwrites all existing settings</p>
67+
*
68+
* @param loggerSettings the loggerSettings
69+
* @return this
70+
*/
71+
public Builder applySettings(final LoggerSettings loggerSettings) {
72+
notNull("loggerSettings", loggerSettings);
73+
maxCommandLoggingDocumentLength = loggerSettings.maxCommandLoggingDocumentLength;
74+
return this;
75+
}
76+
77+
/**
78+
* Sets the max command logging document length.
79+
*
80+
* @param maxCommandLoggingDocumentLength the max command logging document length
81+
* @return this
82+
*/
83+
public Builder maxCommandLoggingDocumentLength(final int maxCommandLoggingDocumentLength) {
84+
this.maxCommandLoggingDocumentLength = maxCommandLoggingDocumentLength;
85+
return this;
86+
}
87+
88+
/**
89+
* Build an instance of {@code LoggerSettings}.
90+
* @return the logger settings for this builder
91+
*/
92+
public LoggerSettings build() {
93+
return new LoggerSettings(this);
94+
}
95+
}
96+
97+
/**
98+
* Gets the max command logging document length.
99+
*
100+
* <p>
101+
* When the driver logs a command and its reply via the {@code org.mongodb.driver.protocol.command} SFL4J logger, it truncates the
102+
* them to the maximum length defined by this setting.
103+
* </p>
104+
*
105+
* <p>
106+
* Defaults to 1000 characters.
107+
* </p>
108+
*
109+
* @return the max command logging document length
110+
*/
111+
public int getMaxCommandLoggingDocumentLength() {
112+
return maxCommandLoggingDocumentLength;
113+
}
114+
115+
116+
@Override
117+
public boolean equals(final Object o) {
118+
if (this == o) {
119+
return true;
120+
}
121+
if (o == null || getClass() != o.getClass()) {
122+
return false;
123+
}
124+
LoggerSettings that = (LoggerSettings) o;
125+
return maxCommandLoggingDocumentLength == that.maxCommandLoggingDocumentLength;
126+
}
127+
128+
@Override
129+
public int hashCode() {
130+
return Objects.hash(maxCommandLoggingDocumentLength);
131+
}
132+
133+
@Override
134+
public String toString() {
135+
return "LoggerSettings{"
136+
+ "maxCommandLoggingDocumentLength=" + maxCommandLoggingDocumentLength
137+
+ '}';
138+
}
139+
140+
private LoggerSettings(final Builder builder) {
141+
maxCommandLoggingDocumentLength = builder.maxCommandLoggingDocumentLength;
142+
}
143+
}

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public final class MongoClientSettings {
8787
private final StreamFactoryFactory streamFactoryFactory;
8888
private final List<CommandListener> commandListeners;
8989
private final CodecRegistry codecRegistry;
90-
90+
private final LoggerSettings loggerSettings;
9191
private final ClusterSettings clusterSettings;
9292
private final SocketSettings socketSettings;
9393
private final SocketSettings heartbeatSocketSettings;
@@ -170,6 +170,7 @@ public static final class Builder {
170170
private StreamFactoryFactory streamFactoryFactory;
171171
private List<CommandListener> commandListeners = new ArrayList<>();
172172

173+
private final LoggerSettings.Builder loggerSettingsBuilder = LoggerSettings.builder();
173174
private final ClusterSettings.Builder clusterSettingsBuilder = ClusterSettings.builder();
174175
private final SocketSettings.Builder socketSettingsBuilder = SocketSettings.builder();
175176
private final ConnectionPoolSettings.Builder connectionPoolSettingsBuilder = ConnectionPoolSettings.builder();
@@ -208,6 +209,7 @@ private Builder(final MongoClientSettings settings) {
208209
streamFactoryFactory = settings.getStreamFactoryFactory();
209210
autoEncryptionSettings = settings.getAutoEncryptionSettings();
210211
contextProvider = settings.getContextProvider();
212+
loggerSettingsBuilder.applySettings(settings.getLoggerSettings());
211213
clusterSettingsBuilder.applySettings(settings.getClusterSettings());
212214
serverSettingsBuilder.applySettings(settings.getServerSettings());
213215
socketSettingsBuilder.applySettings(settings.getSocketSettings());
@@ -263,6 +265,19 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
263265
return this;
264266
}
265267

268+
/**
269+
* Applies the {@link LoggerSettings.Builder} block and then sets the loggerSettings.
270+
*
271+
* @param block the block to apply to the LoggerSettins.
272+
* @return this
273+
* @see MongoClientSettings#getLoggerSettings()
274+
* @since 4.9
275+
*/
276+
public Builder applyToLoggerSettings(final Block<LoggerSettings.Builder> block) {
277+
notNull("block", block).apply(loggerSettingsBuilder);
278+
return this;
279+
}
280+
266281
/**
267282
* Applies the {@link ClusterSettings.Builder} block and then sets the clusterSettings.
268283
*
@@ -769,6 +784,16 @@ public AutoEncryptionSettings getAutoEncryptionSettings() {
769784
return autoEncryptionSettings;
770785
}
771786

787+
/**
788+
* Gets the logger settings.
789+
*
790+
* @return the logger settings
791+
* @since 4.9
792+
*/
793+
public LoggerSettings getLoggerSettings() {
794+
return loggerSettings;
795+
}
796+
772797
/**
773798
* Gets the cluster settings.
774799
*
@@ -863,6 +888,7 @@ public boolean equals(final Object o) {
863888
&& Objects.equals(streamFactoryFactory, that.streamFactoryFactory)
864889
&& Objects.equals(commandListeners, that.commandListeners)
865890
&& Objects.equals(codecRegistry, that.codecRegistry)
891+
&& Objects.equals(loggerSettings, that.loggerSettings)
866892
&& Objects.equals(clusterSettings, that.clusterSettings)
867893
&& Objects.equals(socketSettings, that.socketSettings)
868894
&& Objects.equals(heartbeatSocketSettings, that.heartbeatSocketSettings)
@@ -880,9 +906,9 @@ public boolean equals(final Object o) {
880906
@Override
881907
public int hashCode() {
882908
return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, readConcern, credential, streamFactoryFactory,
883-
commandListeners, codecRegistry, clusterSettings, socketSettings, heartbeatSocketSettings, connectionPoolSettings,
884-
serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi, autoEncryptionSettings,
885-
heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, contextProvider);
909+
commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings, heartbeatSocketSettings,
910+
connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi,
911+
autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, contextProvider);
886912
}
887913

888914
@Override
@@ -897,6 +923,7 @@ public String toString() {
897923
+ ", streamFactoryFactory=" + streamFactoryFactory
898924
+ ", commandListeners=" + commandListeners
899925
+ ", codecRegistry=" + codecRegistry
926+
+ ", loggerSettings=" + loggerSettings
900927
+ ", clusterSettings=" + clusterSettings
901928
+ ", socketSettings=" + socketSettings
902929
+ ", heartbeatSocketSettings=" + heartbeatSocketSettings
@@ -923,6 +950,7 @@ private MongoClientSettings(final Builder builder) {
923950
codecRegistry = builder.codecRegistry;
924951
commandListeners = builder.commandListeners;
925952
applicationName = builder.applicationName;
953+
loggerSettings = builder.loggerSettingsBuilder.build();
926954
clusterSettings = builder.clusterSettingsBuilder.build();
927955
serverSettings = builder.serverSettingsBuilder.build();
928956
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)