Skip to content

Commit 0b33ab4

Browse files
author
Zhen
committed
Finished adding histogram and finished connection pool metrics
1 parent 2c6aa9d commit 0b33ab4

16 files changed

+157
-36
lines changed

driver/src/main/java/org/neo4j/driver/internal/DriverFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import org.neo4j.driver.internal.cluster.loadbalancing.LoadBalancingStrategy;
3939
import org.neo4j.driver.internal.cluster.loadbalancing.RoundRobinLoadBalancingStrategy;
4040
import org.neo4j.driver.internal.logging.NettyLogging;
41-
import org.neo4j.driver.internal.metrics.DriverMetricsHandler;
41+
import org.neo4j.driver.internal.metrics.DriverMetricsListener;
4242
import org.neo4j.driver.internal.metrics.InternalAbstractDriverMetrics;
4343
import org.neo4j.driver.internal.metrics.InternalDriverMetrics;
4444
import org.neo4j.driver.internal.retry.ExponentialBackoffRetryLogic;
@@ -94,7 +94,7 @@ public final Driver newInstance( URI uri, AuthToken authToken, RoutingSettings r
9494
return driver;
9595
}
9696

97-
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsHandler metrics, Config config )
97+
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsListener metrics, Config config )
9898
{
9999
Clock clock = createClock();
100100
ConnectionSettings settings = new ConnectionSettings( authToken, config.connectionTimeoutMillis() );

driver/src/main/java/org/neo4j/driver/internal/async/pool/ConnectionPoolImpl.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@
3636
import org.neo4j.driver.internal.BoltServerAddress;
3737
import org.neo4j.driver.internal.async.ChannelConnector;
3838
import org.neo4j.driver.internal.async.NettyConnection;
39-
import org.neo4j.driver.internal.metrics.DriverMetricsHandler;
39+
import org.neo4j.driver.internal.metrics.DriverMetricsListener;
4040
import org.neo4j.driver.internal.metrics.ListenerEvent;
41-
import org.neo4j.driver.internal.metrics.SimpleTimerListenerEvent;
4241
import org.neo4j.driver.internal.spi.Connection;
4342
import org.neo4j.driver.internal.spi.ConnectionPool;
4443
import org.neo4j.driver.internal.util.Clock;
@@ -56,19 +55,19 @@ public class ConnectionPoolImpl implements ConnectionPool
5655
private final PoolSettings settings;
5756
private final Clock clock;
5857
private final Logger log;
59-
private DriverMetricsHandler driverMetrics;
58+
private DriverMetricsListener driverMetrics;
6059

6160
private final ConcurrentMap<BoltServerAddress,ChannelPool> pools = new ConcurrentHashMap<>();
6261
private final AtomicBoolean closed = new AtomicBoolean();
6362

6463
public ConnectionPoolImpl( ChannelConnector connector, Bootstrap bootstrap, PoolSettings settings,
65-
DriverMetricsHandler metricsHandler, Logging logging, Clock clock )
64+
DriverMetricsListener metricsHandler, Logging logging, Clock clock )
6665
{
6766
this( connector, bootstrap, new NettyChannelTracker( metricsHandler, logging ), settings, metricsHandler, logging, clock );
6867
}
6968

