1. Overview
1.概述
When using Spring Data MongoDB, we may need to log to a higher level than the default one. Typically, we may need to see, for example, some additional information such as statement executions or query parameters.
当使用Spring Data MongoDB时,我们可能需要记录比默认级别更高的日志。通常情况下,我们可能需要看到一些额外的信息,例如语句执行情况或查询参数。
In this short tutorial, we’ll see how to modify the MongoDB logging level for queries.
在这个简短的教程中,我们将看到如何修改MongoDB的查询日志级别。
2. Configure MongoDB Queries Logging
2.配置MongoDB查询日志
MongoDB Support offers the MongoOperations interface or its primary MongoTemplate implementation to access data, so all we need is to configure a debug level for the MongoTemplate class.
MongoDB支持提供MongoOperations接口或其主要MongoTemplate实现来访问数据,因此我们需要的是为MongoTemplate类配置一个调试级别。
Like any Spring or Java application, we can use a logger library and define a logging level for MongoTemplate.
与任何Spring或Java应用程序一样,我们可以使用日志库并为MongoTemplate定义一个日志级别。
Typically, we can write in our configuration file something like:
通常情况下,我们可以在配置文件中写上类似的内容。
<logger name="org.springframework.data.mongodb.core.MongoTemplate" level="DEBUG" />
However, if we’re running a Spring Boot application, we can configure this in our application.properties file:
但是,如果我们运行的是Spring Boot应用程序,我们可以在application.properties文件中对此进行配置。
logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG
Likewise, we can use the YAML syntax:
同样地,我们可以使用YAML语法。
logging:
level:
org:
springframework:
data:
mongodb:
core:
MongoTemplate: DEBUG
3. Test Class for Logging
3.记录的测试类
First, let’s create a Book class:
首先,让我们创建一个Book类。
@Document(collection = "book")
public class Book {
@MongoId
private ObjectId id;
private String bookName;
private String authorName;
// getters and setters
}
We want to create a simple test class and check out logs.
我们想创建一个简单的测试类,并检查出日志。
To demonstrate this, we use Embedded MongoDB. To be sure, let’s check our dependencies first:
为了证明这一点,我们使用Embedded MongoDB。为了确定,让我们先检查一下我们的依赖性。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>${embed.mongo.version}</version>
<scope>test</scope>
</dependency>
Finally, let’s define our test class using Spring Boot Test:
最后,让我们使用Spring Boot Test定义我们的测试类。
@SpringBootTest
@TestPropertySource(properties = { "logging.level.org.springframework.data.mongodb.core.MongoTemplate=DEBUG" })
public class LoggingUnitTest {
private static final String CONNECTION_STRING = "mongodb://%s:%d";
private MongodExecutable mongodExecutable;
private MongoTemplate mongoTemplate;
@AfterEach
void clean() {
mongodExecutable.stop();
}
@BeforeEach
void setup() throws Exception {
String ip = "localhost";
int port = 27017;
ImmutableMongodConfig mongodbConfig = MongodConfig.builder()
.version(Version.Main.PRODUCTION)
.net(new Net(ip, port, Network.localhostIsIPv6()))
.build();
MongodStarter starter = MongodStarter.getDefaultInstance();
mongodExecutable = starter.prepare(mongodbConfig);
mongodExecutable.start();
mongoTemplate = new MongoTemplate(MongoClients.create(String.format(CONNECTION_STRING, ip, port)), "test");
}
// tests
}
4. Log Samples
4.日志样本
In this section, we’ll define some simple test cases and show the relative logs to test the most common scenarios, such as finding, inserting, updating, or aggregating of Documents.
在本节中,我们将定义一些简单的测试用例,并展示相对的日志,以测试最常见的情况,如查找、插入、更新或聚合Documents。
4.1. Insert
4.1. 插入
First, let’s start with inserting a single Document:
首先,让我们从插入一个单一的Document开始。
Book book = new Book();
book.setBookName("Book");
book.setAuthorName("Author");
mongoTemplate.insert(book);
The logs show in which collection we are inserting. When finding a Document, the id is also logged:
日志显示我们是在哪个集合中插入的。当找到一个Document时,ID也被记录下来。
[2022-03-20 17:42:47,093]-[main] DEBUG MongoTemplate - Inserting Document containing fields: [bookName, authorName, _class] in collection: book
...
[2022-03-20 17:42:47,144]-[main] DEBUG MongoTemplate - findOne using query: { "id" : { "$oid" : "623759871ff6275fe96a5ecb"}} fields: Document{{}} for class: class com.baeldung.mongodb.models.Book in collection: book
[2022-03-20 17:42:47,149]-[main] DEBUG MongoTemplate - findOne using query: { "_id" : { "$oid" : "623759871ff6275fe96a5ecb"}} fields: {} in db.collection: test.book
4.2. Update
4.2.更新
Likewise, when updating a Document:
同样地,当更新一个Document时。
Book book = new Book();
book.setBookName("Book");
book.setAuthorName("Author");
mongoTemplate.insert(book);
String authorNameUpdate = "AuthorNameUpdate";
book.setAuthorName(authorNameUpdate);
mongoTemplate.updateFirst(query(where("bookName").is("Book")), update("authorName", authorNameUpdate), Book.class);
We can see the actual updated Document field in the logs:
我们可以在日志中看到实际更新的Document字段。
[2022-03-20 17:48:31,759]-[main] DEBUG MongoTemplate - Calling update using query: { "bookName" : "Book"} and update: { "$set" : { "authorName" : "AuthorNameUpdate"}} in collection: book
4.3. Batch Insert
4.3.批量插入
Let’s add an example for a batch insertion:
让我们增加一个批量插入的例子。
Book book = new Book();
book.setBookName("Book");
book.setAuthorName("Author");
Book book1 = new Book();
book1.setBookName("Book1");
book1.setAuthorName("Author1");
mongoTemplate.insert(Arrays.asList(book, book1), Book.class);
We can see the number of inserted Documents in the logs:
我们可以在日志中看到插入的Documents的数量。
[2022-03-20 17:52:00,564]-[main] DEBUG MongoTemplate - Inserting list of Documents containing 2 items
4.4. Remove
4.4.移除
Also, let’s add an example for removing:
另外,让我们添加一个例子,以便删除。
Book book = new Book();
book.setBookName("Book");
book.setAuthorName("Author");
mongoTemplate.insert(book);
mongoTemplate.remove(book);
We can see in the logs, in this case, the id of the deleted Document:
我们可以在日志中看到,在这种情况下,删除的Document的id。
[2022-03-20 17:56:42,151]-[main] DEBUG MongoTemplate - Remove using query: { "_id" : { "$oid" : "62375cca2a2cba4db774d8c1"}} in collection: book.
4.5. Aggregation
4.5.聚合
Let’s see an example for Aggregation. In this case, we need to define a result class. For example, we’ll aggregate by the author name:
让我们看看Aggregation的一个例子。在这种情况下,我们需要定义一个结果类。例如,我们将按作者姓名进行聚合。
public class GroupByAuthor {
@Id
private String authorName;
private int authCount;
// getters and setters
}
Next, let’s define a test case for grouping:
接下来,让我们定义一个分组的测试案例。
Book book = new Book();
book.setBookName("Book");
book.setAuthorName("Author");
Book book1 = new Book();
book1.setBookName("Book1");
book1.setAuthorName("Author");
Book book2 = new Book();
book2.setBookName("Book2");
book2.setAuthorName("Author");
mongoTemplate.insert(Arrays.asList(book, book1, book2), Book.class);
GroupOperation groupByAuthor = group("authorName")
.count()
.as("authCount");
Aggregation aggregation = newAggregation(groupByAuthor);
AggregationResults<GroupByAuthor> aggregationResults = mongoTemplate.aggregate(aggregation, "book", GroupByAuthor.class);
We can see in the logs by which field we have aggregated and what kind of aggregation pipeline:
我们可以在日志中看到,我们通过哪个字段进行了聚合,以及什么样的聚合管道。
[2022-03-20 17:58:51,237]-[main] DEBUG MongoTemplate - Executing aggregation: [{ "$group" : { "_id" : "$authorName", "authCount" : { "$sum" : 1}}}] in collection book
5. Conclusion
5.总结
In this article, we looked at how to enable a debug logging level for Spring Data MongoDB.
在这篇文章中,我们研究了如何为Spring Data MongoDB启用调试日志级别。
We’ve defined some common query scenarios and looked at their relative logs while doing some live tests.
我们已经定义了一些常见的查询场景,并在做一些现场测试时查看了它们的相对日志。
As always, the code for these examples is available over on GitHub.
一如既往,这些示例的代码可在GitHub上获得。