[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:
parent
3db675d1be
commit
8878a5f3c2
|
@ -281,7 +281,7 @@ class Channel (object):
|
||||||
@type name: str
|
@type name: str
|
||||||
"""
|
"""
|
||||||
self.name = name
|
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):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
|
@ -758,6 +758,7 @@ class Channel (object):
|
||||||
|
|
||||||
def _set_transport(self, transport):
|
def _set_transport(self, transport):
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
|
self.logger = logging.getLogger(self.transport.get_log_channel() + '.' + self.name)
|
||||||
|
|
||||||
def _set_window(self, window_size, max_packet_size):
|
def _set_window(self, window_size, max_packet_size):
|
||||||
self.in_window_size = window_size
|
self.in_window_size = window_size
|
||||||
|
|
|
@ -78,6 +78,9 @@ class SFTPAttributes (object):
|
||||||
return attr
|
return attr
|
||||||
from_stat = classmethod(from_stat)
|
from_stat = classmethod(from_stat)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '<SFTPAttributes: %s>' % self._debug_str()
|
||||||
|
|
||||||
|
|
||||||
### internals...
|
### internals...
|
||||||
|
|
||||||
|
@ -138,6 +141,22 @@ class SFTPAttributes (object):
|
||||||
msg.add_string(val)
|
msg.add_string(val)
|
||||||
return
|
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):
|
def _rwx(n, suid, sticky=False):
|
||||||
if suid:
|
if suid:
|
||||||
suid = 2
|
suid = 2
|
||||||
|
|
|
@ -50,7 +50,9 @@ class SFTPClient (BaseSFTP):
|
||||||
self.request_number = 1
|
self.request_number = 1
|
||||||
if type(sock) is Channel:
|
if type(sock) is Channel:
|
||||||
# override default logger
|
# 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()
|
self._send_version()
|
||||||
|
|
||||||
def from_transport(selfclass, t):
|
def from_transport(selfclass, t):
|
||||||
|
|
|
@ -29,9 +29,9 @@ from sftp import *
|
||||||
|
|
||||||
class SFTPHandle (object):
|
class SFTPHandle (object):
|
||||||
"""
|
"""
|
||||||
Abstract object representing a handle to an open file (or folder) on
|
Abstract object representing a handle to an open file (or folder) in an
|
||||||
the server. Each handle has a string representation used by the client
|
SFTP server implementation. Each handle has a string representation used
|
||||||
to refer to the underlying file.
|
by the client to refer to the underlying file.
|
||||||
|
|
||||||
Server implementations can (and should) subclass SFTPHandle to implement
|
Server implementations can (and should) subclass SFTPHandle to implement
|
||||||
features of a file handle, like L{stat} or L{chattr}.
|
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.
|
it's called on an open file instead of a path.
|
||||||
|
|
||||||
@return: an attributes object for the given file, or an SFTP error
|
@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}
|
@rtype: L{SFTPAttributes} I{or error code}
|
||||||
"""
|
"""
|
||||||
return SFTP_OP_UNSUPPORTED
|
return SFTP_OP_UNSUPPORTED
|
||||||
|
|
|
@ -58,7 +58,9 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
||||||
BaseSFTP.__init__(self)
|
BaseSFTP.__init__(self)
|
||||||
SubsystemHandler.__init__(self, channel, name)
|
SubsystemHandler.__init__(self, channel, name)
|
||||||
self.ultra_debug = True
|
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
|
self.next_handle = 1
|
||||||
# map of handle-string to SFTPHandle for files & folders:
|
# map of handle-string to SFTPHandle for files & folders:
|
||||||
self.file_table = { }
|
self.file_table = { }
|
||||||
|
@ -88,6 +90,13 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
||||||
|
|
||||||
def finish_subsystem(self):
|
def finish_subsystem(self):
|
||||||
self.server.session_ended()
|
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):
|
def convert_errno(e):
|
||||||
"""
|
"""
|
||||||
|
@ -121,7 +130,7 @@ class SFTPServer (BaseSFTP, SubsystemHandler):
|
||||||
requests into local file operations.
|
requests into local file operations.
|
||||||
|
|
||||||
@param filename: name of the file to alter (should usually be an
|
@param filename: name of the file to alter (should usually be an
|
||||||
absolute path).
|
absolute path).
|
||||||
@type filename: str
|
@type filename: str
|
||||||
@param attr: attributes to change.
|
@param attr: attributes to change.
|
||||||
@type attr: L{SFTPAttributes}
|
@type attr: L{SFTPAttributes}
|
||||||
|
|
|
@ -237,12 +237,13 @@ class BaseTransport (threading.Thread):
|
||||||
self.channels = { } # (id -> Channel)
|
self.channels = { } # (id -> Channel)
|
||||||
self.channel_events = { } # (id -> Event)
|
self.channel_events = { } # (id -> Event)
|
||||||
self.channel_counter = 1
|
self.channel_counter = 1
|
||||||
self.logger = logging.getLogger('paramiko.transport')
|
|
||||||
self.window_size = 65536
|
self.window_size = 65536
|
||||||
self.max_packet_size = 32768
|
self.max_packet_size = 32768
|
||||||
self.ultra_debug = False
|
self.ultra_debug = False
|
||||||
self.saved_exception = None
|
self.saved_exception = None
|
||||||
self.clear_to_send = threading.Event()
|
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:
|
# used for noticing when to re-key:
|
||||||
self.received_bytes = 0
|
self.received_bytes = 0
|
||||||
self.received_packets = 0
|
self.received_packets = 0
|
||||||
|
@ -783,15 +784,28 @@ class BaseTransport (threading.Thread):
|
||||||
"""
|
"""
|
||||||
Set the channel for this transport's logging. The default is
|
Set the channel for this transport's logging. The default is
|
||||||
C{"paramiko.transport"} but it can be set to anything you want.
|
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.
|
@param name: new channel name for logging.
|
||||||
@type name: str
|
@type name: str
|
||||||
|
|
||||||
@since: 1.1
|
@since: 1.1
|
||||||
"""
|
"""
|
||||||
|
self.log_name = name
|
||||||
self.logger = logging.getLogger(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...
|
### internals...
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue