You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/11/22 06:10:01 UTC

[2/2] mina-sshd git commit: [SSHD-582] Display mnemonic strings for commands and opcodes as much as possible

[SSHD-582] Display mnemonic strings for commands and opcodes as much as possible


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/652ad7de
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/652ad7de
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/652ad7de

Branch: refs/heads/master
Commit: 652ad7de13616783a5da2d212a0e4e45754f92c6
Parents: 5ed4943
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Sun Nov 22 07:09:43 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Sun Nov 22 07:09:43 2015 +0200

----------------------------------------------------------------------
 .../client/channel/AbstractClientChannel.java   |  19 +-
 .../sshd/client/channel/ChannelDirectTcpip.java |   4 +-
 .../apache/sshd/client/channel/ChannelExec.java |   7 +-
 .../sshd/client/channel/ChannelSession.java     |   7 +-
 .../sshd/client/channel/ChannelShell.java       |   6 +-
 .../sshd/client/channel/ChannelSubsystem.java   |  13 +-
 .../channel/PtyCapableChannelSession.java       |  19 +-
 .../sshd/client/session/ClientSessionImpl.java  |  35 +--
 .../subsystem/sftp/AbstractSftpClient.java      |  82 +++++--
 .../subsystem/sftp/DefaultSftpClient.java       |  28 +--
 .../client/subsystem/sftp/SftpException.java    |   5 +-
 .../client/subsystem/sftp/SftpFileSystem.java   |   4 +-
 .../org/apache/sshd/common/SshConstants.java    |  90 ++++++++
 .../sshd/common/channel/AbstractChannel.java    |  86 +++++---
 .../sshd/common/forward/TcpipClientChannel.java |   6 +-
 .../session/AbstractConnectionService.java      |   8 +-
 .../sshd/common/session/AbstractSession.java    |  92 +++++---
 .../common/subsystem/sftp/SftpConstants.java    |  60 +++++
 .../apache/sshd/common/util/GenericUtils.java   |  17 ++
 .../sshd/common/util/logging/LoggingUtils.java  |  70 ++++++
 .../server/channel/AbstractServerChannel.java   |   6 +-
 .../sshd/server/channel/ChannelSession.java     |  49 +++--
 .../sshd/server/channel/PipeDataReceiver.java   |   4 +-
 .../sshd/server/forward/TcpipServerChannel.java |  10 +-
 .../sshd/server/session/ServerSessionImpl.java  |   6 +-
 .../server/subsystem/sftp/SftpSubsystem.java    | 219 +++++++++++--------
 .../sshd/server/x11/X11ForwardSupport.java      |   4 +-
 .../java/org/apache/sshd/client/ClientTest.java |   5 +-
 .../apache/sshd/common/SshConstantsTest.java    |  62 ++++++
 .../apache/sshd/common/channel/WindowTest.java  |   2 +-
 .../subsystem/sftp/SftpConstantsTest.java       |  62 ++++++
 31 files changed, 830 insertions(+), 257 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
index 513ca28..8674066 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
@@ -76,6 +76,7 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
     protected final AtomicReference<String> exitSignalHolder = new AtomicReference<>(null);
     protected int openFailureReason;
     protected String openFailureMsg;
+    protected String openFailureLang;
     protected OpenFuture openFuture;
 
     protected AbstractClientChannel(String type) {
@@ -87,7 +88,9 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
             @SuppressWarnings("synthetic-access")
             @Override
             public void notifyEvent(String event) throws Exception {
-                log.debug("notifyEvent({})", event);
+                if (log.isDebugEnabled()) {
+                    log.debug("notifyEvent({}): {}", AbstractClientChannel.this, event);
+                }
                 notifyStateChanged();
             }
         };
@@ -222,8 +225,7 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
                 boolean nothingInCommon = Collections.disjoint(mask, cond);
                 if (!nothingInCommon) {
                     if (log.isTraceEnabled()) {
-                        log.trace("WaitFor call returning on channel {}, mask={}, cond={}",
-                                  this, mask, cond);
+                        log.trace("WaitFor call returning on channel {}, mask={}, cond={}", this, mask, cond);
                     }
                     return cond;
                 }
@@ -282,7 +284,7 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN);
         buffer.putString(type);
-        buffer.putInt(id);
+        buffer.putInt(getId());
         buffer.putInt(localWindow.getSize());
         buffer.putInt(localWindow.getPacketSize());
         writePacket(buffer);
