Replace file logger with json based system
This commit is contained in:
parent
1b917f0901
commit
f11ebe6166
@ -89,17 +89,16 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
// the uuid cache instance
|
||||
private final FileUuidCache uuidCache = new FileUuidCache();
|
||||
// the action logger instance
|
||||
private final FileActionLogger actionLogger = new FileActionLogger();
|
||||
private final FileActionLogger actionLogger;
|
||||
|
||||
// the file used to store uuid data
|
||||
private Path uuidDataFile;
|
||||
// the file used to store logged actions
|
||||
private Path actionLogFile;
|
||||
|
||||
protected AbstractConfigurateDao(LuckPermsPlugin plugin, ConfigurateLoader loader, String name, String dataDirectoryName) {
|
||||
super(plugin, name);
|
||||
this.loader = loader;
|
||||
this.dataDirectoryName = dataDirectoryName;
|
||||
this.actionLogger = new FileActionLogger(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,15 +134,15 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
Files.createDirectories(this.dataDirectory);
|
||||
|
||||
this.uuidDataFile = MoreFiles.createFileIfNotExists(this.dataDirectory.resolve("uuidcache.txt"));
|
||||
this.actionLogFile = MoreFiles.createFileIfNotExists(this.dataDirectory.resolve("actions.log"));
|
||||
|
||||
this.uuidCache.load(this.uuidDataFile);
|
||||
this.actionLogger.init(this.actionLogFile);
|
||||
|
||||
this.actionLogger.init(this.dataDirectory.resolve("actions.json"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
this.uuidCache.save(this.uuidDataFile);
|
||||
this.actionLogger.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -152,10 +151,8 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Log getLog() {
|
||||
// File based daos don't support viewing log data from in-game.
|
||||
// You can just read the file in a text editor.
|
||||
return Log.empty();
|
||||
public Log getLog() throws IOException {
|
||||
return this.actionLogger.getLog();
|
||||
}
|
||||
|
||||
protected ConfigurationNode processBulkUpdate(BulkUpdate bulkUpdate, ConfigurationNode node) {
|
||||
|
@ -25,48 +25,152 @@
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.common.command.CommandManager;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.buffers.BufferedRequest;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.gson.JObject;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Date;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.LogRecord;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class FileActionLogger {
|
||||
private static final String LOG_FORMAT = "%s(%s): [%s] %s(%s) --> %s";
|
||||
private final Logger actionLogger = Logger.getLogger("luckperms_actions");
|
||||
|
||||
public void init(Path file) {
|
||||
try {
|
||||
FileHandler fh = new FileHandler(file.toString(), 0, 1, true);
|
||||
fh.setFormatter(new Formatter() {
|
||||
@Override
|
||||
public String format(LogRecord record) {
|
||||
return new Date(record.getMillis()).toString() + ": " + record.getMessage() + "\n";
|
||||
}
|
||||
});
|
||||
this.actionLogger.addHandler(fh);
|
||||
this.actionLogger.setUseParentHandlers(false);
|
||||
this.actionLogger.setLevel(Level.ALL);
|
||||
this.actionLogger.setFilter(record -> true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
/**
|
||||
* The path to save logger content to
|
||||
*/
|
||||
private Path contentFile;
|
||||
|
||||
/**
|
||||
* Lock to ensure the file isn't written to by multiple threads
|
||||
*/
|
||||
private final ReentrantLock writeLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* The queue of entries pending save to the file
|
||||
*/
|
||||
private final Queue<LogEntry> entryQueue = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private final SaveBuffer saveBuffer;
|
||||
|
||||
public FileActionLogger(LuckPermsPlugin plugin) {
|
||||
this.saveBuffer = new SaveBuffer(plugin);
|
||||
}
|
||||
|
||||
public void init(Path contentFile) {
|
||||
this.contentFile = contentFile;
|
||||
}
|
||||
|
||||
public void logAction(LogEntry entry) {
|
||||
this.actionLogger.info(String.format(LOG_FORMAT,
|
||||
(entry.getActor().equals(CommandManager.CONSOLE_UUID) ? "" : entry.getActor() + " "),
|
||||
entry.getActorName(),
|
||||
Character.toString(entry.getType().getCode()),
|
||||
entry.getActed().map(e -> e.toString() + " ").orElse(""),
|
||||
entry.getActedName(),
|
||||
entry.getAction())
|
||||
);
|
||||
this.entryQueue.add(entry);
|
||||
this.saveBuffer.request();
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
this.writeLock.lock();
|
||||
try {
|
||||
// don't perform the i/o process if there's nothing to be written
|
||||
if (this.entryQueue.peek() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// read existing array data into memory
|
||||
JsonArray array;
|
||||
|
||||
if (Files.exists(this.contentFile)) {
|
||||
try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
|
||||
array = Streams.parse(reader).getAsJsonArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
array = new JsonArray();
|
||||
}
|
||||
} else {
|
||||
array = new JsonArray();
|
||||
}
|
||||
|
||||
// poll the queue for new entries
|
||||
for (LogEntry e; (e = this.entryQueue.poll()) != null; ) {
|
||||
JObject object = new JObject()
|
||||
.add("timestamp", e.getTimestamp())
|
||||
.add("actor", e.getActor().toString())
|
||||
.add("actorName", e.getActorName())
|
||||
.add("type", Character.toString(e.getType().getCode()))
|
||||
.add("actedName", e.getActedName())
|
||||
.add("action", e.getAction());
|
||||
|
||||
if (e.getActed().isPresent()) {
|
||||
object.add("acted", e.getActed().get().toString());
|
||||
}
|
||||
|
||||
array.add(object.toJson());
|
||||
}
|
||||
|
||||
// write the full content back to the file
|
||||
try (JsonWriter writer = new JsonWriter(Files.newBufferedWriter(this.contentFile, StandardCharsets.UTF_8))) {
|
||||
writer.setIndent(" ");
|
||||
Streams.write(array, writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
this.writeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Log getLog() throws IOException {
|
||||
Log.Builder log = Log.builder();
|
||||
try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
|
||||
JsonArray array = Streams.parse(reader).getAsJsonArray();
|
||||
for (JsonElement element : array) {
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
|
||||
UUID actedUuid = null;
|
||||
if (object.has("acted")) {
|
||||
actedUuid = UUID.fromString(object.get("acted").getAsString());
|
||||
}
|
||||
|
||||
ExtendedLogEntry e = ExtendedLogEntry.build()
|
||||
.timestamp(object.get("timestamp").getAsLong())
|
||||
.actor(UUID.fromString(object.get("actor").getAsString()))
|
||||
.actorName(object.get("actorName").getAsString())
|
||||
.type(LogEntry.Type.valueOf(object.get("type").getAsCharacter()))
|
||||
.acted(actedUuid)
|
||||
.actedName(object.get("actedName").getAsString())
|
||||
.action(object.get("action").getAsString())
|
||||
.build();
|
||||
|
||||
log.add(e);
|
||||
}
|
||||
}
|
||||
return log.build();
|
||||
}
|
||||
|
||||
private final class SaveBuffer extends BufferedRequest<Void> {
|
||||
public SaveBuffer(LuckPermsPlugin plugin) {
|
||||
super(2000L, 500L, plugin.getBootstrap().getScheduler().async());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Void perform() {
|
||||
FileActionLogger.this.flush();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -183,7 +183,7 @@ public class MongoDao extends AbstractDao {
|
||||
.timestamp(d.getLong("timestamp"))
|
||||
.actor(d.get("actor", UUID.class))
|
||||
.actorName(d.getString("actorName"))
|
||||
.type(LogEntry.Type.valueOf(d.getString("type").toCharArray()[0]))
|
||||
.type(LogEntry.Type.valueOf(d.getString("type").charAt(0)))
|
||||
.acted(actedUuid)
|
||||
.actedName(d.getString("actedName"))
|
||||
.action(d.getString("action"))
|
||||
|
Loading…
Reference in New Issue
Block a user