Console in Textdatei exportieren

gordonsky

Mitglied
Hallo,

um evt. Fehler zu erkennen, würde ich gern immer den Consolenausschrieb abspeichern wenn das Progamm fertig ist.

Aktuel habe ich überhaupt keinen Ansatz.

Kann mir da jemand auf die Sprünge helfen?
 
Die hier ideale Lösung hängt ganz vom Deployment-Modell deiner Anwendung ab. Wenn es als Service z.B. in einer Container-Orchestrierung wie Kubernetes oder in einer anderen Cloud-Plattform läuft, dann gibt es dort schon Logging-Agents, die alles das, was der Prozess nach stdout/stderr schreibt, aufzeichnen und in dem Logging-Tool der Plattform speichern.

Wenn es "einfach nur" ein Programm ist, was du lokal oder auf einem Server Maschine ausführst, dann könntest du einfach z.B. einen Shell-Redirect-Operator (>) verwenden, um stdout/stderr in eine Datei zu schreiben:
Code:
java -jar mein.jar >stdout.txt 2>stderr.txt

Andere aber mehr invasive Möglichkeiten wären, dein Programm selbst anzupassen, und eine Logging-Library zu verwenden.
 
Um die Antwort von @httpdigest noch etwas zu ergänzen: Damit man die Ausgabe auch noch sehen kann und nicht nur alles umleitet könnte man Tools wie tee nutzen.

Und wenn es mehr um kleine Spielereien geht, dann kann man natürlich auch System.out und System.err ersetzen um dann alle Aufrufe zu System.in und System.out auch noch in eine Datei zu schreiben. Das könnte dann ungefähr so aussehen:
Java:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

public class DualOutput {

    public static void main(String[] args) throws IOException {
        FileOutputStream fileOut = new FileOutputStream("output.log");
        
        PrintStream dualOut = new PrintStream(new DualStream(System.out, new PrintStream(fileOut, true)));
        PrintStream dualErr = new PrintStream(new DualStream(System.err, new PrintStream(fileOut, true)));

        System.setOut(dualOut);
        System.setErr(dualErr);

        System.out.println("Dies ist eine Nachricht auf System.out");
        System.err.println("Dies ist eine Nachricht auf System.err");
    }

    public static class DualStream extends PrintStream {
        private final PrintStream stream1;
        private final PrintStream stream2;

        public DualStream(PrintStream stream1, PrintStream stream2) {
            super(stream1);
            this.stream1 = stream1;
            this.stream2 = stream2;
        }

        @Override
        public void write(int b) {
            stream1.write(b);
            stream2.write(b);
        }

        @Override
        public void write(byte[] buf, int off, int len) {
            stream1.write(buf, off, len);
            stream2.write(buf, off, len);
        }

        @Override
        public void flush() {
            stream1.flush();
            stream2.flush();
        }

        @Override
        public void close() {
            stream1.close();
            stream2.close();
        }
    }
}

Aber wie gesagt: Das ist nicht mehr wie eine kleine Spielerei. Wenn man mehr wie eine Spielerei machen will, dann ist die zielführende Aussage aus meiner Sicht ganz klar:
und eine Logging-Library zu verwenden.
 
und eine Logging-Library zu verwenden.
Eine Logging-Library ist nicht unbedingt notwendig. Java selbst stellt auch Logging-Funktionen zu Verfügung.
Java:
package home.playground;

import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

public class Main {

    public static void main(final String[] args) {
        final Logger logger = initLoggerGlobal();
        final LogTester tester = new LogTester();
        try {
            tester.hello("Hello, World!");
            tester.hello("Hello, Logging ...");
            tester.hello(null); // cause exception
        } catch (final IllegalArgumentException e) {
            logger.severe("IllegalArgumentException: " + e.getMessage());
        }
    }

    /**
     * Initializes and configures the global logger to write messages to a file
     * named "log.txt".
     * The logger is set to handle all log levels (from FINEST to SEVERE).
     *
     * @return The configured global logger instance.
     */
    private static Logger initLoggerGlobal() {

        final Logger logger = Logger.getGlobal();

        // File handler set to show all messages (from FINEST to SEVERE)
        FileHandler fileHandler = null;
        try {
            fileHandler = new FileHandler("log.txt", true);
            fileHandler.setLevel(Level.ALL);
            fileHandler.setFormatter(new SimpleFormatter());
        } catch (final Exception e) {
            e.printStackTrace();
        }

        logger.addHandler(fileHandler);
        logger.severe("This is a SEVERE error message");
        logger.warning("This is a WARNING message");
        logger.info("This is an INFO message");
        logger.config("This is a CONFIG message");
        logger.fine("This is a FINE debug message");
        logger.finer("This is a FINER debug message (more detailed)");
        logger.finest("This is a FINEST debug message (most detailed)");
        return logger;
    }
}

class LogTester {

    final Logger logger = Logger.getLogger(this.getClass().getName());

    /**
     * This function is responsible for logging a message with the INFO level.
     *
     * @param message The message to be logged. It cannot be null.
     *
     * @throws IllegalArgumentException If the provided message is null.
     *
     * @return This function does not return any value.
     */
    void hello(final String message) {
        if (message == null) {
            throw new IllegalArgumentException("Message cannot be null");
        }
        logger.info(message);
    }
}
 
Zuletzt bearbeitet:

Zurück
Oben