From: <buc...@us...> - 2012-12-21 08:55:26
|
Revision: 238 http://devmon.svn.sourceforge.net/devmon/?rev=238&view=rev Author: buchanmilne Date: 2012-12-21 08:55:17 +0000 (Fri, 21 Dec 2012) Log Message: ----------- Add new MATCH transform Modified Paths: -------------- trunk/docs/TEMPLATES trunk/modules/dm_templates.pm trunk/modules/dm_tests.pm Modified: trunk/docs/TEMPLATES =================================================================== --- trunk/docs/TEMPLATES 2012-12-21 06:45:18 UTC (rev 237) +++ trunk/docs/TEMPLATES 2012-12-21 08:55:17 UTC (rev 238) @@ -423,7 +423,53 @@ do on the index value should be possible with existing transforms. + 'MATCH' transform: + In some badly designed MIBs multiple types of information are + presented in a single table with two columns (branches), often + in just a name, value format. This transform makes it possible + to split such a combined table out into separate tables, or to + reformat the table so that it has multiple columns. + + For example, the MIB for the TRIDIUM building management system + has a table with outputName and outputValue, data returned looks + as follows: + + TRIDIUM-MIB::outputName.1 = STRING: "I_Inc4_Freq" + TRIDIUM-MIB::outputName.2 = STRING: "I_Inc4_VaN" + TRIDIUM-MIB::outputName.3 = STRING: "I_Inc4_VbN" + TRIDIUM-MIB::outputName.4 = STRING: "I_Inc4_VcN" + ... + TRIDIUM-MIB::outputValue.1 = STRING: "50.06" + TRIDIUM-MIB::outputValue.2 = STRING: "232.91" + TRIDIUM-MIB::outputValue.3 = STRING: "233.39" + TRIDIUM-MIB::outputValue.4 = STRING: "233.98" + + To split the frequences out as a separate repeater, use: + outputFreqRow : MATCH : {outputName} /.*_Freq$/ + outputVaRow : MATCH : {outputName} /.*_VaN$/ + ... + + outputFreqRow will now contain the indexes of outputName that matched + the regular expression, e.g. 1,5,9 etc. , outputVaRow will contain + 2,6,10. To construct a table, use the chain transform to create + repeaters using the matched indexes: + outputFreq : CHAIN : {outputFreqRow} {outputValue} + outputVa : CHAIN : {outputVaRow} {outputValue} + ... + + To create the primary repeater for a table, we do the same on outputName: + IncomerRowName : CHAIN : {outputFreqRow} {outputName} + + In this case, it is preferable to clean up the outputFreq for display: + IncomerName : REGSUB : {IncomerRowName} /(.*)_Freq/$1/ + + A table created as follows: + Incomer|Frequency (Hz)|Voltage A|Voltage B|Voltage C + + Would now contain in its first row: + I_Inc4|50.06|232.91|233.39|233.98 + 'MATH' transform: The MATH transform performs a mathematical expression defined Modified: trunk/modules/dm_templates.pm =================================================================== --- trunk/modules/dm_templates.pm 2012-12-21 06:45:18 UTC (rev 237) +++ trunk/modules/dm_templates.pm 2012-12-21 08:55:17 UTC (rev 238) @@ -542,6 +542,14 @@ last CASE; }; + $func_type eq 'match' and do { + $temp =~ s/^\{\s*\S+?\s*\}\s*\/.+\/\s*$//g; + do_log("MATCH transform should be a perl regex match at " . + "$trans_file, line $l_num", 0) + and next LINE if $temp ne ''; + last CASE; + }; + $func_type eq 'math' and do { $temp =~ s/:\s*\d+\s*$//; $temp =~ s/\{\s*\S+?\s*\}|\s\.\s|\s+x\s+|\*|\+|\/|-|\^|%|\||&|\d+(\.\d*)?|\(|\)//g; Modified: trunk/modules/dm_tests.pm =================================================================== --- trunk/modules/dm_tests.pm 2012-12-21 06:45:18 UTC (rev 237) +++ trunk/modules/dm_tests.pm 2012-12-21 08:55:17 UTC (rev 238) @@ -1619,6 +1619,9 @@ my $oid_h = \%{$oids->{$oid}}; # Extract our parent oids from the expression, first my ($src_oid) = $oid_h->{'trans_data'} =~ /\{(.+?)\}/g; + my ($oidregex) = $oid_h->{'trans_data'} =~ s/\{(.+?)\}//g; + $oidregex =~ s/^\s*//; + $oidregex =~ s/\s*$//; validate_deps($device, $oids, $oid, [$src_oid], '.+') ; # Validate our dependencies, have to do them seperately @@ -1643,6 +1646,24 @@ # Skip if our source oid is freaky-deaky next if $oid_h->{'error'}{$leaf}; + # If we had a regex, skip this index if the value doesnt match + if ( $oidregex ne '' ) { + my $res; + my $val = $src_h->{'val'}{$leaf}; + do_log("Testing value $val from against $oidregex",0) if $g{'debug'}; + my $result = eval "\$res = \$val =~ m$oidregex"; + if($@) { + do_log("Failed eval for REGSUB transform on leaf $leaf of " . + "$oid on $device ($@)", 0); + $oid_h->{'val'}{$leaf} = 'Failed eval'; + $oid_h->{'time'}{$leaf} = time; + $oid_h->{'color'}{$leaf} = 'yellow'; + $oid_h->{'error'}{$leaf} = 1; + next; + } + next if $res; + } + # Our oid sub leaf # my $oid_idx = $src_h->{'val'}{$leaf}; @@ -1666,7 +1687,85 @@ } + # Extract names and values from simple tables ############################# + # Some MIBs just return a table of names and values, with rows that have + # different data, types, meanings, units etc. + # This operator allows the creation of new columns for rows where the name + # column matches the provided regex + sub trans_match { + my ($device, $oids, $oid, $thr) = @_; + my $oid_h = \%{$oids->{$oid}}; + # Extract our parent oids from the expression, first + my $trans_data = $oid_h->{'trans_data'}; + my ($src_oid, $expr) = ($1,$2) + if $trans_data =~ /^\{\s*(\S+?)\s*\}\s*(\/.+\/)\s*$/; + validate_deps($device, $oids, $oid, [$src_oid], '.+') ; + + # Validate our dependencies, have to do them seperately + # validate_deps($device, $oids, 'tmp', [$trg_oid]) or return; + # validate_deps($device, $oids, $oid, [$src_oid], '^\.?(\d+\.)?\d+$') + # or return; + do_log("Transforming $src_oid to $oid via match transform matching $expr",0) if $g{'debug'}; + + my $src_h = \%{$oids->{$src_oid}}; + + # This transform should probably only work for repeater sources + if(!$src_h->{'repeat'}) { + do_log("Trying to index a non-repeater source on $device ($@)", 0); + return; + } + + else { + # Tag the target as a repeater + $oid_h->{'repeat'} = 2; + my $idx = 0; + for my $leaf (sort { $a<=>$b} keys %{$src_h->{'val'}}) { + + # Skip if our source oid is freaky-deaky + next if $oid_h->{'error'}{$leaf}; + + my $res; + my $val = $src_h->{'val'}{$leaf}; + #do_log("Testing value $val from against $expr",0) if $g{'debug'}; + my $result = eval "\$res = \$val =~ m$expr"; + if($@) { + do_log("Failed eval for EXTRACT transform on leaf $leaf of " . + "$oid on $device ($@)", 0); + $oid_h->{'val'}{$leaf} = 'Failed eval'; + $oid_h->{'time'}{$leaf} = time; + $oid_h->{'color'}{$leaf} = 'yellow'; + $oid_h->{'error'}{$leaf} = 1; + next; + } + do_log("$val matched $expr, assigning new $idx from old row $leaf",0) if $g{'debug'} and $res; + next unless $res; + + # Our oid sub leaf + # my $oid_idx = $src_h->{'val'}{$leaf}; + + if(!defined $leaf) { + $oid_h->{'val'}{$leaf} = 'Target val missing - index'; + $oid_h->{'time'}{$leaf} = time; + $oid_h->{'color'}{$leaf} = 'yellow'; + $oid_h->{'error'}{$leaf} = 1; + next; + } + + $oid_h->{'val'}{$idx} = $leaf; + $oid_h->{'time'}{$idx} = $src_h->{'time'}{$leaf}; + $oid_h->{'color'}{$idx} = $src_h->{'color'}{$leaf}; + $oid_h->{'error'}{$idx} = $src_h->{'error'}{$leaf}; + $idx++; + } + + # Apply thresholds + apply_thresh_rep($oids, $thr, $oid); + } + + } + + # Create our outbound message ############################################## sub render_msg { my ($device, $tmpl, $test, $oids) = @_; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |