Skip to content

Commit

Permalink
feat: log to OmegaT_session_yyyyMMddHHmmss.log file
Browse files Browse the repository at this point in the history
Signed-off-by: Hiroshi Miura <[email protected]>
  • Loading branch information
miurahr committed Jul 8, 2024
1 parent 179fb57 commit 77525c6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 47 deletions.
17 changes: 17 additions & 0 deletions src/org/omegat/util/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Properties;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
Expand All @@ -58,15 +61,29 @@ public final class Log {

private static final ILogger LOGGER;

// Line mark is day-of-the-year and five-character random number
private static final String SESSION_ID;
private static final String SESSION_START_DATETIME;

private Log() {
}

static {
SESSION_ID = String.format("%05d", ThreadLocalRandom.current().nextInt(100000));
SESSION_START_DATETIME = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(ZonedDateTime.now());
LOGGER = LoggerFactory.getLogger(ILogger.ROOT_LOGGER_NAME,
OStrings.getResourceBundle());
init();
}

public static String getSessionId() {
return SESSION_ID;
}

public static String getSessionStartDateTime() {
return SESSION_START_DATETIME;
}

private static void init() {
boolean loaded = false;

Expand Down
85 changes: 45 additions & 40 deletions src/org/omegat/util/logging/OmegaTFileHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,20 @@
package org.omegat.util.logging;

import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.logging.ErrorManager;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;

import org.omegat.util.Log;
import org.omegat.util.OStrings;
import org.omegat.util.StaticUtils;

Expand All @@ -65,6 +65,7 @@ public class OmegaTFileHandler extends StreamHandler {
private FileOutputStream lockStream;
private final long maxSize;
private final int count;
private final long retention;

public OmegaTFileHandler() throws IOException {
LogManager manager = LogManager.getLogManager();
Expand All @@ -89,6 +90,13 @@ public OmegaTFileHandler() throws IOException {
count = 10;
}

String retentionStr = manager.getProperty(cname + ".retention");
if (retentionStr != null) {
retention = Integer.parseInt(retentionStr) * 1000L;
} else {
retention = 10 * 24 * 60 * 60 * 1000L;
}

openFiles(new File(StaticUtils.getConfigDir(), "logs"));
}

Expand All @@ -104,19 +112,20 @@ public String getLogFileName() {
*/
@SuppressWarnings("resource")
private void openFiles(final File dir) throws IOException {
dir.mkdirs();
boolean ignored = dir.mkdirs();
for (int instanceIndex = 0; instanceIndex < 100; instanceIndex++) {
String fileName = OStrings.getApplicationName()
String fileName = String.format("%s_%s_%s%s", OStrings.getApplicationName(), Log.getSessionId(),
Log.getSessionStartDateTime(),
// Instance index
+ (instanceIndex > 0 ? ("-" + instanceIndex) : "");
instanceIndex > 0 ? ("-" + instanceIndex) : "");

lockFile = new File(dir, fileName + ".log.lck");
logFileName = fileName;

// try to create lock file
lockStream = new FileOutputStream(lockFile);
if (lockStream.getChannel().tryLock() != null) {
rotate(dir, fileName);
cleanOldLogFiles(dir);
setEncoding(StandardCharsets.UTF_8.name());
setOutputStream(new FileOutputStream(new File(dir, fileName + ".log"), true));
break;
Expand All @@ -131,48 +140,44 @@ public synchronized void close() throws SecurityException {
super.close();
try {
lockStream.close();
lockFile.delete();
boolean ignored = lockFile.delete();
} catch (Exception ex) {
// shouldn't happen
ex.printStackTrace();
}
}

/**
* Rotate log files if need.
*/
private void rotate(final File dir, final String fileName) {
File logFile = new File(dir, fileName + ".log");
if (!logFile.exists() || logFile.length() < maxSize) {
// do not need to rotate
return;
}

String suffix = new SimpleDateFormat("yyyyMMdd.HHmm").format(new Date());
File destFile = new File(dir, fileName + '.' + suffix + ".log");
logFile.renameTo(destFile);
File[] oldLogs = dir.listFiles(new FileFilter() {
public boolean accept(File pathname) {
return pathname.getName().startsWith(fileName + '.') && pathname.getName().endsWith(".log");
}
});
if (oldLogs != null) {
Arrays.sort(oldLogs, new Comparator<File>() {
public int compare(File o1, File o2) {
return o2.getName().compareToIgnoreCase(o1.getName());
}
});
for (int i = count; i < oldLogs.length; i++) {
oldLogs[i].delete();
}
}
}

@Override
public synchronized void publish(LogRecord record) {
if (isLoggable(record)) {
super.publish(record);
flush();
}
}

private void cleanOldLogFiles(File dir) {
if (!dir.exists() || !dir.isDirectory()) {
return;
}

File[] files = dir.listFiles((d, name) -> name.startsWith(OStrings.getApplicationName())
&& name.endsWith(".log"));
if (files == null) {
return;
}

long cutoffTime = System.currentTimeMillis() - retention;

for (File file : files) {
try {
Path filePath = Paths.get(file.getAbsolutePath());
BasicFileAttributes attrs = Files.readAttributes(filePath, BasicFileAttributes.class);
if (attrs.creationTime().toMillis() < cutoffTime) {
Files.delete(filePath);
}
} catch (IOException e) {
Log.log("Failed to delete old log file: " + file.getAbsolutePath());
}
}
}
}
12 changes: 5 additions & 7 deletions src/org/omegat/util/logging/OmegaTLogFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,13 @@
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.LogRecord;

import org.omegat.util.Log;
import org.omegat.util.OStrings;
import org.omegat.util.StringUtil;

Expand All @@ -49,10 +47,8 @@
*/
public class OmegaTLogFormatter extends Formatter {

// Line mark is day-of-the-year and five-character random number
protected static final String LINE_MARK = String.format("%s%05d",
DateTimeFormatter.ofPattern("DDD").format(ZonedDateTime.now()),
ThreadLocalRandom.current().nextInt(100000));
// Line mark is five-character random number
protected final String LINE_MARK;

private String logMask;
private final boolean isMaskContainsMark;
Expand Down Expand Up @@ -83,6 +79,8 @@ public OmegaTLogFormatter() {
LogManager manager = LogManager.getLogManager();
String cname = getClass().getName();

LINE_MARK = Log.getSessionId();

logMask = manager.getProperty(cname + ".mask");
if (logMask == null) {
logMask = "$mark: $level: $text $key";
Expand Down

0 comments on commit 77525c6

Please sign in to comment.