name: java-client-file-logging
description: Add or review lightweight, dependency-free file logging for Java 8 desktop clients. Use when a Swing, JavaFX, or packaged Java client needs daily UTF-8 logs beside its JAR, structured records for login/scan/business events, and explicit user-close or uncaught-exception records without adopting a logging framework.
Java Client File Logging
Use this pattern for a small desktop client where operational support needs inspectable local logs and adding Logback or Log4j is disproportionate. Copy assets/AppLog.java, change its package and APP_NAME, then integrate it before the UI or worker threads start.
Integration Workflow
- Call
AppLog.init() as the first operation in main, before creating Swing/JavaFX components, network clients, or executors.
- Mark confirmed operator shutdown immediately before
System.exit(0) with AppLog.markUserClose().
- Log business boundaries rather than incidental control flow:
login(userId, method, success) for every completed or rejected login.
scan(type, code) immediately after a non-empty scan is accepted.
work(action, code, success) after each MES/device/API operation resolves.
- Run the packaged JAR from its intended release folder and verify the log appears in
<jar-directory>/logs/<app-name>-yyyy-MM-dd.log.
Keep user-facing messages and diagnostics separate: log stable actions and identifiers, not display text or request payloads. Never log passwords, tokens, session IDs, or raw sensitive responses.
Expected Records
The template writes one line per event in this shape:
[2026-07-14 11:00:05.358][INFO][AWT-EventQueue-0] Login succeeded, method=badge-scan, user=10001
It appends to one file per calendar day, writes UTF-8, includes the thread name, serializes writes with a lock, and flushes each event. The shutdown hook writes either a confirmed user-close record or the uncaught exception and stack trace.
Placement Rules
- Derive the base directory from the running code source. For a JAR this is its parent folder; in an IDE it falls back to
user.dir.
- Use the exact same package/import convention as the target application.
- Preserve any existing default uncaught-exception handler when the host application or framework owns it. The supplied template installs one because it is intended for standalone clients; chain to the existing handler if one must remain active.
- Keep
SimpleDateFormat accesses inside the logging lock, as it is not thread-safe.
- Treat logging failure as non-fatal. The client must remain usable when the log directory is read-only or unavailable.
Review Checklist
- Initialization happens before any meaningful client activity.
- All
System.exit paths that mean an intentional close call markUserClose().
- Login, scans, and externally visible operation outcomes are each recorded once.
- Values passed to log methods cannot inject new lines; the helper normalizes CR/LF.
- The release layout leaves the JAR directory writable, or the deployment owner accepts that logging is best-effort.