Skip to content

Commit e73d417

Browse files
bhufmannMatthewKhouzam
authored andcommitted
Only log instances of TraceEventLogRecored when using AsyncFileHandler
Without this change other LogRecords are also logged. Add unit tests for that. Update TraceLoggerBenchmark to account for the filtered out LogRecords. fixes #49 Signed-off-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
1 parent e842f52 commit e73d417

File tree

3 files changed

+150
-6
lines changed

3 files changed

+150
-6
lines changed

src/main/java/org/eclipse/tracecompass/traceeventlogger/AsyncFileHandler.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -333,10 +333,12 @@ public ErrorManager getErrorManager() {
333333
@Override
334334
public synchronized void publish(LogRecord record) {
335335
try {
336-
fRecordBuffer.add(record);
337-
if (fRecordBuffer.size() >= fMaxSize && isLoggable(record)) {
338-
fQueue.put(fRecordBuffer);
339-
fRecordBuffer = new ArrayList<>(fMaxSize);
336+
if (isLoggable(record)) {
337+
fRecordBuffer.add(record);
338+
if (fRecordBuffer.size() >= fMaxSize) {
339+
fQueue.put(fRecordBuffer);
340+
fRecordBuffer = new ArrayList<>(fMaxSize);
341+
}
340342
}
341343
} catch (InterruptedException e) {
342344
Thread.currentThread().interrupt();
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Ericsson
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the “Software”), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20+
* IN THE SOFTWARE.
21+
*
22+
* SPDX-License-Identifier: MIT
23+
*******************************************************************************/
24+
package org.eclipse.tracecompass.traceeventlogger;
25+
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertNotNull;
28+
import static org.junit.Assert.assertTrue;
29+
import static org.junit.Assert.fail;
30+
31+
import java.io.File;
32+
import java.io.IOException;
33+
import java.nio.file.Files;
34+
import java.nio.file.Paths;
35+
import java.util.Collections;
36+
import java.util.List;
37+
import java.util.Objects;
38+
import java.util.logging.Level;
39+
import java.util.logging.LogManager;
40+
import java.util.logging.Logger;
41+
import java.util.logging.SimpleFormatter;
42+
import java.util.logging.StreamHandler;
43+
import java.util.regex.Pattern;
44+
import java.util.stream.Collectors;
45+
46+
import org.junit.Before;
47+
import org.junit.Test;
48+
49+
/**
50+
* Test cases for logger with AsyncFileHandler(line sensitive!)
51+
*
52+
* @author Bernd Hufmann
53+
*/
54+
public class LoggerWithHandlerTest {
55+
56+
private Logger fLogger;
57+
private StreamHandler fStreamHandler;
58+
private File fTempFile;
59+
60+
/**
61+
* Set up logger
62+
*/
63+
@Before
64+
public void before() {
65+
try {
66+
System.setProperty("java.util.logging.SimpleFormatter.format", "%5$s%n"); //$NON-NLS-1$ //$NON-NLS-2$
67+
LogManager.getLogManager().reset();
68+
fLogger = Logger.getAnonymousLogger();
69+
fTempFile = File.createTempFile("test", ".json"); //$NON-NLS-1$ //$NON-NLS-2$
70+
fStreamHandler = new AsyncFileHandler(fTempFile.getAbsolutePath());
71+
fStreamHandler.setLevel(Level.ALL);
72+
fStreamHandler.setEncoding("UTF-8"); //$NON-NLS-1$
73+
fStreamHandler.setFormatter(new SimpleFormatter());
74+
fLogger.addHandler(fStreamHandler);
75+
76+
} catch (IOException e) {
77+
fail(e.getMessage());
78+
}
79+
}
80+
81+
/**
82+
* Test simple logging
83+
*/
84+
@Test
85+
public void testHelloWorld() {
86+
Logger logger = fLogger;
87+
assertNotNull(logger);
88+
try (LogUtils.ScopeLog log = new LogUtils.ScopeLog(logger, Level.INFO, "world")) { //$NON-NLS-1$
89+
// do something
90+
new Object();
91+
}
92+
logger.log(Level.INFO, "Should not be logged"); //$NON-NLS-1$
93+
94+
fStreamHandler.flush();
95+
96+
List<String> filledLines = Collections.emptyList();
97+
// Give writing thread time to write all events
98+
try {
99+
Thread.sleep(3000);
100+
} catch (InterruptedException ex) {
101+
// ignore
102+
}
103+
try {
104+
for (int i = 0; i < 10; i++) {
105+
List<String> allLines = Files.readAllLines(Paths.get(fTempFile.getAbsolutePath()));
106+
filledLines = allLines.stream().filter(Objects::nonNull).collect(Collectors.toList());
107+
if (filledLines.size() >= 2) {
108+
break;
109+
}
110+
try {
111+
Thread.sleep(1000);
112+
} catch (InterruptedException ex) {
113+
// ignore
114+
}
115+
}
116+
assertNotNull(filledLines);
117+
assertEquals(2, filledLines.size());
118+
Pattern pattern = Pattern.compile("\\{.*B.*world.*\\}"); //$NON-NLS-1$
119+
assertTrue(pattern.matcher(filledLines.get(0)).matches());
120+
pattern = Pattern.compile("\\{.*E.*\\}"); //$NON-NLS-1$
121+
assertTrue(pattern.matcher(filledLines.get(1)).matches());
122+
} catch (IOException e) {
123+
fail(e.getMessage());
124+
}
125+
}
126+
}

src/test/java/org/eclipse/tracecompass/traceeventlogger/TestLoggerBenchmark.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ public String format(LogRecord record) {
176176
}
177177
}
178178
}
179+
/*
180+
* Note, that the instances of LogRecord created by OldLogUtils.ScopeLog won't be written to disk by the
181+
* AsyncFileHandler since they are not instances of TraceEventLogRecord.
182+
*/
179183
long end = System.nanoTime();
180184
asyncNew.add(end - start);
181185
for (long i = 0; i < warmUp; i++) {
@@ -227,15 +231,27 @@ private static long linecount(Path path) throws IOException {
227231
@After
228232
public void waiting() {
229233
try {
230-
while (linecount(files[0].toPath()) != linecount(files[1].toPath())) {
234+
int nbRetries = 0;
235+
int maxRetries = 25;
236+
/*
237+
* Note, that files[1] has half of number of events than files[0] because the instances of LogRecord created by
238+
* OldLogUtils.ScopeLog won't be written to disk by the AsyncFileHandler since they are not instances of
239+
* TraceEventLogRecord.
240+
*/
241+
while (linecount(files[0].toPath()) != (2 * linecount(files[1].toPath())) && (nbRetries < maxRetries)) {
231242
if (oldFileHandler != null) {
232243
oldFileHandler.close();
233244
}
234245
if (newFileHandler != null) {
235246
newFileHandler.close();
236247
}
237248
Thread.sleep(100);
238-
249+
nbRetries++;
250+
}
251+
if (nbRetries >= maxRetries) {
252+
System.out.println("Max retries (" + nbRetries //$NON-NLS-1$
253+
+ ") reached: line count of file[0]=" + linecount(files[0].toPath()) //$NON-NLS-1$
254+
+ ", line count of file[1]=" + linecount(files[1].toPath())); //$NON-NLS-1$
239255
}
240256
} catch (IOException | InterruptedException e) {
241257
fail(e.toString());

0 commit comments

Comments
 (0)