| """Implementation of magic functions for IPython's own logging. |
| """ |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| import os |
| import sys |
|
|
| |
| from IPython.core.magic import Magics, magics_class, line_magic |
| from warnings import warn |
| from traitlets import Bool |
|
|
| |
| |
| |
|
|
| @magics_class |
| class LoggingMagics(Magics): |
| """Magics related to all logging machinery.""" |
|
|
| quiet = Bool(False, help= |
| """ |
| Suppress output of log state when logging is enabled |
| """ |
| ).tag(config=True) |
|
|
| @line_magic |
| def logstart(self, parameter_s=''): |
| """Start logging anywhere in a session. |
| |
| %logstart [-o|-r|-t|-q] [log_name [log_mode]] |
| |
| If no name is given, it defaults to a file named 'ipython_log.py' in your |
| current directory, in 'rotate' mode (see below). |
| |
| '%logstart name' saves to file 'name' in 'backup' mode. It saves your |
| history up to that point and then continues logging. |
| |
| %logstart takes a second optional parameter: logging mode. This can be one |
| of (note that the modes are given unquoted): |
| |
| append |
| Keep logging at the end of any existing file. |
| |
| backup |
| Rename any existing file to name~ and start name. |
| |
| global |
| Append to a single logfile in your home directory. |
| |
| over |
| Overwrite any existing log. |
| |
| rotate |
| Create rotating logs: name.1~, name.2~, etc. |
| |
| Options: |
| |
| -o |
| log also IPython's output. In this mode, all commands which |
| generate an Out[NN] prompt are recorded to the logfile, right after |
| their corresponding input line. The output lines are always |
| prepended with a '#[Out]# ' marker, so that the log remains valid |
| Python code. |
| |
| Since this marker is always the same, filtering only the output from |
| a log is very easy, using for example a simple awk call:: |
| |
| awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py |
| |
| -r |
| log 'raw' input. Normally, IPython's logs contain the processed |
| input, so that user lines are logged in their final form, converted |
| into valid Python. For example, %Exit is logged as |
| _ip.run_line_magic("Exit"). If the -r flag is given, all input is logged |
| exactly as typed, with no transformations applied. |
| |
| -t |
| put timestamps before each input line logged (these are put in |
| comments). |
| |
| -q |
| suppress output of logstate message when logging is invoked |
| """ |
|
|
| opts,par = self.parse_options(parameter_s,'ortq') |
| log_output = 'o' in opts |
| log_raw_input = 'r' in opts |
| timestamp = 't' in opts |
| quiet = 'q' in opts |
|
|
| logger = self.shell.logger |
|
|
| |
| |
| if par: |
| try: |
| logfname,logmode = par.split() |
| except: |
| logfname = par |
| logmode = 'backup' |
| else: |
| logfname = logger.logfname |
| logmode = logger.logmode |
| |
| |
| |
| old_logfile = self.shell.logfile |
| if logfname: |
| logfname = os.path.expanduser(logfname) |
| self.shell.logfile = logfname |
|
|
| loghead = u'# IPython log file\n\n' |
| try: |
| logger.logstart(logfname, loghead, logmode, log_output, timestamp, |
| log_raw_input) |
| except: |
| self.shell.logfile = old_logfile |
| warn("Couldn't start log: %s" % sys.exc_info()[1]) |
| else: |
| |
| |
|
|
| if timestamp: |
| |
| |
| logger.timestamp = False |
|
|
| if log_raw_input: |
| input_hist = self.shell.history_manager.input_hist_raw |
| else: |
| input_hist = self.shell.history_manager.input_hist_parsed |
|
|
| if log_output: |
| log_write = logger.log_write |
| output_hist = self.shell.history_manager.output_hist |
| for n in range(1,len(input_hist)-1): |
| log_write(input_hist[n].rstrip() + u'\n') |
| if n in output_hist: |
| log_write(repr(output_hist[n]),'output') |
| else: |
| logger.log_write(u'\n'.join(input_hist[1:])) |
| logger.log_write(u'\n') |
| if timestamp: |
| |
| logger.timestamp = True |
|
|
| if not (self.quiet or quiet): |
| print ('Activating auto-logging. ' |
| 'Current session state plus future input saved.') |
| logger.logstate() |
|
|
| @line_magic |
| def logstop(self, parameter_s=''): |
| """Fully stop logging and close log file. |
| |
| In order to start logging again, a new %logstart call needs to be made, |
| possibly (though not necessarily) with a new filename, mode and other |
| options.""" |
| self.shell.logger.logstop() |
|
|
| @line_magic |
| def logoff(self, parameter_s=''): |
| """Temporarily stop logging. |
| |
| You must have previously started logging.""" |
| self.shell.logger.switch_log(0) |
|
|
| @line_magic |
| def logon(self, parameter_s=''): |
| """Restart logging. |
| |
| This function is for restarting logging which you've temporarily |
| stopped with %logoff. For starting logging for the first time, you |
| must use the %logstart function, which allows you to specify an |
| optional log filename.""" |
|
|
| self.shell.logger.switch_log(1) |
|
|
| @line_magic |
| def logstate(self, parameter_s=''): |
| """Print the status of the logging system.""" |
|
|
| self.shell.logger.logstate() |
|
|