Skip to content
This repository was archived by the owner on Jun 20, 2025. It is now read-only.

Commit 98ace83

Browse files
authored
Merge pull request #50 from scalecube/feature/improve-logging
Improved logging, split by benchmark tests
2 parents 604cb97 + 2d3d55e commit 98ace83

File tree

5 files changed

+112
-25
lines changed

5 files changed

+112
-25
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
/reports
2525
*/reports
2626
*.csv
27+
*.log
28+
*.zip
2729

2830
# Mac-specific directory that no other operating system needs.
2931
.DS_Store

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,6 @@ This method intends for execution asynchronous tasks with consumption some resou
134134
```
135135

136136
It's time to describe the settings in more detail. First, you can see two ramp-up parameters, these are `rampUpDuration` and `rampUpInterval`. They need to specify how long will be processing ramp-up stage and how often will be invoked the resource supplier to receive a new resource. Also, we have two parameters to specify how long will be processing all `unitOfWork`s on the given resource (`executionTaskDuration`) and with another one you can specify some interval that will be applied to invoke the next `unitOfWork` on the given resource (`executionTaskInterval`).
137+
138+
## Additional links
139+
+ [How-to-launch-benchmarks](https://github.com/scalecube/scalecube-benchmarks/wiki/How-to-launch-benchmarks)

benchmarks-api/src/main/java/io/scalecube/benchmarks/BenchmarksSettings.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public class BenchmarksSettings {
2424
private static final long NUM_OF_ITERATIONS = Long.MAX_VALUE;
2525
private static final Duration RAMP_UP_DURATION = Duration.ofSeconds(10);
2626
private static final Duration RAMP_UP_INTERVAL = Duration.ofSeconds(1);
27-
private static final String ALIAS = "alias";
27+
private static final boolean CONSOLE_REPORTER_ENABLED = true;
2828

2929
private final int nThreads;
3030
private final Duration executionTaskDuration;
@@ -38,6 +38,7 @@ public class BenchmarksSettings {
3838
private final long numOfIterations;
3939
private final Duration rampUpDuration;
4040
private final Duration rampUpInterval;
41+
private final boolean consoleReporterEnabled;
4142

4243
private final Map<String, String> options;
4344

@@ -51,23 +52,21 @@ private BenchmarksSettings(Builder builder) {
5152
this.executionTaskInterval = builder.executionTaskInterval;
5253
this.reporterInterval = builder.reporterInterval;
5354
this.numOfIterations = builder.numOfIterations;
54-
55+
this.consoleReporterEnabled = builder.consoleReporterEnabled;
5556
this.rampUpDuration = builder.rampUpDuration;
5657
this.rampUpInterval = builder.rampUpInterval;
57-
5858
this.options = builder.options;
59-
60-
this.registry = new MetricRegistry();
61-
6259
this.durationUnit = builder.durationUnit;
6360
this.rateUnit = builder.rateUnit;
6461

62+
this.registry = new MetricRegistry();
63+
6564
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
6665
this.taskName = minifyClassName(stackTrace[stackTrace.length - 1].getClassName());
6766

6867
String time = LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC)
6968
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"));
70-
this.csvReporterDirectory = Paths.get("benchmarks", "results", find(ALIAS, taskName), time).toFile();
69+
this.csvReporterDirectory = Paths.get("benchmarks", "results", find("alias", taskName), time).toFile();
7170
// noinspection ResultOfMethodCallIgnored
7271
this.csvReporterDirectory.mkdirs();
7372
}
@@ -124,6 +123,10 @@ public Duration rampUpInterval() {
124123
return rampUpInterval;
125124
}
126125

126+
public boolean consoleReporterEnabled() {
127+
return consoleReporterEnabled;
128+
}
129+
127130
@Override
128131
public String toString() {
129132
final StringBuilder sb = new StringBuilder("BenchmarksSettings{");
@@ -138,6 +141,7 @@ public String toString() {
138141
sb.append(", rateUnit=").append(rateUnit);
139142
sb.append(", rampUpDuration=").append(rampUpDuration);
140143
sb.append(", rampUpInterval=").append(rampUpInterval);
144+
sb.append(", consoleReporterEnabled=").append(consoleReporterEnabled);
141145
sb.append(", registry=").append(registry);
142146
sb.append(", options=").append(options);
143147
sb.append('}');
@@ -160,6 +164,7 @@ public static class Builder {
160164
private long numOfIterations = NUM_OF_ITERATIONS;
161165
private Duration rampUpDuration = RAMP_UP_DURATION;
162166
private Duration rampUpInterval = RAMP_UP_INTERVAL;
167+
private boolean consoleReporterEnabled = CONSOLE_REPORTER_ENABLED;
163168

164169
public Builder from(String[] args) {
165170
this.parse(args);
@@ -218,6 +223,11 @@ public Builder rampUpInterval(Duration rampUpInterval) {
218223
return this;
219224
}
220225

226+
public Builder consoleReporterEnabled(boolean consoleReporterEnabled) {
227+
this.consoleReporterEnabled = consoleReporterEnabled;
228+
return this;
229+
}
230+
221231
public BenchmarksSettings build() {
222232
return new BenchmarksSettings(this);
223233
}
@@ -250,6 +260,9 @@ private void parse(String[] args) {
250260
case "rampUpIntervalInMillis":
251261
rampUpInterval(Duration.ofMillis(Long.parseLong(value)));
252262
break;
263+
case "consoleReporterEnabled":
264+
consoleReporterEnabled(Boolean.parseBoolean(value));
265+
break;
253266
default:
254267
addOption(key, value);
255268
break;

benchmarks-api/src/main/java/io/scalecube/benchmarks/BenchmarksState.java

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
import org.reactivestreams.Subscriber;
1919
import org.slf4j.Logger;
2020
import org.slf4j.LoggerFactory;
21+
import org.slf4j.MDC;
2122

2223
import java.time.Duration;
2324
import java.util.List;
25+
import java.util.Map;
2426
import java.util.concurrent.CountDownLatch;
2527
import java.util.concurrent.Executors;
28+
import java.util.concurrent.ThreadFactory;
2629
import java.util.concurrent.TimeUnit;
2730
import java.util.concurrent.atomic.AtomicBoolean;
2831
import java.util.function.BiFunction;
@@ -51,10 +54,12 @@ public class BenchmarksState<SELF extends BenchmarksState<SELF>> {
5154

5255
private static final Logger LOGGER = LoggerFactory.getLogger(BenchmarksState.class);
5356

57+
private static final String MDC_BENCHMARK_DIR = "benchmarkDir";
58+
5459
protected final BenchmarksSettings settings;
5560

56-
protected Scheduler scheduler;
57-
protected List<Scheduler> schedulers;
61+
private Scheduler scheduler;
62+
private List<Scheduler> schedulers;
5863

5964
private ConsoleReporter consoleReporter;
6065
private CsvReporter csvReporter;
@@ -81,25 +86,31 @@ public final void start() {
8186
throw new IllegalStateException("BenchmarksState is already started");
8287
}
8388

89+
MDC.put(MDC_BENCHMARK_DIR, settings.csvReporterDirectory().toString());
90+
8491
LOGGER.info("Benchmarks settings: " + settings);
8592

8693
settings.registry().register(settings.taskName() + "-memory", new MemoryUsageGaugeSet());
8794

88-
consoleReporter = ConsoleReporter.forRegistry(settings.registry())
89-
.outputTo(System.out)
90-
.convertDurationsTo(settings.durationUnit())
91-
.convertRatesTo(settings.rateUnit())
92-
.build();
95+
if (settings.consoleReporterEnabled()) {
96+
consoleReporter = ConsoleReporter.forRegistry(settings.registry())
97+
.outputTo(System.out)
98+
.convertDurationsTo(settings.durationUnit())
99+
.convertRatesTo(settings.rateUnit())
100+
.build();
101+
}
93102

94103
csvReporter = CsvReporter.forRegistry(settings.registry())
95104
.convertDurationsTo(settings.durationUnit())
96105
.convertRatesTo(settings.rateUnit())
97106
.build(settings.csvReporterDirectory());
98107

99-
scheduler = Schedulers.fromExecutor(Executors.newFixedThreadPool(settings.nThreads()));
108+
scheduler = Schedulers.fromExecutor(
109+
Executors.newFixedThreadPool(settings.nThreads(), newThreadFactory()));
100110

101111
schedulers = IntStream.rangeClosed(1, settings.nThreads())
102-
.mapToObj(i -> Schedulers.fromExecutorService(Executors.newSingleThreadScheduledExecutor()))
112+
.mapToObj(i -> Schedulers.fromExecutorService(
113+
Executors.newSingleThreadScheduledExecutor(newThreadFactory())))
103114
.collect(Collectors.toList());
104115

105116
try {
@@ -108,16 +119,20 @@ public final void start() {
108119
throw new IllegalStateException("BenchmarksState beforeAll() failed: " + ex, ex);
109120
}
110121

111-
consoleReporter.start(settings.reporterInterval().toMillis(), TimeUnit.MILLISECONDS);
122+
if (settings.consoleReporterEnabled()) {
123+
consoleReporter.start(settings.reporterInterval().toMillis(), TimeUnit.MILLISECONDS);
124+
}
125+
112126
csvReporter.start(settings.reporterInterval().toMillis(), TimeUnit.MILLISECONDS);
113127

114128
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
115129
if (started.get()) {
116130
csvReporter.report();
117-
consoleReporter.report();
131+
if (consoleReporter != null) {
132+
consoleReporter.report();
133+
}
118134
}
119135
}));
120-
121136
}
122137

123138
/**
@@ -150,6 +165,8 @@ public final void shutdown() {
150165
afterAll();
151166
} catch (Exception ex) {
152167
throw new IllegalStateException("BenchmarksState afterAll() failed: " + ex, ex);
168+
} finally {
169+
MDC.remove(MDC_BENCHMARK_DIR);
153170
}
154171
}
155172

@@ -321,4 +338,24 @@ public final <T> void runWithRampUp(
321338
self.shutdown();
322339
}
323340
}
341+
342+
private ThreadFactory newThreadFactory() {
343+
return runnable -> {
344+
Map<String, String> mdcCopy = MDC.getCopyOfContextMap();
345+
346+
return new Thread(runnable) {
347+
348+
private boolean mdcWasSet;
349+
350+
@Override
351+
public void run() {
352+
if (!mdcWasSet) {
353+
MDC.setContextMap(mdcCopy);
354+
mdcWasSet = true;
355+
}
356+
super.run();
357+
}
358+
};
359+
};
360+
}
324361
}

benchmarks-examples/src/main/resources/log4j2.xml

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,48 @@
44
<Properties>
55
<Property name="patternLayout">%level{length=1} %d{ISO8601} %c{1.} %m [%t]%n</Property>
66
</Properties>
7+
78
<Appenders>
8-
<Console name="STDOUT" target="SYSTEM_OUT">
9-
<PatternLayout pattern="${patternLayout}"/>
10-
</Console>
9+
10+
<Routing name="separateBenchmarkLogs">
11+
<Routes pattern="$${ctx:benchmarkDir}">
12+
<!-- This route is chosen if ThreadContext has values for keys: benchmarkDir -->
13+
<Route>
14+
<RollingFile name="Rolling-${ctx:benchmarkDir}"
15+
fileName="${ctx:benchmarkDir}/benchmarks.log"
16+
filePattern="${ctx:benchmarkDir}/benchmarks-%d{yyyy-MM-dd-HH}-%i.log.zip"
17+
ignoreExceptions="false">
18+
<PatternLayout pattern="${patternLayout}"/>
19+
<Policies>
20+
<TimeBasedTriggeringPolicy/>
21+
<SizeBasedTriggeringPolicy size="50MB"/>
22+
</Policies>
23+
<DefaultRolloverStrategy max="1000"/>
24+
</RollingFile>
25+
</Route>
26+
27+
<!-- This route is chosen if ThreadContext has no value for keys: benchmarkDir -->
28+
<Route key="$${ctx:benchmarkDir}">
29+
<RollingFile name="Rolling-default"
30+
fileName="benchmarks/default.log"
31+
filePattern="benchmarks/default-%d{yyyy-MM-dd-HH}-%i.log.zip"
32+
ignoreExceptions="false">
33+
<PatternLayout pattern="${patternLayout}"/>
34+
<Policies>
35+
<TimeBasedTriggeringPolicy/>
36+
<SizeBasedTriggeringPolicy size="50MB"/>
37+
</Policies>
38+
<DefaultRolloverStrategy max="1000"/>
39+
</RollingFile>
40+
</Route>
41+
42+
</Routes>
43+
</Routing>
1144
</Appenders>
1245

1346
<Loggers>
14-
<Logger name="io.scalecube.config" level="error"/>
15-
<Root level="debug">
16-
<AppenderRef ref="STDOUT"/>
47+
<Root level="${env:logLevel:-info}">
48+
<AppenderRef ref="separateBenchmarkLogs"/>
1749
</Root>
1850
</Loggers>
1951

0 commit comments

Comments
 (0)