javaloggingsshjsch

JSch Logs in files


I want to save JSch logs in file because it does not show anything in the console.

This is my code:

public boolean openConnection() throws ItsSshException {
    boolean connectSuccess = false;

    JSch.setLogger(new MyLogger());

    Properties config = new Properties();
    config.put("StrictHostKeyChecking", "no");
    jschSSH.setConfig(config);
    try {
        sshSession = jschSSH.getSession(username, hostname, port);
        sshSession.setPassword(password);
        sshSession.connect(connectionTimeout);
        LOGGER.info("Connection timeout : " + connectionTimeout);
        Thread.sleep(1000);
        sshHChannel = sshSession.openChannel("shell");
        sshHChannel.connect();
        in = sshHChannel.getInputStream();
        out = new PrintStream(sshHChannel.getOutputStream());
        clearInitialSocketState();
        connectSuccess = true;
    } catch (Exception e) {
        LOGGER.error("Error during connectiong to host: " + hostname +
                     ", port: " + port + "!", e);
        throw new ItsSshException("Error during connectiong to host: " + e.getMessage());
    }
    LOGGER.info("connectSuccess : " + connectSuccess);
    return connectSuccess;
}

public static class MyLogger implements com.jcraft.jsch.Logger {
    static java.util.Hashtable name=new java.util.Hashtable();
    static{
        name.put(new Integer(DEBUG), "DEBUG: ");
        name.put(new Integer(INFO), "INFO: ");
        name.put(new Integer(WARN), "WARN: ");
        name.put(new Integer(ERROR), "ERROR: ");
        name.put(new Integer(FATAL), "FATAL: ");
    }
    public boolean isEnabled(int level){
        return true;
    }
    public void log(int level, String message){
        System.err.print(name.get(new Integer(level)));
        System.err.println(message);
    }
}

Where to put the jsch logger to get some informations in file. I have tried but never successed :D


Solution

  • Use Logger.log in the MyLogger.log:

    public void log(int level, String message){
        LOGGER.log(loggerlevel, message);
    }
    

    A full code can be like:

    static private class MyJSchLogger implements com.jcraft.jsch.Logger {
        private java.util.logging.Logger logger;
        
        public MyJSchLogger(java.util.logging.Logger logger) {
            this.logger = logger;
        }
        
        public boolean isEnabled(int level){
            return true;
        }
        public void log(int level, String message){
            java.util.logging.Level l;
            switch (level)
            {
            case com.jcraft.jsch.Logger.DEBUG:
                l = java.util.logging.Level.FINE;
                break;
            case com.jcraft.jsch.Logger.INFO:
                l = java.util.logging.Level.INFO;
                break;
            case com.jcraft.jsch.Logger.WARN:
                l = java.util.logging.Level.WARNING;
                break;
            default:
            case com.jcraft.jsch.Logger.ERROR:
            case com.jcraft.jsch.Logger.FATAL:
                l = java.util.logging.Level.SEVERE;
                break;
            }
            this.logger.log(l, message);
        }
    }
    

    To associate the logger with JSch use:

    JSch.setLogger(new MyJSchLogger(logger));
    

    Assuming the Java logger exists.

    If not, you can create one like:

    java.util.logging.Logger logger = java.util.logging.Logger.getLogger("MyJSch");
    java.util.logging.FileHandler fh =
        new java.util.logging.FileHandler("C:\\path\\jsch.log");
    java.util.logging.SimpleFormatter formatter =
        new java.util.logging.SimpleFormatter();  
    fh.setFormatter(formatter);  
    logger.addHandler(fh);
    

    Though if you just need to log to a file, you can do it directly:

    JSch.setLogger(new com.jcraft.jsch.Logger() {
        Path path = Paths.get("C:\\path\\jsch.log");
        @Override
        public boolean isEnabled(int level){
            return true;
        }
        public void log(int level, String message){
            try {
                StandardOpenOption option =
                   !Files.exists(path) ?
                       StandardOpenOption.CREATE : StandardOpenOption.APPEND;
                Files.write(path, java.util.Arrays.asList(message), option);
            } catch (IOException e) {
                System.err.println(message);
            }
        }
    });