Skip to content

Commit cbfd1cc

Browse files
authored
Merge pull request #2 from mweirauch/value-handling
Simplify value handling
2 parents 73de618 + 0e7f13e commit cbfd1cc

File tree

6 files changed

+119
-77
lines changed

6 files changed

+119
-77
lines changed

src/main/java/io/github/mweirauch/micrometer/jvm/extras/ProcessMemoryMetrics.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void bindTo(MeterRegistry registry) {
4747
}
4848

4949
private Double value(KEY key) {
50-
return smaps.get(key).doubleValue();
50+
return smaps.get(key);
5151
}
5252

5353
}

src/main/java/io/github/mweirauch/micrometer/jvm/extras/procfs/ProcfsEntry.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import java.io.IOException;
1919
import java.util.Collection;
20+
import java.util.HashMap;
21+
import java.util.Map;
2022
import java.util.Objects;
2123

2224
import org.slf4j.Logger;
@@ -32,30 +34,45 @@ abstract class ProcfsEntry {
3234

3335
private final ProcfsReader reader;
3436

37+
private final Map<ValueKey, Double> values = new HashMap<>();
38+
3539
private long lastHandle = -1;
3640

41+
public interface ValueKey {
42+
//
43+
}
44+
3745
protected ProcfsEntry(ProcfsReader reader) {
3846
this.reader = Objects.requireNonNull(reader);
3947
}
4048

41-
protected final void collect() {
49+
public Double get(ValueKey key) {
50+
Objects.requireNonNull(key);
51+
52+
collect();
53+
return values.getOrDefault(key, defaultValue());
54+
}
55+
56+
/* default */ final void collect() {
4257
synchronized (lock) {
4358
try {
4459
final ReadResult result = reader.read();
4560
if (result != null && (lastHandle == -1 || lastHandle != result.getReadTime())) {
46-
reset();
47-
handle(result.getLines());
61+
values.clear();
62+
values.putAll(handle(result.getLines()));
4863
lastHandle = result.getReadTime();
4964
}
5065
} catch (IOException e) {
51-
reset();
66+
values.clear();
5267
log.warn("Failed reading '" + reader.getEntryPath() + "'!", e);
5368
}
5469
}
5570
}
5671

57-
protected abstract void reset();
72+
protected abstract Map<ValueKey, Double> handle(Collection<String> lines);
5873

59-
protected abstract void handle(Collection<String> lines);
74+
protected Double defaultValue() {
75+
return Double.valueOf(-1);
76+
}
6077

6178
}

src/main/java/io/github/mweirauch/micrometer/jvm/extras/procfs/ProcfsSmaps.java

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616
package io.github.mweirauch.micrometer.jvm.extras.procfs;
1717

1818
import java.util.Collection;
19-
import java.util.EnumSet;
2019
import java.util.HashMap;
2120
import java.util.Map;
2221
import java.util.Objects;
23-
import java.util.concurrent.atomic.AtomicLong;
24-
import java.util.function.LongUnaryOperator;
2522

2623
public class ProcfsSmaps extends ProcfsEntry {
2724

28-
public enum KEY {
25+
public enum KEY implements ValueKey {
2926
/**
3027
* Virtual set size
3128
*/
@@ -50,8 +47,6 @@ public enum KEY {
5047

5148
private static final int KILOBYTE = 1024;
5249

53-
private final Map<KEY, AtomicLong> values = new HashMap<>();
54-
5550
public ProcfsSmaps() {
5651
super(ProcfsReader.getInstance("smaps"));
5752
}
@@ -61,53 +56,39 @@ public ProcfsSmaps() {
6156
}
6257

6358
@Override
64-
protected void reset() {
65-
EnumSet.allOf(KEY.class).forEach(key -> values.put(key, new AtomicLong(-1)));
66-
}
67-
68-
@Override
69-
protected void handle(Collection<String> lines) {
59+
protected Map<ValueKey, Double> handle(Collection<String> lines) {
7060
Objects.requireNonNull(lines);
7161

62+
final Map<ValueKey, Double> values = new HashMap<>();
63+
7264
for (final String line : lines) {
65+
KEY valueKey = null;
7366
if (line.startsWith("Size:")) {
74-
inc(KEY.VSS, parseKiloBytes(line) * KILOBYTE);
67+
valueKey = KEY.VSS;
7568
} else if (line.startsWith("Rss:")) {
76-
inc(KEY.RSS, parseKiloBytes(line) * KILOBYTE);
69+
valueKey = KEY.RSS;
7770
} else if (line.startsWith("Pss:")) {
78-
inc(KEY.PSS, parseKiloBytes(line) * KILOBYTE);
71+
valueKey = KEY.PSS;
7972
} else if (line.startsWith("Swap:")) {
80-
inc(KEY.SWAP, parseKiloBytes(line) * KILOBYTE);
73+
valueKey = KEY.SWAP;
8174
} else if (line.startsWith("SwapPss:")) {
82-
inc(KEY.SWAPPSS, parseKiloBytes(line) * KILOBYTE);
75+
valueKey = KEY.SWAPPSS;
8376
}
84-
}
85-
}
8677

87-
public Long get(KEY key) {
88-
Objects.requireNonNull(key);
89-
90-
collect();
91-
return Long.valueOf(values.get(key).longValue());
92-
}
93-
94-
private void inc(KEY key, long increment) {
95-
Objects.requireNonNull(key);
96-
97-
values.get(key).getAndUpdate(new LongUnaryOperator() {
98-
99-
@Override
100-
public long applyAsLong(long currentValue) {
101-
return currentValue + increment + (currentValue == -1 ? 1 : 0);
78+
if (valueKey != null) {
79+
final Double kiloBytes = parseKiloBytes(line) * KILOBYTE;
80+
values.compute(valueKey, (key, value) -> (value == null) ? kiloBytes
81+
: value.doubleValue() + kiloBytes);
10282
}
83+
}
10384

104-
});
85+
return values;
10586
}
10687

107-
private static long parseKiloBytes(String line) {
88+
private static Double parseKiloBytes(String line) {
10889
Objects.requireNonNull(line);
10990

110-
return Long.parseLong(line.split("\\s+")[1]);
91+
return Double.parseDouble(line.split("\\s+")[1]);
11192
}
11293

11394
}

src/test/java/io/github/mweirauch/micrometer/jvm/extras/ProcessMemoryMetricsTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ public void testInstantiation() {
5151

5252
@Test
5353
public void testGetMetrics() throws Exception {
54-
when(smaps.get(KEY.VSS)).thenReturn(1L);
55-
when(smaps.get(KEY.RSS)).thenReturn(2L);
56-
when(smaps.get(KEY.PSS)).thenReturn(3L);
57-
when(smaps.get(KEY.SWAP)).thenReturn(4L);
58-
when(smaps.get(KEY.SWAPPSS)).thenReturn(5L);
54+
when(smaps.get(KEY.VSS)).thenReturn(1D);
55+
when(smaps.get(KEY.RSS)).thenReturn(2D);
56+
when(smaps.get(KEY.PSS)).thenReturn(3D);
57+
when(smaps.get(KEY.SWAP)).thenReturn(4D);
58+
when(smaps.get(KEY.SWAPPSS)).thenReturn(5D);
5959

6060
final SimpleMeterRegistry registry = new SimpleMeterRegistry();
6161
final ProcessMemoryMetrics uut = new ProcessMemoryMetrics(smaps);

src/test/java/io/github/mweirauch/micrometer/jvm/extras/procfs/ProcfsEntryTest.java

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package io.github.mweirauch.micrometer.jvm.extras.procfs;
1717

18+
import static org.junit.Assert.assertEquals;
1819
import static org.mockito.Mockito.mock;
1920
import static org.mockito.Mockito.spy;
2021
import static org.mockito.Mockito.verify;
@@ -25,14 +26,17 @@
2526
import java.io.IOException;
2627
import java.util.Arrays;
2728
import java.util.Collection;
29+
import java.util.HashMap;
2830
import java.util.List;
31+
import java.util.Map;
2932
import java.util.Objects;
3033

3134
import org.junit.Test;
3235

3336
import com.google.common.testing.NullPointerTester;
3437
import com.google.common.testing.NullPointerTester.Visibility;
3538

39+
import io.github.mweirauch.micrometer.jvm.extras.procfs.ProcfsEntry.ValueKey;
3640
import io.github.mweirauch.micrometer.jvm.extras.procfs.ProcfsReader.ReadResult;
3741

3842
public class ProcfsEntryTest {
@@ -50,22 +54,44 @@ public void testNullContract() {
5054
npt.testInstanceMethods(uut, Visibility.PACKAGE);
5155
}
5256

57+
@Test
58+
public void testValueHandling() throws IOException {
59+
final List<String> lines1 = Arrays.asList("1", "2", "3");
60+
final List<String> lines2 = Arrays.asList("1", "2");
61+
final ReadResult readResult1 = new ReadResult(lines1, 0);
62+
final ReadResult readResult2 = new ReadResult(lines2, 1);
63+
when(reader.read()).thenReturn(
64+
// first three calls to get()
65+
readResult1, readResult1, readResult1,
66+
// last three calls to get()
67+
readResult2, readResult2, readResult2);
68+
69+
assertEquals(Double.valueOf(1), uut.get(TestKey.ONE));
70+
assertEquals(Double.valueOf(2), uut.get(TestKey.TWO));
71+
assertEquals(Double.valueOf(3), uut.get(TestKey.THREE));
72+
73+
assertEquals(Double.valueOf(1), uut.get(TestKey.ONE));
74+
assertEquals(Double.valueOf(2), uut.get(TestKey.TWO));
75+
assertEquals(Double.valueOf(-1), uut.get(TestKey.THREE));
76+
}
77+
5378
@Test
5479
public void testCollectUpdated() throws Exception {
5580
final List<String> lines1 = Arrays.asList("1");
5681
final ReadResult readResult = spy(new ReadResult(lines1, 0));
5782
when(reader.read()).thenReturn(readResult);
5883
final ProcfsEntry entry = spy(uut);
5984

60-
entry.collect();
85+
entry.get(TestKey.ONE);
6186

6287
verify(reader).read();
6388
verifyNoMoreInteractions(reader);
6489
verify(readResult).getReadTime();
6590
verify(readResult).getLines();
6691
verifyNoMoreInteractions(readResult);
67-
verify(entry).reset();
92+
verify(entry).get(TestKey.ONE);
6893
verify(entry).handle(lines1);
94+
verify(entry).defaultValue();
6995
verifyNoMoreInteractions(entry);
7096
}
7197

@@ -88,7 +114,6 @@ public void testCollectCached() throws Exception {
88114
verify(readResult, times(2)).getReadTime();
89115
verify(readResult).getLines();
90116
verifyNoMoreInteractions(readResult);
91-
verify(entry).reset();
92117
verify(entry).handle(lines1);
93118
verifyNoMoreInteractions(entry);
94119
}
@@ -120,10 +145,8 @@ public void testCollectSharedReader() throws IOException {
120145
verify(readResult1, times(2)).getReadTime();
121146
verify(readResult1, times(2)).getLines();
122147
verifyNoMoreInteractions(readResult1);
123-
verify(entry1).reset();
124148
verify(entry1).handle(lines1);
125149
verifyNoMoreInteractions(entry1);
126-
verify(entry2).reset();
127150
verify(entry2).handle(lines1);
128151
verifyNoMoreInteractions(entry2);
129152

@@ -135,28 +158,49 @@ public void testCollectSharedReader() throws IOException {
135158
verify(readResult2, times(4)).getReadTime();
136159
verify(readResult2, times(2)).getLines();
137160
verifyNoMoreInteractions(readResult2);
138-
verify(entry1, times(2)).reset();
139161
verify(entry1).handle(lines2);
140162
verifyNoMoreInteractions(entry1);
141-
verify(entry2, times(2)).reset();
142163
verify(entry2).handle(lines2);
143164
verifyNoMoreInteractions(entry2);
144165
}
145166

167+
private enum TestKey implements ValueKey {
168+
ONE, TWO, THREE
169+
}
170+
146171
private static class TestProcfsEntry extends ProcfsEntry {
147172

148173
protected TestProcfsEntry(ProcfsReader reader) {
149174
super(reader);
150175
}
151176

152177
@Override
153-
protected void reset() {
154-
//
155-
}
156-
157-
@Override
158-
protected void handle(Collection<String> lines) {
178+
protected Map<ValueKey, Double> handle(Collection<String> lines) {
159179
Objects.requireNonNull(lines);
180+
181+
final Map<ValueKey, Double> values = new HashMap<>();
182+
183+
switch (lines.size()) {
184+
case 0:
185+
break;
186+
case 1:
187+
values.put(TestKey.ONE, 1D);
188+
break;
189+
case 2:
190+
values.put(TestKey.ONE, 1D);
191+
values.put(TestKey.TWO, 2D);
192+
break;
193+
case 3:
194+
values.put(TestKey.ONE, 1D);
195+
values.put(TestKey.TWO, 2D);
196+
values.put(TestKey.THREE, 3d);
197+
break;
198+
default:
199+
throw new IllegalArgumentException(
200+
"A maximum of 3 lines is supported. Fix your test!");
201+
}
202+
203+
return values;
160204
}
161205

162206
}

src/test/java/io/github/mweirauch/micrometer/jvm/extras/procfs/ProcfsSmapsTest.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -62,22 +62,22 @@ public void testInstantiation() {
6262
public void testSimple() {
6363
final ProcfsSmaps uut = new ProcfsSmaps(new ProcfsReader(BASE, "smaps-001.txt"));
6464

65-
assertEquals(Long.valueOf(4096), uut.get(KEY.VSS));
66-
assertEquals(Long.valueOf(4096), uut.get(KEY.RSS));
67-
assertEquals(Long.valueOf(2048), uut.get(KEY.PSS));
68-
assertEquals(Long.valueOf(0), uut.get(KEY.SWAP));
69-
assertEquals(Long.valueOf(-1), uut.get(KEY.SWAPPSS));
65+
assertEquals(Double.valueOf(4096), uut.get(KEY.VSS));
66+
assertEquals(Double.valueOf(4096), uut.get(KEY.RSS));
67+
assertEquals(Double.valueOf(2048), uut.get(KEY.PSS));
68+
assertEquals(Double.valueOf(0), uut.get(KEY.SWAP));
69+
assertEquals(Double.valueOf(-1), uut.get(KEY.SWAPPSS));
7070
}
7171

7272
@Test
7373
public void testComplex() {
7474
final ProcfsSmaps uut = new ProcfsSmaps(new ProcfsReader(BASE, "smaps-002.txt"));
7575

76-
assertEquals(Long.valueOf(4318720000L), uut.get(KEY.VSS));
77-
assertEquals(Long.valueOf(30535680), uut.get(KEY.RSS));
78-
assertEquals(Long.valueOf(20059136), uut.get(KEY.PSS));
79-
assertEquals(Long.valueOf(0), uut.get(KEY.SWAP));
80-
assertEquals(Long.valueOf(0), uut.get(KEY.SWAPPSS));
76+
assertEquals(Double.valueOf(4318720000L), uut.get(KEY.VSS));
77+
assertEquals(Double.valueOf(30535680), uut.get(KEY.RSS));
78+
assertEquals(Double.valueOf(20059136), uut.get(KEY.PSS));
79+
assertEquals(Double.valueOf(0), uut.get(KEY.SWAP));
80+
assertEquals(Double.valueOf(0), uut.get(KEY.SWAPPSS));
8181
}
8282

8383
@Test
@@ -87,11 +87,11 @@ public void testReturnDefaultValuesOnReaderFailure() throws IOException {
8787

8888
final ProcfsSmaps uut = new ProcfsSmaps(reader);
8989

90-
assertEquals(Long.valueOf(-1), uut.get(KEY.VSS));
91-
assertEquals(Long.valueOf(-1), uut.get(KEY.RSS));
92-
assertEquals(Long.valueOf(-1), uut.get(KEY.PSS));
93-
assertEquals(Long.valueOf(-1), uut.get(KEY.SWAP));
94-
assertEquals(Long.valueOf(-1), uut.get(KEY.SWAPPSS));
90+
assertEquals(Double.valueOf(-1), uut.get(KEY.VSS));
91+
assertEquals(Double.valueOf(-1), uut.get(KEY.RSS));
92+
assertEquals(Double.valueOf(-1), uut.get(KEY.PSS));
93+
assertEquals(Double.valueOf(-1), uut.get(KEY.SWAP));
94+
assertEquals(Double.valueOf(-1), uut.get(KEY.SWAPPSS));
9595
}
9696

9797
}

0 commit comments

Comments
 (0)