History Logging
(NOTE: Some of the techniques shown or described on this page--marked in purple--require new features in the latest official PIKT 1.19.0 release (pikt-current.tar.gz) that are unavailable in any previous version.)
The Pikt script language features variable persistence: PIKT can remember values and recall them from one script run to the next.
For the variable $foo (or #foo), you reference its previous value as %foo. (Don't confuse this with , which references the value tied to the preceding input line.)
Not every value is remembered. Only variables referenced in their preceding form get remembered. So, for example, if a script employs the variables $a, $b, $c, #x, #y, and #z, but only %b, %y, and %z are referenced in the script, only those values will be logged. In the example, if you revise your script now also to reference %c, the next time the script runs it will have values for %b, %y, and %z, but %c won't be available until the subsequent script run.
% references within rules tie a value to the current input line, so long as you specify a lookup key. That is to say, for example, suppose you have the following (useless, toy) script:
Useless init input proc "=dfl | =behead(1)" =dfdata keys $fsname begin set #x = 0 set #y = #weekday(#now()) set #z = #hour(#now()) rule if #cap > %cap set #x += 1 endif rule set #x *= 2 end if %y == 1 && #z == 12 && #x > %x output mail "for $fsname, cap is $text(#cap), was $text(%cap)" endifSuppose, too, that the last time the alarm script was run the df output was as follows:
/dev/dsk/c0t3d0s0 23063 16865 3898 82% / [line 1] /dev/dsk/c0t3d0s6 210895 198988 0 100% /usr [line 2] /dev/dsk/c0t3d0s3 30991 13439 14462 49% /var [line 3] /dev/dsk/c0t3d0s4 61639 45724 9755 83% /opt [line 4] /dev/dsk/c0t2d0s2 1050367 290966 706886 30% /export/home [line 5]And the current df output is:
/dev/dsk/c0t3d0s0 23063 16865 3898 82% / [line 1] /dev/dsk/c0t3d0s6 210895 198988 0 100% /usr [line 2] /dev/dsk/c0t3d0s3 30991 14344 13557 52% /var [line 3] /dev/dsk/c0t3d0s4 61639 45724 9755 83% /opt [line 4] /dev/dsk/c0t2d0s2 1050367 342223 655629 35% /export/home [line 5]For the first input line of the current script run, #cap is 82%, and %cap is also 82%, both keyed on the $fsname /dev/dsk/c0t3d0s0. For the second input line, #cap is 100%, as is %cap. For the third input line, #cap is 52%, %cap is 49%. And so on.
#x increments during input process whenever #cap exceeds %cap, which happens twice, in lines 3 and 5. It also doubles in value for every input line. Suppose that this script was run on a Tuesday, so #y is 3. #z is set at the script beginning to the current hour.
Here is a complete accounting of what will be logged in the history file (found in =piktdir/var/histories) for possible referencing during the next script run:
/dev/dsk/c0t3d0s0 [$fsname for line 1] 82% [#cap for line 1] 0 [#x for line 1] /dev/dsk/c0t3d0s6 [$fsname for line 2] 100% [#cap for line 2] 0 [#x for line 2] /dev/dsk/c0t3d0s3 [$fsname for line 3] 52% [#cap for line 3] 2 [#x for line 3] /dev/dsk/c0t3d0s4 [$fsname for line 4] 83% [#cap for line 4] 4 [#x for line 4] /dev/dsk/c0t3d0s2 [$fsname for line 5] 35% [#cap for line 5] 10 [#x for line 5] 10 [#x at the end] 3 [#y at the end]The $fsname values are logged, because even though %fsname is not referenced, $fsname is the required lookup key. #cap values are logged, because %cap is referenced in the script, but only within rules. In the end section, #cap is not logged, because there is no current input line to associate it with (we are finished with input).
#x is logged, because of the %x reference, and logged six times, because it has a particular value tied to each of the five input lines, and because its value persists after the end of input processing (after the last rule). #y is referenced as %y, and is invariant through any input processing, so is logged just once, at the end. The value of #z is not logged, because %z is not referenced in the script. (Nor are any of the other variables in =dfdata.)
The rules for history logging are:
- If it is a key variable, whether or not referenced in its history form, its values are logged.
- If it is referenced in its history (%) form, its value(s) is (are) logged.
- If it is a dat variable (specified in the init section), its value is logged, once for every input line. For any given input line, the dat values for that line are invariant (cannot be changed by set statements).
- If it is a non-dat variable set within any rule, hence within the input processing loop, its terminal value is logged, once for every input line. "Terminal value" here means the value at the end of the final rule section (after no matter how many set statements appearing within the rule sections).
- If it is a non-dat variable, its terminal value (here meaning the value at script conclusion) is logged.
Note that only history-referenced dat values require the specification of one or more key variables. If a script makes history reference only to non-dat variables, no key variables need be specified.
From one script run to the next, input lines, and their associated key values, may drop out or get added. If they drop out, their values are not logged. (In the example above, if /dev/dsk/c0t2d0s2 were to disappear, its dat values $fsname and #cap and and its #x value would not be logged.) Moreover, their history values may not be referenced. (If /dev/dsk/c0t2d0s2 were to disappear from input, the associated %cap and %x for that device could no longer be referenced.) If an input line is added (say /export/home were moved to /dev/dsk/c0t1d0s2), its values are logged, but the newly logged values cannot be referenced until the subsequent script run.
Also from one script run to the next, you might add or drop variables, change a variable's data type from, say, string ($) to number (#), change a variable from a scalar to an array (e.g., $foo becomes $foo[]), change its position within the script in a way that impacts on history logging, etc. If Pikt detects critical changes in the script, the history mechanism is suspended for the current script run: you may not reference % values, but current values are logged for recall during the next script run. Pikt takes a conservative, cautious approach toward such changes. Sometimes, if you make too many changes, the history recall mechanism can get confused, and your script will abort. You will know about these failures by periodically reviewing (via another Pikt script) the alarm logs. If this happens, the best recourse is to delete the blocking history file (in =piktdir/var/histories), after which there shouldn't be any more problems.
PIKT retains history info in script quit situations. For example, if a script is in the middle of processing new logfile input when it encounters a 'quit' (or 'die') statement, PIKT will keep the old history data. So, suppose a script begins input processing at line 500 in a 600 line log file. At line 550, say, the script quits for some reason. The next time the script runs, it will again begin input processing at line 500 (and not at the very beginning of the log file). In other words, whenever a Pikt script terminates prematurely, the history (.hst) file is not updated with values from the current, aborted script run; the old history file and all values therein are held over and recalled the next time around.
prev page | 1st page | next page |