Skip to content

Commit f77d9e4

Browse files
committed
DOC-11688 Update logging docs
Motivation ---------- It's all about SLF4J now! Modifications ------------- Rewrote most of the "Logging" section to reflect how SDK 3.5 does logging. Updated the Log4j examples to use Log4j 2. Removed Logback examples. Logback is compatible, but we don't need to document how to configure _every_ SLF4J binding. Added a section about using the SLF4J binding for java.util.logging (JUL), since this is a migration path for people who were not previously using SLF4J. Removed the section on the SDK's logger config, since those settings are deprecated in favor of configuring everything via the SLF4J binding. Reformatted the code example for configuring java.util.logging (JUL) log level.
1 parent 715ce6c commit f77d9e4

2 files changed

Lines changed: 142 additions & 92 deletions

File tree

modules/howtos/examples/CollectingInformationAndLogging.java

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,19 @@ private void init(){
5151
collection = scope.collection("airport");
5252
// end::connection_1[]
5353
}
54+
5455
public void collecting_information_and_logging_1() throws Exception { // file: howtos/pages/collecting-information-and-logging.adoc line: 114
5556
// tag::collecting_information_and_logging_1[]
5657
Logger logger = Logger.getLogger("com.couchbase.client");
5758
logger.setLevel(Level.FINE);
58-
for(Handler h : logger.getParent().getHandlers()) {
59-
if(h instanceof ConsoleHandler){
60-
h.setLevel(Level.FINE);
61-
}
59+
for (Handler h : logger.getParent().getHandlers()) {
60+
if (h instanceof ConsoleHandler) {
61+
h.setLevel(Level.FINE);
62+
}
6263
}
6364
// end::collecting_information_and_logging_1[]
6465
}
6566

66-
public void collecting_information_and_logging_2() throws Exception { // file: howtos/pages/collecting-information-and-logging.adoc line: 131
67-
// tag::collecting_information_and_logging_2[]
68-
ClusterEnvironment environment = ClusterEnvironment
69-
.builder()
70-
.loggerConfig(LoggerConfig
71-
.fallbackToConsole(true)
72-
.disableSlf4J(true)
73-
)
74-
.build();
75-
// end::collecting_information_and_logging_2[]
76-
}
77-
7867
public void collecting_information_and_logging_3() throws Exception { // file: howtos/pages/collecting-information-and-logging.adoc line: 163
7968
// tag::collecting_information_and_logging_3[]
8069
ClusterEnvironment environment = ClusterEnvironment.builder().build();
@@ -105,7 +94,6 @@ public static void main(String[] args) throws Exception{
10594
CollectingInformationAndLogging obj = new CollectingInformationAndLogging();
10695
obj.init();
10796
obj.collecting_information_and_logging_1();
108-
obj.collecting_information_and_logging_2();
10997
obj.collecting_information_and_logging_3();
11098
obj.collecting_information_and_logging_4();
11199
System.out.println("Done.");

modules/howtos/pages/collecting-information-and-logging.adoc

Lines changed: 137 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,126 +7,188 @@
77
{description}
88

99

10-
The Java SDK logs events and also provides an event bus that transmits information about the behavior of your database system, including system and metric events.
11-
It has no hard dependency on a specific logger implementation, but you should add one you are comfortable with.
10+
The Couchbase Java SDK logs events and also provides an event bus that transmits information about the behavior of your database system, including system and metric events.
1211

1312
== Logging
1413

15-
The Couchbase Java SDK has no hard dependency on a specific logger implementation.
16-
It tries to find a logger on the class path and uses that logger if it is supported by the SDK.
17-
If no logger implementation is found, the standard JDK logger is used.
14+
The Couchbase Java SDK uses https://www.slf4j.org[SLF4J], a logging facade that lets you use any logging framework that has an SLF4J binding.
15+
This includes popular Java logging frameworks like Log4j, Logback, and `java.util.logging` (JUL).
1816

19-
The following loggers are supported (and tried in this order):
17+
To see log messages from the Couchbase SDK, add an SLF4J binding as a dependency of your project.
2018

21-
. SLF4J
22-
. JDK Logger (java.util.logging)
23-
24-
*Configuring SLF4J*
25-
26-
To enable SLF4J, put it on the class path, as well as one of the support logger implementations (like logback).
27-
If you want to use logback and include logback-classic, it will be pulled in automatically:
19+
[slf4j-api-versions]
20+
.SLF4J API versions
21+
[NOTE]
22+
====
23+
At the time of writing, there are two different versions of the SLF4J API:
2824
29-
[source,xml]
30-
----
31-
<dependency>
32-
<groupId>ch.qos.logback</groupId>
33-
<artifactId>logback-classic</artifactId>
34-
<version>1.2.3</version>
35-
</dependency>
36-
----
25+
*Version 2* is the modern version of SLF4J.
26+
It is actively maintained, and recommended for most users.
3727
38-
By default, the log level for logback is set to DEBUG, but with the addition of a logback configuration this can be configured (for example, as a `logback.xml` in the resources folder):
28+
*Version 1.7* is no longer maintained, but you can still use it if your preferred SLF4J binding does not support version 2.
3929
40-
[source,xml]
41-
----
42-
<configuration>
43-
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
44-
<encoder>
45-
<pattern>%d{"yyyy-MM-dd'T'HH:mm:ss,SSSXXX", UTC} [%thread] %-5level %logger{36} - %msg%n</pattern>
46-
</encoder>
47-
</appender>
30+
The Couchbase SDK is compatible with both versions of the SLF4J API.
31+
The SDK's Maven POM has a dependency on version 1.7, but you can override this by using version 2 in your project.
32+
====
4833

49-
<root level="info">
50-
<appender-ref ref="STDOUT" />
51-
</root>
52-
</configuration>
53-
----
34+
[log4j2]
35+
=== Using Log4j 2
5436

55-
Consult the https://www.slf4j.org/docs.html[SLF4J documentation^] for advanced configuration.
37+
Log4j 2 is a popular and flexible logging framework.
38+
This section shows how to configure your project to use Log4j 2 with the Couchbase SDK.
5639

57-
*Configuring Log4j*
40+
First, add an https://logging.apache.org/log4j/2.x/log4j-slf4j-impl.html[SLF4J binding for Log4j 2] as a dependency of your project.
41+
The following example uses the binding for SLF4J API version 2.
5842

59-
Log4j can also be used behind the SLF4J logging facade.
43+
[{tabs}]
44+
====
45+
Maven::
46+
+
47+
--
48+
Add these as children of the `dependencies` element.
6049
50+
.`*pom.xml*`
6151
[source,xml]
6252
----
6353
<dependency>
64-
<groupId>org.slf4j</groupId>
65-
<artifactId>slf4j-log4j12</artifactId>
66-
<version>1.7.30</version>
54+
<groupId>org.apache.logging.log4j</groupId>
55+
<artifactId>log4j-slf4j2-impl</artifactId>
56+
<version>2.22.0</version>
6757
</dependency>
68-
----
6958
70-
If no configuration is applied, the following message appears:
59+
<!-- If your SLF4J binding requires API version 2
60+
(like log4j-slf4j2-impl in this example!),
61+
add this dependency to your project to ensure
62+
Maven uses the correct SLF4J API version. -->
63+
<dependency>
64+
<groupId>org.slf4j</groupId>
65+
<artifactId>slf4j-api</artifactId>
66+
<version>2.0.9</version>
67+
</dependency>
68+
----
7169
72-
[source]
70+
TIP: An alternate way to ensure Maven uses the correct version of the SLF4J API is to declare the dependency on `log4j-slf4j2-impl` *before* the dependency on the Couchbase SDK.
71+
See the Maven documentation on https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies[Transitive Dependencies] to learn more about how Maven resolves transitive dependency version conflicts.
72+
--
73+
Gradle::
74+
+
75+
--
76+
.`*build.gradle*`
77+
[source,groovy]
7378
----
74-
log4j:WARN No appenders could be found for logger (reactor.util.Loggers$LoggerFactory).
75-
log4j:WARN Please initialize the log4j system properly.
76-
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
79+
// Add this to the `dependencies` section:
80+
implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.22.0")
7781
----
82+
NOTE: Gradle automatically uses the correct SLF4J API 2.x dependency required by `log4j-slf4j2-impl`, even though the Couchbase SDK declares a dependency on SLF4J API 1.7.
83+
--
84+
====
85+
86+
[configuring-log4j]
87+
==== Configuring Log4j 2 output
88+
89+
Log4j 2 needs a configuration file to tell it which messages to log, where to write them, and how each message should be formatted.
7890

79-
Note that the `Reactor` library which the Java SDK depends upon also uses the same strategy with SLF4J, so logging for both can be configured with the same strategies out of the box.
91+
Here's an example `log4j2.xml` configuration file you can use to get started.
92+
It tells Log4j 2 to log messages to the console, and sets some reasonable logging levels.
8093

81-
This `log4j.xml` sets it to INFO level:
94+
TIP: If your project uses the https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html[Maven Standard Directory Layout], this file should live in the `src/main/resources` directory.
95+
This makes it available at runtime as a class path resource.
8296

97+
.src/main/resources/log4j2.xml
8398
[source,xml]
8499
----
85-
<?xml version="1.0" encoding="UTF-8" ?>
86-
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
87-
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
100+
<?xml version="1.0" encoding="UTF-8"?>
101+
<Configuration status="WARN">
102+
<Appenders>
103+
<Console name="Console" target="SYSTEM_OUT">
104+
<PatternLayout pattern="%d{ISO8601_OFFSET_DATE_TIME_HHCMM} %-5p [%c:%L] %m%n"/>
105+
</Console>
106+
</Appenders>
107+
<Loggers>
108+
<!-- Trace/debug/info messages from the Couchbase SDK's repackaged Netty
109+
are of little interest, unless you're debugging a network issue. -->
110+
<Logger name="com.couchbase.client.core.deps.io.netty" level="warn"/>
88111
89-
<appender name="console" class="org.apache.log4j.ConsoleAppender">
90-
<layout class="org.apache.log4j.PatternLayout">
91-
<param name="ConversionPattern"
92-
value="%d{yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ} %-5p %c{1}:%L - %m%n" />
93-
</layout>
94-
</appender>
112+
<!-- Uncomment if using the 'io.captureTraffic' client setting. -->
113+
<!-- <Logger name="com.couchbase.io" level="trace"/> -->
95114
96-
<root>
97-
<level value="INFO" />
98-
<appender-ref ref="console" />
99-
</root>
115+
<!-- Most messages from the Couchbase SDK are logged under
116+
this prefix. Change the level to "debug" to see more
117+
details about SDK activity, or "warn" to see less.
118+
In production environments, we recommend "info". -->
119+
<Logger name="com.couchbase" level="info"/>
100120
101-
</log4j:configuration>
121+
<!-- The default level for everything else. -->
122+
<Root level="info">
123+
<AppenderRef ref="Console"/>
124+
</Root>
125+
</Loggers>
126+
</Configuration>
102127
----
103128

104-
Consult the https://logging.apache.org/log4j/2.x/javadoc.html[Log4J documentation^] for more information and advanced configuration options.
129+
Consult the https://logging.apache.org/log4j/2.x/manual/configuration.html[Log4J 2 configuration documentation^] for more information and advanced configuration options.
105130

106-
== Configuring the JDK Logger
131+
[jul]
132+
=== Using `java.util.logging` (JUL)
107133

108-
If no logging library is found on the class path, the JDK logger (also known as JUL from `java.util.logging`) is used as a fallback.
134+
If `java.util.logging` (JUL) is your preferred logging framework, add the `slf4j-jdk14` SLF4J binding as dependency of your project.
109135

110-
By default it logs INFO level and above.
111-
If you want to set it to DEBUG (or the JUL equivalent: Fine) you can do it like this programmatically before initializing the `Cluster` object (or creating a custom `ClusterEnvironment`):
136+
[{tabs}]
137+
====
138+
Maven::
139+
+
140+
--
141+
Add these as children of the `dependencies` element.
112142
113-
[source,java]
143+
.`*pom.xml*`
144+
[source,xml]
114145
----
115-
include::example$CollectingInformationAndLogging.java[tag=collecting_information_and_logging_1,indent=0]
146+
<dependency>
147+
<groupId>org.slf4j</groupId>
148+
<artifactId>slf4j-jdk14</artifactId>
149+
<version>2.0.9</version>
150+
</dependency>
151+
152+
<!-- If your SLF4J binding requires API version 2
153+
(like slf4j-jdk14 in this example!),
154+
add this dependency to your project to ensure
155+
Maven uses the correct SLF4J API version. -->
156+
<dependency>
157+
<groupId>org.slf4j</groupId>
158+
<artifactId>slf4j-api</artifactId>
159+
<version>2.0.9</version>
160+
</dependency>
116161
----
117162
118-
You should not use JUL in production because SLF4J and Log4J provide better configuration options and performance.
163+
TIP: An alternate way to ensure Maven uses the correct version of the SLF4J API is to declare the dependency on `slf4j-jdk14` *before* the dependency on the Couchbase SDK.
164+
See the Maven documentation on https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies[Transitive Dependencies] to learn more about how Maven resolves transitive dependency version conflicts.
165+
--
166+
Gradle::
167+
+
168+
--
169+
.`*build.gradle*`
170+
[source,groovy]
171+
----
172+
// Add this to your `dependencies` section:
173+
implementation("org.slf4j:slf4j-jdk14:2.0.9")
174+
----
175+
NOTE: Gradle automatically uses the correct SLF4J API 2.x dependency required by `slf4j-jdk14`, even though the Couchbase SDK declares a dependency on SLF4J API 1.7.
176+
--
177+
====
119178

120-
== Customizing the Logger
179+
[configuring-the-jdk-logger]
180+
==== Configuring a JUL Logger
121181

122-
The logger is configured in a way that it should work out of the box for most users, but there might still be occasion where you want to tweak it. The behavior of the logger can be tuned by customizing the `LoggerConfig` on the `ClusterEnvironment`. For example, if you always want to log to `stderr` and ignore SLF4J (even if present on the classpath) and disable JUL you can configure it this way:
182+
By default, JUL logs INFO level and above.
183+
If you want to set it to DEBUG (or the JUL equivalent: Fine) you can do it like this programmatically before initializing the `Cluster` object (or creating a custom `ClusterEnvironment`):
123184

124185
[source,java]
125186
----
126-
include::example$CollectingInformationAndLogging.java[tag=collecting_information_and_logging_2,indent=0]
187+
include::example$CollectingInformationAndLogging.java[tag=collecting_information_and_logging_1,indent=0]
127188
----
128189

129-
You can also use it to enable the http://logback.qos.ch/manual/mdc.html[Mapped Diagnostic Context^].
190+
TIP: We do not recommend using JUL in production.
191+
Dedicated logging frameworks like Log4j 2 and Logback are more configurable, and tend to perform better than JUL.
130192

131193
== The Event Bus
132194

0 commit comments

Comments
 (0)