global my_sock
global my_data
proc Listener {port action} {
global my_sock
if {$action == "START"} {
set my_sock [socket -server on_connect $port]
} else {
if {[info exists my_sock]} {
puts "Closing my socket"
close $my_sock
}
}
return $my_sock
}
proc on_connect {newsock clientAddress clientPort} {
puts "socket is connected now"
fconfigure $newsock -blocking 0
fileevent $newsock readable [list handleInput $newsock]
}
proc handleInput {f} {
global my_data
if {[eof $f]} {
fileevent $f readable {}
close $f
return
}
set my_data [read -nonewline $f]
regsub -all {<[0-9]+>[0-9]+: } $my_data " " output
if {[string length $output]} {
puts stdout "$output"
}
}
Listener 9500 START
vwait my_sock
save the file to the router that will run the script:
TCLRouter#copy tftp: flash:
Address or name of remote host [142.100.64.100]?
Source filename [syslogd_book.tcl]?
Destination filename [syslogd_book.tcl]?
%Warning:There is a file already existing with this name
Do you want to over write? [confirm]
Accessing tftp://142.100.64.100/syslogd_book.tcl...
Erase flash: before copying? [confirm]
TCLRouter#dir
Directory of flash:/
1 -rw- 757 <no date> syslogd_book.tcl
run the script on the router:
TCLRouter#tclsh flash:syslogd_book.tcl
On R2, type syslog command to save logs to the router that is running the script via tcp port 9500:
R2: logging host 12.12.12.1 transport tcp port 9500
will see the router is recording logs from R2:
TCLRouter#tclsh flash:syslogd_book.tcl
socket is connected now
*Mar 1 00:26:51.763: %LINK-5-CHANGED: Interface Loopback1, changed state to administratively down
*Mar 1 00:26:53.939: %LINK-3-UPDOWN: Interface Loopback1, changed state to up *Mar 1 00:26:54.939: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback1, changed state to up *Mar 1 00:26:57.851: %SYS-6-LOGGINGHOST_STARTSTOP: Logging to host 12.12.12.1 started - reconnection
*Mar 1 00:26:57.867: %LINK-5-CHANGED: Interface Loopback1, changed state to administratively down
*Mar 1 00:26:58.867: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback1, changed state to down
*Mar 1 00:34:26.835: %SYS-5-CONFIG_I: Configured from console by console
Another example explains the question you may be wondering how to store sys logs received from R2 into a file.
code:
global my_sock
global my_data
global my_mode
global my_file
proc Listener {port action filename} {
global my_sock
global my_file
global my_mode
set my_mode 0
if {$action == "START"} {
set my_sock [socket -server on_connect $port]
set my_mode 1
} elseif {$action == "STARTWriting"} {
set my_sock [socket -server on_connect $port]
set my_file [open $filename WRONLY]
set my_mode 2
} else {
if {[info exists my_sock]} {
puts "Closing my socket"
close $my_sock
}
}
return $my_sock
}
if {[info exists my_file]} {
#if the socket is really there, close it
puts "Closing my file"
close $my_file
}
proc on_connect {newsock clientAddress clientPort} {
puts "socket is connected now"
fconfigure $newsock -blocking 0
fileevent $newsock readable [list handleInput $newsock]
}
proc handleInput {f} {
global my_data
global my_file
global my_mode
if {[eof $f]} {
fileevent $f readable {}
close $f
return
}
set my_data [read -nonewline $f]
regsub -all {<[0-9]+>[0-9]+: } $my_data " " output
if {[string length $output]} {
puts stdout "$output"
if {[expr ($my_mode == 2)]} {
puts $my_file $output
}
}
}
###################################
#check if input any
if {$argc == 0} {
puts "Usage: syslogd port filename"
puts "port is the TCP port to listing for incoming connection"
puts "filename is optional parameter to use for writing the syslog data"
return
}
set port [lindex $argv 0]
#check if input a port number
if {[expr (1 != [string is digit $port])]} {
puts "must provide a numeric port number"
return
}
#verify port is in the valid range
if ([expr (1 != (0 < $port))]) {
puts "port number too low"
return
}
#verify port is in the valid range
if ([expr (1 != ($port < 65536))]) {
puts "port number too high"
return
}
if {$argc == 1} {
#only provide port
Listener $port START 0
} elseif {$argc == 2} {
#save filename
set my_filename [lindex $argv 1]
#varify inputs
Listener $port STARTWriting $my_filename
} else {
puts "Usage: syslogd port filename"
puts "port is the TCP port to listing for incoming connection"
puts "filename is optional parameter to use for writing the syslog data"
return
}
exec "term esc 27"
vwait my_sock
run the script on TCLrouter:
TCLRouter#tclsh flash:syslogd_book2.tcl 9500 flash:syslog.txt
socket is connected now
*Mar 1 00:17:52.487: %LINK-3-UPDOWN: Interface Loopback0, changed state to up
*Mar 1 00:17:55.239: %LINK-5-CHANGED: Interface Loopback0, changed state to a
ministratively down
*Mar 1 00:18:03.739: %SYS-6-LOGGINGHOST_STARTSTOP: Logging to host 12.12.12.1
started - CLI initiated
on R2, cancel recording logs to TCLrouter
r2(config)#no logging host 12.12.12.1 transport tcp port 9500
simultaneously, script will stop.
TCLRouter#
Connection to host lost.
a file was generated by the script
TCLRouter(tcl)#dir
Directory of flash:/
1 -rw- 2258 <no date> syslogd_book2.tcl
2 -rw- 308 <no date> syslog.txt
check the file with logs
TCLRouter(tcl)#more flash:syslog.txt
*Mar 1 00:17:52.487: %LINK-3-UPDOWN: Interface Loopback0, changed state to up
*Mar 1 00:17:55.239: %LINK-5-CHANGED: Interface Loopback0, changed state to administratively down
*Mar 1 00:18:03.739: %SYS-6-LOGGINGHOST_STARTSTOP: Logging to host 12.12.12.1 started - CLI initiated
On sender router, you may want to filter some kinds of syslog by using this code:
if [string match "*by console" $::orig_msg] {
return ""
} else {
return $::orig_msg
}
this code is used for filtering the syslog generated after exiting configuration mode.
logging console filtered
logging filter flash:filter3.tcl
you may also want to customize syslog by using tcl script. here is the code:
set text $::format_string
set listp 0
while {$listp < [llength $::msg_args]} {
set beg [string first %s $text]
set end $beg
incr end
set text [string replace $text $beg $end [lindex $msg_args $listp]]
incr listp
}
return "$buginfseq$timestamp: %$facility-$severity-$mnemonic: $text"
save it as filter7.tcl, setup global configurations for "timestamp" and "sequence number"
service timestamps log datetime
service sequence-numbers
exit configuration mode. syslog is displayed as follows:
sender#000077: *Mar 1 03:02:26: SYS-5-CONFIG_I: Configured from console by console
No comments:
Post a Comment