Improved log message in Backup engine
This commit is contained in:
parent
148099a4d2
commit
dcfbb3e06a
@ -1,5 +1,9 @@
|
||||
package fr.pandacube.lib.paper.modules.backup;
|
||||
|
||||
import fr.pandacube.lib.chat.Chat;
|
||||
import fr.pandacube.lib.util.Log;
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeParseException;
|
||||
@ -10,10 +14,12 @@ import java.util.TreeSet;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import fr.pandacube.lib.util.Log;
|
||||
import static fr.pandacube.lib.chat.ChatStatic.text;
|
||||
|
||||
public abstract class BackupCleaner implements UnaryOperator<TreeSet<LocalDateTime>> {
|
||||
|
||||
private static final boolean testOnly = true; // if true, no files are deleted
|
||||
|
||||
public static BackupCleaner KEEPING_N_LAST(int n) {
|
||||
return new BackupCleaner() {
|
||||
@Override
|
||||
@ -66,17 +72,17 @@ public abstract class BackupCleaner implements UnaryOperator<TreeSet<LocalDateTi
|
||||
|
||||
|
||||
|
||||
public void cleanupArchives(File archiveDir) {
|
||||
public void cleanupArchives(File archiveDir, String compressDisplayName) {
|
||||
String[] files = archiveDir.list();
|
||||
|
||||
Log.info("[Backup] Cleaning up backup directory " + archiveDir + "...");
|
||||
Log.info("[Backup] Cleaning up backup directory " + ChatColor.GRAY + compressDisplayName + ChatColor.RESET + "...");
|
||||
|
||||
TreeMap<LocalDateTime, File> datedFiles = new TreeMap<>();
|
||||
|
||||
for (String filename : files) {
|
||||
File file = new File(archiveDir, filename);
|
||||
if (!filename.matches("\\d{8}-\\d{6}\\.zip")) {
|
||||
Log.warning("[Backup] Invalid file in backup directory: " + file);
|
||||
Log.warning("[Backup] " + ChatColor.GRAY + compressDisplayName + ChatColor.RESET + " Invalid file in backup directory: " + filename);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -85,7 +91,7 @@ public abstract class BackupCleaner implements UnaryOperator<TreeSet<LocalDateTi
|
||||
try {
|
||||
ldt = LocalDateTime.parse(dateTimeStr, CompressProcess.dateFileNameFormatter);
|
||||
} catch (DateTimeParseException e) {
|
||||
Log.warning("Unable to parse file name to a date-time: " + file, e);
|
||||
Log.warning("[Backup] " + ChatColor.GRAY + compressDisplayName + ChatColor.RESET + " Unable to parse file name to a date-time: " + filename, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -94,14 +100,31 @@ public abstract class BackupCleaner implements UnaryOperator<TreeSet<LocalDateTi
|
||||
|
||||
TreeSet<LocalDateTime> keptFiles = apply(new TreeSet<>(datedFiles.keySet()));
|
||||
|
||||
Chat c = text("[Backup] ")
|
||||
.then(text(compressDisplayName).gray())
|
||||
.thenText(testOnly ? " Archive cleanup debug (no files are actually deleted):" : "Deleted archive files:\n");
|
||||
boolean oneDeleted = false;
|
||||
for (Entry<LocalDateTime, File> datedFile : datedFiles.entrySet()) {
|
||||
if (keptFiles.contains(datedFile.getKey()))
|
||||
if (keptFiles.contains(datedFile.getKey())) {
|
||||
if (testOnly)
|
||||
c.thenText("- " + datedFile.getValue().getName() + " ")
|
||||
.thenSuccess("kept")
|
||||
.thenText(".\n");
|
||||
continue;
|
||||
// datedFile.getValue().delete(); // TODO check if the filtering is ok before actually removing files
|
||||
Log.info("[Backup] Removed expired backup file " + datedFile.getValue());
|
||||
}
|
||||
oneDeleted = true;
|
||||
c.thenText("- " + datedFile.getValue().getName() + " ");
|
||||
if (testOnly)
|
||||
c.thenFailure("deleted")
|
||||
.thenText(".\n");
|
||||
else
|
||||
datedFile.getValue().delete();
|
||||
}
|
||||
|
||||
Log.info("[Backup] Backup directory " + archiveDir + " cleaned.");
|
||||
if (testOnly || oneDeleted)
|
||||
Log.warning(c.getLegacyText());
|
||||
|
||||
Log.info("[Backup] Backup directory " + ChatColor.GRAY + compressDisplayName + ChatColor.RESET + " cleaned.");
|
||||
}
|
||||
|
||||
|
||||
|
@ -51,102 +51,107 @@ public abstract class CompressProcess implements Comparable<CompressProcess>, Ru
|
||||
protected abstract void onCompressEnd(boolean success);
|
||||
|
||||
protected abstract File getTargetDir();
|
||||
|
||||
|
||||
protected abstract String getDisplayName();
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
backupManager.compressRunning.set(this);
|
||||
|
||||
BiPredicate<File, String> filter = getFilenameFilter();
|
||||
File sourceDir = getSourceDir();
|
||||
|
||||
if (!sourceDir.exists()) {
|
||||
Log.warning(String.format("%% unable to compress %s (check path: %s)", name, sourceDir.getPath()));
|
||||
try {
|
||||
BiPredicate<File, String> filter = getFilenameFilter();
|
||||
File sourceDir = getSourceDir();
|
||||
|
||||
if (!sourceDir.exists()) {
|
||||
Log.warning("[Backup] Unable to compress " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + ": source directory " + sourceDir + " doesn’t exist");
|
||||
return;
|
||||
}
|
||||
|
||||
File targetDir = getTargetDir();
|
||||
File target = new File(targetDir, getDateFileName() + ".zip");
|
||||
|
||||
|
||||
BossBar bossBar = BossBar.bossBar(Chat.text("Archivage"), 0, Color.YELLOW, Overlay.NOTCHED_20);
|
||||
AutoUpdatedBossBar auBossBar = new AutoUpdatedBossBar(bossBar, (bar) -> {
|
||||
bar.setTitle(Chat.infoText("Archivage ")
|
||||
.thenData(getDisplayName())
|
||||
.thenText(" : ")
|
||||
.then(compressor == null
|
||||
? Chat.text("Démarrage...")
|
||||
: compressor.getState()
|
||||
)
|
||||
);
|
||||
bar.setProgress(compressor == null ? 0 : compressor.getProgress());
|
||||
});
|
||||
auBossBar.scheduleUpdateTimeSyncThreadAsync(100, 100);
|
||||
|
||||
onCompressStart();
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(PandaLibPaper.getPlugin(), () -> {
|
||||
Log.info("[Backup] Starting for " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + " ...");
|
||||
|
||||
compressor = new ZipCompressor(sourceDir, target, 9, filter);
|
||||
|
||||
PerformanceAnalysisManager.getInstance().addBossBar(bossBar);
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
compressor.compress();
|
||||
|
||||
success = true;
|
||||
|
||||
Log.info("[Backup] Finished for " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET);
|
||||
|
||||
backupManager.persist.updateDirtyStatusAfterCompress(type, name);
|
||||
|
||||
displayDirtynessStatus();
|
||||
|
||||
try {
|
||||
type.backupCleaner(backupManager.config).cleanupArchives(targetDir, getDisplayName());
|
||||
} catch (Exception e) {
|
||||
Log.severe(e);
|
||||
}
|
||||
}
|
||||
catch (final Exception e) {
|
||||
Log.severe("[Backup] Failed: " + sourceDir + " -> " + target, e);
|
||||
|
||||
FileUtils.delete(target);
|
||||
if (target.exists())
|
||||
Log.warning("unable to delete: " + target);
|
||||
} finally {
|
||||
|
||||
backupManager.compressRunning.set(null);
|
||||
boolean successF = success;
|
||||
Bukkit.getScheduler().runTask(PandaLibPaper.getPlugin(), () -> onCompressEnd(successF));
|
||||
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch(InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
PerformanceAnalysisManager.getInstance().removeBossBar(bossBar);
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
backupManager.compressRunning.set(null);
|
||||
return;
|
||||
}
|
||||
|
||||
File targetDir = getTargetDir();
|
||||
File target = new File(targetDir, getDateFileName() + ".zip");
|
||||
|
||||
|
||||
BossBar bossBar = BossBar.bossBar(Chat.text("Archivage"), 0, Color.YELLOW, Overlay.NOTCHED_20);
|
||||
AutoUpdatedBossBar auBossBar = new AutoUpdatedBossBar(bossBar, (bar) -> {
|
||||
bar.setTitle(Chat.infoText("Archivage ")
|
||||
.thenData(type + "\\" + name)
|
||||
.thenText(" : ")
|
||||
.then(compressor == null
|
||||
? Chat.text("Démarrage...")
|
||||
: compressor.getState()
|
||||
)
|
||||
);
|
||||
bar.setProgress(compressor == null ? 0 : compressor.getProgress());
|
||||
});
|
||||
auBossBar.scheduleUpdateTimeSyncThreadAsync(100, 100);
|
||||
|
||||
onCompressStart();
|
||||
|
||||
Bukkit.getScheduler().runTaskAsynchronously(PandaLibPaper.getPlugin(), () -> {
|
||||
Log.info("[Backup] starting for " + ChatColor.GRAY + type + "\\" + name + ChatColor.RESET + " ...");
|
||||
|
||||
compressor = new ZipCompressor(sourceDir, target, 9, filter);
|
||||
|
||||
PerformanceAnalysisManager.getInstance().addBossBar(bossBar);
|
||||
|
||||
boolean success = false;
|
||||
try {
|
||||
compressor.compress();
|
||||
|
||||
success = true;
|
||||
|
||||
Log.info("[Backup] finished for " + ChatColor.GRAY + type + "\\" + name + ChatColor.RESET);
|
||||
|
||||
backupManager.persist.updateDirtyStatusAfterCompress(type, name);
|
||||
|
||||
displayDirtynessStatus();
|
||||
|
||||
try {
|
||||
type.backupCleaner(backupManager.config).cleanupArchives(targetDir);
|
||||
} catch (Exception e) {
|
||||
Log.severe(e);
|
||||
}
|
||||
}
|
||||
catch (final Exception e) {
|
||||
Log.severe("[Backup] Failed: " + sourceDir + " -> " + target, e);
|
||||
|
||||
FileUtils.delete(target);
|
||||
if (target.exists())
|
||||
Log.warning("unable to delete: " + target);
|
||||
} finally {
|
||||
|
||||
backupManager.compressRunning.set(null);
|
||||
boolean successF = success;
|
||||
Bukkit.getScheduler().runTask(PandaLibPaper.getPlugin(), () -> onCompressEnd(successF));
|
||||
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch(InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
PerformanceAnalysisManager.getInstance().removeBossBar(bossBar);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void displayDirtynessStatus() {
|
||||
if (hasNextScheduled() && type == Type.WORLDS) {
|
||||
Log.info("[Backup] " + ChatColor.GRAY + type + "\\" + name + ChatColor.RESET + " is dirty. Next backup on "
|
||||
Log.info("[Backup] " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + " is dirty. Next backup on "
|
||||
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date(getNext())));
|
||||
}
|
||||
else if (hasNextScheduled()) {
|
||||
Log.info("[Backup] " + ChatColor.GRAY + type + "\\" + name + ChatColor.RESET + " next backup on "
|
||||
Log.info("[Backup] " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + " next backup on "
|
||||
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(new Date(getNext())));
|
||||
}
|
||||
else {
|
||||
Log.info("[Backup] " + ChatColor.GRAY + type + "\\" + name + ChatColor.RESET + " is clean. Next backup not scheduled.");
|
||||
Log.info("[Backup] " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + " is clean. Next backup not scheduled.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +175,7 @@ public abstract class CompressProcess implements Comparable<CompressProcess>, Ru
|
||||
public void logProgress() {
|
||||
if (compressor == null)
|
||||
return;
|
||||
Log.info("[Backup] " + ChatColor.GRAY + type + "\\" + name + ChatColor.RESET + ": " + compressor.getState().getLegacyText());
|
||||
Log.info("[Backup] " + ChatColor.GRAY + getDisplayName() + ChatColor.RESET + ": " + compressor.getState().getLegacyText());
|
||||
}
|
||||
|
||||
|
||||
|
@ -64,6 +64,11 @@ public class CompressWorkdirProcess extends CompressProcess {
|
||||
|
||||
@Override
|
||||
protected File getTargetDir() {
|
||||
return new File(backupManager.config.backupDirectory, "workdir");
|
||||
return new File(backupManager.config.backupDirectory, type.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayName() {
|
||||
return type.toString();
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,11 @@ public class CompressWorldProcess extends CompressProcess {
|
||||
|
||||
@Override
|
||||
protected File getTargetDir() {
|
||||
return new File(backupManager.config.backupDirectory, type.toString() + "/" + name);
|
||||
return new File(backupManager.config.backupDirectory, type + "/" + name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayName() {
|
||||
return type + "/" + name;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@ -74,7 +75,7 @@ public class Persist extends YamlConfiguration {
|
||||
return;
|
||||
if (!isDirty(Type.WORLDS, world.getName())) { // don't set dirty if it is already
|
||||
setDirtySinceNow(Type.WORLDS, world.getName());
|
||||
Log.info("[Backup] " + Type.WORLDS + "\\" + world.getName() + " was saved and is now dirty. Next backup on "
|
||||
Log.info("[Backup] " + ChatColor.GRAY + Type.WORLDS + "/" + world.getName() + ChatColor.RESET + " was saved and is now dirty. Next backup on "
|
||||
+ DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG)
|
||||
.format(new Date(backupManager.getNextCompress(System.currentTimeMillis())))
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user