Skip to content

Commit 1ce6f9b

Browse files
committed
Fix a broken link and externalize example
1 parent d659fd2 commit 1ce6f9b

File tree

7 files changed

+168
-115
lines changed

7 files changed

+168
-115
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.example;
18+
19+
import org.apache.logging.log4j.LogManager;
20+
import org.apache.logging.log4j.Logger;
21+
import org.apache.logging.log4j.message.ParameterizedMessage;
22+
import org.apache.logging.log4j.message.SimpleMessage;
23+
import org.apache.logging.log4j.message.StringMapMessage;
24+
25+
// tag::class[]
26+
public class LoggerNameTest {
27+
28+
Logger logger1 = LogManager.getLogger(LoggerNameTest.class);
29+
30+
Logger logger2 = LogManager.getLogger(LoggerNameTest.class.getName());
31+
32+
Logger logger3 = LogManager.getLogger();
33+
// tag::examples[]
34+
35+
private static final Logger LOGGER = LogManager.getLogger();
36+
37+
static void logExamples() {
38+
// tag::example1[]
39+
LOGGER.info("Hello, {}!", name);
40+
// end::example1[]
41+
// tag::example2[]
42+
LOGGER.log(Level.INFO, messageFactory.createMessage("Hello, {}!", new Object[] {name}));
43+
// end::example2[]
44+
// tag::example3[]
45+
LogManager.getLogger() // <1>
46+
.info("Hello, {}!", name); // <2>
47+
48+
LogManager.getLogger(StringFormatterMessageFactory.INSTANCE) // <3>
49+
.info("Hello, %s!", name); // <4>
50+
// end::example3[]
51+
// tag::formatter[]
52+
Logger logger = LogManager.getFormatterLogger();
53+
logger.debug("Logging in user %s with birthday %s", user.getName(), user.getBirthdayCalendar());
54+
logger.debug(
55+
"Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
56+
logger.debug("Integer.MAX_VALUE = %,d", Integer.MAX_VALUE);
57+
logger.debug("Long.MAX_VALUE = %,d", Long.MAX_VALUE);
58+
// end::formatter[]
59+
// tag::printf[]
60+
Logger logger = LogManager.getLogger("Foo");
61+
logger.debug("Opening connection to {}...", someDataSource);
62+
logger.printf(Level.INFO, "Hello, %s!", userName);
63+
// end::printf[]
64+
// tag::fluent[]
65+
LOGGER.atInfo()
66+
.withMarker(marker)
67+
.withLocation()
68+
.withThrowable(exception)
69+
.log("Login for user `{}` failed", userId);
70+
// end::fluent[]
71+
// tag::string[]
72+
LOGGER.info("foo");
73+
LOGGER.info(new SimpleMessage("foo"));
74+
// end::string[]
75+
// tag::parameterized[]
76+
LOGGER.info("foo {} {}", "bar", "baz");
77+
LOGGER.info(new ParameterizedMessage("foo {} {}", new Object[] {"bar", "baz"}));
78+
// end::parameterized[]
79+
// tag::map[]
80+
LOGGER.info(new StringMapMessage().with("key1", "val1").with("key2", "val2"));
81+
// end::map[]
82+
}
83+
84+
static void contextMap() {
85+
// tag::thread-context1[]
86+
ThreadContext.put("ipAddress", request.getRemoteAddr()); // <1>
87+
ThreadContext.put("hostName", request.getServerName()); // <1>
88+
ThreadContext.put("loginId", session.getAttribute("loginId")); // <1>
89+
// end::thread-context1[]
90+
}
91+
92+
// tag::thread-context2[]
93+
void performWork() {
94+
ThreadContext.push("performWork()"); // <2>
95+
96+
LOGGER.debug("Performing work"); // <3>
97+
// Perform the work
98+
99+
ThreadContext.pop(); // <4>
100+
}
101+
// end::thread-context2[]
102+
103+
static void clean() {
104+
// tag::thread-context3[]
105+
ThreadContext.clear(); // <5>
106+
// end::thread-context3[]
107+
}
108+
// end::examples[]
109+
}
110+
// end::class[]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to you under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.example;
18+
19+
import org.apache.logging.log4j.LogManager;
20+
import org.apache.logging.log4j.Logger;
21+
import org.apache.logging.log4j.Marker;
22+
import org.apache.logging.log4j.MarkerManager;
23+
24+
// tag::class[]
25+
public class MyApp {
26+
27+
private static final Logger LOGGER = LogManager.getLogger();
28+
29+
private static final Marker ACCOUNT_MARKER = MarkerManager.getMarker("ACCOUNT");
30+
31+
public void removeUser(String userId) {
32+
logger.debug(ACCOUNT_MARKER, "Removing user with ID `{}`", userId);
33+
// ...
34+
}
35+
}
36+
// end::class[]

src/site/antora/modules/ROOT/pages/manual/api.adoc

Lines changed: 18 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -103,21 +103,11 @@ For example, `org.apache.logging.appender` and `org.apache.logging.filter` both
103103
104104
In most cases, applications name their loggers by passing the current class's name to `LogManager.getLogger(...)`.
105105
Because this usage is so common, Log4j provides that as the default when the logger name parameter is either omitted or is null.
106-
For example, all `Logger`-typed variables below will have a name of `com.mycompany.LoggerNameTest`:
106+
For example, all `Logger`-typed variables below will have a name of `com.example.LoggerNameTest`:
107107
108108
[source,java]
109109
----
110-
package com.mycompany;
111-
112-
public class LoggerNameTest {
113-
114-
Logger logger1 = LogManager.getLogger(LoggerNameTest.class);
115-
116-
Logger logger2 = LogManager.getLogger(LoggerNameTest.class.getName());
117-
118-
Logger logger3 = LogManager.getLogger();
119-
120-
}
110+
include::example$manual/api/LoggerNameTest.java[tags=class;!examples]
121111
----
122112
123113
[TIP]
@@ -132,29 +122,24 @@ Loggers translate
132122
133123
[source,java]
134124
----
135-
LOGGER.info("Hello, {}!", name)
125+
include::example$manual/api/LoggerNameTest.java[tag=example1,indent=0]
136126
----
137127
138128
calls to the appropriate canonical logging method:
139129
140130
[source,java]
141131
----
142-
LOGGER.log(Level.INFO, messageFactory.createMessage("Hello, {}!", new Object[]{name}));
132+
include::example$manual/api/LoggerNameTest.java[tag=example2,indent=0]
143133
----
144134
145135
Note that how `Hello, {}!` should be encoded given the `\{name}` array as argument completely depends on the link:../javadoc/log4j-api/org/apache/logging/log4j/message/MessageFactory.html[`MessageFactory`] employed.
146136
Log4j allows users to customize this behaviour in several `getLogger()` methods of link:../javadoc/log4j-api/org/apache/logging/log4j/LogManager.html[`LogManager`]:
147137
148138
[source,java]
149139
----
150-
LogManager
151-
.getLogger() // <1>
152-
.info("Hello, {}!", name); // <2>
153-
154-
LogManager
155-
.getLogger(StringFormatterMessageFactory.INSTANCE) // <3>
156-
.info("Hello, %s!", name); // <4>
140+
include::example$manual/api/LoggerNameTest.java[tag=example3,indent=0]
157141
----
142+
158143
<1> Create a logger using the default message factory
159144
<2> Use default parameter placeholders, that is, `{}` style
160145
<3> Explicitly provide the message factory, that is, link:../javadoc/log4j-api/org/apache/logging/log4j/message/StringFormatterMessageFactory.html[`StringFormatterMessageFactory`].
@@ -173,11 +158,7 @@ If you need more control over how the parameters are formatted, you can also use
173158
174159
[source,java]
175160
----
176-
Logger logger = LogManager.getFormatterLogger();
177-
logger.debug("Logging in user %s with birthday %s", user.getName(), user.getBirthdayCalendar());
178-
logger.debug("Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
179-
logger.debug("Integer.MAX_VALUE = %,d", Integer.MAX_VALUE);
180-
logger.debug("Long.MAX_VALUE = %,d", Long.MAX_VALUE);
161+
include::example$manual/api/LoggerNameTest.java[tag=formatter,indent=0]
181162
----
182163
183164
Loggers returned by `getFormatterLogger()` are referred as *formatter loggers*.
@@ -191,9 +172,7 @@ If your main usage is to use `{}`-style parameters, but occasionally you need fi
191172
192173
[source,java]
193174
----
194-
Logger logger = LogManager.getLogger("Foo");
195-
logger.debug("Opening connection to {}...", someDataSource);
196-
logger.printf(Level.INFO, "Hello, %s!", userName);
175+
include::example$manual/api/LoggerNameTest.java[tag=printf,indent=0]
197176
----
198177
199178
[#formatter-perf]
@@ -202,16 +181,6 @@ logger.printf(Level.INFO, "Hello, %s!", userName);
202181
Keep in mind that, contrary to the formatter logger, the default Log4j logger (i.e., `{}`-style parameters) is heavily optimized for several use cases and can operate xref:manual/garbagefree.adoc[garbage-free] when configured correctly.
203182
You might reconsider your formatter logger usages for latency sensitive applications.
204183
205-
[#resource-logger]
206-
=== Resource logger
207-
208-
Resource loggers, introduced in Log4j API `2.24.0`, is a special kind of `Logger` that:
209-
210-
* is a regular class member variable that will be garbage collected along with the class instance
211-
* enriches generated log events with data associated with the resource (i.e., the class instance)
212-
213-
xref:manual/resource-logger.adoc[Read more on resource loggers...]
214-
215184
[#event-logger]
216185
=== Event logger
217186
@@ -250,20 +219,15 @@ The fluent API allows you to log using a fluent interface:
250219
251220
[source,java]
252221
----
253-
logger.atInfo()
254-
.withMarker(marker)
255-
.withLocation()
256-
.withThrowable(exception)
257-
.log("Login for user `{}` failed", userId);
222+
include::example$manual/api/LoggerNameTest.java[tag=fluent,indent=0]
258223
----
259224
260225
xref:manual/logbuilder.adoc[Read more on the Fluent API...]
261226
262227
[#fish-tagging]
263228
== Fish tagging
264229
265-
Just as a fish can be tagged and have its movement tracked (aka. _fish tagging_ footnote:[Fish tagging is first described by Neil Harrison in the _"Patterns for Logging Diagnostic Messages"_ chapter of https://dl.acm.org/doi/10.5555/273448[_"Pattern Languages of Program Design 3"_ edited by R. Martin, D. Riehle, and F. Buschmann in 1997].]), stamping log events with a common tag or set of data
266-
elements allows the complete flow of a transaction or a request to be tracked.
230+
Just as a fish can be tagged and have its movement tracked (aka. _fish tagging_ footnote:[Fish tagging is first described by Neil Harrison in the _"Patterns for Logging Diagnostic Messages"_ chapter of https://dl.acm.org/doi/10.5555/273448[_"Pattern Languages of Program Design 3"_ edited by R. Martin, D. Riehle, and F. Buschmann in 1997].]), stamping log events with a common tag or set of data elements allows the complete flow of a transaction or a request to be tracked.
267231
You can use them for several purposes, such as:
268232
269233
* Provide extra information while serializing the log event
@@ -287,56 +251,11 @@ Markers are programmatic labels developers can associate to log statements:
287251
288252
[source,java]
289253
----
290-
public class MyApp {
291-
292-
private static final Logger LOGGER = LogManager.getLogger();
293-
294-
private static final Marker ACCOUNT_MARKER = MarkerManager.getMarker("ACCOUNT");
295-
296-
public void removeUser(String userId) {
297-
logger.debug(ACCOUNT_MARKER, "Removing user with ID `{}`", userId);
298-
// ...
299-
}
300-
301-
}
254+
include::example$manual/api/MyApp.java[tag=class,indent=0]
302255
----
303256
304257
xref:manual/markers.adoc[Read more on markers...]
305258
306-
[#scoped-context]
307-
=== Scoped Context
308-
309-
Just like a https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/lang/ScopedValue.html[Java's `ScopedValue`], _Scoped Context_ facilitates associating information with a certain block of code and makings this accessible to the rest of the logging system:
310-
311-
[source,java]
312-
----
313-
314-
private class Worker implements Runnable {
315-
316-
private static final Logger LOGGER = LogManager.getLogger();
317-
318-
public void authUser(Request request, Session session) {
319-
// ... // <3>
320-
ScopedContext
321-
.where("ipAddress", request.getRemoteAddr()) // <1>
322-
.where("hostName", request.getServerName()) // <1>
323-
.where("loginId", session.getAttribute("loginId")) // <1>
324-
.run(() -> { // <2>
325-
LOGGER.debug("Authenticating user");
326-
// ...
327-
});
328-
// ... // <3>
329-
}
330-
331-
}
332-
----
333-
<1> Associating properties such that they will only be visible to Log4j **within the scope of the `run()` method**.
334-
These properties can later on be used to, for instance, filter the log event, provide extra information in the layout, etc.
335-
<2> The block determining the visibility scope of the provided properties.
336-
<3> Outside the scope of the `run()` method provided properties will not be visible.
337-
338-
xref:manual/scoped-context.adoc[Read more on Scoped Context...]
339-
340259
[#thread-context]
341260
=== Thread Context
342261
@@ -350,21 +269,13 @@ storage:
350269
351270
[source,java]
352271
----
353-
ThreadContext.put("ipAddress", request.getRemoteAddr()); // <1>
354-
ThreadContext.put("hostName", request.getServerName()); // <1>
355-
ThreadContext.put("loginId", session.getAttribute("loginId")); // <1>
272+
include::example$manual/api/LoggerNameTest.java[tag=thread-context1,indent=0]
356273
357-
void performWork() {
358-
ThreadContext.push("performWork()"); // <2>
274+
include::example$manual/api/LoggerNameTest.java[tag=thread-context2,indent=0]
359275
360-
LOGGER.debug("Performing work"); // <3>
361-
// Perform the work
362-
363-
ThreadContext.pop(); // <4>
364-
}
365-
366-
ThreadContext.clear(); // <5>
276+
include::example$manual/api/LoggerNameTest.java[tag=thread-context3,indent=0]
367277
----
278+
368279
<1> Adding properties to the thread context map
369280
<2> Pushing properties to the thread context stack
370281
<3> Added properties can later on be used to, for instance, filter the log event, provide extra information in the layout, etc.
@@ -394,25 +305,21 @@ Log4j provides several predefined message types to cater for common use cases:
394305
+
395306
[source,java]
396307
----
397-
LOGGER.info("foo");
398-
LOGGER.info(new SimpleMessage("foo"));
308+
include::example$manual/api/LoggerNameTest.java[tag=string,indent=0]
399309
----
400310
401311
* `String`-typed parameterized messages:
402312
+
403313
[source,java]
404314
----
405-
LOGGER.info("foo {} {}", "bar", "baz");
406-
LOGGER.info(new ParameterizedMessage("foo {} {}", new Object[]{"bar", "baz"}));
315+
include::example$manual/api/LoggerNameTest.java[tag=parameterized,indent=0]
407316
----
408317
409318
* `Map`-typed messages:
410319
+
411320
[source,java]
412321
----
413-
LOGGER.info(new StringMapMessage()
414-
.with("key1", "val1")
415-
.with("key2", "val2"));
322+
include::example$manual/api/LoggerNameTest.java[tag=map,indent=0]
416323
----
417324
418325
xref:manual/messages.adoc[Read more on messages...]

src/site/antora/modules/ROOT/partials/log4j-features.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Check out the xref:manual/performance.adoc[Performance] page for details.
3232
3333
Extensibility::
3434
Log4j contains a fully-fledged xref:manual/plugins.adoc[plugin support] that users can leverage to extend functionality.
35-
You can easily add your components (layouts, appenders, filters, etc.) or customize existing ones (e.g., adding new directives to xref:manual/extending.adoc#PatternConverters[Pattern Layout] or xref:manual/json-template-layout.adoc#extending[JSON Template Layout]).
35+
You can easily add your components (layouts, appenders, filters, etc.) or customize existing ones (e.g., adding new directives to xref:manual/pattern-layout.adoc#extending[Pattern Layout] or xref:manual/json-template-layout.adoc#extending[JSON Template Layout]).
3636
Check out the xref:manual/extending.adoc[Extending Log4j] page.
3737
3838
Powerful API::

src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-context-selector.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ link:../javadoc/log4j-core/org/apache/logging/log4j/core/osgi/BundleContextSelec
5151
Creates a separate logger context per OSGi bundle and synchronous loggers
5252
5353
link:../javadoc/log4j-core/org/apache/logging/log4j/core/selector/JndiContextSelector.html[`org.apache.logging.log4j.core.selector.JndiContextSelector`]::
54-
Creates loggers contexts based on a JNDI lookup and synchronous loggers See xref:jakarta.adoc#use-jndi-context-selector[Web application] for details.
54+
Creates loggers contexts based on a JNDI lookup and synchronous loggers See xref:jakarta.adoc#jndi-configuration[Web application] for details.

0 commit comments

Comments
 (0)