When an instance of
Interpreter class is created, an associated instance of
History is also loaded automatically. This class offers the ability to track
user Tcl call history with time stamp information. In addition, the
class offers users to mark the beginning and end of important events as
separate history queues, with filters that looks for particular Tcl calls. This
can be very effective when used to debug what-went-wrong during Python-Tcl
# Example # ------- # # how history is tracked and read from pyats.tcl import Interpreter, History tcl = Interpreter() # note the history attribute assert type(tcl.history) is History # make some tcl calls tcl.eval('set testVar 1') tcl.eval('set testVar 2') # let's take a look at the history tcl.history.filter() # output: # deque( # [<HistoryEntry '2014-06-04T23:30:12.939354: set testVar 1' at ...>, # <HistoryEntry '2014-06-04T23:30:18.665275: set testVar 2' at ...>, # maxlen=9999]) # print it in a more usable fashion: for i in tcl.history.filter(): print(i.timestamp, '-', i.api) # output: # 2014-06-04 23:30:12.939354 - set testVar 1 # 2014-06-04 23:30:18.665275 - set testVar 2
How It Works¶
History is stored as a first-in-last-out queue with a maximum limit. Each time
the user makes a call to
eval, it is added to the history with the current
timestamp. When the max queue is reached, the earliest historical entry is
deleted to save from ever-growing memory usage.
Each historical event is saved as a
HistoryEntry object. Each of these
timestamp being the time when the API was called
api being the Tcl command itself.
The default max limit for the queue is 9999. This can be altered if user
manually replace the
history attribute of the an
with a new one with bigger queue:
# continuing from above... # replace the history tracker with a new, bigger one tcl.history = History(max_history = 15000) # note that this deletes all historical event up until now tcl.history # output: # deque(, maxlen=15000)
the API may be multi-line if multiple semi-colon
; separated Tcl
commands were evaluated in the same
filter API returns by default the last 20 historical events for better
viewing. Use this API to return an iterable history list. You can also use it
to only filter calls that match a particular regular expression.
# continuing from above (but assuming we didn't reset the history) tcl.history.filter(regex = 'testVar 1') # output: # [<HistoryEntry '2014-06-04T23:30:12.939354: set testVar 1' at ...>]
Consider markers as separate history queues that can be used to mark and store important events. Eg: start at the beginning of a testcase and end of it, in order to give users full picture of what Tcl commands were called within that testcase.
By default, all history is appended to the master queue. This queue is always updated with each Tcl call. When a new marker is started, all subsequent Tcl calls are saved to both the new marker and the master queue, until stopped. There may be an indefinite number of markers active (limited by CPU/memory of course).
Consider the master queue as a broad picture into everything, with the individual marker queues as a snapshot of a particular time/event.
# Example # ------- # # showing how markers work from pyats import tcl # run some Tcl code tcl.eval('set test 1') # create a new marker tcl.history.start_marker('testMarker') # run code under new marker tcl.eval('set a 1') # now create another marker tcl.history.start_marker('testMarker2') # run code under new marker as well tcl.eval('set b 2') # stop the markers tcl.history.end_marker('testMarker') tcl.history.end_marker('testMarker2') # run more code tcl.eval('set c 3') # now let's see history vs marker behavior # all calls are in the master (default) marker tcl.history.filter() # output: # [<HistoryEntry '2014-08-19T14:17:57.697085: set test 1' at ...>, # <HistoryEntry '2014-08-19T14:18:12.505794: set a 1' at ...>, # <HistoryEntry '2014-08-19T14:18:29.150347: set b 2' at ...>, # <HistoryEntry '2014-08-19T14:18:52.338709: set c 3' at ...>] # 'testMarker' only has 1 calls tcl.history.filter(marker='testMarker') # output: # [<HistoryEntry '2014-08-19T14:18:12.505794: set a 1' at ...>, # <HistoryEntry '2014-08-19T14:18:29.150347: set b 2' at ...>] # 'testMarker2' only contains 1 call tcl.history.filter(marker='testMarker2') # output: # [<HistoryEntry '2014-08-19T14:18:29.150347: set b 2' at ...>]
Marker usage is pretty much trivial. For detailed usage to the API, refer to the API documentation.