Skip to content

Commit 89e8328

Browse files
authored
[AMLII-1817] Added support for emitting logs with thread name (#525)
* Added support for emitting logs with thread name * Making thread name in logs the default, can be disabled via system property
1 parent d62420b commit 89e8328

File tree

4 files changed

+127
-89
lines changed

4 files changed

+127
-89
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
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
* [BUGFIX] Telemetry is no longer initialized when telemetry is disabled [#522][]
56

67
# 0.49.1 / 2024-04-09
@@ -768,7 +769,6 @@ Changelog
768769
[#477]: https://github.com/DataDog/jmxfetch/issues/477
769770
[#509]: https://github.com/DataDog/jmxfetch/issues/509
770771
[#512]: https://github.com/DataDog/jmxfetch/pull/512
771-
[#522]: https://github.com/DataDog/jmxfetch/pull/522
772772
[@alz]: https://github.com/alz
773773
[@aoking]: https://github.com/aoking
774774
[@arrawatia]: https://github.com/arrawatia

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ 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());
5151

5252
// Set up the shutdown hook to properly close resources
5353
attachShutdownHook();

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

Lines changed: 101 additions & 72 deletions
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;
@@ -41,14 +36,24 @@ public class CustomLogger {
4136
private static boolean millisecondLogging =
4237
System.getProperty("jmxfetch.millisecondLogging", "false").equals("true");
4338

39+
// Enable by setting -Djmxfetch.disableThreadLogging,
40+
// if true, log record will not include thread name
41+
private static final boolean disableThreadLogging =
42+
System.getProperty("jmxfetch.disableThreadLogging", "false").equals("true");
43+
4444
private static final ConcurrentHashMap<String, AtomicInteger> messageCount
4545
= new ConcurrentHashMap<String, AtomicInteger>();
4646

4747
private static final String DATE_JDK14_LAYOUT = "yyyy-MM-dd HH:mm:ss z";
4848
private static final String DATE_JDK14_LAYOUT_RFC3339 = "yyyy-MM-dd'T'HH:mm:ssXXX";
49-
private static final String JDK14_LAYOUT = "%s | JMX | %2$s | %3$s | %4$s%5$s%n";
49+
private static final String JDK14_LAYOUT =
50+
"%s | JMX | %2$s | %3$s | %4$s%5$s%n";
51+
private static final String JDK14_WITH_THREADS_LAYOUT =
52+
"%s | JMX | %2$s | %3$s | %4$s | %5$s%6$s%n";
5053
private static final String JDK14_LAYOUT_FILE_LINE =
51-
"%s | JMX | %2$s | %3$s:%4$d | %5$s%6$s%n";
54+
"%s | JMX | %2$s | %3$s:%4$d | %5$s%6$s%n";
55+
private static final String JDK14_WITH_THREADS_LAYOUT_FILE_LINE =
56+
"%s | JMX | %2$s | %3$s | %4$s:%5$d | %6$s%7$s%n";
5257

5358
private static final int MAX_FILE_SIZE = 5 * 1024 * 1024;
5459

@@ -67,66 +72,7 @@ private static boolean isStdOut(String target) {
6772
/** setup and configure the logging. */
6873
public static synchronized void setup(LogLevel level, String logLocation,
6974
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-
};
75+
SimpleFormatter formatter = getFormatter(logFormatRfc3339);
13076

13177
// log level
13278
Level julLevel = level.toJulLevel();
@@ -138,14 +84,14 @@ public synchronized String format(LogRecord lr) {
13884
manager.reset();
13985

14086
// prepare the different handlers
141-
ConsoleHandler stdoutHandler = null;
87+
ConsoleHandler stdoutHandler;
14288
ConsoleHandler stderrHandler = null;
14389
FileHandler fileHandler = null;
14490

14591
// the logLocation isn't always containing a file, it is sometimes
14692
// referring to a standard output. We want to create a FileHandler only
14793
// if the logLocation is a file on the FS.
148-
if (logLocation != null && logLocation.length() > 0) {
94+
if (logLocation != null && !logLocation.isEmpty()) {
14995
if (!isStdOut(logLocation) && !isStdErr(logLocation)) {
15096
// file logging
15197
try {
@@ -178,14 +124,97 @@ public synchronized String format(LogRecord lr) {
178124
if (fileHandler != null) {
179125
jmxfetchLogger.addHandler(fileHandler);
180126
}
181-
if (stdoutHandler != null) { // always non-null but doesn't cost much
182-
jmxfetchLogger.addHandler(stdoutHandler);
183-
}
127+
128+
jmxfetchLogger.addHandler(stdoutHandler);
129+
184130
if (stderrHandler != null) {
185131
jmxfetchLogger.addHandler(stderrHandler);
186132
}
187133
}
188134

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

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

Lines changed: 23 additions & 14 deletions
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,36 @@ 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);
6876
}
6977

7078
/**
@@ -117,11 +125,13 @@ public void run() {
117125
.append(this.msgSize)
118126
.append(" and RFC 3339 mode set to ")
119127
.append(this.rfc3339)
128+
.append(" and log thread name set to ")
129+
.append(this.logThreadName)
120130
.append(" logged ")
121131
.append(count.get())
122132
.append(" messsages.");
123133

124-
System.out.println(sb.toString());
134+
System.out.println(sb);
125135
}
126136

127137
private String getRandomString(int length) {
@@ -135,8 +145,7 @@ private String getRandomString(int length) {
135145
(random.nextFloat() * (rightLimit - leftLimit + 1));
136146
buffer.append((char) randomLimitedInt);
137147
}
138-
String generatedString = buffer.toString();
139148

140-
return generatedString;
149+
return buffer.toString();
141150
}
142151
}

0 commit comments

Comments
 (0)