Skip to content

Commit 7a7fd4d

Browse files
committed
Added support for emitting logs with thread name
1 parent 1969237 commit 7a7fd4d

File tree

6 files changed

+144
-89
lines changed

6 files changed

+144
-89
lines changed

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
Changelog
22
=========
33
# 0.49.2-SNAPSHOT / TBC
4+
* [FEATURE] Added support for emitting logs with thread name [#525][]
45

56
# 0.49.1 / 2024-04-09
67
* [FEATURE] Add ZGC Major and Minor Cycles and ZGC Major and Minor Pauses beans support out of the box (Generational ZGC support) [#509][]
@@ -766,7 +767,8 @@ Changelog
766767
[#469]: https://github.com/DataDog/jmxfetch/issues/469
767768
[#477]: https://github.com/DataDog/jmxfetch/issues/477
768769
[#509]: https://github.com/DataDog/jmxfetch/issues/509
769-
[#512]: https://github.com/DataDog/jmxfetch/pull/512
770+
[#512]: https://github.com/DataDog/jmxfetch/issues/512
771+
[#525]: https://github.com/DataDog/jmxfetch/issues/525
770772
[@alz]: https://github.com/alz
771773
[@aoking]: https://github.com/aoking
772774
[@arrawatia]: https://github.com/arrawatia

src/main/java/org/datadog/jmxfetch/AppConfig.java

+11
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ public class AppConfig {
9696
@Builder.Default
9797
private boolean logFormatRfc3339 = false;
9898

99+
@Parameter(
100+
names = {"--log_thread_name"},
101+
description = "Logs the thread name with each message",
102+
required = false)
103+
@Builder.Default
104+
private boolean logThreadName = false;
105+
99106
@Parameter(
100107
names = {"--conf_directory", "-D"},
101108
description = "Absolute path to the conf.d directory",
@@ -444,6 +451,10 @@ public boolean isLogFormatRfc3339() {
444451
return logFormatRfc3339;
445452
}
446453

454+
public boolean isLogThreadName() {
455+
return logThreadName;
456+
}
457+
447458
/** Returns path to auto-discovery pipe. Deprecated.. */
448459
public String getAutoDiscoveryPipe() {
449460
String pipePath;

src/main/java/org/datadog/jmxfetch/JmxFetch.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ public static void main(String[] args) {
4646

4747
// Set up the logger to add file handler
4848
CustomLogger.setup(LogLevel.fromString(config.getLogLevel()),
49-
config.getLogLocation(),
50-
config.isLogFormatRfc3339());
49+
config.getLogLocation(),
50+
config.isLogFormatRfc3339(),
51+
config.isLogThreadName());
5152

5253
// Set up the shutdown hook to properly close resources
5354
attachShutdownHook();

src/main/java/org/datadog/jmxfetch/util/CustomLogger.java

+102-71
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,17 @@
22

33
import lombok.extern.slf4j.Slf4j;
44

5-
import org.datadog.jmxfetch.util.LogLevel;
6-
import org.datadog.jmxfetch.util.StdoutConsoleHandler;
7-
85
import java.io.PrintWriter;
96
import java.io.StringWriter;
107
import java.text.SimpleDateFormat;
118
import java.util.Arrays;
129
import java.util.Date;
13-
import java.util.Enumeration;
1410
import java.util.List;
1511
import java.util.Locale;
1612
import java.util.concurrent.ConcurrentHashMap;
1713
import java.util.concurrent.atomic.AtomicInteger;
1814
import java.util.logging.ConsoleHandler;
1915
import java.util.logging.FileHandler;
20-
import java.util.logging.Filter;
2116
import java.util.logging.Handler;
2217
import java.util.logging.Level;
2318
import java.util.logging.LogManager;
@@ -47,8 +42,12 @@ public class CustomLogger {
4742
private static final String DATE_JDK14_LAYOUT = "yyyy-MM-dd HH:mm:ss z";
4843
private static final String DATE_JDK14_LAYOUT_RFC3339 = "yyyy-MM-dd'T'HH:mm:ssXXX";
4944
private static final String JDK14_LAYOUT = "%s | JMX | %2$s | %3$s | %4$s%5$s%n";
45+
private static final String JDK14_WITH_THREADS_LAYOUT =
46+
"%s | JMX | %2$s | %3$s | %4$s | %5$s%6$s%n";
5047
private static final String JDK14_LAYOUT_FILE_LINE =
5148
"%s | JMX | %2$s | %3$s:%4$d | %5$s%6$s%n";
49+
private static final String JDK14_WITH_THREADS_LAYOUT_FILE_LINE =
50+
"%s | JMX | %2$s | %3$s | %4$s:%5$d | %6$s%7$s%n";
5251

5352
private static final int MAX_FILE_SIZE = 5 * 1024 * 1024;
5453

@@ -66,67 +65,8 @@ private static boolean isStdOut(String target) {
6665

6766
/** setup and configure the logging. */
6867
public static synchronized void setup(LogLevel level, String logLocation,
69-
boolean logFormatRfc3339) {
70-
String target = "CONSOLE";
71-
String dateFormat = logFormatRfc3339 ? DATE_JDK14_LAYOUT_RFC3339 : DATE_JDK14_LAYOUT;
72-
if (millisecondLogging) {
73-
dateFormat = dateFormat.replace("ss", "ss.SSS");
74-
}
75-
final SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat,
76-
Locale.getDefault());
77-
78-
// log format
79-
SimpleFormatter formatter = new SimpleFormatter() {
80-
private static final String format = JDK14_LAYOUT;
81-
82-
private String simpleClassName(String str) {
83-
int start = str.lastIndexOf('.');
84-
int end = str.indexOf('$');
85-
if (start == -1 || start + 1 == str.length()) {
86-
return str;
87-
}
88-
if (end == -1 || end <= start || end > str.length()) {
89-
end = str.length();
90-
}
91-
return str.substring(start + 1, end);
92-
}
93-
94-
@Override
95-
public synchronized String format(LogRecord lr) {
96-
String exception = "";
97-
if (lr.getThrown() != null) {
98-
StringWriter writer = new StringWriter();
99-
PrintWriter stream = new PrintWriter(writer);
100-
stream.println();
101-
lr.getThrown().printStackTrace(stream);
102-
stream.close();
103-
exception = writer.toString();
104-
}
105-
106-
if (enableFileLineLogging) {
107-
Throwable throwable = new Throwable();
108-
StackTraceElement logEmissionFrame = throwable.getStackTrace()[6];
109-
110-
return String.format(JDK14_LAYOUT_FILE_LINE,
111-
dateFormatter.format(new Date()).toString(),
112-
LogLevel.fromJulLevel(lr.getLevel()).toString(),
113-
logEmissionFrame.getFileName(),
114-
logEmissionFrame.getLineNumber(),
115-
lr.getMessage(),
116-
exception
117-
);
118-
119-
}
120-
121-
return String.format(format,
122-
dateFormatter.format(new Date()).toString(),
123-
LogLevel.fromJulLevel(lr.getLevel()).toString(),
124-
simpleClassName(lr.getSourceClassName()),
125-
lr.getMessage(),
126-
exception
127-
);
128-
}
129-
};
68+
boolean logFormatRfc3339, boolean logThreadName) {
69+
SimpleFormatter formatter = getFormatter(logFormatRfc3339, logThreadName);
13070

13171
// log level
13272
Level julLevel = level.toJulLevel();
@@ -138,14 +78,14 @@ public synchronized String format(LogRecord lr) {
13878
manager.reset();
13979

14080
// prepare the different handlers
141-
ConsoleHandler stdoutHandler = null;
81+
ConsoleHandler stdoutHandler;
14282
ConsoleHandler stderrHandler = null;
14383
FileHandler fileHandler = null;
14484

14585
// the logLocation isn't always containing a file, it is sometimes
14686
// referring to a standard output. We want to create a FileHandler only
14787
// if the logLocation is a file on the FS.
148-
if (logLocation != null && logLocation.length() > 0) {
88+
if (logLocation != null && !logLocation.isEmpty()) {
14989
if (!isStdOut(logLocation) && !isStdErr(logLocation)) {
15090
// file logging
15191
try {
@@ -178,14 +118,105 @@ public synchronized String format(LogRecord lr) {
178118
if (fileHandler != null) {
179119
jmxfetchLogger.addHandler(fileHandler);
180120
}
181-
if (stdoutHandler != null) { // always non-null but doesn't cost much
182-
jmxfetchLogger.addHandler(stdoutHandler);
183-
}
121+
122+
jmxfetchLogger.addHandler(stdoutHandler);
123+
184124
if (stderrHandler != null) {
185125
jmxfetchLogger.addHandler(stderrHandler);
186126
}
187127
}
188128

129+
private static SimpleFormatter getFormatter(
130+
final boolean logFormatRfc3339,
131+
final boolean logThreadName) {
132+
String dateFormat = logFormatRfc3339 ? DATE_JDK14_LAYOUT_RFC3339 : DATE_JDK14_LAYOUT;
133+
if (millisecondLogging) {
134+
dateFormat = dateFormat.replace("ss", "ss.SSS");
135+
}
136+
final SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat,
137+
Locale.getDefault());
138+
139+
// log format
140+
return new SimpleFormatter() {
141+
private final String formatLayout =
142+
logThreadName ? JDK14_WITH_THREADS_LAYOUT : JDK14_LAYOUT;
143+
144+
private String simpleClassName(String str) {
145+
int start = str.lastIndexOf('.');
146+
int end = str.indexOf('$');
147+
if (start == -1 || start + 1 == str.length()) {
148+
return str;
149+
}
150+
if (end == -1 || end <= start) {
151+
end = str.length();
152+
}
153+
return str.substring(start + 1, end);
154+
}
155+
156+
@Override
157+
public synchronized String format(LogRecord lr) {
158+
String exception = "";
159+
if (lr.getThrown() != null) {
160+
StringWriter writer = new StringWriter();
161+
PrintWriter stream = new PrintWriter(writer);
162+
stream.println();
163+
lr.getThrown().printStackTrace(stream);
164+
stream.close();
165+
exception = writer.toString();
166+
}
167+
168+
if (enableFileLineLogging) {
169+
Throwable throwable = new Throwable();
170+
StackTraceElement logEmissionFrame = throwable.getStackTrace()[6];
171+
172+
final String logFormat;
173+
if (logThreadName) {
174+
logFormat = JDK14_WITH_THREADS_LAYOUT_FILE_LINE;
175+
} else {
176+
logFormat = JDK14_LAYOUT_FILE_LINE;
177+
}
178+
if (logThreadName) {
179+
return String.format(logFormat,
180+
dateFormatter.format(new Date()),
181+
LogLevel.fromJulLevel(lr.getLevel()).toString(),
182+
Thread.currentThread().getName(),
183+
logEmissionFrame.getFileName(),
184+
logEmissionFrame.getLineNumber(),
185+
lr.getMessage(),
186+
exception
187+
);
188+
}
189+
return String.format(logFormat,
190+
dateFormatter.format(new Date()),
191+
LogLevel.fromJulLevel(lr.getLevel()).toString(),
192+
logEmissionFrame.getFileName(),
193+
logEmissionFrame.getLineNumber(),
194+
lr.getMessage(),
195+
exception
196+
);
197+
}
198+
199+
if (logThreadName) {
200+
return String.format(formatLayout,
201+
dateFormatter.format(new Date()),
202+
LogLevel.fromJulLevel(lr.getLevel()).toString(),
203+
Thread.currentThread().getName(),
204+
simpleClassName(lr.getSourceClassName()),
205+
lr.getMessage(),
206+
exception
207+
);
208+
}
209+
return String.format(formatLayout,
210+
dateFormatter.format(new Date()),
211+
LogLevel.fromJulLevel(lr.getLevel()).toString(),
212+
simpleClassName(lr.getSourceClassName()),
213+
lr.getMessage(),
214+
exception
215+
);
216+
}
217+
};
218+
}
219+
189220
/** closeHandlers closes all opened handlers. */
190221
public static synchronized void shutdown() {
191222
for (Handler handler : jmxfetchLogger.getHandlers()) {

src/test/java/org/datadog/jmxfetch/TestCommon.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public static void init() throws Exception {
7373
if (level == null) {
7474
level = "ALL";
7575
}
76-
CustomLogger.setup(LogLevel.ALL, "/tmp/jmxfetch_test.log", false);
76+
CustomLogger.setup(LogLevel.ALL, "/tmp/jmxfetch_test.log", false, true);
7777
}
7878

7979
/**

src/test/java/org/datadog/jmxfetch/util/CustomLoggerPerfTest.java

+24-14
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public final class CustomLoggerPerfTest {
3434
private final int msgSize; // length of log message in bytes
3535
private final int uPause; // length of log message in bytes
3636
private final boolean rfc3339; // length of log message in bytes
37+
private final boolean logThreadName;
3738

3839
private AtomicBoolean running;
3940
private final ExecutorService executor;
@@ -42,29 +43,37 @@ public final class CustomLoggerPerfTest {
4243

4344
@Parameters
4445
public static Collection<Object[]> data() {
45-
return Arrays.asList(new Object[][] {
46-
{ 90, 100, 1, 128, false }, // 90 seconds, 100 microsecond pause, 1 worker, 128 byte string, false
47-
{ 90, 100, 1, 512, false }, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, false
48-
{ 90, 100, 1, 1024, false }, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, false
49-
{ 90, 100, 1, 128, true }, // 90 seconds, 100 microsecond pause, 1 worker, 128 byte string, true
50-
{ 90, 100, 1, 512, true }, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, true
51-
{ 90, 100, 1, 1024, true }, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, true
52-
});
46+
return Arrays.asList(new Object[][]{
47+
{90, 100, 1, 128, false, false}, // 90 seconds, 100 microsecond pause, 1 worker, 128 byte string, false, false
48+
{90, 100, 1, 512, false, false}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, false, false
49+
{90, 100, 1, 1024, false, false}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, false, false
50+
{90, 100, 1, 128, false, true}, // 90 seconds, 100 microsecond pause, 1 worker, 128 byte string, false, true
51+
{90, 100, 1, 512, false, true}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, false, true
52+
{90, 100, 1, 1024, false, true}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, false, true
53+
{90, 100, 1, 128, true, false}, // 90 seconds, 100 microsecond pause, 1 worker, 128 byte string, true, false
54+
{90, 100, 1, 512, true, false}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, true, false
55+
{90, 100, 1, 1024, true, false}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, true, false
56+
{90, 100, 1, 128, true, true}, // 90 seconds, 100 microsecond pause, 1 worker, 128 byte string, true, true
57+
{90, 100, 1, 512, true, true}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, true, true
58+
{90, 100, 1, 1024, true, true}, // 90 seconds, 100 microsecond pause, 1 worker, 512 byte string, true, true
59+
});
5360
}
5461

55-
public CustomLoggerPerfTest(int duration, int uPause, int testWorkers, int msgSize, boolean rfc3339) throws IOException {
62+
public CustomLoggerPerfTest(int duration, int uPause, int testWorkers, int msgSize, boolean rfc3339, boolean logThreadName) throws IOException {
5663
this.duration = duration;
5764
this.testWorkers = testWorkers;
5865
this.msgSize = msgSize;
5966
this.uPause = uPause;
6067
this.rfc3339 = rfc3339;
68+
this.logThreadName =logThreadName;
6169

6270
this.executor = Executors.newFixedThreadPool(testWorkers);
6371
this.running = new AtomicBoolean(true);
6472

6573
CustomLogger.setup(LogLevel.fromString("INFO"),
66-
null, //stdout
67-
rfc3339);
74+
null, //stdout
75+
rfc3339,
76+
logThreadName);
6877
}
6978

7079
/**
@@ -117,11 +126,13 @@ public void run() {
117126
.append(this.msgSize)
118127
.append(" and RFC 3339 mode set to ")
119128
.append(this.rfc3339)
129+
.append(" and log thread name set to ")
130+
.append(this.logThreadName)
120131
.append(" logged ")
121132
.append(count.get())
122133
.append(" messsages.");
123134

124-
System.out.println(sb.toString());
135+
System.out.println(sb);
125136
}
126137

127138
private String getRandomString(int length) {
@@ -135,8 +146,7 @@ private String getRandomString(int length) {
135146
(random.nextFloat() * (rightLimit - leftLimit + 1));
136147
buffer.append((char) randomLimitedInt);
137148
}
138-
String generatedString = buffer.toString();
139149

140-
return generatedString;
150+
return buffer.toString();
141151
}
142152
}

0 commit comments

Comments
 (0)