kieker.analysis.plugin.reader.filesystem.FSZipReader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kieker Show documentation
Show all versions of kieker Show documentation
Kieker: Application Performance Monitoring and Dynamic Software Analysis
The newest version!
/***************************************************************************
* Copyright 2022 Kieker Project (http://kieker-monitoring.net)
*
* Licensed 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 kieker.analysis.plugin.reader.filesystem;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import kieker.analysis.generic.source.file.MappingException;
import kieker.analysis.plugin.reader.util.IMonitoringRecordReceiver;
import kieker.common.exception.MonitoringRecordException;
import kieker.common.exception.UnknownRecordTypeException;
import kieker.common.registry.reader.ReaderRegistry;
import kieker.common.util.filesystem.FSUtil;
/**
* Reads the contents of a single zip file and passes the records to the registered receiver of type {@link IMonitoringRecordReceiver}.
*
* @author Jan Waller
*
* @since 1.7
* @deprecated 1.15 replaced by teetime log reading facilities
*/
@Deprecated
public final class FSZipReader implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(FSZipReader.class);
private final File zipFile;
private final IMonitoringRecordReceiver recordReceiver;
private final boolean ignoreUnknownRecordTypes;
private final ReaderRegistry stringRegistry = new ReaderRegistry<>();
private boolean terminated;
private final BinaryFileStreamProcessor binaryFileStreamProcessor;
private final TextFileStreamProcessor textFileStreamProcessor;
/**
* Creates a new instance of this class.
*
* @param zipFile
* The File object for the zip file.
* @param recordReceiver
* The receiver handling the records.
* @param ignoreUnknownRecordTypes
* select only records of this type; null selects all
*/
public FSZipReader(final File zipFile, final IMonitoringRecordReceiver recordReceiver, final boolean ignoreUnknownRecordTypes) {
if ((zipFile == null) || !zipFile.isFile() || !zipFile.getName().endsWith(FSUtil.ZIP_FILE_EXTENSION)) {
throw new IllegalArgumentException("Invalid zip file");
}
this.zipFile = zipFile;
this.recordReceiver = recordReceiver;
this.ignoreUnknownRecordTypes = ignoreUnknownRecordTypes;
this.binaryFileStreamProcessor = new BinaryFileStreamProcessor(this.stringRegistry, recordReceiver);
this.textFileStreamProcessor = new TextFileStreamProcessor(ignoreUnknownRecordTypes, this.stringRegistry, recordReceiver);
}
/**
* Starts reading and returns after each record has been passed to the registered {@link #recordReceiver}.
*/
@Override
public final void run() {
ZipInputStream zipInputStream = null;
try {
zipInputStream = new ZipInputStream(Files.newInputStream(this.zipFile.toPath(), StandardOpenOption.READ));
ZipEntry zipEntry;
while ((null != (zipEntry = zipInputStream.getNextEntry())) && !zipEntry.getName().equals(FSUtil.MAP_FILENAME)) { // NOCS NOPMD
// do nothing, just skip to the map file if present
}
if (null == zipEntry) {
LOGGER.error("The zip file does not contain a Kieker log: {}", this.zipFile.toString());
this.recordReceiver.newEndOfFileRecord();
return;
}
// read mapping file
this.readMappingFile(zipInputStream);
} catch (final IOException ex) {
LOGGER.error("Error accessing ZipInputStream", ex);
this.recordReceiver.newEndOfFileRecord();
return;
} finally {
if (null != zipInputStream) {
try {
zipInputStream.close();
} catch (final IOException ex) {
LOGGER.error("Failed to close ZipInputStream", ex);
}
}
}
// when we arrive here, we have a valid zip file and read the mapping file
// start again with the zip file
BufferedReader reader = null;
DataInputStream input = null;
try {
zipInputStream = new ZipInputStream(Files.newInputStream(this.zipFile.toPath(), StandardOpenOption.READ));
reader = new BufferedReader(new InputStreamReader(zipInputStream, FSUtil.ENCODING));
input = new DataInputStream(new BufferedInputStream(zipInputStream, 1024 * 1024));
ZipEntry zipEntry;
while (null != (zipEntry = zipInputStream.getNextEntry())) { // NOCS NOPMD
if (this.terminated) {
LOGGER.info("Shutting down DirectoryReader.");
break;
}
final String filename = zipEntry.getName();
if (filename.startsWith(FSUtil.FILE_PREFIX)) {
if (filename.endsWith(FSUtil.DAT_FILE_EXTENSION)) {
LOGGER.info("< Loading {}", filename);
try {
this.textFileStreamProcessor.processInputChannel(input);
} catch (MappingException | MonitoringRecordException | UnknownRecordTypeException e) {
LOGGER.error("Cannot deserialize text record {}", e);
}
} else if (filename.endsWith(".bin")) {
LOGGER.info("< Loading {}", filename);
if (this.ignoreUnknownRecordTypes) { // NOPMD (deeply nested if)
LOGGER.warn("The property '{}' is not supported for binary files. But trying to read '{}'",
FSReader.CONFIG_PROPERTY_NAME_IGNORE_UNKNOWN_RECORD_TYPES, filename);
}
try {
this.binaryFileStreamProcessor.createRecordsFromBinaryFile(input);
} catch (IOException | MonitoringRecordException e) {
LOGGER.error("Cannot deserialize binary record {}", e);
}
this.terminated = true;
}
}
}
} catch (final IOException ex) {
LOGGER.error("Error accessing ZipInputStream", ex);
this.recordReceiver.newEndOfFileRecord();
return;
} finally {
try {
zipInputStream.close();
} catch (final IOException ex) {
LOGGER.error("Failed to close ZipInputStream", ex);
}
try {
if (null != reader) {
reader.close();
}
} catch (final IOException ex) {
LOGGER.error("Failed to close ZipInputStream", ex);
}
try {
if (null != input) {
input.close();
}
} catch (final IOException ex) {
LOGGER.error("Failed to close ZipInputStream", ex);
}
}
this.recordReceiver.newEndOfFileRecord();
}
/**
* Reads the mapping file located in the zip file.
*
* @throws IOException
*/
private final void readMappingFile(final ZipInputStream zipInputStream) throws IOException {
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(zipInputStream, FSUtil.ENCODING));
String line;
while ((line = in.readLine()) != null) { // NOPMD (assign)
if (line.length() == 0) {
continue; // ignore empty lines
}
final int split = line.indexOf('=');
if (split == -1) {
LOGGER.error("Failed to parse line: {} from mapping file in zip file {}. Each line must contain ID=VALUE pairs.", line, this.zipFile.toString());
continue; // continue on errors
}
final String key = line.substring(0, split);
final String value = FSUtil.decodeNewline(line.substring(split + 1));
// the leading $ is optional
final Integer id;
try {
id = Integer.valueOf((key.charAt(0) == '$') ? key.substring(1) : key); // NOCS
} catch (final NumberFormatException ex) {
LOGGER.error("Error reading mapping file, id must be integer", ex);
continue; // continue on errors
}
final String prevVal = this.stringRegistry.register(id, value);
if (prevVal != null) {
LOGGER.error("Found addional entry for id='{}', old value was '{}' new value is '{}'", id, prevVal, value);
}
}
} finally {
if (in != null) {
in.close(); // this also closes the zipInputStream
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy