Show More
@@ -0,0 +1,169 b'' | |||||
|
1 | """Implementation of magic functions for IPython's own logging. | |||
|
2 | """ | |||
|
3 | #----------------------------------------------------------------------------- | |||
|
4 | # Copyright (c) 2012 The IPython Development Team. | |||
|
5 | # | |||
|
6 | # Distributed under the terms of the Modified BSD License. | |||
|
7 | # | |||
|
8 | # The full license is in the file COPYING.txt, distributed with this software. | |||
|
9 | #----------------------------------------------------------------------------- | |||
|
10 | ||||
|
11 | #----------------------------------------------------------------------------- | |||
|
12 | # Imports | |||
|
13 | #----------------------------------------------------------------------------- | |||
|
14 | ||||
|
15 | # Stdlib | |||
|
16 | import os | |||
|
17 | import sys | |||
|
18 | ||||
|
19 | # Our own packages | |||
|
20 | from IPython.core.magic import Magics, register_magics, line_magic | |||
|
21 | from IPython.utils.warn import warn | |||
|
22 | ||||
|
23 | #----------------------------------------------------------------------------- | |||
|
24 | # Magic implementation classes | |||
|
25 | #----------------------------------------------------------------------------- | |||
|
26 | ||||
|
27 | @register_magics | |||
|
28 | class LoggingMagics(Magics): | |||
|
29 | """Magics related to all logging machinery.""" | |||
|
30 | ||||
|
31 | @line_magic | |||
|
32 | def logstart(self, parameter_s=''): | |||
|
33 | """Start logging anywhere in a session. | |||
|
34 | ||||
|
35 | %logstart [-o|-r|-t] [log_name [log_mode]] | |||
|
36 | ||||
|
37 | If no name is given, it defaults to a file named 'ipython_log.py' in your | |||
|
38 | current directory, in 'rotate' mode (see below). | |||
|
39 | ||||
|
40 | '%logstart name' saves to file 'name' in 'backup' mode. It saves your | |||
|
41 | history up to that point and then continues logging. | |||
|
42 | ||||
|
43 | %logstart takes a second optional parameter: logging mode. This can be one | |||
|
44 | of (note that the modes are given unquoted):\\ | |||
|
45 | append: well, that says it.\\ | |||
|
46 | backup: rename (if exists) to name~ and start name.\\ | |||
|
47 | global: single logfile in your home dir, appended to.\\ | |||
|
48 | over : overwrite existing log.\\ | |||
|
49 | rotate: create rotating logs name.1~, name.2~, etc. | |||
|
50 | ||||
|
51 | Options: | |||
|
52 | ||||
|
53 | -o: log also IPython's output. In this mode, all commands which | |||
|
54 | generate an Out[NN] prompt are recorded to the logfile, right after | |||
|
55 | their corresponding input line. The output lines are always | |||
|
56 | prepended with a '#[Out]# ' marker, so that the log remains valid | |||
|
57 | Python code. | |||
|
58 | ||||
|
59 | Since this marker is always the same, filtering only the output from | |||
|
60 | a log is very easy, using for example a simple awk call:: | |||
|
61 | ||||
|
62 | awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py | |||
|
63 | ||||
|
64 | -r: log 'raw' input. Normally, IPython's logs contain the processed | |||
|
65 | input, so that user lines are logged in their final form, converted | |||
|
66 | into valid Python. For example, %Exit is logged as | |||
|
67 | _ip.magic("Exit"). If the -r flag is given, all input is logged | |||
|
68 | exactly as typed, with no transformations applied. | |||
|
69 | ||||
|
70 | -t: put timestamps before each input line logged (these are put in | |||
|
71 | comments).""" | |||
|
72 | ||||
|
73 | opts,par = self.parse_options(parameter_s,'ort') | |||
|
74 | log_output = 'o' in opts | |||
|
75 | log_raw_input = 'r' in opts | |||
|
76 | timestamp = 't' in opts | |||
|
77 | ||||
|
78 | logger = self.shell.logger | |||
|
79 | ||||
|
80 | # if no args are given, the defaults set in the logger constructor by | |||
|
81 | # ipython remain valid | |||
|
82 | if par: | |||
|
83 | try: | |||
|
84 | logfname,logmode = par.split() | |||
|
85 | except: | |||
|
86 | logfname = par | |||
|
87 | logmode = 'backup' | |||
|
88 | else: | |||
|
89 | logfname = logger.logfname | |||
|
90 | logmode = logger.logmode | |||
|
91 | # put logfname into rc struct as if it had been called on the command | |||
|
92 | # line, so it ends up saved in the log header Save it in case we need | |||
|
93 | # to restore it... | |||
|
94 | old_logfile = self.shell.logfile | |||
|
95 | if logfname: | |||
|
96 | logfname = os.path.expanduser(logfname) | |||
|
97 | self.shell.logfile = logfname | |||
|
98 | ||||
|
99 | loghead = '# IPython log file\n\n' | |||
|
100 | try: | |||
|
101 | logger.logstart(logfname, loghead, logmode, log_output, timestamp, | |||
|
102 | log_raw_input) | |||
|
103 | except: | |||
|
104 | self.shell.logfile = old_logfile | |||
|
105 | warn("Couldn't start log: %s" % sys.exc_info()[1]) | |||
|
106 | else: | |||
|
107 | # log input history up to this point, optionally interleaving | |||
|
108 | # output if requested | |||
|
109 | ||||
|
110 | if timestamp: | |||
|
111 | # disable timestamping for the previous history, since we've | |||
|
112 | # lost those already (no time machine here). | |||
|
113 | logger.timestamp = False | |||
|
114 | ||||
|
115 | if log_raw_input: | |||
|
116 | input_hist = self.shell.history_manager.input_hist_raw | |||
|
117 | else: | |||
|
118 | input_hist = self.shell.history_manager.input_hist_parsed | |||
|
119 | ||||
|
120 | if log_output: | |||
|
121 | log_write = logger.log_write | |||
|
122 | output_hist = self.shell.history_manager.output_hist | |||
|
123 | for n in range(1,len(input_hist)-1): | |||
|
124 | log_write(input_hist[n].rstrip() + '\n') | |||
|
125 | if n in output_hist: | |||
|
126 | log_write(repr(output_hist[n]),'output') | |||
|
127 | else: | |||
|
128 | logger.log_write('\n'.join(input_hist[1:])) | |||
|
129 | logger.log_write('\n') | |||
|
130 | if timestamp: | |||
|
131 | # re-enable timestamping | |||
|
132 | logger.timestamp = True | |||
|
133 | ||||
|
134 | print ('Activating auto-logging. ' | |||
|
135 | 'Current session state plus future input saved.') | |||
|
136 | logger.logstate() | |||
|
137 | ||||
|
138 | @line_magic | |||
|
139 | def logstop(self, parameter_s=''): | |||
|
140 | """Fully stop logging and close log file. | |||
|
141 | ||||
|
142 | In order to start logging again, a new %logstart call needs to be made, | |||
|
143 | possibly (though not necessarily) with a new filename, mode and other | |||
|
144 | options.""" | |||
|
145 | self.logger.logstop() | |||
|
146 | ||||
|
147 | @line_magic | |||
|
148 | def logoff(self, parameter_s=''): | |||
|
149 | """Temporarily stop logging. | |||
|
150 | ||||
|
151 | You must have previously started logging.""" | |||
|
152 | self.shell.logger.switch_log(0) | |||
|
153 | ||||
|
154 | @line_magic | |||
|
155 | def logon(self, parameter_s=''): | |||
|
156 | """Restart logging. | |||
|
157 | ||||
|
158 | This function is for restarting logging which you've temporarily | |||
|
159 | stopped with %logoff. For starting logging for the first time, you | |||
|
160 | must use the %logstart function, which allows you to specify an | |||
|
161 | optional log filename.""" | |||
|
162 | ||||
|
163 | self.shell.logger.switch_log(1) | |||
|
164 | ||||
|
165 | @line_magic | |||
|
166 | def logstate(self, parameter_s=''): | |||
|
167 | """Print the status of the logging system.""" | |||
|
168 | ||||
|
169 | self.shell.logger.logstate() |
@@ -2007,7 +2007,7 b' class InteractiveShell(SingletonConfigurable):' | |||||
2007 |
|
2007 | |||
2008 | self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics, |
|
2008 | self.register_magics(m.AutoMagics, m.BasicMagics, m.CodeMagics, | |
2009 | m.ConfigMagics, mf.DeprecatedMagics, m.ExecutionMagics, |
|
2009 | m.ConfigMagics, mf.DeprecatedMagics, m.ExecutionMagics, | |
2010 |
mf.ExtensionsMagics, m.HistoryMagics, m |
|
2010 | mf.ExtensionsMagics, m.HistoryMagics, m.LoggingMagics, | |
2011 | m.NamespaceMagics, m.OSMagics, mf.PylabMagics ) |
|
2011 | m.NamespaceMagics, m.OSMagics, mf.PylabMagics ) | |
2012 |
|
2012 | |||
2013 | # FIXME: Move the color initialization to the DisplayHook, which |
|
2013 | # FIXME: Move the color initialization to the DisplayHook, which |
@@ -16,174 +16,17 b'' | |||||
16 |
|
16 | |||
17 | # Stdlib |
|
17 | # Stdlib | |
18 | import os |
|
18 | import os | |
19 | import re |
|
|||
20 | import sys |
|
|||
21 | from pprint import pformat |
|
|||
22 |
|
19 | |||
23 | # Our own packages |
|
20 | # Our own packages | |
24 | from IPython.config.application import Application |
|
21 | from IPython.config.application import Application | |
25 | from IPython.core import oinspect |
|
22 | from IPython.core.magic import Magics, register_magics, line_magic | |
26 | from IPython.core import page |
|
|||
27 | from IPython.core.error import UsageError |
|
|||
28 | from IPython.core.magic import (Magics, compress_dhist, |
|
|||
29 | register_magics, line_magic) |
|
|||
30 | from IPython.testing.skipdoctest import skip_doctest |
|
23 | from IPython.testing.skipdoctest import skip_doctest | |
31 | from IPython.utils.io import file_read, nlprint |
|
|||
32 | from IPython.utils.path import get_py_filename, unquote_filename |
|
|||
33 | from IPython.utils.process import abbrev_cwd |
|
|||
34 | from IPython.utils.terminal import set_term_title |
|
|||
35 | from IPython.utils.warn import warn |
|
|||
36 |
|
24 | |||
37 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
38 | # Magic implementation classes |
|
26 | # Magic implementation classes | |
39 | #----------------------------------------------------------------------------- |
|
27 | #----------------------------------------------------------------------------- | |
40 |
|
28 | |||
41 | @register_magics |
|
29 | @register_magics | |
42 | class LoggingMagics(Magics): |
|
|||
43 | """Magics related to all logging machinery.""" |
|
|||
44 |
|
||||
45 | @line_magic |
|
|||
46 | def logstart(self, parameter_s=''): |
|
|||
47 | """Start logging anywhere in a session. |
|
|||
48 |
|
||||
49 | %logstart [-o|-r|-t] [log_name [log_mode]] |
|
|||
50 |
|
||||
51 | If no name is given, it defaults to a file named 'ipython_log.py' in your |
|
|||
52 | current directory, in 'rotate' mode (see below). |
|
|||
53 |
|
||||
54 | '%logstart name' saves to file 'name' in 'backup' mode. It saves your |
|
|||
55 | history up to that point and then continues logging. |
|
|||
56 |
|
||||
57 | %logstart takes a second optional parameter: logging mode. This can be one |
|
|||
58 | of (note that the modes are given unquoted):\\ |
|
|||
59 | append: well, that says it.\\ |
|
|||
60 | backup: rename (if exists) to name~ and start name.\\ |
|
|||
61 | global: single logfile in your home dir, appended to.\\ |
|
|||
62 | over : overwrite existing log.\\ |
|
|||
63 | rotate: create rotating logs name.1~, name.2~, etc. |
|
|||
64 |
|
||||
65 | Options: |
|
|||
66 |
|
||||
67 | -o: log also IPython's output. In this mode, all commands which |
|
|||
68 | generate an Out[NN] prompt are recorded to the logfile, right after |
|
|||
69 | their corresponding input line. The output lines are always |
|
|||
70 | prepended with a '#[Out]# ' marker, so that the log remains valid |
|
|||
71 | Python code. |
|
|||
72 |
|
||||
73 | Since this marker is always the same, filtering only the output from |
|
|||
74 | a log is very easy, using for example a simple awk call:: |
|
|||
75 |
|
||||
76 | awk -F'#\\[Out\\]# ' '{if($2) {print $2}}' ipython_log.py |
|
|||
77 |
|
||||
78 | -r: log 'raw' input. Normally, IPython's logs contain the processed |
|
|||
79 | input, so that user lines are logged in their final form, converted |
|
|||
80 | into valid Python. For example, %Exit is logged as |
|
|||
81 | _ip.magic("Exit"). If the -r flag is given, all input is logged |
|
|||
82 | exactly as typed, with no transformations applied. |
|
|||
83 |
|
||||
84 | -t: put timestamps before each input line logged (these are put in |
|
|||
85 | comments).""" |
|
|||
86 |
|
||||
87 | opts,par = self.parse_options(parameter_s,'ort') |
|
|||
88 | log_output = 'o' in opts |
|
|||
89 | log_raw_input = 'r' in opts |
|
|||
90 | timestamp = 't' in opts |
|
|||
91 |
|
||||
92 | logger = self.shell.logger |
|
|||
93 |
|
||||
94 | # if no args are given, the defaults set in the logger constructor by |
|
|||
95 | # ipython remain valid |
|
|||
96 | if par: |
|
|||
97 | try: |
|
|||
98 | logfname,logmode = par.split() |
|
|||
99 | except: |
|
|||
100 | logfname = par |
|
|||
101 | logmode = 'backup' |
|
|||
102 | else: |
|
|||
103 | logfname = logger.logfname |
|
|||
104 | logmode = logger.logmode |
|
|||
105 | # put logfname into rc struct as if it had been called on the command |
|
|||
106 | # line, so it ends up saved in the log header Save it in case we need |
|
|||
107 | # to restore it... |
|
|||
108 | old_logfile = self.shell.logfile |
|
|||
109 | if logfname: |
|
|||
110 | logfname = os.path.expanduser(logfname) |
|
|||
111 | self.shell.logfile = logfname |
|
|||
112 |
|
||||
113 | loghead = '# IPython log file\n\n' |
|
|||
114 | try: |
|
|||
115 | logger.logstart(logfname, loghead, logmode, log_output, timestamp, |
|
|||
116 | log_raw_input) |
|
|||
117 | except: |
|
|||
118 | self.shell.logfile = old_logfile |
|
|||
119 | warn("Couldn't start log: %s" % sys.exc_info()[1]) |
|
|||
120 | else: |
|
|||
121 | # log input history up to this point, optionally interleaving |
|
|||
122 | # output if requested |
|
|||
123 |
|
||||
124 | if timestamp: |
|
|||
125 | # disable timestamping for the previous history, since we've |
|
|||
126 | # lost those already (no time machine here). |
|
|||
127 | logger.timestamp = False |
|
|||
128 |
|
||||
129 | if log_raw_input: |
|
|||
130 | input_hist = self.shell.history_manager.input_hist_raw |
|
|||
131 | else: |
|
|||
132 | input_hist = self.shell.history_manager.input_hist_parsed |
|
|||
133 |
|
||||
134 | if log_output: |
|
|||
135 | log_write = logger.log_write |
|
|||
136 | output_hist = self.shell.history_manager.output_hist |
|
|||
137 | for n in range(1,len(input_hist)-1): |
|
|||
138 | log_write(input_hist[n].rstrip() + '\n') |
|
|||
139 | if n in output_hist: |
|
|||
140 | log_write(repr(output_hist[n]),'output') |
|
|||
141 | else: |
|
|||
142 | logger.log_write('\n'.join(input_hist[1:])) |
|
|||
143 | logger.log_write('\n') |
|
|||
144 | if timestamp: |
|
|||
145 | # re-enable timestamping |
|
|||
146 | logger.timestamp = True |
|
|||
147 |
|
||||
148 | print ('Activating auto-logging. ' |
|
|||
149 | 'Current session state plus future input saved.') |
|
|||
150 | logger.logstate() |
|
|||
151 |
|
||||
152 | @line_magic |
|
|||
153 | def logstop(self, parameter_s=''): |
|
|||
154 | """Fully stop logging and close log file. |
|
|||
155 |
|
||||
156 | In order to start logging again, a new %logstart call needs to be made, |
|
|||
157 | possibly (though not necessarily) with a new filename, mode and other |
|
|||
158 | options.""" |
|
|||
159 | self.logger.logstop() |
|
|||
160 |
|
||||
161 | @line_magic |
|
|||
162 | def logoff(self, parameter_s=''): |
|
|||
163 | """Temporarily stop logging. |
|
|||
164 |
|
||||
165 | You must have previously started logging.""" |
|
|||
166 | self.shell.logger.switch_log(0) |
|
|||
167 |
|
||||
168 | @line_magic |
|
|||
169 | def logon(self, parameter_s=''): |
|
|||
170 | """Restart logging. |
|
|||
171 |
|
||||
172 | This function is for restarting logging which you've temporarily |
|
|||
173 | stopped with %logoff. For starting logging for the first time, you |
|
|||
174 | must use the %logstart function, which allows you to specify an |
|
|||
175 | optional log filename.""" |
|
|||
176 |
|
||||
177 | self.shell.logger.switch_log(1) |
|
|||
178 |
|
||||
179 | @line_magic |
|
|||
180 | def logstate(self, parameter_s=''): |
|
|||
181 | """Print the status of the logging system.""" |
|
|||
182 |
|
||||
183 | self.shell.logger.logstate() |
|
|||
184 |
|
||||
185 |
|
||||
186 | @register_magics |
|
|||
187 | class ExtensionsMagics(Magics): |
|
30 | class ExtensionsMagics(Magics): | |
188 | """Magics to manage the IPython extensions system.""" |
|
31 | """Magics to manage the IPython extensions system.""" | |
189 |
|
32 |
@@ -12,13 +12,14 b'' | |||||
12 | # Imports |
|
12 | # Imports | |
13 | #----------------------------------------------------------------------------- |
|
13 | #----------------------------------------------------------------------------- | |
14 |
|
14 | |||
15 |
from |
|
15 | from ..magic import Magics, register_magics | |
16 | from .auto import AutoMagics |
|
16 | from .auto import AutoMagics | |
17 | from .basic import BasicMagics |
|
17 | from .basic import BasicMagics | |
18 | from .code import CodeMagics, MacroToEdit |
|
18 | from .code import CodeMagics, MacroToEdit | |
19 | from .config import ConfigMagics |
|
19 | from .config import ConfigMagics | |
20 | from .execution import ExecutionMagics |
|
20 | from .execution import ExecutionMagics | |
21 | from .history import HistoryMagics |
|
21 | from .history import HistoryMagics | |
|
22 | from .logging import LoggingMagics | |||
22 | from .namespace import NamespaceMagics |
|
23 | from .namespace import NamespaceMagics | |
23 | from .osm import OSMagics |
|
24 | from .osm import OSMagics | |
24 |
|
25 |
General Comments 0
You need to be logged in to leave comments.
Login now