Reputation: 5747
I am using pexpect to handle my telnet and ssh communication.
I am also writing all request/response in a logfile. using pexpect.logfile(filename)
.
I would like to have timestamps in the logfile as well. I can not find it anywhere in the documentation! Does anyone have any idea how to implement this functionality?
Upvotes: 3
Views: 3504
Reputation: 11213
If you take a look at the pexpect.py source file, you'll see that the approach taken to logging is simply writing what is sent/received to the child process to a stream (which can be a file or, for example, sys.stdout
if you prefer to log to the console). Therefore what you asked for is impossible without changing the pexpect
sources, to for example, be able to use a standard library logging module logger for output (hint: maybe a good opportunity to contribute an enhancement to the project?).
Upvotes: 1
Reputation: 414685
logfile
can be any object that has write()
, flush()
methods:
from datetime import datetime
class TimestampedFile(object):
def __init__(self, file):
self.file = file
def write(self, data):
# .. filter data however you like
ts = datetime.utcnow().isoformat() # generate timestamp
return self.file.write("%s %s\n" % (ts, data)) # write to original file
def flush(self):
self.file.flush()
with open(filename, 'w') as file:
pexpect.run('echo "hello world!"', logfile=TimestampedFile(file))
Your logging example could be simplified:
class FileAdapter(object):
def __init__(self, logger):
self.logger = logger
def write(self, data):
# NOTE: data can be a partial line, multiple lines
data = data.strip() # ignore leading/trailing whitespace
if data: # non-blank
self.logger.info(data)
def flush(self):
pass # leave it to logging to flush properly
# setup logging to include a timestamp
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.INFO)
# ... run command sometime later
pexpect.run('echo "hello world!"', logfile=FileAdapter(logging.getLogger('foo')))
Upvotes: 6
Reputation: 5747
After some searching I found the below code which works for me! Take a look at the below code:
import logging
import pexpect
import re
# this is the method called by the pexpect object to log
def _write(*args, **kwargs):
content = args[0]
# Ignore other params, pexpect only use one arg
if content in [' ', '', '\n', '\r', '\r\n']:
return # don't log empty lines
for eol in ['\r\n', '\r', '\n']:
# remove ending EOL, the logger will add it anyway
content = re.sub('\%s$' % eol, '', content)
return logger.info(content) # call the logger info method with the reworked content
# our flush method
def _doNothing():
pass
logger = logging.getLogger('foo')
hdlr = logging.FileHandler('/bar.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
# give the logger the methods required by pexpect
logger.write = _write
logger.flush = _doNothing
p = pexpect.spawn('echo "hello world !"', logfile=logger)
Upvotes: 0