diff --git a/community/dbms/pom.xml b/community/dbms/pom.xml
index 40b011141a6c7..f2994605bf52b 100644
--- a/community/dbms/pom.xml
+++ b/community/dbms/pom.xml
@@ -164,6 +164,11 @@
${project.version}
+
+ org.jprocesses
+ jProcesses
+
+
org.apache.commons
commons-compress
diff --git a/community/dbms/src/main/java/org/neo4j/commandline/dbms/DiagnosticsReportCommand.java b/community/dbms/src/main/java/org/neo4j/commandline/dbms/DiagnosticsReportCommand.java
index 46fbea10655be..d032483afe9a9 100644
--- a/community/dbms/src/main/java/org/neo4j/commandline/dbms/DiagnosticsReportCommand.java
+++ b/community/dbms/src/main/java/org/neo4j/commandline/dbms/DiagnosticsReportCommand.java
@@ -19,6 +19,9 @@
*/
package org.neo4j.commandline.dbms;
+import org.jutils.jprocesses.JProcesses;
+import org.jutils.jprocesses.model.ProcessInfo;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
@@ -30,6 +33,7 @@
import java.util.Date;
import java.util.HashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -43,9 +47,10 @@
import org.neo4j.commandline.arguments.OptionalNamedArg;
import org.neo4j.commandline.arguments.PositionalArgument;
import org.neo4j.commandline.arguments.common.OptionalCanonicalPath;
-import org.neo4j.dbms.report.jmx.JmxDump;
-import org.neo4j.dbms.report.jmx.LocalVirtualMachine;
+import org.neo4j.dbms.diagnostics.jmx.JmxDump;
+import org.neo4j.dbms.diagnostics.jmx.LocalVirtualMachine;
import org.neo4j.diagnostics.DiagnosticsOfflineReportProvider;
+import org.neo4j.diagnostics.DiagnosticsReportSource;
import org.neo4j.diagnostics.DiagnosticsReportSources;
import org.neo4j.diagnostics.DiagnosticsReporter;
import org.neo4j.helpers.Args;
@@ -57,7 +62,7 @@
public class DiagnosticsReportCommand implements AdminCommand
{
- private static OptionalNamedArg destinationArgument =
+ private static final OptionalNamedArg destinationArgument =
new OptionalCanonicalPath( "to", "/tmp/", "reports/", "Destination directory for reports" );
private static final Arguments arguments = new Arguments()
.withArgument( new OptionalListArgument() )
@@ -67,18 +72,16 @@ public class DiagnosticsReportCommand implements AdminCommand
private final Path homeDir;
private final Path configDir;
- private final OutsideWorld outsideWorld;
static final String[] DEFAULT_CLASSIFIERS = new String[]{"logs", "config"};
private boolean verbose;
- private PrintStream err;
- private PrintStream out;
- private FileSystemAbstraction fs;
+ private final PrintStream err;
+ private final PrintStream out;
+ private final FileSystemAbstraction fs;
DiagnosticsReportCommand( Path homeDir, Path configDir, OutsideWorld outsideWorld )
{
this.homeDir = homeDir;
this.configDir = configDir;
- this.outsideWorld = outsideWorld;
this.fs = outsideWorld.fileSystem();
this.out = outsideWorld.outStream();
this.err = outsideWorld.errorStream();
@@ -103,31 +106,7 @@ public void execute( String[] stringArgs ) throws IncorrectUsage, CommandFailed
}
Config config = Config.fromFile( configFile ).withHome( homeDir ).withConnectorsDisabled().build();
- File storeDirectory = config.get( database_path );
-
- DiagnosticsReporter reporter = new DiagnosticsReporter( out );
-
- // Find all offline providers and register them
- for ( DiagnosticsOfflineReportProvider provider : Service.load( DiagnosticsOfflineReportProvider.class ) )
- {
- provider.init( fs, config, storeDirectory );
- reporter.registerOfflineProvider( provider );
- }
-
- // Register sources provided by this tool
- reporter.registerSource( "config",
- DiagnosticsReportSources.newDiagnosticsFile( "neo4j.conf", fs, configFile ) );
-
- // Online connection
- JmxDump jmxDump = connectToNeo4jInstance();
- if ( jmxDump != null )
- {
- reporter.registerSource( "threads", jmxDump.threadDump() );
- reporter.registerSource( "heap", jmxDump.heapDump() );
- reporter.registerSource( "sysprop", jmxDump.systemProperties() );
- //reporter.registerSource( "env", null );
- }
-
+ DiagnosticsReporter reporter = createAndRegisterSources( config, configFile );
Set availableClassifiers = reporter.getAvailableClassifiers();
// Passing '--list' should print list and end execution
@@ -188,9 +167,73 @@ public void execute( String[] stringArgs ) throws IncorrectUsage, CommandFailed
}
}
- private JmxDump connectToNeo4jInstance()
+ private DiagnosticsReporter createAndRegisterSources( Config config, File configFile )
+ {
+ DiagnosticsReporter reporter = new DiagnosticsReporter( out );
+ File storeDirectory = config.get( database_path );
+
+ // Find all offline providers and register them
+ for ( DiagnosticsOfflineReportProvider provider : Service.load( DiagnosticsOfflineReportProvider.class ) )
+ {
+ provider.init( fs, config, storeDirectory );
+ reporter.registerOfflineProvider( provider );
+ }
+
+ // Register sources provided by this tool
+ reporter.registerSource( "config", DiagnosticsReportSources.newDiagnosticsFile( "neo4j.conf", fs, configFile ) );
+ reporter.registerSource( "ps", runningProcesses() );
+
+ // Online connection
+ Optional jmxDump = connectToNeo4jInstance();
+ if ( jmxDump.isPresent() )
+ {
+ JmxDump jmx = jmxDump.get();
+ reporter.registerSource( "threads", jmx.threadDump() );
+ reporter.registerSource( "heap", jmx.heapDump() );
+ reporter.registerSource( "sysprop", jmx.systemProperties() );
+ //reporter.registerSource( "env", null ); // TODO:
+ }
+ return reporter;
+ }
+
+ private Optional connectToNeo4jInstance()
{
out.println( "Trying to find running instance of neo4j" );
+
+ Optional pid = getPid();
+ if ( pid.isPresent() )
+ {
+ try
+ {
+ LocalVirtualMachine vm = LocalVirtualMachine.from( pid.get() );
+ out.println( "Attached to running process with process id " + pid );
+ try
+ {
+ JmxDump jmxDump = JmxDump.connectTo( vm.getJmxAddress() );
+ jmxDump.attachSystemProperties( vm.getSystemProperties() );
+ out.println( "Connected to JMX endpoint" );
+ return Optional.of( jmxDump );
+ }
+ catch ( IOException e )
+ {
+ printError( "Unable to communicate with JMX endpoint. Reason: " + e.getMessage(), e );
+ }
+ }
+ catch ( IOException e )
+ {
+ printError( "Unable to connect to process. Reason: " + e.getMessage(), e );
+ }
+ }
+ else
+ {
+ out.println( "No running instance of neo4j was found. Online reports will be omitted." );
+ }
+
+ return Optional.empty();
+ }
+
+ private Optional getPid()
+ {
Path pidFile = homeDir.resolve( "run/neo4j.pid" );
if ( fs.fileExists( pidFile.toFile() ) )
{
@@ -199,29 +242,9 @@ private JmxDump connectToNeo4jInstance()
String pidFileContent = reader.readLine();
try
{
- long pid = Long.parseLong( pidFileContent );
-
- try
- {
- LocalVirtualMachine vm = LocalVirtualMachine.from( pid );
- out.println( "Attached to running process with process id " + pid );
- try
- {
- JmxDump jmxDump = JmxDump.connectTo( vm.getJmxAddress() );
- jmxDump.attachSystemProperties( vm.getSystemProperties() );
- out.println( "Connected to JMX endpoint" );
- return jmxDump;
- }
- catch ( IOException e )
- {
- printError( "Unable to communicate with JMX endpoint. Reason: " + e.getMessage(), e );
- }
- }
- catch ( IOException e )
- {
- printError( "Unable to connect to process. Reason: " + e.getMessage(), e );
- }
+ return Optional.of( Long.parseLong( pidFileContent ) );
}
+
catch ( NumberFormatException e )
{
printError( pidFile.toString() + " does not contain a valid id. Found: " + pidFileContent );
@@ -232,12 +255,7 @@ private JmxDump connectToNeo4jInstance()
printError( "Error reading the .pid file. Reason: " + e.getMessage(), e );
}
}
- else
- {
- out.println( "No running instance of neo4j was found. Online reports will be omitted." );
- }
-
- return null;
+ return Optional.empty();
}
private void printError( String message )
@@ -282,11 +300,37 @@ static String describeClassifier( String classifier )
return "include the raft log";
case "queries":
return "include the output of dbms.listQueries()";
+ case "ps":
+ return "include a list of running processes";
default:
}
throw new IllegalArgumentException( "Unknown classifier: " + classifier );
}
+ private static DiagnosticsReportSource runningProcesses()
+ {
+ return DiagnosticsReportSources.newDiagnosticsString( "ps.txt", () ->
+ {
+ List processesList = JProcesses.getProcessList();
+
+ StringBuilder sb = new StringBuilder();
+ for (final ProcessInfo processInfo : processesList) {
+ sb.append( "Process PID: " ).append( processInfo.getPid() ).append( '\n' )
+ .append( "Process Name: " ).append( processInfo.getName() ).append( '\n' )
+ .append( "Process Time: " ).append( processInfo.getTime() ).append( '\n' )
+ .append( "User: " ).append( processInfo.getUser() ).append( '\n' )
+ .append( "Virtual Memory: " ).append( processInfo.getVirtualMemory() ).append( '\n' )
+ .append( "Physical Memory: " ).append( processInfo.getPhysicalMemory() ).append( '\n' )
+ .append( "CPU usage: " ).append( processInfo.getCpuUsage() ).append( '\n' )
+ .append( "Start Time: " ).append( processInfo.getStartTime() ).append( '\n' )
+ .append( "Priority: " ).append( processInfo.getPriority() ).append( '\n' )
+ .append( "Full command: " ).append( processInfo.getCommand() ).append( '\n' )
+ .append("------------------").append( '\n' );
+ }
+ return sb.toString();
+ });
+ }
+
/**
* Helper class to format output of {@link Usage}. Parsing is done manually in this command module.
*/
diff --git a/community/dbms/src/main/java/org/neo4j/dbms/report/jmx/JmxDump.java b/community/dbms/src/main/java/org/neo4j/dbms/diagnostics/jmx/JmxDump.java
similarity index 97%
rename from community/dbms/src/main/java/org/neo4j/dbms/report/jmx/JmxDump.java
rename to community/dbms/src/main/java/org/neo4j/dbms/diagnostics/jmx/JmxDump.java
index b715e1721d832..ed9bb97b4b2e8 100644
--- a/community/dbms/src/main/java/org/neo4j/dbms/report/jmx/JmxDump.java
+++ b/community/dbms/src/main/java/org/neo4j/dbms/diagnostics/jmx/JmxDump.java
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.neo4j.dbms.report.jmx;
+package org.neo4j.dbms.diagnostics.jmx;
import com.sun.management.HotSpotDiagnosticMXBean;
@@ -193,8 +193,10 @@ public void addToArchive( Path archiveDestination, DiagnosticsReporterProgressCa
monitor.info( "archiving..." );
long size = Files.size( tempFile );
InputStream in = Files.newInputStream( tempFile );
- ProgressAwareInputStream inStream = new ProgressAwareInputStream( in, size, monitor::percentChanged );
- Files.copy( inStream, archiveDestination );
+ try ( ProgressAwareInputStream inStream = new ProgressAwareInputStream( in, size, monitor::percentChanged ) )
+ {
+ Files.copy( inStream, archiveDestination );
+ }
Files.delete( tempFile );
}
diff --git a/community/dbms/src/main/java/org/neo4j/dbms/report/jmx/LocalVirtualMachine.java b/community/dbms/src/main/java/org/neo4j/dbms/diagnostics/jmx/LocalVirtualMachine.java
similarity index 98%
rename from community/dbms/src/main/java/org/neo4j/dbms/report/jmx/LocalVirtualMachine.java
rename to community/dbms/src/main/java/org/neo4j/dbms/diagnostics/jmx/LocalVirtualMachine.java
index 1f3a0c2cf6e2e..0469f9624b5d1 100644
--- a/community/dbms/src/main/java/org/neo4j/dbms/report/jmx/LocalVirtualMachine.java
+++ b/community/dbms/src/main/java/org/neo4j/dbms/diagnostics/jmx/LocalVirtualMachine.java
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.neo4j.dbms.report.jmx;
+package org.neo4j.dbms.diagnostics.jmx;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
diff --git a/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandIT.java b/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandIT.java
index 099f483091912..cffc2a03356c3 100644
--- a/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandIT.java
+++ b/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandIT.java
@@ -20,7 +20,6 @@
package org.neo4j.commandline.dbms;
import org.junit.After;
-import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -45,6 +44,7 @@
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
@@ -74,7 +74,7 @@ public void tearDown()
public void shouldBeAbleToAttachToPidAndRunThreadDump() throws IOException, CommandFailed, IncorrectUsage
{
long pid = getPID();
- Assume.assumeTrue( pid != 0 );
+ assertThat( pid, is( not( 0 ) ) );
// Write config file
Files.createFile( testDirectory.file( "neo4j.conf" ).toPath() );
diff --git a/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandTest.java b/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandTest.java
index 01429ae5ca3d6..1cf0f0e1418ab 100644
--- a/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandTest.java
+++ b/community/dbms/src/test/java/org/neo4j/commandline/dbms/DiagnosticsReportCommandTest.java
@@ -19,6 +19,7 @@
*/
package org.neo4j.commandline.dbms;
+import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -69,6 +70,7 @@ public class DiagnosticsReportCommandTest
private Path homeDir;
private Path configDir;
private Path configFile;
+ private String originalUserDir;
public static class MyDiagnosticsOfflineReportProvider extends DiagnosticsOfflineReportProvider
{
@@ -101,7 +103,14 @@ public void setUp() throws Exception
Files.createFile( configFile );
// To make sure files are resolved from the working directory
- System.setProperty( "user.dir", testDirectory.absolutePath().getAbsolutePath() );
+ originalUserDir = System.setProperty( "user.dir", testDirectory.absolutePath().getAbsolutePath() );
+ }
+
+ @After
+ public void tearDown()
+ {
+ // Restore directory
+ System.setProperty( "user.dir", originalUserDir );
}
@Test
diff --git a/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReportSources.java b/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReportSources.java
index 38d2903ff234b..12e248a8586c0 100644
--- a/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReportSources.java
+++ b/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReportSources.java
@@ -22,7 +22,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
@@ -126,8 +126,10 @@ public void addToArchive( Path archiveDestination, DiagnosticsReporterProgressCa
InputStream in = fs.openAsInputStream( source );
// Track progress of the file reading, source might be a very large file
- ProgressAwareInputStream inStream = new ProgressAwareInputStream( in, size, monitor::percentChanged );
- Files.copy( inStream, archiveDestination );
+ try ( ProgressAwareInputStream inStream = new ProgressAwareInputStream( in, size, monitor::percentChanged ) )
+ {
+ Files.copy( inStream, archiveDestination );
+ }
}
}
@@ -153,7 +155,7 @@ public void addToArchive( Path archiveDestination, DiagnosticsReporterProgressCa
throws IOException
{
String message = messageSupplier.get();
- Files.write( archiveDestination, message.getBytes( Charset.forName( "UTF8" ) ), StandardOpenOption.CREATE,
+ Files.write( archiveDestination, message.getBytes( StandardCharsets.UTF_8 ), StandardOpenOption.CREATE,
StandardOpenOption.APPEND );
}
}
diff --git a/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReporter.java b/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReporter.java
index 7de02f813e418..5044194c698af 100644
--- a/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReporter.java
+++ b/community/kernel/src/main/java/org/neo4j/diagnostics/DiagnosticsReporter.java
@@ -110,6 +110,7 @@ public Set getAvailableClassifiers()
return availableClassifiers;
}
+ // TODO:
private static class Mon implements DiagnosticsReporterProgressCallback
{
private final String prefix;
diff --git a/pom.xml b/pom.xml
index c95a8658be063..de58bc793cb4f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1174,6 +1174,11 @@
metrics-graphite
3.1.2
+
+ org.jprocesses
+ jProcesses
+ 1.6.4
+
com.google.code.findbugs