mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-10-31 02:38:03 +00:00 
			
		
		
		
	firemod: Fix stats gathering bugs, allow reading data from text file.
The stats gathering thing might introduce other bugs, but at least it seems to work better than before. The old regex logic was too complex for me to follow.
This commit is contained in:
		
							
								
								
									
										139
									
								
								lf_firemod.pl
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								lf_firemod.pl
									
									
									
									
									
								
							| @@ -35,7 +35,7 @@ our $endp_name        = ""; | ||||
| our $endp_cmd         = ""; | ||||
| our $port_name        = ""; | ||||
| our $speed            = "-1"; | ||||
| our $action           = "show_port"; | ||||
| our $action           = ""; | ||||
| our $do_cmd           = "NA"; | ||||
| our $lfmgr_host       = "localhost"; | ||||
| our $lfmgr_port       = 4001; | ||||
| @@ -63,6 +63,7 @@ our $cx_endps        = ""; | ||||
| our $list_cx_name    = "all"; | ||||
| our $test_mgr        = "default_tm"; | ||||
| our $list_test_mgr   = "all"; | ||||
| our $stats_from_file = ""; | ||||
|  | ||||
| our $fail_msg         = ""; | ||||
| our $manual_check     = 0; | ||||
| @@ -86,6 +87,9 @@ our $usage = "$0  --action { list_ports | show_port | ||||
|       # Special Keys: | ||||
|       #  --endp_vals tx_bps         (Tx Bytes) | ||||
|       #  --endp_vals rx_bps         (Rx Bytes) | ||||
|   [--stats_from_file [file-name] | ||||
|       # Read 'show-endp' ouput from a file instead of direct query from LANforge. | ||||
|       # This can save a lot of time if we already have the output available. | ||||
|   [--mgr       {host-name | IP}] | ||||
|   [--mgr_port  {ip port}] | ||||
|   [--cmd       {lf-cli-command text}] | ||||
| @@ -165,9 +169,10 @@ GetOptions | ||||
|    'endp_name|e=s' => \$::endp_name, | ||||
|    'endp_cmd=s'    => \$::endp_cmd, | ||||
|    'endp_vals|o=s' => \$::endp_vals, | ||||
|    'stats_from_file=s' => \$::stats_from_file, | ||||
|    'action|a=s'    => \$::action, | ||||
|    'cmd|c=s'       => \$::do_cmd, | ||||
|    'mgr|m=s'       => \$::lfmgr_host, | ||||
|    'manager|mgr|m=s'       => \$::lfmgr_host, | ||||
|    'mgr_port|p=i'  => \$::lfmgr_port, | ||||
|    'resource|r=i'  => \$::resource, | ||||
|    'port_name=s'   => \$::port_name, | ||||
| @@ -223,6 +228,10 @@ if ($::do_cmd ne "NA") { | ||||
| our @valid_actions = split(/,/, "show_endp,set_endp,start_endp,stop_endp,delete_endp,create_endp,create_arm," | ||||
|        ."show_port,do_cmd,list_ports,list_endp,create_cx,list_cx,show_cx,delete_cx,delete_cxe" ); | ||||
|  | ||||
| if (($::action eq "") && ((defined $::endp_vals) && ("$::endp_vals" ne ""))) { | ||||
|   $::action = "show_endp"; | ||||
| } | ||||
|  | ||||
| if (! (grep {$_ eq $::action} @::valid_actions )) { | ||||
|   die("Invalid action: $::action\n$::usage\n"); | ||||
| } | ||||
| @@ -238,8 +247,11 @@ if ($::quiet eq "1" ) { | ||||
| } | ||||
| # Open connection to the LANforge server. | ||||
|  | ||||
| my $t = undef; | ||||
|  | ||||
| if ($stats_from_file eq "") { | ||||
|   # Wait up to 60 seconds when requesting info from LANforge. | ||||
| my $t = new Net::Telnet(Prompt => '/default\@btbits\>\>/', | ||||
|   $t = new Net::Telnet(Prompt => '/default\@btbits\>\>/', | ||||
| 		       Timeout => 60); | ||||
|  | ||||
|   $t->open(Host    => $::lfmgr_host, | ||||
| @@ -266,6 +278,7 @@ else { | ||||
|     $::utils->cli_rcv_silent(0);  # Show output from telnet | ||||
|   } | ||||
|   $::utils->log_cli("# $0 ".`date "+%Y-%m-%d %H:%M:%S"`); | ||||
| } | ||||
|  | ||||
| if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm,list_endp")) { | ||||
| 	$::max_speed = $::speed if( $::max_speed eq "-1"); | ||||
| @@ -315,7 +328,14 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|          # options are reformatted | ||||
|  | ||||
|          my $i; | ||||
|          my @lines         = split(NL, $::utils->doAsyncCmd("nc_show_endp $endp_name")); | ||||
| 	 my @lines = (); | ||||
| 	 if ($stats_from_file ne "") { | ||||
| 	   @lines = split(NL, get_stats_from_file($stats_from_file, $endp_name)); | ||||
| 	 } | ||||
|          else { | ||||
| 	   @lines = split(NL, $::utils->doAsyncCmd("nc_show_endp $endp_name")); | ||||
| 	 } | ||||
|  | ||||
|          for($i=0; $i<@lines; $i++) { | ||||
|             $lines[$i] = $lines[$i]." #"; | ||||
|          } | ||||
| @@ -323,12 +343,12 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|          my @parts; | ||||
|          my @matches       = grep( /$matcher/, @lines); | ||||
|          my $match; | ||||
|          #print "MATCHER $matcher".NL; | ||||
|          #print "MATCHER $matcher  matches:\n" . join("\n", @matches) . NL; | ||||
|          for my $end_val (split(',', $::endp_vals)) { | ||||
|             my $endval_done = 0; | ||||
|             for $match (@matches) { | ||||
|                last if ($endval_done); | ||||
|                #print "\nM: $end_val> $match\n"; | ||||
|                #print "\nMatch-line: $end_val> $match\n"; | ||||
|  | ||||
|                # no value between colon separated tags can be very | ||||
|                # confusing to parse, let's force a dumb value in if we find that | ||||
| @@ -343,7 +363,7 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                if (  $match =~ /Rx (Bytes|Pkts)/ && $end_val =~ /rx_/) { | ||||
|                   my $value = 0; | ||||
|                   ($option) = ($match =~ /(Rx (Bytes|Pkts))/); | ||||
|                   #print "Option: $option".NL; | ||||
|                   #print "# case 1, Option: $option" . NL; | ||||
|                   @parts      = ($match =~ m{ Total: (\d+) +Time: \d+s\s+ Cur: (\d+) +(\d+)\/s \#$}); | ||||
|                   #print "\n RX: ".join(",",@parts)."\n"; | ||||
|                   if ( defined $option_map{ $option } ) { | ||||
| @@ -366,6 +386,7 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                } | ||||
|                elsif (  $match =~ /Cx Detected/) { | ||||
|                   my $value = 0; | ||||
|                   #print "# case 2\n"; | ||||
|                   ($option) = ($match =~ /(Cx Detected)/); | ||||
|                   if ( defined $option_map{ $option } ) { | ||||
|                      $value = 0 + ($match =~ /:\s+(\d+)/)[0]; | ||||
| @@ -377,7 +398,7 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                elsif (  $match =~ /Tx (Bytes|Pkts)/ && $end_val =~ /tx_/) { | ||||
|                   my $value = 0; | ||||
|                   ($option) = ($match =~ /(Tx (Bytes|Pkts))/); | ||||
|                   #print "Option: $option".NL; | ||||
|                   #print "# case 3, Option: $option" . NL; | ||||
|                   @parts      = ($match =~ m{ Total: (\d+) +Time: \d+s\s+ Cur: (\d+) +(\d+)\/s \#$}); | ||||
|                   #print "\n TX: ".join(",",@parts)."\n"; | ||||
|                   if ( defined $option_map{ $option } ) { | ||||
| @@ -403,7 +424,7 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                   my $value = 0; | ||||
|                   ($option) = ($match =~ /([TR][Xx] (((OOO|Duplicate|Failed) (Bytes|Pkts))|Wrong Dev|CRC Failed|Bit Errors|Dropped)|Conn (Established|Timeouts)|TCP Retransmits)/); | ||||
|                   @parts      = $match =~ m{ Total: (\d+) +Time: \d+s\s+ Cur: (\d+) +(\d+)\/s \#$}; | ||||
|                   #print "\n TX: ".join(",",@parts)."\n"; | ||||
|                   #print "\n# case 4 TX: ".join(",",@parts)."\n"; | ||||
|                   if ( defined $option_map{ $option } ) { | ||||
|                      #print "$match\n"; | ||||
|                      $match =~ s/""/ /g; | ||||
| @@ -415,6 +436,7 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                elsif (  $match =~ /(Bytes|Packets) (Rcvd|Transmitted)/ ) { | ||||
|                   ($option) = ($match =~ /((Bytes|Packets) (Rcvd|Transmitted))/); | ||||
|                   @parts      = ($match =~ m{ Total: (\d+) +Time: \d+s\s+ Cur: (\d+) +(\d+)\/s \#$}); | ||||
|                   #print "\n# case 5 TX: ".join(",",@parts)."\n"; | ||||
|                   my $value = 0; | ||||
|                   if ( defined $option_map{ $option } ) { | ||||
|                      if ($end_val =~ /rx_(bps|pps)/ ) { | ||||
| @@ -436,6 +458,8 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                   } | ||||
|                } | ||||
|                else { | ||||
| 		  #print "Default case...\n"; | ||||
|  | ||||
|                   # special case | ||||
|                   $match =~ s/Shelf: (\d+), /Shelf: $1  / | ||||
|                      if ($match =~ /^\s*Shelf:/ ); | ||||
| @@ -458,25 +482,35 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|                      if ($match =~/CWND: (\d+) /); | ||||
|                   # ~specials | ||||
|  | ||||
|                   @parts         = ($match =~ m/( *[^ ]+):( *\S+ [^ #]*)(?! #|\S+:)/g); | ||||
|                   for (my $i=0; $i < @parts; $i+=2) { | ||||
|                      $option     = $parts[$i]; | ||||
|                      #print "     parts[$option] "; | ||||
|                      $option     =~ s/^\s*(.*)\s*$/$1/; | ||||
|                      if ( defined $option_map{ $option } ) { | ||||
|                         my $value = $parts[ $i + 1 ]; | ||||
|                         if ($value =~ /^\s*([^ ]+):\s+/) { | ||||
|                            $value   = "-"; | ||||
|                         } | ||||
|                         else { | ||||
|                            $value   =~ s/^\s*(.*)\s*$/$1/; | ||||
|                         } | ||||
|                         #print "\n      D end_val[$end_val] option[$option] now ".$value."\n"; | ||||
|                         $option_map{ $option } = $value; | ||||
| 		  #print "  match: $match\n"; | ||||
| 		  if ($match =~ /.*$end_val:\s+(\S+)/) { | ||||
| 		    my $value = $1; | ||||
| 		    #print " Found value: $value for key: $end_val\n"; | ||||
| 		    $option_map{ $end_val } = $value; | ||||
| 		    $endval_done++; | ||||
|                         last; | ||||
|                      } | ||||
| 		  } | ||||
|  | ||||
| 		  # This below just does not work right, for instance with L3 endp and these values:  RealRxRate,RealTxRate,MinTxRate | ||||
| 		  # --Ben | ||||
|                   #@parts         = ($match =~ m/( *[^ ]+):( *\S+ [^ #]*)(?! #|\S+:)/g); | ||||
|                   #for (my $i=0; $i < @parts; $i+=2) { | ||||
|                   #   $option     = $parts[$i]; | ||||
|                   #   $option     =~ s/^\s*(.*)\s*$/$1/;  # Trim whitespace | ||||
|                   #   print "     parts[$option] "; | ||||
|                   #   if ( defined $option_map{ $option } ) { | ||||
|                   #      my $value = $parts[ $i + 1 ]; | ||||
|                   #      if ($value =~ /^\s*([^ ]+):\s+/) { | ||||
|                   #         $value   = "-"; | ||||
|                   #      } | ||||
|                   #      else { | ||||
|                   #         $value   =~ s/^\s*(.*)\s*$/$1/; | ||||
|                   #      } | ||||
|                   #      #print "\n      D end_val[$end_val] option[$option] now ".$value."\n"; | ||||
|                   #      $option_map{ $option } = $value; | ||||
|                   #      $endval_done++; | ||||
|                   #      last; | ||||
|                   #   } | ||||
|                   #} | ||||
|                } | ||||
|             } # ~matches | ||||
|          } # ~endp_vals | ||||
| @@ -484,10 +518,15 @@ if (grep {$_ eq $::action} split(',', "show_endp,set_endp,create_endp,create_arm | ||||
|             print $option.": ".$option_map{ $option }.NL; | ||||
|          } | ||||
|       } | ||||
|       else { | ||||
| 	if ($stats_from_file ne "") { | ||||
| 	  print get_stats_from_file($stats_from_file, $endp_name); | ||||
| 	} | ||||
| 	else { | ||||
| 	  print $::utils->doAsyncCmd("nc_show_endp $::endp_name"); | ||||
| 	} | ||||
|       } | ||||
|    } | ||||
|    elsif ($::action eq "create_arm") { | ||||
|       die("Must choose packets per second: --arm_pps\n$::usage") | ||||
|          if (! defined $::arm_pps || $::arm_pps eq ""); | ||||
| @@ -745,3 +784,51 @@ else { | ||||
| } | ||||
|  | ||||
| exit(0); | ||||
|  | ||||
| sub get_stats_from_file { | ||||
|   my $fname = shift; | ||||
|   my $endp_name = shift; | ||||
|  | ||||
|   open(F, "<$fname") or die("Can't open $fname for reading: $!\n"); | ||||
|  | ||||
|   my $endp_text = ""; | ||||
|   my $ep = ""; | ||||
|  | ||||
|   my @lines = (); | ||||
|   while ( my $line = <F>) { | ||||
|     @lines = (@lines, $line); | ||||
|   } | ||||
|   # Append dummy line to make it easier to terminate the parse logic. | ||||
|   @lines = (@lines, "Endpoint [________] (NOT_RUNNING)\n"); | ||||
|  | ||||
|   my $i; | ||||
|   for ($i = 0; $i<@lines;$i++) { | ||||
|     my $line = $lines[$i]; | ||||
|     chomp($line); | ||||
|     if (($line =~ /Endpoint\s+\[(.*)\]/) || | ||||
| 	($line =~ /WanLink\s+\[(.*)\]/) || | ||||
| 	($line =~ /ArmEndp\s+\[(.*)\]/) || | ||||
| 	# TODO: Layer-4 ? | ||||
| 	($line =~ /VoipEndp\s+\[(.*)\]/)) { | ||||
|       my $m1 = $1; | ||||
|  | ||||
|       #print "Found starting line: $line  name: $m1  endp_name: $endp_name\n"; | ||||
|  | ||||
|       if ($endp_text ne "") { | ||||
| 	# See if existing endp entry matches? | ||||
| 	if ($ep eq $endp_name) { | ||||
| 	  return $endp_text; | ||||
| 	} | ||||
|       } | ||||
|  | ||||
|       $endp_text = "$line\n"; | ||||
|       $ep = $m1; | ||||
|     } | ||||
|     else { | ||||
|       if ($endp_text ne "") { | ||||
| 	$endp_text .= "$line\n"; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return ""; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ben Greear
					Ben Greear