Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more contributor license * agreements. See the NOTICE file distributed with this work for additional information regarding * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. You may obtain a * copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. * */ package org.apache.geode.management.internal.cli.util; import static java.util.stream.Collectors.toList; import org.apache.commons.io.FileUtils; import org.apache.geode.internal.logging.LogService; import org.apache.geode.management.internal.configuration.utils.ZipUtils; import org.apache.logging.log4j.Logger; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.List; import java.util.function.Predicate; import java.util.stream.Stream; /** * this LogExporter only finds the .log and .gfs files under in the same directory of the base files * it doesn't use the base file's filename patterns to find the related logs/stats yet. */ public class LogExporter { private static final Logger LOGGER = LogService.getLogger(); private final LogFilter logFilter; private final File baseLogFile; private final File baseStatsFile; /** * @param logFilter the filter that's used to check if we need to accept the file or the logLine * @param baseLogFile if not null, we will export the logs in that directory * @param baseStatsFile if not null, we will export stats in that directory */ public LogExporter(LogFilter logFilter, File baseLogFile, File baseStatsFile) { assert logFilter != null; this.logFilter = logFilter; this.baseLogFile = baseLogFile; this.baseStatsFile = baseStatsFile; } /** * * @return Path to the zip file that has all the filtered files, null if no files are selected to * export. */ public Path export() throws IOException { Path tempDirectory = Files.createTempDirectory("exportLogs"); if (baseLogFile != null) { for (Path logFile : findLogFiles(baseLogFile.toPath().getParent())) { Path filteredLogFile = tempDirectory.resolve(logFile.getFileName()); writeFilteredLogFile(logFile, filteredLogFile); } } if (baseStatsFile != null) { for (Path statFile : findStatFiles(baseStatsFile.toPath().getParent())) { Files.copy(statFile, tempDirectory.resolve(statFile.getFileName())); } } Path zipFile = null; if (tempDirectory.toFile().listFiles().length > 0) { zipFile = Files.createTempFile("logExport", ".zip"); ZipUtils.zipDirectory(tempDirectory, zipFile); LOGGER.info("Zipped files to: " + zipFile); } FileUtils.deleteDirectory(tempDirectory.toFile()); return zipFile; } protected void writeFilteredLogFile(Path originalLogFile, Path filteredLogFile) throws IOException { this.logFilter.startNewFile(); try (BufferedReader reader = new BufferedReader(new FileReader(originalLogFile.toFile()))) { try (BufferedWriter writer = new BufferedWriter(new FileWriter(filteredLogFile.toFile()))) { String line; while ((line = reader.readLine()) != null) { LogFilter.LineFilterResult result = this.logFilter.acceptsLine(line); if (result == LogFilter.LineFilterResult.REMAINDER_OF_FILE_REJECTED) { break; } if (result == LogFilter.LineFilterResult.LINE_ACCEPTED) { writeLine(line, writer); } } } } } private void writeLine(String line, BufferedWriter writer) { try { writer.write(line); writer.newLine(); } catch (IOException e) { throw new RuntimeException("Unable to write to log file", e); } } /** * @return combined size of stat archives and filtered log files in bytes */ public long estimateFilteredSize() throws IOException { long filteredSize = 0; if (baseLogFile != null) { for (Path logFile : findLogFiles(baseLogFile.toPath().getParent())) { filteredSize += filterAndSize(logFile); } } if (baseStatsFile != null) { for (Path statFile : findStatFiles(baseStatsFile.toPath().getParent())) { filteredSize += statFile.toFile().length(); } } return filteredSize; } /** * @return size of file in bytes */ private long filterAndSize(Path originalLogFile) throws IOException { long size = 0; this.logFilter.startNewFile(); try (BufferedReader reader = new BufferedReader(new FileReader(originalLogFile.toFile()))) { String line; while ((line = reader.readLine()) != null) { LogFilter.LineFilterResult result = this.logFilter.acceptsLine(line); if (result == LogFilter.LineFilterResult.REMAINDER_OF_FILE_REJECTED) { break; } if (result == LogFilter.LineFilterResult.LINE_ACCEPTED) { size += line.length() + File.separator.length(); } } } return size; } List<Path> findLogFiles(Path workingDir) throws IOException { Predicate<Path> logFileSelector = (Path file) -> file.toString().toLowerCase().endsWith(".log"); return findFiles(workingDir, logFileSelector); } List<Path> findStatFiles(Path workingDir) throws IOException { Predicate<Path> statFileSelector = (Path file) -> file.toString().toLowerCase().endsWith(".gfs"); return findFiles(workingDir, statFileSelector); } private List<Path> findFiles(Path workingDir, Predicate<Path> fileSelector) throws IOException { Stream<Path> selectedFiles/* = null */; if (!workingDir.toFile().isDirectory()) { return Collections.emptyList(); } selectedFiles = Files.list(workingDir).filter(fileSelector).filter(this.logFilter::acceptsFile); return selectedFiles.collect(toList()); } }