7069
ConnectionPoolImpl( ChannelConnector connector, Bootstrap bootstrap, NettyChannelTracker nettyChannelTracker,
71-
PoolSettings settings, DriverMetricsHandler driverMetrics, Logging logging, Clock clock )
70+
PoolSettings settings, DriverMetricsListener driverMetrics, Logging logging, Clock clock )
7271
{
7372
this.connector = connector;
7473
this.bootstrap = bootstrap;
@@ -85,11 +84,10 @@ public CompletionStage<Connection> acquire( BoltServerAddress address )
8584
{
8685
log.trace( "Acquiring a connection from pool towards %s", address );
8786

88-
// TODO no need to init if no driver metrics
89-
ListenerEvent acquireEvent = new SimpleTimerListenerEvent();
90-
9187
assertNotClosed();
9288
ChannelPool pool = getOrCreatePool( address );
89+
90+
ListenerEvent acquireEvent = driverMetrics.createListenerEvent();
9391
driverMetrics.beforeAcquiring( address, acquireEvent );
9492
Future<Channel> connectionFuture = pool.acquire();
9593

driver/src/main/java/org/neo4j/driver/internal/async/pool/NettyChannelTracker.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import java.util.concurrent.atomic.AtomicInteger;
2727

2828
import org.neo4j.driver.internal.BoltServerAddress;
29-
import org.neo4j.driver.internal.metrics.DriverMetricsHandler;
29+
import org.neo4j.driver.internal.metrics.DriverMetricsListener;
3030
import org.neo4j.driver.v1.Logger;
3131
import org.neo4j.driver.v1.Logging;
3232

@@ -37,9 +37,9 @@ public class NettyChannelTracker implements ChannelPoolHandler
3737
private final Map<BoltServerAddress,AtomicInteger> addressToInUseChannelCount = new ConcurrentHashMap<>();
3838
private final Map<BoltServerAddress,AtomicInteger> addressToIdleChannelCount = new ConcurrentHashMap<>();
3939
private final Logger log;
40-
private DriverMetricsHandler metricsHandler;
40+
private DriverMetricsListener metricsHandler;
4141

42-
public NettyChannelTracker( DriverMetricsHandler metricsHandler, Logging logging )
42+
public NettyChannelTracker( DriverMetricsListener metricsHandler, Logging logging )
4343
{
4444
this.metricsHandler = metricsHandler;
4545
this.log = logging.getLog( getClass().getSimpleName() );

driver/src/main/java/org/neo4j/driver/internal/metrics/DriverMetricsHandler.java renamed to driver/src/main/java/org/neo4j/driver/internal/metrics/DriverMetricsListener.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import org.neo4j.driver.internal.BoltServerAddress;
2222
import org.neo4j.driver.internal.spi.ConnectionPool;
2323

24-
public interface DriverMetricsHandler
24+
public interface DriverMetricsListener
2525
{
2626
void addPoolMetrics(BoltServerAddress serverAddress, ConnectionPool pool);
2727

@@ -36,4 +36,6 @@ public interface DriverMetricsHandler
3636
void beforeAcquiring( BoltServerAddress serverAddress, ListenerEvent listenerEvent );
3737

3838
void afterAcquired( BoltServerAddress serverAddress, ListenerEvent listenerEvent );
39+
40+
ListenerEvent createListenerEvent();
3941
}

driver/src/main/java/org/neo4j/driver/internal/metrics/HistogramSanpshot.java renamed to driver/src/main/java/org/neo4j/driver/internal/metrics/HistogramSnapshot.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,23 @@
2020

2121
import org.neo4j.driver.internal.metrics.spi.Histogram;
2222

23-
public class HistogramSanpshot implements Histogram
23+
public class HistogramSnapshot implements Histogram
2424
{
2525
private Histogram copy;
2626
private Histogram origin;
2727

28-
public HistogramSanpshot( Histogram copy, Histogram origin )
28+
public HistogramSnapshot( Histogram copy, Histogram origin )
2929
{
3030
this.copy = copy;
3131
this.origin = origin;
3232
}
3333

34+
@Override
35+
public long min()
36+
{
37+
return copy.min();
38+
}
39+
3440
@Override
3541
public long max()
3642
{

driver/src/main/java/org/neo4j/driver/internal/metrics/InternalAbstractDriverMetrics.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.neo4j.driver.internal.metrics.spi.DriverMetrics;
2727
import org.neo4j.driver.internal.spi.ConnectionPool;
2828

29-
public abstract class InternalAbstractDriverMetrics implements DriverMetrics, DriverMetricsHandler
29+
public abstract class InternalAbstractDriverMetrics implements DriverMetrics, DriverMetricsListener
3030
{
3131
public static final InternalAbstractDriverMetrics DEV_NULL_METRICS = new InternalAbstractDriverMetrics()
3232
{
@@ -72,6 +72,12 @@ public void afterAcquired( BoltServerAddress serverAddress, ListenerEvent listen
7272

7373
}
7474

75+
@Override
76+
public ListenerEvent createListenerEvent()
77+
{
78+
return null;
79+
}
80+
7581
@Override
7682
public Map<String,ConnectionPoolMetrics> connectionPoolMetrics()
7783
{

driver/src/main/java/org/neo4j/driver/internal/metrics/InternalConnectionPoolMetrics.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ public Histogram acquisitionTimeHistogram()
152152
@Override
153153
public String toString()
154154
{
155-
return format( "[created=%s, closed=%s, toCreate=%s, failedToCreate=%s inUse=%s, idle=%s, poolStatus=%s, acquisitionTimeHistogram=%n%s]",
155+
return format( "[created=%s, closed=%s, toCreate=%s, failedToCreate=%s inUse=%s, idle=%s, poolStatus=%s, acquisitionTimeHistogram=%s]",
156156
created(), closed(), toCreate(), failedToCreate(), inUse(), idle(), poolStatus(), acquisitionTimeHistogram() );
157157
}
158158
}

driver/src/main/java/org/neo4j/driver/internal/metrics/InternalDriverMetrics.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ public void afterAcquired( BoltServerAddress serverAddress, ListenerEvent listen
9292
poolMetrics.afterAcquire( listenerEvent );
9393
}
9494

95+
@Override
96+
public ListenerEvent createListenerEvent()
97+
{
98+
return new NanoTimeBasedListenerEvent();
99+
}
100+
95101
@Override
96102
public Map<String,ConnectionPoolMetrics> connectionPoolMetrics()
97103
{

driver/src/main/java/org/neo4j/driver/internal/metrics/InternalHistogram.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727

2828
import org.neo4j.driver.internal.metrics.spi.Histogram;
2929

30+
import static java.lang.String.format;
31+
3032
public class InternalHistogram implements Histogram
3133
{
32-
private static final long DEFAULT_HIGHEST_TRACKABLE_MS = Duration.ofMinutes( 10 ).toMillis();
34+
private static final long DEFAULT_HIGHEST_TRACKABLE_MS = Duration.ofMinutes( 10 ).toNanos();
3335

3436
private final AbstractHistogram delegate;
3537

@@ -54,6 +56,12 @@ public void recordValue( long value )
5456
this.delegate.recordValue( newValue );
5557
}
5658

59+
@Override
60+
public long min()
61+
{
62+
return delegate.getMinValue();
63+
}
64+
5765
@Override
5866
public long max()
5967
{
@@ -109,11 +117,17 @@ private static long truncateValue( long value, AbstractHistogram histogram )
109117

110118
public Histogram snapshot()
111119
{
112-
return new HistogramSanpshot( new InternalHistogram( this.delegate.copy() ), this );
120+
return new HistogramSnapshot( new InternalHistogram( this.delegate.copy() ), this );
113121
}
114122

115123
@Override
116124
public String toString()
125+
{
126+
return format("[min=%sns, max=%sns, mean=%sns, stdDeviation=%s, totalCount=%s]",
127+
min(), max(), mean(), stdDeviation(), totalCount());
128+
}
129+
130+
public String printDistribution()
117131
{
118132
ByteArrayOutputStream stream = new ByteArrayOutputStream();
119133
PrintStream writer = new PrintStream( stream );

driver/src/main/java/org/neo4j/driver/internal/metrics/SimpleTimerListenerEvent.java renamed to driver/src/main/java/org/neo4j/driver/internal/metrics/NanoTimeBasedListenerEvent.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@
1919

2020
package org.neo4j.driver.internal.metrics;
2121

22-
public class SimpleTimerListenerEvent implements ListenerEvent
22+
public class NanoTimeBasedListenerEvent implements ListenerEvent
2323
{
24-
private long startTimestamp;
24+
private long startNanoTime;
2525

2626
@Override
2727
public void start()
2828
{
29-
startTimestamp = System.currentTimeMillis();
29+
startNanoTime = System.nanoTime();
3030
}
3131

3232
@Override
3333
public long elapsed()
3434
{
35-
return System.currentTimeMillis() - startTimestamp;
35+
return System.nanoTime() - startNanoTime;
3636
}
3737
}

driver/src/main/java/org/neo4j/driver/internal/metrics/spi/Histogram.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
public interface Histogram
2222
{
23+
long min();
2324
long max();
2425
double mean();
2526
double stdDeviation();

driver/src/test/java/org/neo4j/driver/internal/DriverFactoryTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
import org.neo4j.driver.internal.async.BootstrapFactory;
3434
import org.neo4j.driver.internal.cluster.RoutingSettings;
3535
import org.neo4j.driver.internal.cluster.loadbalancing.LoadBalancer;
36-
import org.neo4j.driver.internal.metrics.DriverMetricsHandler;
36+
import org.neo4j.driver.internal.metrics.DriverMetricsListener;
3737
import org.neo4j.driver.internal.metrics.InternalDriverMetrics;
3838
import org.neo4j.driver.internal.retry.RetryLogic;
3939
import org.neo4j.driver.internal.retry.RetrySettings;
@@ -185,7 +185,7 @@ public void shouldNotCreateDriverMetrics() throws Throwable
185185
// Given
186186
Config config = mock( Config.class );
187187
// When
188-
DriverMetricsHandler handler = DriverFactory.createDriverMetrics( config );
188+
DriverMetricsListener handler = DriverFactory.createDriverMetrics( config );
189189
// Then
190190
assertThat( handler, is( DEV_NULL_METRICS ) );
191191
}
@@ -197,7 +197,7 @@ public void shouldCreateDriverMetricsIfMonitoringEnabled() throws Throwable
197197
System.setProperty( "driver.metrics.enabled", "True" );
198198
Config config = mock( Config.class );
199199
// When
200-
DriverMetricsHandler handler = DriverFactory.createDriverMetrics( config );
200+
DriverMetricsListener handler = DriverFactory.createDriverMetrics( config );
201201
// Then
202202
assertThat( handler instanceof InternalDriverMetrics, is( true ) );
203203
}
@@ -247,7 +247,7 @@ protected InternalDriver createRoutingDriver( BoltServerAddress address, Connect
247247
}
248248

249249
@Override
250-
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsHandler metrics, Config config )
250+
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsListener metrics, Config config )
251251
{
252252
return connectionPool;
253253
}
@@ -282,7 +282,7 @@ protected SessionFactory createSessionFactory( ConnectionProvider connectionProv
282282
}
283283

284284
@Override
285-
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsHandler metrics, Config config )
285+
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsListener metrics, Config config )
286286
{
287287
return connectionPoolMock();
288288
}
@@ -304,7 +304,7 @@ protected Bootstrap createBootstrap()
304304
}
305305

306306
@Override
307-
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsHandler metrics, Config config )
307+
protected ConnectionPool createConnectionPool( AuthToken authToken, SecurityPlan securityPlan, Bootstrap bootstrap, DriverMetricsListener metrics, Config config )
308308
{
309309
return connectionPoolMock();
310310
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2002-2018 "Neo Technology,"
3+
* Network Engine for Objects in Lund AB [http://neotechnology.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.internal.metrics;
20+
21+
import org.junit.Test;
22+
23+
import org.neo4j.driver.internal.metrics.spi.Histogram;
24+
25+
import static java.lang.Math.abs;
26+
import static org.hamcrest.Matchers.equalTo;
27+
import static org.hamcrest.Matchers.lessThan;
28+
import static org.junit.Assert.assertThat;
29+
30+
public class InternalHistogramTest
31+
{
32+
@Test
33+
public void shouldRecordSmallValuesPrecisely() throws Throwable
34+
{
35+
// Given
36+
InternalHistogram histogram = new InternalHistogram();
37+
histogram.recordValue( 0 );
38+
histogram.recordValue( 1 );
39+
histogram.recordValue( 2 );
40+
histogram.recordValue( 3 );
41+
histogram.recordValue( 4 );
42+
43+
// When
44+
assertThat( histogram.min(), equalTo( 0L ) );
45+
assertThat( histogram.max(), equalTo( 4L ) );
46+
assertThat( histogram.mean(), equalTo( 2.0 ) );
47+
assertThat( histogram.totalCount(), equalTo( 5L ) );
48+
}
49+
50+
@Test
51+
public void shouldRecordBigValuesPrecisely() throws Throwable
52+
{
53+
// Given
54+
InternalHistogram histogram = new InternalHistogram();
55+
histogram.recordValue( 0 );
56+
histogram.recordValue( 100000 );
57+
histogram.recordValue( 200000 );
58+
histogram.recordValue( 300000 );
59+
histogram.recordValue( 400000 );
60+
61+
// When
62+
assertThat( histogram.min(), equalTo( 0L ) );
63+
assertThat( abs( histogram.max() - 400000L ), lessThan( 500L ) );
64+
assertThat( abs( histogram.mean() - 200000.0 ), lessThan( 500.0 ) );
65+
assertThat( histogram.totalCount(), equalTo( 5L ) );
66+
}
67+
68+
@Test
69+
public void shouldResetOnOriginalHistogram() throws Throwable
70+
{
71+
// Given
72+
InternalHistogram histogram = new InternalHistogram();
73+
histogram.recordValue( 0 );
74+
histogram.recordValue( 1 );
75+
histogram.recordValue( 2 );
76+
histogram.recordValue( 3 );
77+
histogram.recordValue( 4 );
78+
79+
// When
80+
assertThat( histogram.totalCount(), equalTo( 5L ) );
81+
Histogram snapshot = histogram.snapshot();
82+
snapshot.reset();
83+
84+
// Then
85+
assertThat( histogram.totalCount(), equalTo( 0L ) );
86+
}
87+
88+
}

0 commit comments

Comments
 (0)