@@ -296,7 +298,7 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
 
     @Override
     public void handleOpenSuccess(int recipient, int rwSize, int packetSize, Buffer buffer) {
-        this.recipient = recipient;
+        setRecipient(recipient);
 
         Session session = getSession();
         FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
@@ -331,8 +333,15 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
     public void handleOpenFailure(Buffer buffer) {
         int reason = buffer.getInt();
         String msg = buffer.getString();
+        String lang = buffer.getString();
+        if (log.isDebugEnabled()) {
+            log.debug("handleOpenFailure({}) reason={}, lang={}, msg={}",
+                      this, SshConstants.getOpenErrorCodeName(reason), lang, msg);
+        }
+
         this.openFailureReason = reason;
         this.openFailureMsg = msg;
+        this.openFailureLang = lang;
         this.openFuture.setException(new SshException(msg));
         this.closeFuture.setClosed();
         this.doCloseImmediately();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
index 070c40c..921b419 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
@@ -70,13 +70,13 @@ public class ChannelDirectTcpip extends AbstractClientChannel {
 
         openFuture = new DefaultOpenFuture(lock);
         if (log.isDebugEnabled()) {
-            log.debug("Send SSH_MSG_CHANNEL_OPEN on channel {}", Integer.valueOf(id));
+            log.debug("Send SSH_MSG_CHANNEL_OPEN on channel {}", getId());
         }
 
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN);
         buffer.putString(type);
-        buffer.putInt(id);
+        buffer.putInt(getId());
         buffer.putInt(localWindow.getSize());
         buffer.putInt(localWindow.getPacketSize());
         buffer.putString(remote.getHostName());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
index d33d9e1..813b292 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
@@ -43,10 +43,13 @@ public class ChannelExec extends PtyCapableChannelSession {
     protected void doOpen() throws IOException {
         doOpenPty();
 
-        log.debug("Send SSH_MSG_CHANNEL_REQUEST exec on {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("doOpen({}) send SSH_MSG_CHANNEL_REQUEST exec command={}", this, command);
+        }
+
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
-        buffer.putInt(recipient);
+        buffer.putInt(getRecipient());
         buffer.putString("exec");
         buffer.putBoolean(false);
         buffer.putString(command);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
index 6fbae18..72e2a09 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
@@ -118,7 +118,8 @@ public class ChannelSession extends AbstractClientChannel {
             } catch (Exception e) {
                 // we log it as DEBUG since it is relatively harmless
                 if (log.isDebugEnabled()) {
-                    log.debug("Failed (" + e.getClass().getSimpleName() + ") to shutdown stream pumper: " + e.getMessage());
+                    log.debug("doCloseImmediately({}) failed {} to shutdown stream pumper: {}",
+                              this, e.getClass().getSimpleName(), e.getMessage());
                 }
             } finally {
                 pumper = null;
@@ -146,7 +147,9 @@ public class ChannelSession extends AbstractClientChannel {
             }
         } catch (Exception e) {
             if (!isClosing()) {
-                log.debug("Caught exception", e);
+                if (log.isDebugEnabled()) {
+                    log.debug("pumpInputStream({}) Caught {} : {}", this, e.getClass().getSimpleName(), e.getMessage());
+                }
                 close(false);
             }
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
index a10edc5..fb7b94e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
@@ -39,11 +39,13 @@ public class ChannelShell extends PtyCapableChannelSession {
     protected void doOpen() throws IOException {
         doOpenPty();
 
-        log.debug("Send SSH_MSG_CHANNEL_REQUEST shell on {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("doOpen({}) send SSH_MSG_CHANNEL_REQUEST shell", this);
+        }
 
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
-        buffer.putInt(recipient);
+        buffer.putInt(getRecipient());
         buffer.putString("shell");
         buffer.putBoolean(false);
         writePacket(buffer);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
index c261702..1880990 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
@@ -54,14 +54,16 @@ public class ChannelSubsystem extends ChannelSession {
 
     @Override
     protected void doOpen() throws IOException {
-        log.debug("Send SSH_MSG_CHANNEL_REQUEST exec on {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("doOpen({}) SSH_MSG_CHANNEL_REQUEST exec", this);
+        }
 
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
-        buffer.putInt(recipient);
+        buffer.putInt(getRecipient());
         buffer.putString("subsystem");
         buffer.putBoolean(false);
-        buffer.putString(subsystem);
+        buffer.putString(getSubsystem());
         writePacket(buffer);
 
         super.doOpen();
@@ -75,4 +77,9 @@ public class ChannelSubsystem extends ChannelSession {
             }
         });
     }
+
+    @Override
+    public String toString() {
+        return super.toString() + "[" + getSubsystem() + "]";
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
index ae2862f..1928188 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
@@ -200,6 +200,11 @@ public class PtyCapableChannelSession extends ChannelSession {
     }
 
     public void sendWindowChange(int columns, int lines, int height, int width) throws IOException {
+        if (log.isDebugEnabled()) {
+            log.debug("sendWindowChange({}) cols={}, lines={}, height={}, width={}",
+                      this, columns, lines, height, width);
+        }
+
         ptyColumns = columns;
         ptyLines = lines;
         ptyHeight = height;
@@ -207,7 +212,7 @@ public class PtyCapableChannelSession extends ChannelSession {
 
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
-        buffer.putInt(recipient);
+        buffer.putInt(getRecipient());
         buffer.putString("window-change");
         buffer.putBoolean(false);
         buffer.putInt(ptyColumns);
@@ -221,11 +226,11 @@ public class PtyCapableChannelSession extends ChannelSession {
         Session session = getSession();
         if (agentForwarding) {
             if (log.isDebugEnabled()) {
-                log.debug("Send agent forwarding request on {} - recipient={}", this, Integer.valueOf(recipient));
+                log.debug("doOpenPty({}) Send agent forwarding request", this);
             }
 
             Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
-            buffer.putInt(recipient);
+            buffer.putInt(getRecipient());
             buffer.putString("auth-agent-req@openssh.com");
             buffer.putBoolean(false);
             writePacket(buffer);
@@ -233,12 +238,12 @@ public class PtyCapableChannelSession extends ChannelSession {
 
         if (usePty) {
             if (log.isDebugEnabled()) {
-                log.debug("Send SSH_MSG_CHANNEL_REQUEST pty-req on {}: type={}, cols={}, lines={}, height={}, width={}, modes={}",
+                log.debug("doOpenPty({}) Send SSH_MSG_CHANNEL_REQUEST pty-req: type={}, cols={}, lines={}, height={}, width={}, modes={}",
                           this, ptyType, ptyColumns, ptyLines, ptyHeight, ptyWidth, ptyModes);
             }
 
             Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
-            buffer.putInt(recipient);
+            buffer.putInt(getRecipient());
             buffer.putString("pty-req");
             buffer.putBoolean(false);
             buffer.putString(ptyType);
@@ -261,14 +266,14 @@ public class PtyCapableChannelSession extends ChannelSession {
 
         if (GenericUtils.size(env) > 0) {
             if (log.isDebugEnabled()) {
-                log.debug("Send SSH_MSG_CHANNEL_REQUEST env on {}: {}", this, env);
+                log.debug("doOpenPty({}) Send SSH_MSG_CHANNEL_REQUEST env: {}", this, env);
             }
 
             for (Map.Entry<String, String> entry : env.entrySet()) {
                 String key = entry.getKey();
                 String value = entry.getValue();
                 Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST, key.length() + value.length() + Integer.SIZE);
-                buffer.putInt(recipient);
+                buffer.putInt(getRecipient());
                 buffer.putString("env");
                 buffer.putBoolean(false);
                 buffer.putString(key);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
index 0f4df8f..0c9de7c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
@@ -188,7 +188,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
     public void addPasswordIdentity(String password) {
         identities.add(ValidateUtils.checkNotNullAndNotEmpty(password, "No password provided"));
         if (log.isDebugEnabled()) { // don't show the password in the log
-            log.debug("addPasswordIdentity(" + KeyUtils.getFingerPrint(password) + ")");
+            log.debug("addPasswordIdentity({}) {}", this, KeyUtils.getFingerPrint(password));
         }
     }
 
@@ -215,7 +215,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
         identities.add(kp);
 
         if (log.isDebugEnabled()) {
-            log.debug("addPublicKeyIdentity(" + KeyUtils.getFingerPrint(kp.getPublic()) + ")");
+            log.debug("addPublicKeyIdentity({}) {}", this, KeyUtils.getFingerPrint(kp.getPublic()));
         }
     }
 
@@ -329,7 +329,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
             } else if ((!c2sEncClientNone) || (!s2cEncClientNone)) {
                 kexFuture.setValue(new SshException("Client does not support none cipher"));
             } else {
-                log.info("Switching to none cipher " + this);
+                log.info("switchToNoneCipher({}) switching", this);
 
                 Map<KexProposalOption, String> proposal = new EnumMap<KexProposalOption, String>(KexProposalOption.class);
                 synchronized (clientProposal) {
@@ -376,7 +376,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
         ConnectionService service = getConnectionService();
         int id = service.registerChannel(channel);
         if (log.isDebugEnabled()) {
-            log.debug("createShellChannel(id={}) created", Integer.valueOf(id));
+            log.debug("createShellChannel({}) created id={}", this, id);
         }
         return channel;
     }
@@ -387,7 +387,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
         ConnectionService service = getConnectionService();
         int id = service.registerChannel(channel);
         if (log.isDebugEnabled()) {
-            log.debug("createExecChannel(id={})[{}] created", Integer.valueOf(id), command);
+            log.debug("createExecChannel({})[{}] created id={}", this, command, id);
         }
         return channel;
     }
@@ -398,7 +398,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
         ConnectionService service = getConnectionService();
         int id = service.registerChannel(channel);
         if (log.isDebugEnabled()) {
-            log.debug("createSubsystemChannel(id={})[{}] created", Integer.valueOf(id), subsystem);
+            log.debug("createSubsystemChannel({})[{}] created id={}", this, subsystem, id);
         }
         return channel;
     }
@@ -409,7 +409,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
         ConnectionService service = getConnectionService();
         int id = service.registerChannel(channel);
         if (log.isDebugEnabled()) {
-            log.debug("createDirectTcpipChannel(id={})[{} => {}] created", Integer.valueOf(id), local, remote);
+            log.debug("createDirectTcpipChannel({})[{} => {}] created id={}", this, local, remote, id);
         }
         return channel;
     }
@@ -554,8 +554,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
                 boolean nothingInCommon = Collections.disjoint(cond, mask);
                 if (!nothingInCommon) {
                     if (log.isTraceEnabled()) {
-                        log.trace("WaitFor call returning on session {}, mask={}, cond={}",
-                                  this, mask, cond);
+                        log.trace("waitFor(}{}) call return mask={}, cond={}", this, mask, cond);
                     }
                     return cond;
                 }
@@ -567,7 +566,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
                         timeout = t - System.currentTimeMillis();
                         if (timeout <= 0L) {
                             if (log.isTraceEnabled()) {
-                                log.trace("WaitFor call timeout on session {}, mask={}", this, mask);
+                                log.trace("WaitFor({}) call timeout mask={}", this, mask);
                             }
                             cond.add(ClientSessionEvent.TIMEOUT);
                             return cond;
@@ -576,7 +575,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
                 }
 
                 if (log.isTraceEnabled()) {
-                    log.trace("Waiting {} millis for lock on session {}, mask={}, cond={}", timeout, this, mask, cond);
+                    log.trace("waitFor({}) Waiting {} millis for lock on mask={}, cond={}", this, timeout, mask, cond);
                 }
 
                 long nanoStart = System.nanoTime();
@@ -590,7 +589,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
                     long nanoEnd = System.nanoTime();
                     long nanoDuration = nanoEnd - nanoStart;
                     if (log.isTraceEnabled()) {
-                        log.trace("Lock notified on session {} after {} nanos", this, nanoDuration);
+                        log.trace("waitFor({}) Lock notified after {} nanos", this, nanoDuration);
                     }
                 } catch (InterruptedException e) {
                     long nanoEnd = System.nanoTime();
@@ -609,11 +608,16 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
         if (serverVersion == null) {
             return false;
         }
-        log.debug("Server version string: {}", serverVersion);
+
+        if (log.isDebugEnabled()) {
+            log.debug("readIdentification({}) Server version string: {}", this, serverVersion);
+        }
+
         if (!(serverVersion.startsWith(DEFAULT_SSH_VERSION_PREFIX) || serverVersion.startsWith("SSH-1.99-"))) {
             throw new SshException(SshConstants.SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED,
                     "Unsupported protocol version: " + serverVersion);
         }
+
         return true;
     }
 
@@ -673,7 +677,10 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
             return;
         }
         initialServiceRequestSent = true;
-        log.debug("Send SSH_MSG_SERVICE_REQUEST for {}", currentServiceFactory.getName());
+        if (log.isDebugEnabled()) {
+            log.debug("sendInitialServiceRequest({}) Send SSH_MSG_SERVICE_REQUEST for {}",
+                      this, currentServiceFactory.getName());
+        }
         Buffer request = createBuffer(SshConstants.SSH_MSG_SERVICE_REQUEST);
         request.putString(currentServiceFactory.getName());
         writePacket(request);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
index 762bd7d..d648b2b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
@@ -221,7 +221,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             String lang = buffer.getString();
             checkStatus(id, substatus, msg, lang);
         } else {
-            throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+            handleUnexpectedPacket(SftpConstants.SSH_FXP_STATUS, id, type, length, buffer);
         }
     }
 
@@ -235,7 +235,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
      */
     protected void checkStatus(int id, int substatus, String msg, String lang) throws IOException {
         if (log.isTraceEnabled()) {
-            log.trace("checkStatus(id=" + id + ") status: " + substatus + " [" + lang + "]" + msg);
+            log.trace("checkStatus({})[id={}] status={} lang={} msg={}",
+                      getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
         }
 
         if (substatus != SftpConstants.SSH_FX_OK) {
@@ -275,12 +276,19 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             String msg = buffer.getString();
             String lang = buffer.getString();
             if (log.isTraceEnabled()) {
-                log.trace("checkHandle(id={}) - status: {} [{}] {}", Integer.valueOf(id), Integer.valueOf(substatus), lang, msg);
+                log.trace("checkHandle({})[id={}] - status: {} [{}] {}",
+                          getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
             }
             throwStatusException(id, substatus, msg, lang);
         }
 
-        throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+        return handleUnexpectedHandlePacket(id, type, length, buffer);
+    }
+
+    protected byte[] handleUnexpectedHandlePacket(int id, int type, int length, Buffer buffer) throws IOException {
+        handleUnexpectedPacket(SftpConstants.SSH_FXP_HANDLE, id, type, length, buffer);
+        throw new SshException("No handling for unexpected packet id=" + id
+                             + ", type=" + SftpConstants.getCommandMessageName(type) + ", length=" + length);
     }
 
     /**
@@ -311,12 +319,22 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             String msg = buffer.getString();
             String lang = buffer.getString();
             if (log.isTraceEnabled()) {
-                log.trace("checkAttributes(id={}) - status: {} [{}] {}", Integer.valueOf(id), Integer.valueOf(substatus), lang, msg);
+                log.trace("checkAttributes()[id={}] - status: {} [{}] {}",
+                          getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
             }
             throwStatusException(id, substatus, msg, lang);
         }
 
-        throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+        return handleUnexpectedAttributesPacket(id, type, length, buffer);
+    }
+
+    protected Attributes handleUnexpectedAttributesPacket(int id, int type, int length, Buffer buffer) throws IOException {
+        IOException err = handleUnexpectedPacket(SftpConstants.SSH_FXP_ATTRS, id, type, length, buffer);
+        if (err != null) {
+            throw err;
+        }
+
+        return null;
     }
 
     /**
@@ -351,7 +369,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             }
             Attributes attrs = readAttributes(buffer);
             if (log.isTraceEnabled()) {
-                log.trace("checkOneName(id={}) ({})[{}]: {}", Integer.valueOf(id), name, longName, attrs);
+                log.trace("checkOneName({})[id={}] ({})[{}]: {}",
+                          getClientChannel(), id, name, longName, attrs);
             }
             return name;
         }
@@ -361,13 +380,23 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             String msg = buffer.getString();
             String lang = buffer.getString();
             if (log.isTraceEnabled()) {
-                log.trace("checkOneName(id={}) - status: {} [{}] {}", Integer.valueOf(id), Integer.valueOf(substatus), lang, msg);
+                log.trace("checkOneName({})[id={}] - status: {} [{}] {}",
+                          getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
             }
 
             throwStatusException(id, substatus, msg, lang);
         }
 
-        throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+        return handleUnknownOneNamePacket(id, type, length, buffer);
+    }
+
+    protected String handleUnknownOneNamePacket(int id, int type, int length, Buffer buffer) throws IOException {
+        IOException err = handleUnexpectedPacket(SftpConstants.SSH_FXP_NAME, id, type, length, buffer);
+        if (err != null) {
+            throw err;
+        }
+
+        return null;
     }
 
     protected Attributes readAttributes(Buffer buffer) throws IOException {
@@ -772,7 +801,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             String msg = buffer.getString();
             String lang = buffer.getString();
             if (log.isTraceEnabled()) {
-                log.trace("checkData(id={}) - status: {} [{}] {}", Integer.valueOf(id), Integer.valueOf(substatus), lang, msg);
+                log.trace("checkData({})[id={}] - status: {} [{}] {}",
+                          getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
             }
 
             if (substatus == SftpConstants.SSH_FX_EOF) {
@@ -782,7 +812,16 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             throwStatusException(id, substatus, msg, lang);
         }
 
-        throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+        return handleUnknownDataPacket(id, type, length, buffer);
+    }
+
+    protected int handleUnknownDataPacket(int id, int type, int length, Buffer buffer) throws IOException {
+        IOException err = handleUnexpectedPacket(SftpConstants.SSH_FXP_DATA, id, type, length, buffer);
+        if (err != null) {
+            throw err;
+        }
+
+        return 0;
     }
 
     @Override
@@ -889,7 +928,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
                 String longName = (version == SftpConstants.SFTP_V3) ? buffer.getString() : null;
                 Attributes attrs = readAttributes(buffer);
                 if (log.isTraceEnabled()) {
-                    log.trace("checkDir(id={})[{}] ({})[{}]: {}", Integer.valueOf(id), Integer.valueOf(i), name, longName, attrs);
+                    log.trace("checkDir({})[id={}][{}] ({})[{}]: {}",
+                              getClientChannel(), id, i, name, longName, attrs);
                 }
 
                 entries.add(new DirEntry(name, longName, attrs));
@@ -902,7 +942,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             String msg = buffer.getString();
             String lang = buffer.getString();
             if (log.isTraceEnabled()) {
-                log.trace("checkDir(id={}) - status: {} [{}] {}", Integer.valueOf(id), Integer.valueOf(substatus), lang, msg);
+                log.trace("checkDir({})[id={}] - status: {} [{}] {}",
+                          getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
             }
 
             if (substatus == SftpConstants.SSH_FX_EOF) {
@@ -912,7 +953,20 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
             throwStatusException(id, substatus, msg, lang);
         }
 
-        throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+        return handleUnknownDirListingPacket(id, type, length, buffer);
+    }
+
+    protected List<DirEntry> handleUnknownDirListingPacket(int id, int type, int length, Buffer buffer) throws IOException {
+        IOException err = handleUnexpectedPacket(SftpConstants.SSH_FXP_NAME, id, type, length, buffer);
+        if (err != null) {
+            throw err;
+        }
+        return Collections.emptyList();
+    }
+
+    protected IOException handleUnexpectedPacket(int expected, int id, int type, int length, Buffer buffer) throws IOException {
+        throw new SshException("Unexpected SFTP packet received while awaiting " + SftpConstants.getCommandMessageName(expected)
+                             + ": type=" + SftpConstants.getCommandMessageName(type) + ", id=" + id + ", length=" + length);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
index 8d2c057..8c5bb4d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
@@ -47,12 +47,6 @@ import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V3;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V6;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_INIT;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_STATUS;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_VERSION;
-
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
@@ -153,7 +147,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
         int rpos = incoming.rpos();
         for (int count = 0; receive(incoming); count++) {
             if (log.isTraceEnabled()) {
-                log.trace("Processed " + count + " data messages");
+                log.trace("data({}) Processed {} data messages", getClientChannel(), count);
             }
         }
 
@@ -219,7 +213,8 @@ public class DefaultSftpClient extends AbstractSftpClient {
         int id = cmdId.incrementAndGet();
         int len = buffer.available();
         if (log.isTraceEnabled()) {
-            log.trace("send(cmd={}, len={}) id={}", cmd, len, id);
+            log.trace("send({}) cmd={}, len={}, id={}",
+                      getClientChannel(), SftpConstants.getCommandMessageName(cmd), len, id);
         }
 
         OutputStream dos = channel.getInvertedIn();
@@ -281,8 +276,8 @@ public class DefaultSftpClient extends AbstractSftpClient {
         // Init packet
         OutputStream dos = channel.getInvertedIn();
         BufferUtils.writeInt(dos, 5 /* total length */, workBuf);
-        dos.write(SSH_FXP_INIT);
-        BufferUtils.writeInt(dos, SFTP_V6, workBuf);
+        dos.write(SftpConstants.SSH_FXP_INIT);
+        BufferUtils.writeInt(dos, SftpConstants.SFTP_V6, workBuf);
         dos.flush();
 
         Buffer buffer;
@@ -301,8 +296,8 @@ public class DefaultSftpClient extends AbstractSftpClient {
         int length = buffer.getInt();
         int type = buffer.getUByte();
         int id = buffer.getInt();
-        if (type == SSH_FXP_VERSION) {
-            if (id < SFTP_V3) {
+        if (type == SftpConstants.SSH_FXP_VERSION) {
+            if (id < SftpConstants.SFTP_V3) {
                 throw new SshException("Unsupported sftp version " + id);
             }
             version = id;
@@ -312,17 +307,18 @@ public class DefaultSftpClient extends AbstractSftpClient {
                 byte[] data = buffer.getBytes();
                 extensions.put(name, data);
             }
-        } else if (type == SSH_FXP_STATUS) {
+        } else if (type == SftpConstants.SSH_FXP_STATUS) {
             int substatus = buffer.getInt();
             String msg = buffer.getString();
             String lang = buffer.getString();
             if (log.isTraceEnabled()) {
-                log.trace("init(id={}) - status: {} [{}] {}", Integer.valueOf(id), Integer.valueOf(substatus), lang, msg);
+                log.trace("init({})[id={}] - status: {} [{}] {}",
+                          getClientChannel(), id, SftpConstants.getStatusName(substatus), lang, msg);
             }
 
             throwStatusException(id, substatus, msg, lang);
         } else {
-            throw new SshException("Unexpected SFTP packet received: type=" + type + ", id=" + id + ", length=" + length);
+            handleUnexpectedPacket(SftpConstants.SSH_FXP_VERSION, id, type, length, buffer);
         }
     }
 
@@ -350,7 +346,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
 
         int selected = selector.selectVersion(current, new ArrayList<>(available));
         if (log.isDebugEnabled()) {
-            log.debug("negotiateVersion({}) {} -> {}", current, available, selected);
+            log.debug("negotiateVersion({}) current={} {} -> {}", getClientChannel(), current, available, selected);
         }
 
         if (selected == current) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpException.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpException.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpException.java
index 38c37ae..d87022c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpException.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpException.java
@@ -20,6 +20,8 @@ package org.apache.sshd.client.subsystem.sftp;
 
 import java.io.IOException;
 
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+
 /**
  * @author <a href="http://mina.apache.org">Apache MINA Project</a>
  */
@@ -38,7 +40,6 @@ public class SftpException extends IOException {
 
     @Override
     public String toString() {
-        String message = getMessage();
-        return "SFTP error (" + getStatus() + "): " + message;
+        return "SFTP error (" + SftpConstants.getStatusName(getStatus()) + "): " + getMessage();
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
index 91b6849..5f4e6ae 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
@@ -496,13 +496,13 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> implements ClientSe
         @Override
         public int send(int cmd, Buffer buffer) throws IOException {
             if (!isOpen()) {
-                throw new IOException("send(cmd=" + cmd + ") client is closed");
+                throw new IOException("send(cmd=" + SftpConstants.getCommandMessageName(cmd) + ") client is closed");
             }
 
             if (delegate instanceof RawSftpClient) {
                 return ((RawSftpClient) delegate).send(cmd, buffer);
             } else {
-                throw new StreamCorruptedException("send(cmd=" + cmd + ") delegate is not a " + RawSftpClient.class.getSimpleName());
+                throw new StreamCorruptedException("send(cmd=" + SftpConstants.getCommandMessageName(cmd) + ") delegate is not a " + RawSftpClient.class.getSimpleName());
             }
         }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/SshConstants.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/SshConstants.java b/sshd-core/src/main/java/org/apache/sshd/common/SshConstants.java
index 1d134ad..a7beba6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/SshConstants.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/SshConstants.java
@@ -18,6 +18,16 @@
  */
 package org.apache.sshd.common;
 
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Predicate;
+import org.apache.sshd.common.util.logging.LoggingUtils;
 
 /**
  * This interface defines constants for the SSH protocol.
@@ -81,6 +91,16 @@ public final class SshConstants {
     public static final byte SSH_MSG_CHANNEL_SUCCESS = 99;
     public static final byte SSH_MSG_CHANNEL_FAILURE = 100;
 
+    // Names of opcodes that have the same value
+    public static final Set<String> AMBIGUOUS_OPCODES =
+            Collections.unmodifiableSet(
+                    new HashSet<String>(
+                            Arrays.asList(
+                                "SSH_MSG_KEX_FIRST", "SSH_MSG_KEXDH_INIT", "SSH_MSG_KEX_DH_GEX_REQUEST_OLD",
+                                "SSH_MSG_KEXDH_REPLY", "SSH_MSG_KEX_DH_GEX_GROUP",
+                                "SSH_MSG_USERAUTH_INFO_REQUEST", "SSH_MSG_USERAUTH_PK_OK", "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ"
+                                    )));
+
     //
     // Disconnect error codes
     //
@@ -114,4 +134,74 @@ public final class SshConstants {
         throw new UnsupportedOperationException("No instance allowed");
     }
 
+    private static class LazyMessagesMapHolder {
+
+        private static final Map<Integer, String> MESSAGES_MAP =
+                LoggingUtils.generateMnemonicMap(SshConstants.class, new Predicate<Field>() {
+                    @Override
+                    public boolean evaluate(Field f) {
+                        String name = f.getName();
+                        return name.startsWith("SSH_MSG_") && (!AMBIGUOUS_OPCODES.contains(name));
+                    }
+                });
+    }
+
+    /**
+     * Converts a command value to a user-friendly name
+     *
+     * @param cmd The command value
+     * @return The user-friendly name - if not one of the defined {@code SSH_MSG_XXX}
+     * values then returns the string representation of the command's value
+     */
+    public static String getCommandMessageName(int cmd) {
+        @SuppressWarnings("synthetic-access")
+        String name = LazyMessagesMapHolder.MESSAGES_MAP.get(cmd);
+        if (GenericUtils.isEmpty(name)) {
+            return Integer.toString(cmd);
+        } else {
+            return name;
+        }
+    }
+
+    private static class LazyReasonsMapHolder {
+        private static final Map<Integer, String> REASONS_MAP = LoggingUtils.generateMnemonicMap(SshConstants.class, "SSH2_DISCONNECT_");
+    }
+
+    /**
+     * Converts a disconnect reason value to a user-friendly name
+     *
+     * @param reason The disconnect reason value
+     * @return The user-friendly name - if not one of the defined {@code SSH2_DISCONNECT_}
+     * values then returns the string representation of the reason's value
+     */
+    public static String getDisconnectReasonName(int reason) {
+        @SuppressWarnings("synthetic-access")
+        String name = LazyReasonsMapHolder.REASONS_MAP.get(reason);
+        if (GenericUtils.isEmpty(name)) {
+            return Integer.toString(reason);
+        } else {
+            return name;
+        }
+    }
+
+    private static class LazyOpenCodesMapHolder {
+        private static final Map<Integer, String> OPEN_CODES_MAP = LoggingUtils.generateMnemonicMap(SshConstants.class, "SSH_OPEN_");
+    }
+
+    /**
+     * Converts an open error value to a user-friendly name
+     *
+     * @param code The open error value
+     * @return The user-friendly name - if not one of the defined {@code SSH_OPEN_}
+     * values then returns the string representation of the reason's value
+     */
+    public static String getOpenErrorCodeName(int code) {
+        @SuppressWarnings("synthetic-access")
+        String name = LazyOpenCodesMapHolder.OPEN_CODES_MAP.get(code);
+        if (GenericUtils.isEmpty(name)) {
+            return Integer.toString(code);
+        } else {
+            return name;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
index c5b3495..549b42d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
@@ -76,8 +76,6 @@ public abstract class AbstractChannel
     protected final Window localWindow;
     protected final Window remoteWindow;
     protected ConnectionService service;
-    protected int id;
-    protected int recipient;
     protected final AtomicBoolean eof = new AtomicBoolean(false);
     protected AtomicReference<GracefulState> gracefulState = new AtomicReference<GracefulState>(GracefulState.Opened);
     protected final DefaultCloseFuture gracefulFuture = new DefaultCloseFuture(lock);
@@ -88,6 +86,8 @@ public abstract class AbstractChannel
     protected final Collection<ChannelListener> channelListeners = new CopyOnWriteArraySet<>();
     protected final ChannelListener channelListenerProxy;
 
+    private int id = -1;
+    private int recipient = -1;
     private Session session;
     private final Map<String, Object> properties = new ConcurrentHashMap<>();
 
@@ -116,6 +116,12 @@ public abstract class AbstractChannel
         return recipient;
     }
 
+    protected void setRecipient(int recipient) {
+        if (log.isDebugEnabled()) {
+            log.debug("setRecipient({}) recipient={}", this, recipient);
+        }
+        this.recipient = recipient;
+    }
     @Override
     public Window getLocalWindow() {
         return localWindow;
@@ -161,8 +167,7 @@ public abstract class AbstractChannel
         String req = buffer.getString();
         boolean wantReply = buffer.getBoolean();
         if (log.isDebugEnabled()) {
-            log.debug("Received SSH_MSG_CHANNEL_REQUEST {} on channel {} (wantReply {})",
-                      req, this, Boolean.valueOf(wantReply));
+            log.debug("handleRequest({}) SSH_MSG_CHANNEL_REQUEST {} wantReply={}", this, req, wantReply);
         }
 
         for (RequestHandler<Channel> handler : handlers) {
@@ -170,14 +175,16 @@ public abstract class AbstractChannel
             try {
                 result = handler.process(this, req, wantReply, buffer);
             } catch (Exception e) {
-                log.warn("Error processing channel request " + req, e);
+                log.warn("handleRequest({}) {} while {}#process({}): {}",
+                         this, e.getClass().getSimpleName(), handler.getClass().getSimpleName(), req, e.getMessage());
                 result = RequestHandler.Result.ReplyFailure;
             }
 
             // if Unsupported then check the next handler in line
             if (RequestHandler.Result.Unsupported.equals(result)) {
                 if (log.isTraceEnabled()) {
-                    log.trace("{}#process({}): {}", handler.getClass().getSimpleName(), req, result);
+                    log.trace("handleRequest({})[{}#process({})]: {}",
+                              this, handler.getClass().getSimpleName(), req, result);
                 }
             } else {
                 sendResponse(buffer, req, result, wantReply);
@@ -186,13 +193,13 @@ public abstract class AbstractChannel
         }
 
         // none of the handlers processed the request
-        log.warn("Unknown channel request: {}", req);
+        log.warn("handleRequest({}) Unknown channel request: {}", this, req);
         sendResponse(buffer, req, RequestHandler.Result.Unsupported, wantReply);
     }
 
     protected void sendResponse(Buffer buffer, String req, RequestHandler.Result result, boolean wantReply) throws IOException {
         if (log.isDebugEnabled()) {
-            log.debug("sendResponse({}) result={}, want-reply={}", req, result, Boolean.valueOf(wantReply));
+            log.debug("sendResponse({}) request={} result={}, want-reply={}", this, req, result, wantReply);
         }
 
         if (RequestHandler.Result.Replied.equals(result) || (!wantReply)) {
@@ -214,6 +221,9 @@ public abstract class AbstractChannel
 
     @Override
     public void init(ConnectionService service, Session session, int id) throws IOException {
+        if (log.isDebugEnabled()) {
+            log.debug("init() service={} session={} id={}", service, session, id);
+        }
         this.service = service;
         this.session = session;
         this.id = id;
@@ -268,7 +278,9 @@ public abstract class AbstractChannel
 
     @Override
     public void handleClose() throws IOException {
-        log.debug("Received SSH_MSG_CHANNEL_CLOSE on channel {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("handleClose({}) SSH_MSG_CHANNEL_CLOSE on channel", this);
+        }
         if (gracefulState.compareAndSet(GracefulState.Opened, GracefulState.CloseReceived)) {
             close(false);
         } else if (gracefulState.compareAndSet(GracefulState.CloseSent, GracefulState.Closed)) {
@@ -304,14 +316,16 @@ public abstract class AbstractChannel
         }
 
         @Override
-        public CloseFuture close(boolean immediately) {
+        public CloseFuture close(final boolean immediately) {
+            final Channel channel = AbstractChannel.this;
+            if (log.isDebugEnabled()) {
+                log.debug("close({})[immediately={}] SSH_MSG_CHANNEL_CLOSE on channel", channel, immediately);
+            }
+
             setClosing(true);
             if (immediately) {
                 gracefulFuture.setClosed();
             } else if (!gracefulFuture.isClosed()) {
-                final Channel channel = AbstractChannel.this;
-                log.debug("Send SSH_MSG_CHANNEL_CLOSE on channel {}", channel);
-
                 Session s = getSession();
                 Buffer buffer = s.createBuffer(SshConstants.SSH_MSG_CHANNEL_CLOSE, Short.SIZE);
                 buffer.putInt(getRecipient());
@@ -323,20 +337,27 @@ public abstract class AbstractChannel
                         @Override
                         public void operationComplete(IoWriteFuture future) {
                             if (future.isWritten()) {
-                                log.debug("Message SSH_MSG_CHANNEL_CLOSE written on channel {}", channel);
+                                if (log.isDebugEnabled()) {
+                                    log.debug("close({})[immediately={}] SSH_MSG_CHANNEL_CLOSE written on channel", channel, immediately);
+                                }
                                 if (gracefulState.compareAndSet(GracefulState.Opened, GracefulState.CloseSent)) {
                                     // Waiting for CLOSE message to come back from the remote side
                                 } else if (gracefulState.compareAndSet(GracefulState.CloseReceived, GracefulState.Closed)) {
                                     gracefulFuture.setClosed();
                                 }
                             } else {
-                                log.debug("Failed to write SSH_MSG_CHANNEL_CLOSE on channel {}", channel);
+                                if (log.isDebugEnabled()) {
+                                    log.debug("close({})[immediately={}] failed to write SSH_MSG_CHANNEL_CLOSE on channel", channel, immediately);
+                                }
                                 channel.close(true);
                             }
                         }
                     });
                 } catch (IOException e) {
-                    log.debug("Exception caught while writing SSH_MSG_CHANNEL_CLOSE packet on channel " + channel, e);
+                    if (log.isDebugEnabled()) {
+                        log.debug("close({})[immediately={}] {} while writing SSH_MSG_CHANNEL_CLOSE packet on channel: {}",
+                                  channel, immediately, e.getClass().getSimpleName(), e.getMessage());
+                    }
                     channel.close(true);
                 }
             }
@@ -345,7 +366,8 @@ public abstract class AbstractChannel
             if ((service != null) && isShutdownOnExit() && (!service.isShutdown())) {
                 Collection<?> running = service.shutdownNow();
                 if (log.isDebugEnabled()) {
-                    log.debug("Shutdown executor service on close - running count=" + GenericUtils.size(running));
+                    log.debug("close({})[immediately={}] shutdown executor service on close - running count={}",
+                              channel, immediately, GenericUtils.size(running));
                 }
             }
 
@@ -409,9 +431,11 @@ public abstract class AbstractChannel
         if (len < 0 || len > ByteArrayBuffer.MAX_LEN) {
             throw new IllegalStateException("Bad item length: " + len);
         }
-        log.debug("Received SSH_MSG_CHANNEL_DATA on channel {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("handleData({}) SSH_MSG_CHANNEL_DATA len={}", this, len);
+        }
         if (log.isTraceEnabled()) {
-            log.trace("Received channel data: {}", BufferUtils.printHex(buffer.array(), buffer.rpos(), len));
+            log.trace("handleData({}) data: {}", this, BufferUtils.printHex(buffer.array(), buffer.rpos(), len));
         }
         doWriteData(buffer.array(), buffer.rpos(), len);
     }
@@ -421,7 +445,9 @@ public abstract class AbstractChannel
         int ex = buffer.getInt();
         // Only accept extended data for stderr
         if (ex != 1) {
-            log.debug("Send SSH_MSG_CHANNEL_FAILURE on channel {}", this);
+            if (log.isDebugEnabled()) {
+                log.debug("handleExtendedData({}) send SSH_MSG_CHANNEL_FAILURE", this);
+            }
             Session s = getSession();
             buffer = s.prepareBuffer(SshConstants.SSH_MSG_CHANNEL_FAILURE, BufferUtils.clear(buffer));
             buffer.putInt(getRecipient());
@@ -432,9 +458,9 @@ public abstract class AbstractChannel
         if (len < 0 || len > ByteArrayBuffer.MAX_LEN) {
             throw new IllegalStateException("Bad item length: " + len);
         }
-        log.debug("Received SSH_MSG_CHANNEL_EXTENDED_DATA on channel {}", this);
+        log.debug("handleExtendedData({}) SSH_MSG_CHANNEL_EXTENDED_DATA len={}", this, len);
         if (log.isTraceEnabled()) {
-            log.trace("Received channel extended data: {}", BufferUtils.printHex(buffer.array(), buffer.rpos(), len));
+            log.trace("handleExtendedData({}) extended data: {}", this, BufferUtils.printHex(buffer.array(), buffer.rpos(), len));
         }
         doWriteExtendedData(buffer.array(), buffer.rpos(), len);
     }
@@ -449,21 +475,27 @@ public abstract class AbstractChannel
 
     @Override
     public void handleEof() throws IOException {
-        log.debug("Received SSH_MSG_CHANNEL_EOF on channel {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("handleEof({}) SH_MSG_CHANNEL_EOF", this);
+        }
         setEofSignalled(true);
         notifyStateChanged();
     }
 
     @Override
     public void handleWindowAdjust(Buffer buffer) throws IOException {
-        log.debug("Received SSH_MSG_CHANNEL_WINDOW_ADJUST on channel {}", this);
         int window = buffer.getInt();
+        if (log.isDebugEnabled()) {
+            log.debug("handleWindowAdjust({}) SSH_MSG_CHANNEL_WINDOW_ADJUST window={}", this, window);
+        }
         remoteWindow.expand(window);
     }
 
     @Override
     public void handleFailure() throws IOException {
-        log.debug("Received SSH_MSG_CHANNEL_FAILURE on channel {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("handleFailure({}) SSH_MSG_CHANNEL_FAILURE", this);
+        }
         // TODO: do something to report failed requests?
     }
 
@@ -472,7 +504,7 @@ public abstract class AbstractChannel
     protected abstract void doWriteExtendedData(byte[] data, int off, int len) throws IOException;
 
     protected void sendEof() throws IOException {
-        log.debug("Send SSH_MSG_CHANNEL_EOF on channel {}", this);
+        log.debug("sendEof({}) SSH_MSG_CHANNEL_EOF", this);
         Session s = getSession();
         Buffer buffer = s.createBuffer(SshConstants.SSH_MSG_CHANNEL_EOF, Short.SIZE);
         buffer.putInt(getRecipient());
@@ -490,7 +522,7 @@ public abstract class AbstractChannel
 
     protected void sendWindowAdjust(int len) throws IOException {
         if (log.isDebugEnabled()) {
-            log.debug("Send SSH_MSG_CHANNEL_WINDOW_ADJUST (len={}) on channel {}", len, this);
+            log.debug("sendWindowAdjust({}) SSH_MSG_CHANNEL_WINDOW_ADJUST len={}", this, len);
         }
         Session s = getSession();
         Buffer buffer = s.createBuffer(SshConstants.SSH_MSG_CHANNEL_WINDOW_ADJUST, Short.SIZE);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
index 8eeb9b7..a1a8f78 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
@@ -85,12 +85,14 @@ public class TcpipClientChannel extends AbstractClientChannel {
             throw new SshException("Session has been closed");
         }
         openFuture = new DefaultOpenFuture(lock);
-        log.debug("Send SSH_MSG_CHANNEL_OPEN on channel {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("open({}) send SSH_MSG_CHANNEL_OPEN", this);
+        }
 
         Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN);
         buffer.putString(type);
-        buffer.putInt(id);
+        buffer.putInt(getId());
         buffer.putInt(localWindow.getSize());
         buffer.putInt(localWindow.getPacketSize());
         buffer.putString(dst.getAddress().getHostAddress());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
index 65d7e64..1e51b6f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
@@ -332,7 +332,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
         if (channel == null) {
             buffer.rpos(buffer.rpos() - 5);
             int cmd = buffer.getUByte();
-            throw new SshException("Received " + cmd + " on unknown channel " + recipient);
+            throw new SshException("Received " + SshConstants.getCommandMessageName(cmd) + " on unknown channel " + recipient);
         }
         return channel;
     }
@@ -350,7 +350,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
             buf.putInt(id);
             buf.putInt(SshConstants.SSH_OPEN_CONNECT_FAILED);
             buf.putString("SSH server is shutting down: " + type);
-            buf.putString("");
+            buf.putString("");  // TODO add language tag
             session.writePacket(buf);
             return;
         }
@@ -359,7 +359,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
             buf.putInt(id);
             buf.putInt(SshConstants.SSH_OPEN_CONNECT_FAILED);
             buf.putString("additional sessions disabled");
-            buf.putString("");
+            buf.putString("");  // TODO add language tag
             session.writePacket(buf);
             return;
         }
@@ -370,7 +370,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
             buf.putInt(id);
             buf.putInt(SshConstants.SSH_OPEN_UNKNOWN_CHANNEL_TYPE);
             buf.putString("Unsupported channel type: " + type);
-            buf.putString("");
+            buf.putString("");  // TODO add language tag
             session.writePacket(buf);
             return;
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
index 21e1963..e092a32 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
@@ -375,35 +375,32 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
 
     protected void doHandleMessage(Buffer buffer) throws Exception {
         int cmd = buffer.getUByte();
+        if (log.isTraceEnabled()) {
+            log.trace("doHandleMessage({}) process {}", this, SshConstants.getCommandMessageName(cmd));
+        }
+
         switch (cmd) {
             case SshConstants.SSH_MSG_DISCONNECT: {
                 handleDisconnect(buffer);
                 break;
             }
             case SshConstants.SSH_MSG_IGNORE: {
-                log.debug("Received SSH_MSG_IGNORE");
+                handleIgnore(buffer);
                 break;
             }
             case SshConstants.SSH_MSG_UNIMPLEMENTED: {
-                int code = buffer.getInt();
-                if (log.isDebugEnabled()) {
-                    log.debug("Received SSH_MSG_UNIMPLEMENTED #{}", Integer.valueOf(code));
-                }
+                handleUnimplented(buffer);
                 break;
             }
             case SshConstants.SSH_MSG_DEBUG: {
-                boolean display = buffer.getBoolean();
-                String msg = buffer.getString();
-                if (log.isDebugEnabled()) {
-                    log.debug("Received SSH_MSG_DEBUG (display={}) '{}'", Boolean.valueOf(display), msg);
-                }
+                handleDebug(buffer);
                 break;
             }
             case SshConstants.SSH_MSG_SERVICE_REQUEST:
                 handleServiceRequest(buffer);
                 break;
             case SshConstants.SSH_MSG_SERVICE_ACCEPT:
-                handleServiceAccept();
+                handleServiceAccept(buffer);
                 break;
             case SshConstants.SSH_MSG_KEXINIT:
                 handleKexInit(buffer);
@@ -424,47 +421,83 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
                     currentService.process(cmd, buffer);
                     resetIdleTimeout();
                 } else {
-                    throw new IllegalStateException("Unsupported command " + cmd);
+                    throw new IllegalStateException("Unsupported command " + SshConstants.getCommandMessageName(cmd));
                 }
                 break;
         }
         checkRekey();
     }
 
-    protected void handleDisconnect(Buffer buffer) {
+    protected void handleIgnore(Buffer buffer) throws Exception {
+        if (log.isDebugEnabled()) {
+            log.debug("handleIgnore({}) SSH_MSG_IGNORE", this);
+        }
+    }
+
+    protected void handleUnimplented(Buffer buffer) throws Exception {
+        int seqNo = buffer.getInt();
+        if (log.isDebugEnabled()) {
+            log.debug("handleUnimplented({}) SSH_MSG_UNIMPLEMENTED #{}", this, seqNo);
+        }
+    }
+
+    protected void handleDebug(Buffer buffer) throws Exception {
+        boolean display = buffer.getBoolean();
+        String msg = buffer.getString();
+        String lang = buffer.getString();
+        if (log.isDebugEnabled()) {
+            log.debug("handleDebug({}) SSH_MSG_DEBUG (display={}) [lang={}] '{}'",
+                      this, display, lang, msg);
+        }
+    }
+
+    protected void handleDisconnect(Buffer buffer) throws Exception  {
         int code = buffer.getInt();
         String msg = buffer.getString();
+        String lang = buffer.getString();
         if (log.isDebugEnabled()) {
-            log.debug("Received SSH_MSG_DISCONNECT (reason={}, msg={})", Integer.valueOf(code), msg);
+            log.debug("handleDisconnect({}) SSH_MSG_DISCONNECT reason={}, [lang={}] msg={}",
+                      this, SshConstants.getDisconnectReasonName(code), lang, msg);
         }
         close(true);
     }
 
     protected void handleServiceRequest(Buffer buffer) throws IOException {
-        String service = buffer.getString();
-        log.debug("Received SSH_MSG_SERVICE_REQUEST '{}'", service);
+        String serviceName = buffer.getString();
+        if (log.isDebugEnabled()) {
+            log.debug("handleServiceRequest({}) SSH_MSG_SERVICE_REQUEST '{}'", this, serviceName);
+        }
         validateKexState(SshConstants.SSH_MSG_SERVICE_REQUEST, KexState.DONE);
         try {
-            startService(service);
+            startService(serviceName);
         } catch (Exception e) {
-            log.debug("Service " + service + " rejected", e);
-            disconnect(SshConstants.SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE, "Bad service request: " + service);
+            if (log.isDebugEnabled()) {
+                log.debug("handleServiceRequest({}) Service {} rejected: {} = {}",
+                          this, serviceName, e.getClass().getSimpleName(), e.getMessage());
+            }
+            disconnect(SshConstants.SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE, "Bad service request: " + serviceName);
             return;
         }
-        log.debug("Accepted service {}", service);
+        if (log.isDebugEnabled()) {
+            log.debug("handleServiceRequest({}) Accepted service {}", this, serviceName);
+        }
         Buffer response = prepareBuffer(SshConstants.SSH_MSG_SERVICE_ACCEPT, BufferUtils.clear(buffer));
-        response.putString(service);
+        response.putString(serviceName);
         writePacket(response);
     }
 
-    protected void handleServiceAccept() throws IOException {
-        log.debug("Received SSH_MSG_SERVICE_ACCEPT");
+    protected void handleServiceAccept(Buffer buffer) throws IOException {
+        String serviceName = buffer.getString();
+        if (log.isDebugEnabled()) {
+            log.debug("handleServiceAccept({}) SSH_MSG_SERVICE_ACCEPT service={}", this, serviceName);
+        }
         validateKexState(SshConstants.SSH_MSG_SERVICE_ACCEPT, KexState.DONE);
-        serviceAccept();
     }
 
     protected void handleKexInit(Buffer buffer) throws Exception {
-        log.debug("Received SSH_MSG_KEXINIT");
+        if (log.isDebugEnabled()) {
+            log.debug("handleKexInit({}) SSH_MSG_KEXINIT", this);
+        }
         receiveKexInit(buffer);
         if (kexState.compareAndSet(KexState.DONE, KexState.RUN)) {
             sendKexInit();
@@ -483,7 +516,9 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
     }
 
     protected void handleNewKeys(int cmd) throws Exception {
-        log.debug("Received SSH_MSG_NEWKEYS");
+        if (log.isDebugEnabled()) {
+            log.debug("handleNewKeys({}) SSH_MSG_NEWKEYS", this);
+        }
         validateKexState(cmd, KexState.KEYS);
         receiveNewKeys();
 
@@ -518,7 +553,8 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
     protected void validateKexState(int cmd, KexState expected) {
         KexState actual = kexState.get();
         if (!expected.equals(actual)) {
-            throw new IllegalStateException("Received KEX command=" + cmd + " while in state=" + actual + " instead of " + expected);
+            throw new IllegalStateException("Received KEX command=" + SshConstants.getCommandMessageName(cmd)
+                                          + " while in state=" + actual + " instead of " + expected);
         }
     }
 
@@ -1259,7 +1295,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
 
     @Override
     public void disconnect(int reason, String msg) throws IOException {
-        log.info("Disconnecting: {} - {}", reason, msg);
+        log.info("Disconnecting({}): {} - {}", this, SshConstants.getDisconnectReasonName(reason), msg);
         Buffer buffer = createBuffer(SshConstants.SSH_MSG_DISCONNECT, msg.length() + Short.SIZE);
         buffer.putInt(reason);
         buffer.putString(msg);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
index 8cbb6f7..ff7a081 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
@@ -18,6 +18,13 @@
  */
 package org.apache.sshd.common.subsystem.sftp;
 
+import java.lang.reflect.Field;
+import java.util.Map;
+
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Predicate;
+import org.apache.sshd.common.util.logging.LoggingUtils;
+
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
@@ -249,4 +256,57 @@ public final class SftpConstants {
     private SftpConstants() {
         throw new UnsupportedOperationException("No instance");
     }
+
+    private static class LazyCommandNameHolder {
+        private static final Map<Integer, String> NAMES_MAP =
+                LoggingUtils.generateMnemonicMap(SftpConstants.class, new Predicate<Field>() {
+                    @Override
+                    public boolean evaluate(Field f) {
+                        String name = f.getName();
+                        return name.startsWith("SSH_FXP_")
+                            // exclude the rename modes which are not opcodes
+                            && (!name.startsWith("SSH_FXP_RENAME_"))
+                            // exclude the realpath modes wich are not opcodes
+                            && (!name.startsWith("SSH_FXP_REALPATH_"));
+                    }
+                });
+    }
+
+    /**
+     * Converts a command value to a user-friendly name
+     *
+     * @param cmd The command value
+     * @return The user-friendly name - if not one of the defined {@code SSH_FXP_XXX}
+     * values then returns the string representation of the command's value
+     */
+    public static String getCommandMessageName(int cmd) {
+        @SuppressWarnings("synthetic-access")
+        String name = LazyCommandNameHolder.NAMES_MAP.get(cmd);
+        if (GenericUtils.isEmpty(name)) {
+            return Integer.toString(cmd);
+        } else {
+            return name;
+        }
+    }
+
+    private static class LazyStatusNameHolder {
+        private static final Map<Integer, String> STATUS_MAP = LoggingUtils.generateMnemonicMap(SftpConstants.class, "SSH_FX_");
+    }
+
+    /**
+     * Converts a return status value to a user-friendly name
+     *
+     * @param status The status value
+     * @return The user-friendly name - if not one of the defined {@code SSH_FX_XXX}
+     * values then returns the string representation of the status value
+     */
+    public static String getStatusName(int status) {
+        @SuppressWarnings("synthetic-access")
+        String name = LazyStatusNameHolder.STATUS_MAP.get(status);
+        if (GenericUtils.isEmpty(name)) {
+            return Integer.toString(status);
+        } else {
+            return name;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
index faffd01..6e55663 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
@@ -47,6 +47,11 @@ public final class GenericUtils {
     public static final byte[] EMPTY_BYTE_ARRAY = {};
     public static final String[] EMPTY_STRING_ARRAY = {};
     public static final Object[] EMPTY_OBJECT_ARRAY = {};
+    public static final List<Class<?>> NUMERIC_PRIMITIVE_CLASSES =
+            Collections.unmodifiableList(Arrays.<Class<?>>asList(
+                        Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE,
+                        Float.TYPE, Double.TYPE
+                    ));
 
     /**
      * The complement of {@link String#CASE_INSENSITIVE_ORDER}
@@ -473,4 +478,16 @@ public final class GenericUtils {
         return (int) (value ^ (value >>> 32));
     }
 
+    public static boolean isNumericClass(Class<?> clazz) {
+        if (clazz == null) {
+            return false;
+        }
+
+        // turns out that the primitive types are not assignable to Number
+        if (Number.class.isAssignableFrom(clazz)) {
+            return true;
+        }
+
+        return NUMERIC_PRIMITIVE_CLASSES.indexOf(clazz) >= 0;
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/common/util/logging/LoggingUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/logging/LoggingUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/logging/LoggingUtils.java
index fe4cad6..4f896a4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/logging/LoggingUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/logging/LoggingUtils.java
@@ -19,9 +19,15 @@
 
 package org.apache.sshd.common.util.logging;
 
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Objects;
 import java.util.logging.Level;
 
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Predicate;
 import org.slf4j.Logger;
 
 /**
@@ -34,6 +40,70 @@ public final class LoggingUtils {
     }
 
     /**
+     * Scans using reflection API for all fields that are {@code public static final}
+     * that start with the given common prefix (case <U>sensitive</U>) and are of type
+     * {@link Number}.
+     *
+     * @param clazz The {@link Class} to query
+     * @param commonPrefix The expected common prefix
+     * @return A {@link Map} of all the matching fields, where key=the field's {@link Integer}
+     * value and mapping=the field's name
+     * @see #generateMnemonicMap(Class, Predicate)
+     */
+    public static Map<Integer, String> generateMnemonicMap(Class<?> clazz, final String commonPrefix) {
+        return generateMnemonicMap(clazz, new Predicate<Field>() {
+            @Override
+            public boolean evaluate(Field f) {
+                String name = f.getName();
+                return name.startsWith(commonPrefix);
+            }
+        });
+    }
+
+    /**
+     * Scans using reflection API for all <U>numeric {@code public static final}</U> fields
+     * that are also accepted by the predicate. Any field that is not such or fail to retrieve
+     * its value, or has a duplicate value is <U>silently</U> skipped.
+     *
+     * @param clazz The {@link Class} to query
+     * @param acceptor The {@link Predicate} used to decide whether to process the {@link Field}
+     * (besides being a {@link Number} and {@code public static final}).
+     * @return A {@link Map} of all the matching fields, where key=the field's {@link Integer}
+     * value and mapping=the field's name
+     */
+    public static Map<Integer, String> generateMnemonicMap(Class<?> clazz, Predicate<? super Field> acceptor) {
+        Map<Integer, String> result = new HashMap<>();
+        for (Field f : clazz.getFields()) {
+            String name = f.getName();
+            int mods = f.getModifiers();
+            if ((!Modifier.isPublic(mods)) || (!Modifier.isStatic(mods)) || (!Modifier.isFinal(mods))) {
+                continue;
+            }
+
+            Class<?> type = f.getType();
+            if (!GenericUtils.isNumericClass(type)) {
+                continue;
+            }
+
+            if (!acceptor.evaluate(f)) {
+                continue;
+            }
+
+            try {
+                Number value = (Number) f.get(null);
+                String prev = result.put(value.intValue(), name);
+                if (prev != null) {
+                    continue;   // debug breakpoint
+                }
+            } catch (Exception e) {
+                continue;   // debug breakpoint
+            }
+        }
+
+        return result;
+    }
+
+    /**
      * Verifies if the given level is above the required threshold for logging.
      *
      * @param level     The {@link Level} to evaluate

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/652ad7de/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
index 095d164..45d074b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
@@ -50,7 +50,7 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
 
     @Override
     public OpenFuture open(int recipient, int rwSize, int packetSize, Buffer buffer) {
-        this.recipient = recipient;
+        setRecipient(recipient);
 
         Session s = getSession();
         FactoryManager manager = ValidateUtils.checkNotNull(s.getFactoryManager(), "No factory manager");
@@ -93,12 +93,12 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
         if (!exitStatusSent) {
             exitStatusSent = true;
             if (log.isDebugEnabled()) {
-                log.debug("Send SSH_MSG_CHANNEL_REQUEST exit-status on channel {}", Integer.valueOf(id));
+                log.debug("sendExitStatus({}) SSH_MSG_CHANNEL_REQUEST exit-status={}", this, v);
             }
 
             Session session = getSession();
             Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST, Long.SIZE);
-            buffer.putInt(recipient);
+            buffer.putInt(getRecipient());
             buffer.putString("exit-status");
             buffer.putBoolean(false);   // want-reply - must be FALSE - see https://tools.ietf.org/html/rfc4254 section 6.10
             buffer.putInt(v);