Skip to content
This repository
Fetching contributors…

Cannot retrieve contributors at this time

file 170 lines (137 sloc) 6.458 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
"""Implementation of magic functions for IPython's own logging.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2012 The IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Stdlib
import os
import sys

# Our own packages
from IPython.core.magic import Magics, magics_class, line_magic
from IPython.utils.warn import warn
from IPython.utils.py3compat import str_to_unicode

#-----------------------------------------------------------------------------
# Magic implementation classes
#-----------------------------------------------------------------------------

@magics_class
class LoggingMagics(Magics):
    """Magics related to all logging machinery."""

    @line_magic
    def logstart(self, parameter_s=''):
        """Start logging anywhere in a session.

%logstart [-o|-r|-t] [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: well, that says it.\\
backup: rename (if exists) to name~ and start name.\\
global: single logfile in your home dir, appended to.\\
over : overwrite 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.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)."""

        opts,par = self.parse_options(parameter_s,'ort')
        log_output = 'o' in opts
        log_raw_input = 'r' in opts
        timestamp = 't' in opts

        logger = self.shell.logger

        # if no args are given, the defaults set in the logger constructor by
        # ipython remain valid
        if par:
            try:
                logfname,logmode = par.split()
            except:
                logfname = par
                logmode = 'backup'
        else:
            logfname = logger.logfname
            logmode = logger.logmode
        # put logfname into rc struct as if it had been called on the command
        # line, so it ends up saved in the log header Save it in case we need
        # to restore it...
        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:
            # log input history up to this point, optionally interleaving
            # output if requested

            if timestamp:
                # disable timestamping for the previous history, since we've
                # lost those already (no time machine here).
                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(str_to_unicode(repr(output_hist[n])),'output')
            else:
                logger.log_write(u'\n'.join(input_hist[1:]))
                logger.log_write(u'\n')
            if timestamp:
                # re-enable timestamping
                logger.timestamp = True

            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()
Something went wrong with that request. Please try again.