Re: Message Latency

#56187
Terry Kellum
Participant

    I have a script that analyzes the interface log file in our LIS (SCC).  It compares the LIS timestamp in the logfile to the MSH timestamp.  It calcs the longest, shortest and average latencies.  Since this covers the timeframe from HIS application level to LIS application level, we see this as fulfilling the CAP requirement to monitor engine latencies.  We’re just getting the bigger picture (2 Cloverleaf engines, 1 at the hospital and one in our lab).

    Code:


    #!/usr/bin/tclsh

    # int_eng_stat.tcl – 20041019 – Terry Kellum
    #
    #                        Test program for evaluating the SCC rcv.trace file
    #                        for “total interface throughput” evaluation.
    #                        Code identifies the time of receipt of HL7 transactions
    #                        in SCC and compares this time with the MSH[7] timestamp
    #                        to gather statistics on message processing thruput.
    ############################################################################
    #    Goals for this script are to print a daily report of statistics
    #    and to save this data into a monthly statistics file.  This file
    #    will then be evaluated on the second day of the month to print out
    #    a monthly summary which can be filed, while the dailies can be discarded.
    #    The statistics file would then be zeroed and the process started again.
    #############################################################################

    ###################
    # Initialization
    ###################
    # User Defines
    set debug 0
    set yesterday [clock format [expr [clock seconds] – 86400] -format %Y%m%d]
    set rcvfile “/u/db/dat/I/HIS/RES$yesterday/rcv.trace”
    set statfile “/usr/local/int_eng.stat”
    set tempdailyfile “/usr/local/daily.stat”
    set tempmonthfile “/usr/local/monthly.stat”
    set prndest m21
    #set prndest lp

    # Script Defines
    set monthlyran 0
    set tottrans 0
    set today [clock format [clock seconds] -format %Y%m%d]
    set dayofmonth [clock format [clock seconds] -format %d]
    set dailymin 120
    set dailymax 0
    set dailyruntot 0
    set monmax 0
    array set dailylist “”
    set transparseerr 0

    ##########################
    # Procs
    ##########################
    proc load_statfile {filename} {
     global dailylist
     if {[file exists $filename] == 1} {
       set file [open $filename r]
       while {[gets $file line] >= 0} {
         set recordlist [list [lindex $line 0] [lindex $line 1]]
         set dailylist([lindex $recordlist 0]) [lindex $recordlist 1]
       }
       close $file
     } else {
       puts “No Stats file: $filename Found.”
     }
    }

    proc save_statfile {filename} {
     global dailylist
     if {[file exists $filename] ==1} {
       file copy -force “$filename” “$filename.bak”
     }
     set file [open $filename w 0666]
     foreach key [lsort [array names dailylist]] {
       puts $file [list $key $dailylist($key)]
     }
     close $file
    }

    ####################
    # Monthly Code
    ####################

    if {$dayofmonth == 2} {
     ## Second day of month – Do the monthly output
     set monthlyran 1
     load_statfile $statfile
     set prnfileid [open “$tempmonthfile” w 0666]
     puts $prnfileid ”                           Terre Haute Medical Lab Inc.                           ”
     puts $prnfileid ”                         Monthly Interface Statistics Report                        ”
     puts $prnfileid ”                        ———————————–                       ”
     puts $prnfileid ”                               Date: $today                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ” This report provides a summary of the past month’s interface statistics.          ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”     Date          Min (S)       Max (S)     Average (S)     Number of Trans       ”
     puts $prnfileid ”    ———-    ——–      ——–    ————    —————–      ”

     foreach key [lsort [array names dailylist]] {
     set min [lindex $dailylist($key) 0]
     set max [lindex $dailylist($key) 2]
     set avg [expr [lindex $dailylist($key) 4] / [lindex $dailylist($key) 5]]
     set numtrans [lindex $dailylist($key) 5]
     set tottrans [expr $tottrans + $numtrans]
     puts $prnfileid ”    $key        $min           $max         $avg             $numtrans             ”

     }

     puts $prnfileid ”                                                          ———————-  ”
     puts $prnfileid ”                                                       Total: $tottrans            ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ” Written Comments:                                                                 ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                          Reviewed By:___________  ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ”                                                                 Date:___________  ”
     puts $prnfileid ”                                                                                   ”
     puts $prnfileid ” This document replaces all daily reports for this month.  Please destroy all      ”
     puts $prnfileid ” daily reports unless they contain written comments.                               ”
     
     close $prnfileid
     exec lp -d$prndest $tempmonthfile
     # Cleanup for daily
     unset dailylist
     array set dailylist “”

    }

    ####################
    # Daily Code
    ####################
    ## Do the daily every day
    set file [open “$rcvfile” r]

    # Read lines from the file.  Store if line after “rcv…”
    while {[gets $file line] >= 0} {
     if {[string equal $line “rcv…”] ==1} {
       lappend linelist [gets $file]
     }
    }
    close $file

    # Process each line in the list
    foreach line $linelist {
     #Get time at start of line- This is the SCC time of receipt
     set scctime [string range $line 0 7]
     #Get the MSH7 field
     set msh [lindex [split $line “|”] 6 ]
     #Normalize the time so clock scan can read it
     set mshtime “[string range $msh 8 9]:[string range $msh 10 11]”
     #Calculate the number of seconds for this trans
     if {[catch {set secdif [expr [clock scan $scctime] – [clock scan $mshtime]]}] != 0} {
       puts “Parse Error: $line”
       incr transparseerr
     }
     #If the trans spans midnight, you’ll get crazy times like -86347
     #  Makes the assumption of a minute if the time is crazy.
     if {$secdif < 0} {set secdif 60}  #puts "   secdif = $secdif"  #Store the minimum  if {$secdif < $dailymin} {    set dailymin $secdif    set dailyminline $line  }  #Store the maximum  if {$secdif > $dailymax} {
       set dailymax $secdif
       set dailymaxline $line
     }
     #Update the running total to calculate the mean later
     set dailyruntot [expr $dailyruntot + $secdif]
    }
    set numtrans [llength $linelist]

    if {$debug == 1} {
     puts “$dailymin  –> $dailyminline”
     puts “$dailymax  –> $dailymaxline”
     puts “[expr $dailyruntot / [llength $linelist]]”
    }

    #Only load statfile if monthly did not run.  Will overwrite!
    if {$monthlyran != 1} {
     load_statfile $statfile
    }

    #Compensate for parse errors
    if {$transparseerr != 0} {
     set numtrans [expr $numtrans – $transparseerr]  
    }

    set dailylist($yesterday) [list $dailymin $dailyminline $dailymax $dailymaxline
                                   $dailyruntot $numtrans]
    if {$debug == 1} {
     puts “[lindex $dailylist($yesterday) 0] –> [lindex $dailylist($yesterday) 5]”
    }
    save_statfile $statfile

    set prnfileid [open “$tempdailyfile” w 0666]

    puts $prnfileid ”                           Terre Haute Medical Lab Inc.                           ”
    puts $prnfileid ”                         Daily Interface Statistics Report                        ”
    puts $prnfileid ”                        ———————————–                       ”
    puts $prnfileid ”                               Date: $today                                       ”
    puts $prnfileid ”                                                                                  ”
    puts $prnfileid ”                                                                                  ”
    puts $prnfileid ”  This report provides an analysis summary of interface transaction time between  ”
    puts $prnfileid ”  assembly of the HL7 transaction in the sending systems, and the receipt time    ”
    puts $prnfileid ”                               in the SCC LIS.                                    ”
    puts $prnfileid ”  It must be understood that some sending systems can introduce considerable      ”
    puts $prnfileid ”    delay in processing transactions as they do not send the transactions         ”
    puts $prnfileid ”  immediatly after construction.  Delays of 15 minutes or more are not unusual    ”
    puts $prnfileid ”  for the APS Experior system. (MSH-4 Code A)  It is for this reason that the     ”
    puts $prnfileid ”               mean transaction transit time is calculated.                       ”
    puts $prnfileid ” ================================================================================ ”
    puts $prnfileid ”  Date of Processing: $yesterday   Number of Transactions Processed: [llength $linelist]”
    puts $prnfileid ”                                                                                                  ”
    puts $prnfileid ”  Minimum processing time: $dailymin Seconds   Maximum processing time: $dailymax Seconds            ”
    puts $prnfileid ”                                                                                                  ”
    puts $prnfileid ”          Average of all processing times: [expr $dailyruntot / $numtrans] Seconds”
    puts $prnfileid ”                                                                                   ”
    if {$transparseerr != 0} {
    puts $prnfileid ”  Number of transaction parse errors: $transparseerr                               ”
    puts $prnfileid ”  Transaction parse errors are caused by some type of TCP/IP transmission          ”
    puts $prnfileid ”  problem that results in a null message.  These are ignored by the LIS, but may   ”
    puts $prnfileid ”  be an indication of connection problems if they occur in large numbers.          ”
    }
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”  Longest time to process was on transaction:                                      ”
    puts $prnfileid ”     $dailymaxline                                                                 ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”  Written Comments:                                                                ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                             Reviewed By:_________ ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                    Date:_________ ”
    puts $prnfileid ”                                                                                   ”
    puts $prnfileid ”                                                                                   ”

    close $prnfileid

    exec lp -d$prndest $tempdailyfile

    # fin

    This is specific to the SCC log file, but gives you an idea what we are doing.

    Your mileage may vary.

    Offer not valid in the states of FL and AK.    ðŸ˜€