Add logging

This commit is contained in:
Nathan McRae 2025-01-20 22:38:01 -08:00
parent 1ae75d4891
commit 5a3df459f9
4 changed files with 102 additions and 6 deletions

View File

@ -0,0 +1,34 @@
package name.nathanmcrae.numbersstation;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public class CustomFormatter extends Formatter {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
@Override
public String format(LogRecord record) {
String timestamp = dateFormat.format(new Date(record.getMillis()));
String logLevel = record.getLevel().getName();
String className = record.getSourceClassName();
String methodName = record.getSourceMethodName();
String message = formatMessage(record);
StringBuilder logMessage = new StringBuilder();
logMessage.append(String.format("%s\t%s\t%s\t%s\t%s", timestamp, logLevel, className, methodName, message));
if (record.getThrown() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
record.getThrown().printStackTrace(pw);
logMessage.append("\n\t").append(sw.toString());
}
logMessage.append(System.lineSeparator());
return logMessage.toString();
}
}

View File

@ -1,21 +1,74 @@
package name.nathanmcrae.numbersstation; package name.nathanmcrae.numbersstation;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.FileHandler;
import java.util.logging.Logger;
import java.util.logging.Level;
import javafx.application.Application; import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.stage.Stage; import javafx.stage.Stage;
public class Main extends Application { public class Main extends Application {
private static final Logger logger = Logger.getLogger(Main.class.getName());
private static Path statePath = null;
public Path getStatePath() {
if (statePath == null) {
String stateHome = System.getenv("XDG_STATE_HOME");
if (stateHome == null || stateHome.isEmpty() || !Paths.get(stateHome).isAbsolute()) {
String userHome = System.getProperty("user.home");
statePath = Paths.get(userHome, ".local", "state", "numbers-station");
} else {
statePath = Paths.get(stateHome, "numbers-station");
}
}
return statePath;
}
@Override @Override
public void start(Stage primaryStage) throws Exception { public void start(Stage primaryStage) throws Exception {
setupLogger();
Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml")); Parent root = FXMLLoader.load(getClass().getResource("MainView.fxml"));
primaryStage.setTitle("Numbers Station"); primaryStage.setTitle("Numbers Station");
primaryStage.setScene(new Scene(root)); primaryStage.setScene(new Scene(root));
primaryStage.show(); primaryStage.show();
logger.info("Application started");
}
private void setupLogger() {
try {
Path logFile = getStatePath().resolve("main.log");
if (!Files.exists(logFile.getParent())) {
Files.createDirectories(logFile.getParent());
}
FileHandler fileHandler = new FileHandler(logFile.toString(), true);
fileHandler.setFormatter(new CustomFormatter());
logger.addHandler(fileHandler);
} catch (IOException e) {
System.out.println("Failed to set up logger: " + e.getMessage());
}
} }
public static void main(String[] args) { public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
logger.log(Level.SEVERE, "Unhandled exception caught", throwable);
});
Platform.setImplicitExit(false);
Thread.currentThread().setUncaughtExceptionHandler((thread, throwable) -> {
logger.log(Level.SEVERE, "Unhandled exception in JavaFX application thread", throwable);
});
launch(args); launch(args);
} }
} }

View File

@ -10,6 +10,8 @@ import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Random; import java.util.Random;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
@ -29,6 +31,8 @@ import javafx.stage.Modality;
import javafx.stage.Stage; import javafx.stage.Stage;
public class MainController implements Initializable { public class MainController implements Initializable {
private static final Logger logger = Logger.getLogger(Main.class.getName());
private Stage settingsStage; private Stage settingsStage;
private Stage selectStationStage; private Stage selectStationStage;
private MainSettings settings; private MainSettings settings;
@ -75,7 +79,7 @@ public class MainController implements Initializable {
updateStationSettings(selectedStation); updateStationSettings(selectedStation);
}); });
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); logger.log(Level.SEVERE, "Exception while opening settings", e);
} }
} else { } else {
settingsStage.toFront(); settingsStage.toFront();
@ -83,7 +87,7 @@ public class MainController implements Initializable {
} }
@FXML @FXML
private void handleSelectStationButtonPress() { private void handleSelectStationButtonPress() throws Exception {
if (selectStationStage == null || !selectStationStage.isShowing()) { if (selectStationStage == null || !selectStationStage.isShowing()) {
try { try {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StationSelectionView.fxml")); FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("StationSelectionView.fxml"));
@ -107,7 +111,7 @@ public class MainController implements Initializable {
updateStationSettings(newSelectedStation); updateStationSettings(newSelectedStation);
}); });
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); logger.log(Level.SEVERE, "Exception while selecting station", e);
} }
} else { } else {
selectStationStage.toFront(); selectStationStage.toFront();
@ -139,9 +143,8 @@ public class MainController implements Initializable {
} }
} }
} catch (IOException e) { } catch (IOException e) {
// Print the contents of filePath logger.log(Level.SEVERE, "Failed to load settings from " + filePath.toString(), e);
System.out.println("File contents: " + Files.readString(filePath)); System.out.println("File contents: " + Files.readString(filePath));
e.printStackTrace();
} }
} }
@ -216,6 +219,8 @@ public class MainController implements Initializable {
} }
private void updateStationSettings(StationSettings newStationSettings) { private void updateStationSettings(StationSettings newStationSettings) {
logger.info("Updating station settings: " + newStationSettings.getName());
if (newStationSettings == null) { if (newStationSettings == null) {
return; return;
} }

View File

@ -11,8 +11,11 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.logging.Logger;
public class MainSettings { public class MainSettings {
private static final Logger logger = Logger.getLogger(Main.class.getName());
private int digitsPerGroup; private int digitsPerGroup;
private String username; private String username;
private int refreshInterval; private int refreshInterval;
@ -30,7 +33,7 @@ public class MainSettings {
Path directoryPath; Path directoryPath;
Path filePath; Path filePath;
if (configHome != null && !configHome.isEmpty()) { if (configHome != null && !configHome.isEmpty() && Paths.get(configHome).isAbsolute()) {
directoryPath = Paths.get(configHome, "numbers-station"); directoryPath = Paths.get(configHome, "numbers-station");
} else { } else {
String userHome = System.getProperty("user.home"); String userHome = System.getProperty("user.home");
@ -81,6 +84,7 @@ public class MainSettings {
} }
xmlMapper.writeValue(new File(filePath.toString()), this); xmlMapper.writeValue(new File(filePath.toString()), this);
logger.info("Settings saved to " + filePath.toString());
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }