org.neo4j.kernel.diagnostics.DiagnosticsReportSources Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of neo4j-kernel Show documentation
Show all versions of neo4j-kernel Show documentation
Neo4j kernel is a lightweight, embedded Java database designed to
store data structured as graphs rather than tables. For more
information, see http://neo4j.org.
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.kernel.diagnostics;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.DirectoryStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.neo4j.io.fs.FileSystemAbstraction;
/**
* Contains helper methods to create create {@link DiagnosticsReportSource}.
*/
public final class DiagnosticsReportSources {
private DiagnosticsReportSources() {
// util class
}
/**
* Create a diagnostics source that will copy a file into the archive.
*
* @param destination final destination in archive.
* @param fs filesystem abstraction to use.
* @param source source file to archive
* @return a diagnostics source consuming a file.
*/
public static DiagnosticsReportSource newDiagnosticsFile(
String destination, FileSystemAbstraction fs, Path source) {
return new DiagnosticsFileReportSource(destination, fs, source);
}
/**
* @param destinationFolder destination folder (including trailing '/') in archive.
* @param fs filesystem abstraction to use.
* @param file input log file, should be without rotation numbers.
* @return a list diagnostics sources consisting of the log file including all rotated away files.
*/
public static List newDiagnosticsRotatingFile(
String destinationFolder, FileSystemAbstraction fs, Path file) {
return newDiagnosticsMatchingFiles(destinationFolder, fs, file.getParent(), path -> path.getFileName()
.toString()
.startsWith(file.getFileName().toString()));
}
/**
* @param destinationFolder destination folder (including trailing '/') in archive.
* @param fs filesystem abstraction to use.
* @param sourceFolder folder to look for files in
* @param filter filter when listing files
* @return a list of diagnostics sources consisting of the files matching the filter.
*/
public static List newDiagnosticsMatchingFiles(
String destinationFolder,
FileSystemAbstraction fs,
Path sourceFolder,
DirectoryStream.Filter filter) {
List files = new ArrayList<>();
try {
Path[] paths = fs.listFiles(sourceFolder, filter);
if (paths != null) {
for (Path path : paths) {
files.add(newDiagnosticsFile(
destinationFolder + path.getFileName().toString(), fs, path));
}
}
} catch (IOException e) {
files.add(newDiagnosticsString(
destinationFolder + "error", () -> "Error reading files in directory: " + e.getMessage()));
}
return files;
}
/**
* Create a diagnostics source from a string. Can be used to dump simple messages to a file in the archive. Files
* are opened with append option so this method can be used to accumulate messages from multiple source to a single
* file in the archive.
*
* @param destination final destination in archive.
* @param messageSupplier a string supplier with the final message.
* @return a diagnostics source consuming a string.
*/
public static DiagnosticsReportSource newDiagnosticsString(String destination, Supplier messageSupplier) {
return new DiagnosticsStringReportSource(destination, messageSupplier);
}
private static class DiagnosticsFileReportSource implements DiagnosticsReportSource {
private final String destination;
private final FileSystemAbstraction fs;
private final Path source;
DiagnosticsFileReportSource(String destination, FileSystemAbstraction fs, Path source) {
this.destination = destination;
this.fs = fs;
this.source = source;
}
@Override
public String destinationPath() {
return destination;
}
@Override
public InputStream newInputStream() throws IOException {
return fs.openAsInputStream(source);
}
@Override
public long estimatedSize() {
try {
return fs.getFileSize(source);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
}
private static class DiagnosticsStringReportSource implements DiagnosticsReportSource {
private final String destination;
private final Supplier messageSupplier;
private DiagnosticsStringReportSource(String destination, Supplier messageSupplier) {
this.destination = destination;
this.messageSupplier = messageSupplier;
}
@Override
public String destinationPath() {
return destination;
}
@Override
public InputStream newInputStream() {
final String message = messageSupplier.get();
return new ByteArrayInputStream(message.getBytes(StandardCharsets.UTF_8));
}
@Override
public long estimatedSize() {
return 0; // Size of strings should be negligible
}
}
}