mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Encrypt logs on disk, store encryption key in DB.
This commit is contained in:
@@ -1,8 +1,16 @@
|
|||||||
package org.briarproject.bramble.api;
|
package org.briarproject.bramble.api;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||||
|
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
public abstract class StringMap extends Hashtable<String, String> {
|
public abstract class StringMap extends Hashtable<String, String> {
|
||||||
|
|
||||||
protected StringMap(Map<String, String> m) {
|
protected StringMap(Map<String, String> m) {
|
||||||
@@ -52,4 +60,19 @@ public abstract class StringMap extends Hashtable<String, String> {
|
|||||||
public void putLong(String key, long value) {
|
public void putLong(String key, long value) {
|
||||||
put(key, String.valueOf(value));
|
put(key, String.valueOf(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public byte[] getBytes(String key) {
|
||||||
|
String s = get(key);
|
||||||
|
if (s == null) return null;
|
||||||
|
try {
|
||||||
|
return fromHexString(s);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putBytes(String key, byte[] value) {
|
||||||
|
put(key, toHexString(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,4 +19,10 @@ public interface StreamDecrypterFactory {
|
|||||||
*/
|
*/
|
||||||
StreamDecrypter createContactExchangeStreamDecrypter(InputStream in,
|
StreamDecrypter createContactExchangeStreamDecrypter(InputStream in,
|
||||||
SecretKey headerKey);
|
SecretKey headerKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link StreamDecrypter} for decrypting a log stream.
|
||||||
|
*/
|
||||||
|
StreamDecrypter createLogStreamDecrypter(InputStream in,
|
||||||
|
SecretKey headerKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ public interface StreamEncrypterFactory {
|
|||||||
* Creates a {@link StreamEncrypter} for encrypting a contact exchange
|
* Creates a {@link StreamEncrypter} for encrypting a contact exchange
|
||||||
* stream.
|
* stream.
|
||||||
*/
|
*/
|
||||||
StreamEncrypter createContactExchangeStreamDecrypter(OutputStream out,
|
StreamEncrypter createContactExchangeStreamEncrypter(OutputStream out,
|
||||||
|
SecretKey headerKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link StreamEncrypter} for encrypting a log stream.
|
||||||
|
*/
|
||||||
|
StreamEncrypter createLogStreamEncrypter(OutputStream out,
|
||||||
SecretKey headerKey);
|
SecretKey headerKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,13 @@ public interface StreamReaderFactory {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link InputStream InputStream} for reading from a contact
|
* Creates an {@link InputStream InputStream} for reading from a contact
|
||||||
* exchangestream.
|
* exchange stream.
|
||||||
*/
|
*/
|
||||||
InputStream createContactExchangeStreamReader(InputStream in,
|
InputStream createContactExchangeStreamReader(InputStream in,
|
||||||
SecretKey headerKey);
|
SecretKey headerKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an {@link InputStream} for reading from a log stream.
|
||||||
|
*/
|
||||||
|
InputStream createLogStreamReader(InputStream in, SecretKey headerKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,15 +9,18 @@ import java.io.OutputStream;
|
|||||||
public interface StreamWriterFactory {
|
public interface StreamWriterFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link OutputStream OutputStream} for writing to a
|
* Creates a {@link StreamWriter} for writing to a transport stream.
|
||||||
* transport stream
|
|
||||||
*/
|
*/
|
||||||
StreamWriter createStreamWriter(OutputStream out, StreamContext ctx);
|
StreamWriter createStreamWriter(OutputStream out, StreamContext ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an {@link OutputStream OutputStream} for writing to a contact
|
* Creates a {@link StreamWriter} for writing to a contact exchange stream.
|
||||||
* exchange stream.
|
|
||||||
*/
|
*/
|
||||||
StreamWriter createContactExchangeStreamWriter(OutputStream out,
|
StreamWriter createContactExchangeStreamWriter(OutputStream out,
|
||||||
SecretKey headerKey);
|
SecretKey headerKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link StreamWriter} for writing to a log stream.
|
||||||
|
*/
|
||||||
|
StreamWriter createLogStreamWriter(OutputStream out, SecretKey headerKey);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,4 +36,10 @@ class StreamDecrypterFactoryImpl implements StreamDecrypterFactory {
|
|||||||
SecretKey headerKey) {
|
SecretKey headerKey) {
|
||||||
return new StreamDecrypterImpl(in, cipherProvider.get(), 0, headerKey);
|
return new StreamDecrypterImpl(in, cipherProvider.get(), 0, headerKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamDecrypter createLogStreamDecrypter(InputStream in,
|
||||||
|
SecretKey headerKey) {
|
||||||
|
return createContactExchangeStreamDecrypter(in, headerKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamEncrypter createContactExchangeStreamDecrypter(
|
public StreamEncrypter createContactExchangeStreamEncrypter(
|
||||||
OutputStream out, SecretKey headerKey) {
|
OutputStream out, SecretKey headerKey) {
|
||||||
AuthenticatedCipher cipher = cipherProvider.get();
|
AuthenticatedCipher cipher = cipherProvider.get();
|
||||||
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
|
byte[] streamHeaderNonce = new byte[STREAM_HEADER_NONCE_LENGTH];
|
||||||
@@ -60,4 +60,10 @@ class StreamEncrypterFactoryImpl implements StreamEncrypterFactory {
|
|||||||
return new StreamEncrypterImpl(out, cipher, 0, null, streamHeaderNonce,
|
return new StreamEncrypterImpl(out, cipher, 0, null, streamHeaderNonce,
|
||||||
headerKey, frameKey);
|
headerKey, frameKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamEncrypter createLogStreamEncrypter(OutputStream out,
|
||||||
|
SecretKey headerKey) {
|
||||||
|
return createContactExchangeStreamEncrypter(out, headerKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,15 +24,21 @@ class StreamReaderFactoryImpl implements StreamReaderFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream createStreamReader(InputStream in, StreamContext ctx) {
|
public InputStream createStreamReader(InputStream in, StreamContext ctx) {
|
||||||
return new StreamReaderImpl(
|
return new StreamReaderImpl(streamDecrypterFactory
|
||||||
streamDecrypterFactory.createStreamDecrypter(in, ctx));
|
.createStreamDecrypter(in, ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream createContactExchangeStreamReader(InputStream in,
|
public InputStream createContactExchangeStreamReader(InputStream in,
|
||||||
SecretKey headerKey) {
|
SecretKey headerKey) {
|
||||||
return new StreamReaderImpl(
|
return new StreamReaderImpl(streamDecrypterFactory
|
||||||
streamDecrypterFactory.createContactExchangeStreamDecrypter(in,
|
.createContactExchangeStreamDecrypter(in, headerKey));
|
||||||
headerKey));
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream createLogStreamReader(InputStream in,
|
||||||
|
SecretKey headerKey) {
|
||||||
|
return new StreamReaderImpl(streamDecrypterFactory
|
||||||
|
.createLogStreamDecrypter(in, headerKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,21 @@ class StreamWriterFactoryImpl implements StreamWriterFactory {
|
|||||||
@Override
|
@Override
|
||||||
public StreamWriter createStreamWriter(OutputStream out,
|
public StreamWriter createStreamWriter(OutputStream out,
|
||||||
StreamContext ctx) {
|
StreamContext ctx) {
|
||||||
return new StreamWriterImpl(
|
return new StreamWriterImpl(streamEncrypterFactory
|
||||||
streamEncrypterFactory.createStreamEncrypter(out, ctx));
|
.createStreamEncrypter(out, ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StreamWriter createContactExchangeStreamWriter(OutputStream out,
|
public StreamWriter createContactExchangeStreamWriter(OutputStream out,
|
||||||
SecretKey headerKey) {
|
SecretKey headerKey) {
|
||||||
return new StreamWriterImpl(
|
return new StreamWriterImpl(streamEncrypterFactory
|
||||||
streamEncrypterFactory.createContactExchangeStreamDecrypter(out,
|
.createContactExchangeStreamEncrypter(out, headerKey));
|
||||||
headerKey));
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StreamWriter createLogStreamWriter(OutputStream out,
|
||||||
|
SecretKey headerKey) {
|
||||||
|
return new StreamWriterImpl(streamEncrypterFactory
|
||||||
|
.createLogStreamEncrypter(out, headerKey));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.api.logging;
|
package org.briarproject.briar.api.logging;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -10,7 +11,25 @@ import java.util.logging.Handler;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public interface PersistentLogManager {
|
public interface PersistentLogManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The namespace of the (@link Settings) where the log key is stored.
|
||||||
|
*/
|
||||||
|
String LOG_SETTINGS_NAMESPACE = "log";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Settings} key under which the log key is stored.
|
||||||
|
*/
|
||||||
|
String LOG_KEY_KEY = "logKey";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and returns a persistent log handler that stores its logs in
|
||||||
|
* the given directory.
|
||||||
|
*/
|
||||||
Handler createLogHandler(File dir) throws IOException;
|
Handler createLogHandler(File dir) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads and returns the persistent log entries stored in the given
|
||||||
|
* directory, or an empty list if no log entries are found.
|
||||||
|
*/
|
||||||
Collection<String> getPersistedLog(File dir) throws IOException;
|
Collection<String> getPersistedLog(File dir) throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package org.briarproject.briar.logging;
|
package org.briarproject.briar.logging;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.briar.api.logging.PersistentLogManager;
|
import org.briarproject.briar.api.logging.PersistentLogManager;
|
||||||
|
|
||||||
import java.util.logging.Formatter;
|
import java.util.logging.Formatter;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.Module;
|
import dagger.Module;
|
||||||
import dagger.Provides;
|
import dagger.Provides;
|
||||||
|
|
||||||
@@ -16,8 +19,11 @@ public class LoggingModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@Singleton
|
||||||
PersistentLogManager providePersistentLogManager(
|
PersistentLogManager providePersistentLogManager(
|
||||||
PersistentLogManagerImpl logManager) {
|
LifecycleManager lifecycleManager,
|
||||||
return logManager;
|
PersistentLogManagerImpl persistentLogManager) {
|
||||||
|
lifecycleManager.registerOpenDatabaseHook(persistentLogManager);
|
||||||
|
return persistentLogManager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
package org.briarproject.briar.logging;
|
package org.briarproject.briar.logging;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||||
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager.OpenDatabaseHook;
|
||||||
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
import org.briarproject.bramble.api.lifecycle.ShutdownManager;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.settings.Settings;
|
||||||
import org.briarproject.bramble.api.system.Scheduler;
|
import org.briarproject.bramble.api.system.Scheduler;
|
||||||
|
import org.briarproject.bramble.api.transport.StreamReaderFactory;
|
||||||
|
import org.briarproject.bramble.api.transport.StreamWriter;
|
||||||
|
import org.briarproject.bramble.api.transport.StreamWriterFactory;
|
||||||
import org.briarproject.briar.api.logging.PersistentLogManager;
|
import org.briarproject.briar.api.logging.PersistentLogManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -21,16 +33,20 @@ import java.util.logging.Handler;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.logging.StreamHandler;
|
import java.util.logging.StreamHandler;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.ThreadSafe;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
|
|
||||||
@ThreadSafe
|
@ThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class PersistentLogManagerImpl implements PersistentLogManager {
|
class PersistentLogManagerImpl implements PersistentLogManager,
|
||||||
|
OpenDatabaseHook {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(PersistentLogManagerImpl.class.getName());
|
Logger.getLogger(PersistentLogManagerImpl.class.getName());
|
||||||
@@ -42,16 +58,47 @@ class PersistentLogManagerImpl implements PersistentLogManager {
|
|||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
private final ShutdownManager shutdownManager;
|
private final ShutdownManager shutdownManager;
|
||||||
|
private final DatabaseComponent db;
|
||||||
|
private final StreamReaderFactory streamReaderFactory;
|
||||||
|
private final StreamWriterFactory streamWriterFactory;
|
||||||
private final Formatter formatter;
|
private final Formatter formatter;
|
||||||
|
private final SecretKey logKey;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile SecretKey oldLogKey = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
PersistentLogManagerImpl(@Scheduler ScheduledExecutorService scheduler,
|
PersistentLogManagerImpl(
|
||||||
@IoExecutor Executor ioExecutor, ShutdownManager shutdownManager,
|
@Scheduler ScheduledExecutorService scheduler,
|
||||||
Formatter formatter) {
|
@IoExecutor Executor ioExecutor,
|
||||||
|
ShutdownManager shutdownManager,
|
||||||
|
DatabaseComponent db,
|
||||||
|
StreamReaderFactory streamReaderFactory,
|
||||||
|
StreamWriterFactory streamWriterFactory,
|
||||||
|
Formatter formatter,
|
||||||
|
CryptoComponent crypto) {
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
this.shutdownManager = shutdownManager;
|
this.shutdownManager = shutdownManager;
|
||||||
|
this.db = db;
|
||||||
|
this.streamReaderFactory = streamReaderFactory;
|
||||||
|
this.streamWriterFactory = streamWriterFactory;
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
|
logKey = crypto.generateSecretKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
|
Settings s = db.getSettings(txn, LOG_SETTINGS_NAMESPACE);
|
||||||
|
// Load the old log key, if any
|
||||||
|
byte[] oldKeyBytes = s.getBytes(LOG_KEY_KEY);
|
||||||
|
if (oldKeyBytes != null && oldKeyBytes.length == SecretKey.LENGTH) {
|
||||||
|
LOG.info("Loaded old log key");
|
||||||
|
oldLogKey = new SecretKey(oldKeyBytes);
|
||||||
|
}
|
||||||
|
// Store the current log key
|
||||||
|
s.putBytes(LOG_KEY_KEY, logKey.getBytes());
|
||||||
|
db.mergeSettings(txn, s, LOG_SETTINGS_NAMESPACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,11 +111,24 @@ class PersistentLogManagerImpl implements PersistentLogManager {
|
|||||||
LOG.warning("Failed to rename log file");
|
LOG.warning("Failed to rename log file");
|
||||||
try {
|
try {
|
||||||
OutputStream out = new FileOutputStream(logFile);
|
OutputStream out = new FileOutputStream(logFile);
|
||||||
StreamHandler handler = new StreamHandler(out, formatter);
|
StreamWriter writer =
|
||||||
|
streamWriterFactory.createLogStreamWriter(out, logKey);
|
||||||
|
StreamHandler handler =
|
||||||
|
new StreamHandler(writer.getOutputStream(), formatter);
|
||||||
|
// Flush the log periodically in case we're killed without getting
|
||||||
|
// the chance to run shutdown hooks
|
||||||
scheduler.scheduleWithFixedDelay(() ->
|
scheduler.scheduleWithFixedDelay(() ->
|
||||||
ioExecutor.execute(handler::flush),
|
ioExecutor.execute(handler::flush),
|
||||||
FLUSH_INTERVAL_MS, FLUSH_INTERVAL_MS, MILLISECONDS);
|
FLUSH_INTERVAL_MS, FLUSH_INTERVAL_MS, MILLISECONDS);
|
||||||
shutdownManager.addShutdownHook(handler::flush);
|
// Flush the log and terminate the stream at shutdown
|
||||||
|
shutdownManager.addShutdownHook(() -> {
|
||||||
|
handler.flush();
|
||||||
|
try {
|
||||||
|
writer.sendEndOfStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
return handler;
|
return handler;
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
@@ -77,14 +137,23 @@ class PersistentLogManagerImpl implements PersistentLogManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<String> getPersistedLog(File dir) throws IOException {
|
public Collection<String> getPersistedLog(File dir) throws IOException {
|
||||||
|
SecretKey oldLogKey = this.oldLogKey;
|
||||||
|
if (oldLogKey == null) {
|
||||||
|
LOG.info("Old log key has not been loaded");
|
||||||
|
return emptyList();
|
||||||
|
}
|
||||||
File oldLogFile = new File(dir, OLD_LOG_FILE);
|
File oldLogFile = new File(dir, OLD_LOG_FILE);
|
||||||
if (oldLogFile.exists()) {
|
if (oldLogFile.exists()) {
|
||||||
LOG.info("Reading old log file");
|
LOG.info("Reading old log file");
|
||||||
List<String> lines = new ArrayList<>();
|
List<String> lines = new ArrayList<>();
|
||||||
Scanner s = new Scanner(oldLogFile);
|
try (InputStream in = new FileInputStream(oldLogFile)) {
|
||||||
while (s.hasNextLine()) lines.add(s.nextLine());
|
InputStream reader = streamReaderFactory
|
||||||
s.close();
|
.createLogStreamReader(in, oldLogKey);
|
||||||
return lines;
|
Scanner s = new Scanner(reader);
|
||||||
|
while (s.hasNextLine()) lines.add(s.nextLine());
|
||||||
|
s.close();
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Old log file does not exist");
|
LOG.info("Old log file does not exist");
|
||||||
return emptyList();
|
return emptyList();
|
||||||
|
|||||||
Reference in New Issue
Block a user