# $Header: bufcache.tcl 30-mar-99.03:15:47 dholail Exp $
#
# copyright (c) 1999 by the Oracle Corporation
#
# NAME:
#
#  bufcache.tcl : Event tcl file that checks if the buffer cache hit
#                 ratio is too low
#
# 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 buffer cache hit ratio.
#
# $Log:  $
# Revision 1.4  1995/10/18  22:55:51  yliu
# moved the init code into EvalEvent
#
# Revision 1.3  1995/10/10  23:25:48  yliu
# added no of occurrence
#
# Revision 1.2  1995/09/28  23:06:18  yliu
# use message file
#
# Revision 1.1  1995/09/14  22:59:49  yliu
# Initial revision
#

# Event definition
oradefine event /oracle/rdbms/perf/bufcache description=VOC-01111 \
report=VOC-01112
oraarguments no_occurrence alert_threshold warning_threshold
oravardesc no_occurrence unsigned default=3 message=VOC-01113
oravardesc alert_threshold number minimum=0 maximum=100 default=70 message=VOC-01114
oravardesc warning_threshold number minimum=0 maximum=100 default=80 message=VOC-01115
oraresults ratio
oravardesc ratio number
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_values(consistent_gets) 0
set prev_values(block_gets) 0
set prev_values(physical_reads) 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_values


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

    # get current values
    if {[catch {set curr_values(consistent_gets) [lindex [oradbsnmp get \
        oraDbSysConsistentGets.$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_values(block_gets) [lindex [oradbsnmp get \
        oraDbSysDbBlockGets.$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_values(physical_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
        }
    }

    # During initialization, copy current values to previous values
    if {$initial == 1} {
        foreach att_name [array names curr_values] {
            set prev_values($att_name) $curr_values($att_name)
        }
        set initial 0
        return $NO_EVENT
    }


    # calculate delta 
    foreach att_name [array names curr_values] {
        set delta($att_name) [expr $curr_values($att_name) - $prev_values($att_name)]
        set prev_values($att_name) $curr_values($att_name)
    }


    set v1 [expr double ($delta(physical_reads))]
    set v2 [expr double ($delta(block_gets))]
    set v3 [expr double ($delta(consistent_gets))]

    # deal with rollovers
    if { ($v1 < 0) || ($v2 < 0) || ($v3 < 0) } {
        ORATCL_DEBUG "bufcache : $oramsg(oraobject) : [oratime] : rollover - $v1,$v2,$v3"
        return $NO_EVENT
    }


    # calculate total
    set total [expr $v2 + $v3]


    # watch out for divide by 0
    if { $total == 0 } {
        ORATCL_DEBUG "bufcache : $oramsg(oraobject) : [oratime] : divide by zero - $v2,$v3,$total"
        return $NO_EVENT
    }


    # calculate ratio 
    set ratio [expr [expr 1 - [divide $v1 $total]] * 100]
    set ratio [format "%3.2f" $ratio]


    # ignore negative ratios
    if { $ratio < 0 } {
        ORATCL_DEBUG "bufcache : $oramsg(oraobject) : [oratime] : negative ratio - $v1,$v2,$v3,$ratio"
        return $NO_EVENT
    }


    # print out event trace info 
    ORATCL_DEBUG "bufcache : $oramsg(oraobject) : [oratime] : $v1,$v2,$v3,$ratio"


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


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

        set last_report $ret_code
        return $ret_code 
    }
}

