Skip to content

Commit 10e4f70

Browse files
authored
Merge pull request #30 from graphfoundation/story-threadLogging-3.3
3.3 - Thread Logging
2 parents 4733081 + 05fd5da commit 10e4f70

File tree

4 files changed

+103
-6
lines changed

4 files changed

+103
-6
lines changed

src/main/java/apoc/ApocKernelExtensionFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public IndexUpdateTransactionEventHandler.LifeCycle getIndexUpdateLifeCycle() {
7171
public void start() throws Throwable {
7272
ApocConfiguration.initialize(db);
7373
Pools.NEO4J_SCHEDULER = dependencies.scheduler();
74+
ThreadPoolExecutorLogger.LOG = log.getUserLog( ThreadPoolExecutorLogger.class );
7475
registerCustomProcedures();
7576
ttlLifeCycle = new TTLLifeCycle(Pools.NEO4J_SCHEDULER, db, log.getUserLog(TTLLifeCycle.class));
7677
ttlLifeCycle.start();

src/main/java/apoc/Pools.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class Pools {
1616
static final String CONFIG_JOBS_SCHEDULED_NUM_THREADS = "jobs.scheduled.num_threads";
1717
static final String CONFIG_JOBS_POOL_NUM_THREADS = "jobs.pool.num_threads";
1818
static final String CONFIG_BROKERS_NUM_THREADS = "brokers.num_threads";
19+
static final String CONFIG_DEBUG_LOG_THREADS = "jobs.debug.logs";
1920

2021
public final static int DEFAULT_SCHEDULED_THREADS = Runtime.getRuntime().availableProcessors() / 4;
2122
public final static int DEFAULT_POOL_THREADS = Runtime.getRuntime().availableProcessors() * 2;
@@ -46,9 +47,8 @@ private Pools() {
4647
public static ExecutorService createDefaultPool() {
4748
int threads = getNoThreadsInDefaultPool();
4849
int queueSize = threads * 25;
49-
return new ThreadPoolExecutor(threads / 2, threads, 30L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(queueSize),
50-
new CallerBlocksPolicy());
51-
// new ThreadPoolExecutor.CallerRunsPolicy());
50+
return new ThreadPoolExecutorLogger(threads / 2, threads, 30L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(queueSize),
51+
new CallerBlocksPolicy(), "DEFAULT", threadPoolDebug());
5252
}
5353
static class CallerBlocksPolicy implements RejectedExecutionHandler {
5454
@Override
@@ -80,7 +80,9 @@ public static int getNoThreadsInBrokerPool() {
8080
}
8181

8282
private static ExecutorService createSinglePool() {
83-
return Executors.newSingleThreadExecutor();
83+
return new ThreadPoolExecutorLogger(1, 1,
84+
0L, TimeUnit.MILLISECONDS,
85+
new LinkedBlockingQueue<Runnable>(), "SINGLE", threadPoolDebug() );
8486
}
8587

8688
private static ScheduledExecutorService createScheduledPool() {
@@ -90,8 +92,8 @@ private static ScheduledExecutorService createScheduledPool() {
9092
private static ExecutorService createBrokerPool() {
9193
int threads = getNoThreadsInBrokerPool();
9294
int queueSize = threads * 25;
93-
return new ThreadPoolExecutor(threads / 2, threads, 30L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(queueSize),
94-
new CallerBlocksPolicy());
95+
return new ThreadPoolExecutorLogger(threads / 2, threads, 30L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(queueSize),
96+
new CallerBlocksPolicy(), "BROKER", threadPoolDebug() );
9597
}
9698

9799
public static <T> Future<Void> processBatch(List<T> batch, GraphDatabaseService db, Consumer<T> action) {
@@ -114,4 +116,9 @@ public static <T> T force(Future<T> future) throws ExecutionException {
114116
}
115117
}
116118
}
119+
120+
public static Boolean threadPoolDebug()
121+
{
122+
return Boolean.valueOf( ApocConfiguration.get( CONFIG_DEBUG_LOG_THREADS, "false" ) );
123+
}
117124
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package apoc;
2+
3+
import org.neo4j.logging.Log;
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
import java.util.concurrent.BlockingQueue;
8+
import java.util.concurrent.RejectedExecutionHandler;
9+
import java.util.concurrent.ThreadPoolExecutor;
10+
import java.util.concurrent.TimeUnit;
11+
12+
public class ThreadPoolExecutorLogger extends ThreadPoolExecutor
13+
{
14+
public static Log LOG;
15+
private Boolean debugLog;
16+
private String poolName;
17+
18+
public ThreadPoolExecutorLogger( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
19+
String poolName, Boolean threadPoolDebug )
20+
{
21+
super( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue );
22+
this.poolName = poolName;
23+
this.debugLog = threadPoolDebug;
24+
}
25+
26+
public ThreadPoolExecutorLogger( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue,
27+
RejectedExecutionHandler handler, String poolName, Boolean threadPoolDebug )
28+
{
29+
super( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler );
30+
this.poolName = poolName;
31+
this.debugLog = threadPoolDebug;
32+
}
33+
34+
@Override
35+
protected void beforeExecute( Thread t, Runnable r )
36+
{
37+
if ( LOG != null && debugLog )
38+
{
39+
LOG.debug( "BeforeExecute Logging:\n" +
40+
"Pool: " + this.poolName + "\n" +
41+
"Active Thread Count: " + this.getActiveCount() + "\n" +
42+
"Thread Name: " + t.getName() + "\n" +
43+
"Thread Id: " + t.getId() + "\n" +
44+
"Thread Priority: " + t.getPriority() + "\n"
45+
);
46+
}
47+
super.beforeExecute( t, r );
48+
}
49+
50+
public Log getLog()
51+
{
52+
return LOG;
53+
}
54+
55+
public void setLog( Log log )
56+
{
57+
this.LOG = log;
58+
}
59+
60+
public Map<String,Object> getInfo()
61+
{
62+
Map<String,Object> loggingResult = new HashMap<>( );
63+
loggingResult.put( "poolName", poolName );
64+
loggingResult.put( "activeCount", this.getActiveCount() );
65+
loggingResult.put( "corePoolSize", this.getCorePoolSize() );
66+
loggingResult.put( "poolSize", this.getPoolSize() );
67+
loggingResult.put( "largestPoolSize", this.getLargestPoolSize() );
68+
loggingResult.put( "maximumPoolSize", this.getMaximumPoolSize() );
69+
loggingResult.put( "taskCount", this.getTaskCount() );
70+
loggingResult.put( "completedTaskCount", this.getCompletedTaskCount() );
71+
72+
return loggingResult;
73+
}
74+
}

src/main/java/apoc/log/Logging.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package apoc.log;
22

3+
import apoc.Pools;
4+
import apoc.ThreadPoolExecutorLogger;
5+
import apoc.result.MapResult;
36
import org.neo4j.logging.Log;
47
import org.neo4j.procedure.Context;
58
import org.neo4j.procedure.Description;
69
import org.neo4j.procedure.Name;
710
import org.neo4j.procedure.Procedure;
11+
812
import java.util.Map;
13+
import java.util.stream.Stream;
914

1015
/**
1116
* @author bradnussbaum
@@ -49,4 +54,14 @@ public void debug( @Name( "message" ) String message,
4954
log.debug( message, params );
5055
}
5156

57+
@Procedure
58+
@Description( "apoc.log.threadPools() - logs threading info." )
59+
public Stream<MapResult> threadPools()
60+
{
61+
Map<String,Object> singleInfo = ((ThreadPoolExecutorLogger) Pools.SINGLE).getInfo();
62+
Map<String,Object> defaultInfo = ((ThreadPoolExecutorLogger) Pools.DEFAULT).getInfo();
63+
Map<String,Object> brokerInfo = ((ThreadPoolExecutorLogger) Pools.BROKER).getInfo();
64+
65+
return Stream.of( new MapResult( singleInfo ), new MapResult( defaultInfo ), new MapResult( brokerInfo ) );
66+
}
5267
}

0 commit comments

Comments
 (0)