0

I have a JTextArea in my program which I would like to display the program's logs. I've done some digging and found OutputStreamAppender in the Log4j2 documentation, which I assume I could use to output logs to an OutputStream which I could then pipe into the JTextArea. Unfortunately there isn't much documentation (at least that I could find) on this. Am I on the right track here? If so, how do I use OutputStreamAppender? If not, what should I be doing? I'd rather not create my own Appender.

Thanks

BlockyPenguin
  • 75
  • 1
  • 6
  • Why not just open the actual log file in your text area? – g00se May 17 '23 at 14:32
  • 1
    Does this answer your question? [How to output logs to a JTextArea using Log4j2](https://stackoverflow.com/questions/24005748/how-to-output-logs-to-a-jtextarea-using-log4j2) – jon hanson May 17 '23 at 14:32
  • @g00se Because it's set up to use a new file name each time, based on the date and time of the program being started. I'm not sure how I'd be able to easily identify the newest file. – BlockyPenguin May 17 '23 at 14:35
  • @jonhanson Whilst I could do that, it involves creating a new Appender, something I'd rather not do. – BlockyPenguin May 17 '23 at 14:36
  • *it's set up to use a new file name each time* Example name? – g00se May 17 '23 at 14:41
  • @g00se It's in the format `dd MMM yyyy HH.mm.ss`, so, for example: `17 May 2023 15.44.31.log` – BlockyPenguin May 17 '23 at 14:45

1 Answers1

1

Maybe try something like (quick and dirty - you'd definitely want to guard against endless looping):

import java.time.format.*;
import java.time.*;
import java.util.Comparator;
import java.nio.file.*;
import java.io.IOException;

public class FName {
    public static void main(String[] args) {
        try {
            //System.out.println(FName.getLatestLogFileName(Path.of("/tmp")));
            System.out.println(FName.findLatestLogFileName(Path.of("/tmp")));
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    public static Path findLatestLogFileName(Path logsDir) throws Exception {
        // Tighten this pattern up as necessary
        final String LOGFILE_PAT =".*\\.log";
        return Files.find(logsDir, 1, (p, attr) ->p.getFileName().toString().matches(LOGFILE_PAT)).
            sorted(Comparator.comparingLong(p ->p.toFile().lastModified())).
            reduce((first, second) -> second).
            orElse(null);
    }

    public static Path getLatestLogFileName(Path logsDir) {
        Path result = null;
        LocalDateTime ldt = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MMMM uuuu HH.mm.ss");
        boolean foundLogFile = false;
        while (result == null) {
            Path test = logsDir.resolve(Path.of(dtf.format(ldt) + ".log"));
            if (Files.exists(test)) {
                result = test;
            } else {
                ldt = ldt.minusSeconds(1);
            }
        }
        return result;
    }
}
g00se
  • 3,207
  • 2
  • 5
  • 9
  • Have to say that brute force iteration could be quite lengthy if the log file's more than a few days old ;) – g00se May 17 '23 at 15:31
  • This solution works, thank you for that, but I can't help but feel it could be a little more elegant - having my program write to a file and then read from it again just for a graphical log seems clunky. I'll leave this question open for a while, and if no alternatives arise then I shall use this and mark yours as the accepted answer. Thanks again! – BlockyPenguin May 17 '23 at 17:58
  • Well of course, "elegant" could really only be the 'proper' solution, which, as you've seen, requires quite a lot of code. But another way which would be more efficient would be to sort the files in the log dir by timestamp. – g00se May 17 '23 at 18:51
  • My added method is much more efficient – g00se May 17 '23 at 21:44