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

Support configuration of max document length for command logging #1072

Merged
merged 3 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 146 additions & 0 deletions driver-core/src/main/com/mongodb/LoggerSettings.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* Copyright 2008-present MongoDB, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.mongodb;

import com.mongodb.annotations.Immutable;

import java.util.Objects;

import static com.mongodb.assertions.Assertions.notNull;

/**
* An immutable class representing settings for logging.
*
* <p>
* The driver logs using the SLF4J 1.0 API with a root logger of {@code org.mongodb.driver}. See
* <a href="https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/logging">Logging Fundamentals</a>
* for additional information.
* </p>
*
* @since 4.9
*/
@Immutable
public final class LoggerSettings {
private final int maxDocumentLength;
/**
* Gets a builder for an instance of {@code LoggerSettings}.
* @return the builder
*/
public static Builder builder() {
return new Builder();
}

/**
* Creates a builder instance.
*
* @param loggerSettings existing LoggerSettings to default the builder settings on.
* @return a builder
*/
public static Builder builder(final LoggerSettings loggerSettings) {
return builder().applySettings(loggerSettings);
}

/**
* A builder for an instance of {@code LoggerSettings}.
*/
public static final class Builder {
private int maxDocumentLength = 1000;
private Builder() {
}

/**
* Applies the loggerSettings to the builder
*
* <p>Note: Overwrites all existing settings</p>
*
* @param loggerSettings the loggerSettings
* @return this
*/
public Builder applySettings(final LoggerSettings loggerSettings) {
notNull("loggerSettings", loggerSettings);
maxDocumentLength = loggerSettings.maxDocumentLength;
return this;
}

/**
* Sets the max document length.
*
* @param maxDocumentLength the max document length
* @return this
* @see #getMaxDocumentLength()
*/
public Builder maxDocumentLength(final int maxDocumentLength) {
this.maxDocumentLength = maxDocumentLength;
return this;
}

/**
* Build an instance of {@code LoggerSettings}.
* @return the logger settings for this builder
*/
public LoggerSettings build() {
return new LoggerSettings(this);
}
}

/**
* Gets the max length of the extended JSON representation of a BSON document within a log message.
*
* <p>
* For example, when the driver logs a command or its reply via the {@code org.mongodb.driver.protocol.command} SFL4J logger, it
* truncates its JSON representation to the maximum length defined by this setting.
* </p>
*
* <p>
* Defaults to 1000 characters.
* </p>
*
* @return the max document length
*/
public int getMaxDocumentLength() {
return maxDocumentLength;
}


@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LoggerSettings that = (LoggerSettings) o;
return maxDocumentLength == that.maxDocumentLength;
}

@Override
public int hashCode() {
return Objects.hash(maxDocumentLength);
}

@Override
public String toString() {
return "LoggerSettings{"
+ "maxDocumentLength=" + maxDocumentLength
+ '}';
}

private LoggerSettings(final Builder builder) {
maxDocumentLength = builder.maxDocumentLength;
}
}
36 changes: 32 additions & 4 deletions driver-core/src/main/com/mongodb/MongoClientSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public final class MongoClientSettings {
private final StreamFactoryFactory streamFactoryFactory;
private final List<CommandListener> commandListeners;
private final CodecRegistry codecRegistry;

private final LoggerSettings loggerSettings;
private final ClusterSettings clusterSettings;
private final SocketSettings socketSettings;
private final SocketSettings heartbeatSocketSettings;
Expand Down Expand Up @@ -170,6 +170,7 @@ public static final class Builder {
private StreamFactoryFactory streamFactoryFactory;
private List<CommandListener> commandListeners = new ArrayList<>();

private final LoggerSettings.Builder loggerSettingsBuilder = LoggerSettings.builder();
private final ClusterSettings.Builder clusterSettingsBuilder = ClusterSettings.builder();
private final SocketSettings.Builder socketSettingsBuilder = SocketSettings.builder();
private final ConnectionPoolSettings.Builder connectionPoolSettingsBuilder = ConnectionPoolSettings.builder();
Expand Down Expand Up @@ -208,6 +209,7 @@ private Builder(final MongoClientSettings settings) {
streamFactoryFactory = settings.getStreamFactoryFactory();
autoEncryptionSettings = settings.getAutoEncryptionSettings();
contextProvider = settings.getContextProvider();
loggerSettingsBuilder.applySettings(settings.getLoggerSettings());
clusterSettingsBuilder.applySettings(settings.getClusterSettings());
serverSettingsBuilder.applySettings(settings.getServerSettings());
socketSettingsBuilder.applySettings(settings.getSocketSettings());
Expand Down Expand Up @@ -263,6 +265,19 @@ public Builder applyConnectionString(final ConnectionString connectionString) {
return this;
}

/**
* Applies the {@link LoggerSettings.Builder} block and then sets the loggerSettings.
*
* @param block the block to apply to the LoggerSettins.
* @return this
* @see MongoClientSettings#getLoggerSettings()
* @since 4.9
*/
public Builder applyToLoggerSettings(final Block<LoggerSettings.Builder> block) {
notNull("block", block).apply(loggerSettingsBuilder);
return this;
}

/**
* Applies the {@link ClusterSettings.Builder} block and then sets the clusterSettings.
*
Expand Down Expand Up @@ -769,6 +784,16 @@ public AutoEncryptionSettings getAutoEncryptionSettings() {
return autoEncryptionSettings;
}

/**
* Gets the logger settings.
*
* @return the logger settings
* @since 4.9
*/
public LoggerSettings getLoggerSettings() {
return loggerSettings;
}

/**
* Gets the cluster settings.
*
Expand Down Expand Up @@ -863,6 +888,7 @@ public boolean equals(final Object o) {
&& Objects.equals(streamFactoryFactory, that.streamFactoryFactory)
&& Objects.equals(commandListeners, that.commandListeners)
&& Objects.equals(codecRegistry, that.codecRegistry)
&& Objects.equals(loggerSettings, that.loggerSettings)
&& Objects.equals(clusterSettings, that.clusterSettings)
&& Objects.equals(socketSettings, that.socketSettings)
&& Objects.equals(heartbeatSocketSettings, that.heartbeatSocketSettings)
Expand All @@ -880,9 +906,9 @@ public boolean equals(final Object o) {
@Override
public int hashCode() {
return Objects.hash(readPreference, writeConcern, retryWrites, retryReads, readConcern, credential, streamFactoryFactory,
commandListeners, codecRegistry, clusterSettings, socketSettings, heartbeatSocketSettings, connectionPoolSettings,
serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi, autoEncryptionSettings,
heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, contextProvider);
commandListeners, codecRegistry, loggerSettings, clusterSettings, socketSettings, heartbeatSocketSettings,
connectionPoolSettings, serverSettings, sslSettings, applicationName, compressorList, uuidRepresentation, serverApi,
autoEncryptionSettings, heartbeatSocketTimeoutSetExplicitly, heartbeatConnectTimeoutSetExplicitly, contextProvider);
}

@Override
Expand All @@ -897,6 +923,7 @@ public String toString() {
+ ", streamFactoryFactory=" + streamFactoryFactory
+ ", commandListeners=" + commandListeners
+ ", codecRegistry=" + codecRegistry
+ ", loggerSettings=" + loggerSettings
+ ", clusterSettings=" + clusterSettings
+ ", socketSettings=" + socketSettings
+ ", heartbeatSocketSettings=" + heartbeatSocketSettings
Expand All @@ -923,6 +950,7 @@ private MongoClientSettings(final Builder builder) {
codecRegistry = builder.codecRegistry;
commandListeners = builder.commandListeners;
applicationName = builder.applicationName;
loggerSettings = builder.loggerSettingsBuilder.build();
clusterSettings = builder.clusterSettingsBuilder.build();
serverSettings = builder.serverSettingsBuilder.build();
socketSettings = builder.socketSettingsBuilder.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.mongodb.internal.connection;

import com.mongodb.LoggerSettings;
import com.mongodb.MongoCompressor;
import com.mongodb.MongoCredential;
import com.mongodb.MongoDriverInformation;
Expand Down Expand Up @@ -54,6 +55,7 @@ public Cluster createCluster(final ClusterSettings originalClusterSettings, fina
final InternalConnectionPoolSettings internalConnectionPoolSettings,
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
@Nullable final MongoCredential credential,
final LoggerSettings loggerSettings,
@Nullable final CommandListener commandListener,
@Nullable final String applicationName,
@Nullable final MongoDriverInformation mongoDriverInformation,
Expand Down Expand Up @@ -89,14 +91,14 @@ public Cluster createCluster(final ClusterSettings originalClusterSettings, fina

if (clusterSettings.getMode() == ClusterConnectionMode.LOAD_BALANCED) {
ClusterableServerFactory serverFactory = new LoadBalancedClusterableServerFactory(serverSettings,
connectionPoolSettings, internalConnectionPoolSettings, streamFactory, credential, commandListener, applicationName,
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(), compressorList,
serverApi);
connectionPoolSettings, internalConnectionPoolSettings, streamFactory, credential, loggerSettings, commandListener,
applicationName, mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(),
compressorList, serverApi);
return new LoadBalancedCluster(clusterId, clusterSettings, serverFactory, dnsSrvRecordMonitorFactory);
} else {
ClusterableServerFactory serverFactory = new DefaultClusterableServerFactory(serverSettings,
connectionPoolSettings, internalConnectionPoolSettings,
streamFactory, heartbeatStreamFactory, credential, commandListener, applicationName,
streamFactory, heartbeatStreamFactory, credential, loggerSettings, commandListener, applicationName,
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build(), compressorList,
serverApi);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.mongodb.internal.connection;

import com.mongodb.LoggerSettings;
import com.mongodb.MongoCompressor;
import com.mongodb.MongoCredential;
import com.mongodb.MongoDriverInformation;
Expand Down Expand Up @@ -46,6 +47,7 @@ public class DefaultClusterableServerFactory implements ClusterableServerFactory
private final StreamFactory streamFactory;
private final MongoCredentialWithCache credential;
private final StreamFactory heartbeatStreamFactory;
private final LoggerSettings loggerSettings;
private final CommandListener commandListener;
private final String applicationName;
private final MongoDriverInformation mongoDriverInformation;
Expand All @@ -57,7 +59,9 @@ public DefaultClusterableServerFactory(
final ServerSettings serverSettings, final ConnectionPoolSettings connectionPoolSettings,
final InternalConnectionPoolSettings internalConnectionPoolSettings,
final StreamFactory streamFactory, final StreamFactory heartbeatStreamFactory,
@Nullable final MongoCredential credential, @Nullable final CommandListener commandListener,
@Nullable final MongoCredential credential,
final LoggerSettings loggerSettings,
@Nullable final CommandListener commandListener,
@Nullable final String applicationName, @Nullable final MongoDriverInformation mongoDriverInformation,
final List<MongoCompressor> compressorList, @Nullable final ServerApi serverApi) {
this.serverSettings = serverSettings;
Expand All @@ -66,6 +70,7 @@ public DefaultClusterableServerFactory(
this.streamFactory = streamFactory;
this.credential = credential == null ? null : new MongoCredentialWithCache(credential);
this.heartbeatStreamFactory = heartbeatStreamFactory;
this.loggerSettings = loggerSettings;
this.commandListener = commandListener;
this.applicationName = applicationName;
this.mongoDriverInformation = mongoDriverInformation;
Expand All @@ -81,11 +86,11 @@ public ClusterableServer create(final Cluster cluster, final ServerAddress serve
ServerMonitor serverMonitor = new DefaultServerMonitor(serverId, serverSettings, cluster.getClock(),
// no credentials, compressor list, or command listener for the server monitor factory
new InternalStreamConnectionFactory(clusterMode, true, heartbeatStreamFactory, null, applicationName,
mongoDriverInformation, emptyList(), null, serverApi),
mongoDriverInformation, emptyList(), loggerSettings, null, serverApi),
clusterMode, serverApi, sdamProvider);
ConnectionPool connectionPool = new DefaultConnectionPool(serverId,
new InternalStreamConnectionFactory(clusterMode, streamFactory, credential, applicationName,
mongoDriverInformation, compressorList, commandListener, serverApi),
mongoDriverInformation, compressorList, loggerSettings, commandListener, serverApi),
connectionPoolSettings, internalConnectionPoolSettings, sdamProvider);
ServerListener serverListener = singleServerListener(serverSettings);
SdamServerDescriptionManager sdam = new DefaultSdamServerDescriptionManager(cluster, serverId, serverListener, serverMonitor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.mongodb.internal.connection;

import com.mongodb.LoggerSettings;
import com.mongodb.MongoClientException;
import com.mongodb.MongoCompressor;
import com.mongodb.MongoException;
Expand All @@ -40,6 +41,7 @@
import com.mongodb.connection.Stream;
import com.mongodb.connection.StreamFactory;
import com.mongodb.event.CommandListener;
import com.mongodb.internal.VisibleForTesting;
import com.mongodb.internal.async.SingleResultCallback;
import com.mongodb.internal.diagnostics.logging.Logger;
import com.mongodb.internal.diagnostics.logging.Loggers;
Expand Down Expand Up @@ -125,6 +127,7 @@ public class InternalStreamConnection implements InternalConnection {
private final AtomicBoolean opened = new AtomicBoolean();

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

@VisibleForTesting(otherwise = VisibleForTesting.AccessModifier.PRIVATE)
public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMode, final ServerId serverId,
final ConnectionGenerationSupplier connectionGenerationSupplier,
final StreamFactory streamFactory, final List<MongoCompressor> compressorList,
final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer) {
this(clusterConnectionMode, false, serverId, connectionGenerationSupplier, streamFactory, compressorList, commandListener,
connectionInitializer);
this(clusterConnectionMode, false, serverId, connectionGenerationSupplier, streamFactory, compressorList,
LoggerSettings.builder().build(), commandListener, connectionInitializer);
}

public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMode, final boolean isMonitoringConnection,
final ServerId serverId,
final ConnectionGenerationSupplier connectionGenerationSupplier,
final StreamFactory streamFactory, final List<MongoCompressor> compressorList,
final LoggerSettings loggerSettings,
final CommandListener commandListener, final InternalConnectionInitializer connectionInitializer) {
this.clusterConnectionMode = clusterConnectionMode;
this.isMonitoringConnection = isMonitoringConnection;
Expand All @@ -162,6 +167,7 @@ public InternalStreamConnection(final ClusterConnectionMode clusterConnectionMod
this.streamFactory = notNull("streamFactory", streamFactory);
this.compressorList = notNull("compressorList", compressorList);
this.compressorMap = createCompressorMap(compressorList);
this.loggerSettings = loggerSettings;
this.commandListener = commandListener;
this.connectionInitializer = notNull("connectionInitializer", connectionInitializer);
description = new ConnectionDescription(serverId);
Expand Down Expand Up @@ -854,7 +860,7 @@ private CommandEventSender createCommandEventSender(final CommandMessage message
final RequestContext requestContext) {
if (!isMonitoringConnection && opened() && (commandListener != null || COMMAND_PROTOCOL_LOGGER.isRequired(DEBUG, getClusterId()))) {
return new LoggingCommandEventSender(SECURITY_SENSITIVE_COMMANDS, SECURITY_SENSITIVE_HELLO_COMMANDS, description,
commandListener, requestContext, message, bsonOutput, COMMAND_PROTOCOL_LOGGER);
commandListener, requestContext, message, bsonOutput, COMMAND_PROTOCOL_LOGGER, loggerSettings);
} else {
return new NoOpCommandEventSender();
}
Expand Down
Loading