[project @ Arch-1:robey@lag.net--2003-public%secsh--dev--1.0--patch-140]

more flexible logging
some tweaks to make channels etc follow the logger setting of their parent
transport, so that setting the log channel for a paramiko transport will
cause all sub-logging to branch out from that channel.

also, close all open file handles when the sftp server ends.
This commit is contained in:
Robey Pointer 2005-01-17 10:09:09 +00:00
parent 3db675d1be
commit 8878a5f3c2
6 changed files with 55 additions and 10 deletions

View File

@ -281,7 +281,7 @@ class Channel (object):
@type name: str
"""
self.name = name
self.logger = logging.getLogger('paramiko.chan.' + name)
self.logger = logging.getLogger(self.transport.get_log_channel() + '.' + self.name)
def get_name(self):
"""
@ -758,6 +758,7 @@ class Channel (object):
def _set_transport(self, transport):
self.transport = transport
self.logger = logging.getLogger(self.transport.get_log_channel() + '.' + self.name)
def _set_window(self, window_size, max_packet_size):
self.in_window_size = window_size

View File

@ -78,6 +78,9 @@ class SFTPAttributes (object):
return attr
from_stat = classmethod(from_stat)
def __repr__(self):
return '<SFTPAttributes: %s>' % self._debug_str()
### internals...
@ -138,6 +141,22 @@ class SFTPAttributes (object):
msg.add_string(val)
return
def _debug_str(self):
out = '[ '
if hasattr(self, 'st_size'):
out += 'size=%d ' % self.st_size
if hasattr(self, 'st_uid') or hasattr(self, 'st_gid'):
out += 'uid=%d gid=%d ' % (getattr(self, 'st_uid', 0), getattr(self, 'st_gid', 0))
if hasattr(self, 'st_mode'):
out += 'mode=%d ' % self.st_mode
if hasattr(self, 'st_atime') or hasattr(self, 'st_mtime'):
out += 'atime=%d mtime=%d ' % (getattr(self, 'st_atime', 0),
getattr(self, 'st_mtime', 0))
for k, v in self.attr.iteritems():
out += '"%s"=%s ' % (str(k), repr(v))
out += ']'
return out
def _rwx(n, suid, sticky=False):
if suid:
suid = 2

View File

@ -50,7 +50,9 @@ class SFTPClient (BaseSFTP):
self.request_number = 1
if type(sock) is Channel:
# override default logger
self.logger = logging.getLogger('paramiko.chan.' + sock.get_name() + '.sftp')
transport = self.sock.get_transport()
self.logger = logging.getLogger(transport.get_log_channel() + '.' +
self.sock.get_name() + '.sftp')
self._send_version()
def from_transport(selfclass, t):

View File

@ -29,9 +29,9 @@ from sftp import *
class SFTPHandle (object):
"""
Abstract object representing a handle to an open file (or folder) on
the server. Each handle has a string representation used by the client
to refer to the underlying file.
Abstract object representing a handle to an open file (or folder) in an
SFTP server implementation. Each handle has a string representation used
by the client to refer to the underlying file.
Server implementations can (and should) subclass SFTPHandle to implement
features of a file handle, like L{stat} or L{chattr}.
@ -138,7 +138,7 @@ class SFTPHandle (object):
it's called on an open file instead of a path.
@return: an attributes object for the given file, or an SFTP error
code (like L{SFTP_PERMISSION_DENIED}).
code (like L{SFTP_PERMISSION_DENIED}).
@rtype: L{SFTPAttributes} I{or error code}
"""
return SFTP_OP_UNSUPPORTED

View File

@ -58,7 +58,9 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
BaseSFTP.__init__(self)
SubsystemHandler.__init__(self, channel, name)
self.ultra_debug = True
self.logger = logging.getLogger('paramiko.chan.' + channel.get_name() + '.sftp')
transport = channel.get_transport()
self.logger = logging.getLogger(transport.get_log_channel() + '.' +
channel.get_name() + '.sftp')
self.next_handle = 1
# map of handle-string to SFTPHandle for files & folders:
self.file_table = { }
@ -88,6 +90,13 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
def finish_subsystem(self):
self.server.session_ended()
# close any file handles that were left open (so we can return them to the OS quickly)
for f in self.file_table.itervalues():
f.close()
for f in self.folder_table.itervalues():
f.close()
self.file_table = {}
self.folder_table = {}
def convert_errno(e):
"""
@ -121,7 +130,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
requests into local file operations.
@param filename: name of the file to alter (should usually be an
absolute path).
absolute path).
@type filename: str
@param attr: attributes to change.
@type attr: L{SFTPAttributes}

View File

@ -237,12 +237,13 @@ class BaseTransport (threading.Thread):
self.channels = { } # (id -> Channel)
self.channel_events = { } # (id -> Event)
self.channel_counter = 1
self.logger = logging.getLogger('paramiko.transport')
self.window_size = 65536
self.max_packet_size = 32768
self.ultra_debug = False
self.saved_exception = None
self.clear_to_send = threading.Event()
self.log_name = 'paramiko.transport'
self.logger = logging.getLogger(self.log_name)
# used for noticing when to re-key:
self.received_bytes = 0
self.received_packets = 0
@ -783,15 +784,28 @@ class BaseTransport (threading.Thread):
"""
Set the channel for this transport's logging. The default is
C{"paramiko.transport"} but it can be set to anything you want.
(See the C{logging} module for more info.)
(See the C{logging} module for more info.) SSH Channels will log
to a sub-channel of the one specified.
@param name: new channel name for logging.
@type name: str
@since: 1.1
"""
self.log_name = name
self.logger = logging.getLogger(name)
def get_log_channel(self):
"""
Return the channel name used for this transport's logging.
@return: channel name.
@rtype: str
@since: 1.2
"""
return self.log_name
### internals...