add Logger
This commit is contained in:
parent
8f9d7d5297
commit
7142cd06dd
5
pom.xml
5
pom.xml
|
@ -59,6 +59,11 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.diogonunes</groupId>
|
||||
<artifactId>JColor</artifactId>
|
||||
<version>5.5.1</version>
|
||||
</dependency>
|
||||
<!-- testing dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
|
|
@ -1,24 +1,10 @@
|
|||
import net.horizoncode.sysbackup.cli.CLIProcessor;
|
||||
import net.horizoncode.sysbackup.SysBackup;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class Bootstrapper {
|
||||
|
||||
public static void main(String[] args) throws URISyntaxException {
|
||||
|
||||
File jarFile =
|
||||
new File(Bootstrapper.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||
|
||||
File executionPath =
|
||||
new File(
|
||||
new File(Bootstrapper.class.getProtectionDomain().getCodeSource().getLocation().toURI())
|
||||
.getParent());
|
||||
|
||||
if (!jarFile.isFile()) System.out.println("Dev environment detected!");
|
||||
|
||||
CLIProcessor cliProcessor = new CLIProcessor();
|
||||
cliProcessor.startCLI(
|
||||
args, jarFile.isFile() ? executionPath : new File(System.getProperty("user.dir")));
|
||||
new SysBackup().start(args);
|
||||
}
|
||||
}
|
||||
|
|
29
src/main/java/net/horizoncode/sysbackup/SysBackup.java
Normal file
29
src/main/java/net/horizoncode/sysbackup/SysBackup.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
package net.horizoncode.sysbackup;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.horizoncode.sysbackup.cli.CLIProcessor;
|
||||
import net.horizoncode.sysbackup.logging.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class SysBackup {
|
||||
|
||||
@Getter private static final Logger logger = Logger.builder().logFile(new File("log")).build();
|
||||
|
||||
public void start(String[] args) throws URISyntaxException {
|
||||
File jarFile =
|
||||
new File(SysBackup.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||
|
||||
File executionPath =
|
||||
new File(
|
||||
new File(SysBackup.class.getProtectionDomain().getCodeSource().getLocation().toURI())
|
||||
.getParent());
|
||||
|
||||
if (!jarFile.isFile()) getLogger().log(Logger.LogLevel.INFO, "Dev environment detected!");
|
||||
|
||||
CLIProcessor cliProcessor = new CLIProcessor();
|
||||
cliProcessor.startCLI(
|
||||
args, jarFile.isFile() ? executionPath : new File(System.getProperty("user.dir")));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package net.horizoncode.sysbackup.cli;
|
||||
|
||||
import net.horizoncode.sysbackup.SysBackup;
|
||||
import net.horizoncode.sysbackup.config.Config;
|
||||
import net.horizoncode.sysbackup.logging.Logger;
|
||||
import net.horizoncode.sysbackup.tasks.TaskBuilder;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
|
@ -27,7 +29,7 @@ public class CLIProcessor {
|
|||
" java -jar sysbackup.jar generateTaskConf magento",
|
||||
" java -jar sysbackup.jar backup magento"
|
||||
};
|
||||
Arrays.stream(usage).forEachOrdered(System.out::println);
|
||||
Arrays.stream(usage).forEach(System.out::println);
|
||||
}
|
||||
|
||||
public void startCLI(String[] args, File executionPath) {
|
||||
|
@ -37,25 +39,28 @@ public class CLIProcessor {
|
|||
return;
|
||||
}
|
||||
|
||||
Logger logger = SysBackup.getLogger();
|
||||
|
||||
for (int index = 0; index < args.length; index++) {
|
||||
switch (args[index].toLowerCase(Locale.ROOT)) {
|
||||
case "backup":
|
||||
{
|
||||
if (args.length <= 1) {
|
||||
System.err.println("Please specify a output task config name!");
|
||||
logger.log(Logger.LogLevel.WARN, "Please specify a output task config name!");
|
||||
return;
|
||||
}
|
||||
String fileName = args[1];
|
||||
File tasksFolder = new File(executionPath, "tasks");
|
||||
if (!tasksFolder.exists())
|
||||
if (!tasksFolder.mkdir()) System.err.println("Failed to create tasks folder!");
|
||||
if (!tasksFolder.mkdir())
|
||||
logger.log(Logger.LogLevel.ERROR, "Failed to create tasks folder!");
|
||||
File taskFile = new File(tasksFolder, fileName + ".toml");
|
||||
if (!taskFile.exists()) {
|
||||
System.err.println("TaskFile " + fileName + ".toml does not exist!");
|
||||
logger.log(Logger.LogLevel.ERROR, "TaskFile %s.toml does not exist!", fileName);
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("setuping TaskBuilder...");
|
||||
logger.log(Logger.LogLevel.INFO, "setupping TaskBuilder...");
|
||||
Config taskConfig = new Config(taskFile);
|
||||
TaskBuilder taskBuilder =
|
||||
TaskBuilder.builder()
|
||||
|
@ -69,48 +74,57 @@ public class CLIProcessor {
|
|||
case "generatetaskconf":
|
||||
{
|
||||
if (args.length <= 1) {
|
||||
System.err.println("Please specify a output task config name!");
|
||||
logger.log(Logger.LogLevel.ERROR, "Please specify a output task config name!");
|
||||
return;
|
||||
}
|
||||
String fileName = args[1];
|
||||
File tasksFolder = new File(executionPath, "tasks");
|
||||
if (!tasksFolder.exists())
|
||||
if (!tasksFolder.mkdir()) System.err.println("Failed to create tasks folder!");
|
||||
System.out.println("Saving task config " + fileName + ".toml...");
|
||||
FileUtils.copyInputStreamToFile(
|
||||
Objects.requireNonNull(getClass().getResourceAsStream("/" + "exampletask.toml")),
|
||||
new File(tasksFolder, fileName + ".toml"));
|
||||
System.out.println(fileName + ".toml saved!");
|
||||
if (!tasksFolder.mkdir())
|
||||
logger.log(Logger.LogLevel.ERROR, "Failed to create tasks folder!");
|
||||
logger.log(Logger.LogLevel.INFO, "Saving task config %s.toml...", fileName);
|
||||
try {
|
||||
FileUtils.copyInputStreamToFile(
|
||||
Objects.requireNonNull(
|
||||
getClass().getResourceAsStream("/" + "exampletask.toml")),
|
||||
new File(tasksFolder, fileName + ".toml"));
|
||||
} catch (IOException exception) {
|
||||
logger.log(Logger.LogLevel.ERROR, "Failed to save task config.");
|
||||
}
|
||||
logger.log(Logger.LogLevel.INFO, "%s.toml saved!", fileName);
|
||||
break;
|
||||
}
|
||||
case "checktaskconf":
|
||||
{
|
||||
if (args.length <= 1) {
|
||||
System.err.println("Please specify a output task config name!");
|
||||
logger.log(Logger.LogLevel.ERROR, "Please specify a output task config name!");
|
||||
return;
|
||||
}
|
||||
String fileName = args[1];
|
||||
File tasksFolder = new File(executionPath, "tasks");
|
||||
if (!tasksFolder.exists())
|
||||
if (!tasksFolder.mkdir()) System.err.println("Failed to create tasks folder!");
|
||||
if (!tasksFolder.mkdir())
|
||||
logger.log(Logger.LogLevel.ERROR, "Failed to create tasks folder!");
|
||||
File taskFile = new File(tasksFolder, fileName + ".toml");
|
||||
if (!taskFile.exists()) {
|
||||
System.err.println("TaskFile " + fileName + ".toml does not exist!");
|
||||
logger.log(Logger.LogLevel.ERROR, "TaskFile %s.toml does not exist!", fileName);
|
||||
return;
|
||||
}
|
||||
TomlParseResult toml;
|
||||
try {
|
||||
toml = Toml.parse(taskFile.toPath());
|
||||
} catch (IOException e) {
|
||||
System.err.println("failed to read TaskFile.");
|
||||
logger.log(Logger.LogLevel.ERROR, "failed to read TaskFile.");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
if (toml.hasErrors()) {
|
||||
System.err.printf(
|
||||
"TaskFile checked: found %d issues!:\n", (long) toml.errors().size());
|
||||
toml.errors().forEach(error -> System.err.println(error.toString()));
|
||||
logger.log(
|
||||
Logger.LogLevel.ERROR,
|
||||
"TaskFile checked: found %d issues!:\n",
|
||||
(long) toml.errors().size());
|
||||
toml.errors().forEach(error -> logger.log(Logger.LogLevel.ERROR, error.toString()));
|
||||
} else {
|
||||
System.out.println("TaskFile checked successfully: no issues found!");
|
||||
logger.log(Logger.LogLevel.INFO, "TaskFile checked successfully: no issues found!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -122,6 +136,7 @@ public class CLIProcessor {
|
|||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
SysBackup.getLogger().log(Logger.LogLevel.ERROR, t.getMessage());
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
|
48
src/main/java/net/horizoncode/sysbackup/logging/Logger.java
Normal file
48
src/main/java/net/horizoncode/sysbackup/logging/Logger.java
Normal file
|
@ -0,0 +1,48 @@
|
|||
package net.horizoncode.sysbackup.logging;
|
||||
|
||||
import com.diogonunes.jcolor.Ansi;
|
||||
import com.diogonunes.jcolor.Attribute;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@Builder
|
||||
public class Logger {
|
||||
private File logFile;
|
||||
|
||||
public void log(LogLevel logLevel, String message, Object... args) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
|
||||
String prefix =
|
||||
String.format(
|
||||
"[%s - %s] ",
|
||||
sdf.format(new Date()), Ansi.colorize(logLevel.name(), logLevel.getColor()));
|
||||
String line = prefix + message;
|
||||
System.out.printf(line + "\r\n", args);
|
||||
|
||||
// append to logfile
|
||||
try {
|
||||
FileUtils.writeStringToFile(
|
||||
logFile, line.replaceAll("\u001B\\[[;\\d]*m", "") + "\r\n", StandardCharsets.UTF_8, true);
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public enum LogLevel {
|
||||
INFO(Attribute.CYAN_TEXT()),
|
||||
WARN(Attribute.YELLOW_TEXT()),
|
||||
ERROR(Attribute.RED_TEXT());
|
||||
|
||||
@Getter private final Attribute color;
|
||||
|
||||
LogLevel(Attribute color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,9 @@ package net.horizoncode.sysbackup.tasks;
|
|||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import net.horizoncode.sysbackup.SysBackup;
|
||||
import net.horizoncode.sysbackup.config.Config;
|
||||
import net.horizoncode.sysbackup.logging.Logger;
|
||||
import net.horizoncode.sysbackup.tasks.impl.DatabaseTask;
|
||||
import net.horizoncode.sysbackup.tasks.impl.FileSystemTask;
|
||||
import net.horizoncode.sysbackup.tasks.impl.VacuumTask;
|
||||
|
@ -32,17 +34,19 @@ public class TaskBuilder {
|
|||
|
||||
public void start() {
|
||||
|
||||
Logger logger = SysBackup.getLogger();
|
||||
|
||||
File rootBackupDir = new File(executionPath, "backups");
|
||||
if (!rootBackupDir.exists())
|
||||
if (!rootBackupDir.mkdir()) {
|
||||
System.err.println("Failed to create root backup directory!");
|
||||
logger.log(Logger.LogLevel.ERROR, "Failed to create root backup directory!");
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
File backupDir = new File(rootBackupDir, getTaskName());
|
||||
if (!backupDir.exists())
|
||||
if (!backupDir.mkdir()) {
|
||||
System.err.println("Failed to create backup directory!");
|
||||
logger.log(Logger.LogLevel.ERROR, "Failed to create backup directory!");
|
||||
System.exit(2);
|
||||
}
|
||||
|
||||
|
@ -71,7 +75,8 @@ public class TaskBuilder {
|
|||
|
||||
int value = getTaskConfig().getIntOrDefault("vacuum.time", 5);
|
||||
|
||||
System.out.printf("Adding VacuumTask with lifetime of %d %s%n", value, unit.name());
|
||||
logger.log(
|
||||
Logger.LogLevel.INFO, "Adding VacuumTask with lifetime of %d %s%n", value, unit.name());
|
||||
taskList.add(
|
||||
new VacuumTask(backupDir, unit, value) {
|
||||
@Override
|
||||
|
@ -82,14 +87,14 @@ public class TaskBuilder {
|
|||
}
|
||||
|
||||
if (doFS && getTaskConfig().getToml().contains("filesystem.targets")) {
|
||||
System.out.println("Adding FileSystemTask...");
|
||||
logger.log(Logger.LogLevel.INFO, "Adding FileSystemTask...");
|
||||
TomlArray filesArray = getTaskConfig().getArray("filesystem.targets");
|
||||
|
||||
IntStream.range(0, filesArray.size())
|
||||
.forEach(
|
||||
value -> {
|
||||
String target = filesArray.getString(value);
|
||||
System.out.println("Adding \"" + target + "\"");
|
||||
logger.log(Logger.LogLevel.INFO, "Adding \"%s\"", target);
|
||||
taskList.add(
|
||||
new FileSystemTask(target, outputFile) {
|
||||
@Override
|
||||
|
@ -113,7 +118,7 @@ public class TaskBuilder {
|
|||
.password(password.toCharArray())
|
||||
.build();
|
||||
|
||||
System.out.println("Adding DatabaseTask for database \"" + database + "\"");
|
||||
logger.log(Logger.LogLevel.INFO, "Adding DatabaseTask for database \"%s\"", database);
|
||||
|
||||
taskList.add(
|
||||
new DatabaseTask(databaseCredentials, outputFile) {
|
||||
|
@ -123,7 +128,7 @@ public class TaskBuilder {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
System.err.println("username, password or database is empty.");
|
||||
logger.log(Logger.LogLevel.ERROR, "username, password or database is empty.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +139,7 @@ public class TaskBuilder {
|
|||
Task nextTask = taskList.poll();
|
||||
if (nextTask != null) nextTask.start();
|
||||
else {
|
||||
System.out.println("Backup completed!");
|
||||
SysBackup.getLogger().log(Logger.LogLevel.INFO, "Backup completed!");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import lombok.Getter;
|
|||
import me.tongfei.progressbar.ProgressBar;
|
||||
import me.tongfei.progressbar.ProgressBarBuilder;
|
||||
import me.tongfei.progressbar.ProgressBarStyle;
|
||||
import net.horizoncode.sysbackup.SysBackup;
|
||||
import net.horizoncode.sysbackup.logging.Logger;
|
||||
import net.horizoncode.sysbackup.tasks.Task;
|
||||
import net.lingala.zip4j.ZipFile;
|
||||
import net.lingala.zip4j.progress.ProgressMonitor;
|
||||
|
@ -29,6 +31,7 @@ public class DatabaseTask extends Task {
|
|||
@Override
|
||||
public void start() {
|
||||
try {
|
||||
Logger logger = SysBackup.getLogger();
|
||||
String commandArgs =
|
||||
"mysqldump -u "
|
||||
+ getDatabaseCredentials().username
|
||||
|
@ -51,6 +54,7 @@ public class DatabaseTask extends Task {
|
|||
.lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Logger.LogLevel.ERROR, e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
@ -63,13 +67,13 @@ public class DatabaseTask extends Task {
|
|||
new InputStreamReader(process.getErrorStream(), StandardCharsets.UTF_8))
|
||||
.lines()
|
||||
.collect(Collectors.joining("\n"));
|
||||
System.out.println(text);
|
||||
logger.log(Logger.LogLevel.ERROR, text);
|
||||
onDone();
|
||||
return;
|
||||
}
|
||||
|
||||
if (databaseContent.isEmpty()) {
|
||||
System.err.println("database content is empty");
|
||||
logger.log(Logger.LogLevel.ERROR, "database content is empty");
|
||||
onDone();
|
||||
return;
|
||||
}
|
||||
|
@ -84,7 +88,7 @@ public class DatabaseTask extends Task {
|
|||
BufferedWriter writer = new BufferedWriter(new FileWriter(outputSQLFile));
|
||||
writer.write(databaseContent);
|
||||
writer.close();
|
||||
System.out.println("Adding database to backup zip...");
|
||||
logger.log(Logger.LogLevel.INFO, "Adding database to backup zip...");
|
||||
try (ZipFile zipFile = new ZipFile(getOutputFile())) {
|
||||
ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
|
||||
zipFile.setRunInThread(true);
|
||||
|
@ -103,6 +107,7 @@ public class DatabaseTask extends Task {
|
|||
}
|
||||
pb.stepTo(progressMonitor.getTotalWork());
|
||||
} catch (Exception exception) {
|
||||
logger.log(Logger.LogLevel.ERROR, exception.getMessage());
|
||||
exception.printStackTrace();
|
||||
outputSQLFile.deleteOnExit();
|
||||
onDone();
|
||||
|
@ -111,11 +116,13 @@ public class DatabaseTask extends Task {
|
|||
outputSQLFile.deleteOnExit();
|
||||
onDone();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Logger.LogLevel.ERROR, ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
onDone();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
SysBackup.getLogger().log(Logger.LogLevel.ERROR, e.getMessage());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package net.horizoncode.sysbackup.tasks.impl;
|
|||
import me.tongfei.progressbar.ProgressBar;
|
||||
import me.tongfei.progressbar.ProgressBarBuilder;
|
||||
import me.tongfei.progressbar.ProgressBarStyle;
|
||||
import net.horizoncode.sysbackup.SysBackup;
|
||||
import net.horizoncode.sysbackup.logging.Logger;
|
||||
import net.horizoncode.sysbackup.tasks.Task;
|
||||
import net.lingala.zip4j.ZipFile;
|
||||
import net.lingala.zip4j.progress.ProgressMonitor;
|
||||
|
@ -17,9 +19,11 @@ public class FileSystemTask extends Task {
|
|||
|
||||
public FileSystemTask(String folderOrFilePath, File outputZipFile) {
|
||||
this.target = Paths.get(folderOrFilePath).toFile();
|
||||
Logger logger = SysBackup.getLogger();
|
||||
if (!target.exists()) {
|
||||
onDone();
|
||||
System.err.println("File or folder named \"" + folderOrFilePath + "\" does not exist.");
|
||||
logger.log(
|
||||
Logger.LogLevel.ERROR, "File or folder named \"%s\" does not exist.", folderOrFilePath);
|
||||
System.exit(2);
|
||||
return;
|
||||
}
|
||||
|
@ -29,8 +33,9 @@ public class FileSystemTask extends Task {
|
|||
|
||||
@Override
|
||||
public void start() {
|
||||
Logger logger = SysBackup.getLogger();
|
||||
try (ZipFile zipFile = new ZipFile(outputZipFile)) {
|
||||
System.out.println("Indexing files...");
|
||||
logger.log(Logger.LogLevel.INFO, "Indexing files...");
|
||||
ProgressMonitor progressMonitor = zipFile.getProgressMonitor();
|
||||
zipFile.setRunInThread(true);
|
||||
zipFile.addFolder(target);
|
||||
|
@ -48,12 +53,14 @@ public class FileSystemTask extends Task {
|
|||
}
|
||||
pb.stepTo(progressMonitor.getTotalWork());
|
||||
} catch (Exception exception) {
|
||||
logger.log(Logger.LogLevel.ERROR, exception.getMessage());
|
||||
exception.printStackTrace();
|
||||
onDone();
|
||||
}
|
||||
progressMonitor.endProgressMonitor();
|
||||
onDone();
|
||||
} catch (Exception ex) {
|
||||
logger.log(Logger.LogLevel.ERROR, ex.getMessage());
|
||||
ex.printStackTrace();
|
||||
onDone();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ package net.horizoncode.sysbackup.threading;
|
|||
import lombok.Getter;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
||||
public class ThreadPool {
|
||||
|
@ -11,13 +10,10 @@ public class ThreadPool {
|
|||
@Getter private final ExecutorService pool;
|
||||
|
||||
public ThreadPool(int corePoolSize, int maxPoolSize) {
|
||||
this.pool = scheduledExecutorService(corePoolSize, maxPoolSize);
|
||||
}
|
||||
|
||||
private ScheduledExecutorService scheduledExecutorService(int corePoolSize, int maxPoolSize) {
|
||||
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
|
||||
new ScheduledThreadPoolExecutor(corePoolSize);
|
||||
scheduledThreadPoolExecutor.setMaximumPoolSize(maxPoolSize);
|
||||
return scheduledThreadPoolExecutor;
|
||||
|
||||
this.pool = scheduledThreadPoolExecutor;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user