# $Header: diskio.tcl 30-mar-99.06:39:33 dholail Exp $
#
# copyright (c) 1999 by the Oracle Corporation
#
# NAME:
#
#  diskio.tcl : Event tcl file that checks if the disk i/o rate (blocks/sec)
#               has exceeded its threshold.
#
# ARGUMENTS:
#           argv(0) == no of occurrance
#           argv(1) == threshold value for alert
#           argv(2) == threshold value for warning
#
# RETURN:
#           $SCRIPT_FAIL or
#           $CLEAR_EVENT or
#           $NO_EVENT or
#           $WARNING_EVENT or
#           $ALERT_EVENT
#
# OUTPUT:
#           the current disk i/o rate
#
# $Log:  $
# Revision 1.10 1998/02/12  groyal
# improved error messages issued for script evaluation failures

# Revision 1.9  1996/06/24  23:54:31  yliu
# fixed bug 370148
#
# Revision 1.8  1996/02/07  01:48:12  yliu
# use character set conversion
#
# Revision 1.7  1996/01/10  01:32:57  yliu
# use message file
#
# Revision 1.6  1995/10/25 01:29:08  yliu
# add connect string to the parameter list
#
# Revision 1.5  1995/10/18  22:37:00  yliu
# moved the init code into EvalEvent
#
# Revision 1.4  1995/10/10  23:32:17  yliu
# added no of occurrence
#

# Event definition

oradefine event /oracle/rdbms/perf/diskio description=VOC-01141 \
report=VOC-01142
oraarguments connect_str no_occurrence alert_threshold warning_threshold
oravardesc connect_str oracle_signon
oravardesc no_occurrence unsigned default=3 message=VOC-01143
oravardesc alert_threshold unsigned message=VOC-01144
oravardesc warning_threshold unsigned message=VOC-01145
oraresults current
oravardesc current unsigned
oradefine end


# Initialize global variables
#comment out to fix bug#606739
#set last_report $CLEAR_EVENT
set output ""
set no_occurrence 0
set initial 1
set prev_second 0
set prev_reads 0
set prev_writes 0


# The main event checking functions
proc EvalEvent {} {


    # Declare globals we will use
    global argv last_report output no_occurrence initial
    global SCRIPT_FAIL CLEAR_EVENT NO_EVENT WARNING_EVENT ALERT_EVENT
    global oramsg prev_second prev_reads prev_writes


    # initialize the return code and output
    set ret_code $CLEAR_EVENT
    set output ""
    set err ""

    # get the current values and time
    if {[catch {set curr_second [oraclock]} err]} {
	lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {[catch {set curr_reads [lindex [oradbsnmp get \
        oraDbSysPhysReads.$oramsg(oraindex)] 1]} err]} {
	lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    if {[catch {set curr_writes [lindex [oradbsnmp get \
        oraDbSysPhysWrites.$oramsg(oraindex)] 1]} err]} {
	lappend output $err
        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }

    # During initialization, copy current values to previous values
    if {$initial == 1} {
        set prev_second $curr_second
        set prev_reads $curr_reads
        set prev_writes $curr_writes
        set initial 0
        return $NO_EVENT
    }


    # Calculate disk i/o rate
    set duration [expr $curr_second - $prev_second]
    set delta_reads [expr $curr_reads - $prev_reads]
    set delta_writes [expr $curr_writes - $prev_writes]

    if { $duration < 0 || $duration == 0 } {
        lappend output [format [msgtxt [NETWORK] nms 1005] "diskio.tcl"]  
        lappend output [msgtxt [NETWORK] nms 1081]

        ORATCL_DEBUG "diskio : $oramsg(oraobject) : [oratime] : invalid duration : $duration" 

        if {$last_report == $SCRIPT_FAIL} {
            return $NO_EVENT
        } else {
            set last_report $SCRIPT_FAIL
            return $SCRIPT_FAIL
        }
    }


    # deal with rollovers
    if { ($delta_reads < 0) || ($delta_writes < 0) } {
        ORATCL_DEBUG "diskio : $oramsg(oraobject) : [oratime] : rollover : $delta_reads,$delta_writes"
        return $NO_EVENT
    }

    set rate [divide [expr $delta_reads + $delta_writes] $duration]

    set prev_second $curr_second
    set prev_reads $curr_reads
    set prev_writes $curr_writes


    # print out event trace info 
    ORATCL_DEBUG "diskio : $oramsg(oraobject) : [oratime] : [expr $delta_reads + $delta_writes],$rate"


    # Check for alert and warning threshold
    if {$rate > [lindex $argv 2]} {
        if {$no_occurrence < [expr [lindex $argv 1]-1]} {
            incr no_occurrence
        } else {
            set ret_code $ALERT_EVENT
            set output $rate
        }
    } elseif {$rate > [lindex $argv 3]} {
        if {$no_occurrence < [expr [lindex $argv 1]-1]} {
            incr no_occurrence
        } else {
            set ret_code $WARNING_EVENT
            set output $rate
        }
    } else {
        set no_occurrence 0
    } 

    
    # return
    if {$last_report == $ret_code} {
        return $NO_EVENT
    } else {
        ORATCL_DEBUG "diskio : $oramsg(oraobject) : [oratime] : MESSAGE - $ret_code, $output"
        set last_report $ret_code
        return $ret_code 
    }
}

