source: trunk/libIGCM/libIGCM_debug/libIGCM_debug.ksh @ 1153

Last change on this file since 1153 was 1153, checked in by sdipsl, 9 years ago
  • r1150 missed this bit. Need to flush messages when something wrong happened. See #242
  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

    The fact that you are presently reading this means that you have had
    knowledge of the CeCILL license and that you accept its terms.
  • Property svn:keywords set to Revision Author Date
File size: 30.4 KB
RevLine 
[913]1#!/bin/ksh
[2]2
3#**************************************************************
4# Author: Patrick Brockmann, Martial Mancip
[373]5# Contact: Patrick.Brockmann__at__cea.fr Martial.Mancip__at__ipsl.jussieu.fr
6# $Revision::                                          $ Revision of last commit
7# $Author::                                            $ Author of last commit
8# $Date::                                              $ Date of last commit
[2]9# IPSL (2006)
10#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
11#
12#**************************************************************
13
14#==================================================
15# The documentation of this file can be automatically generated
[913]16# if you use the prefix #D- for comments to be extracted.
[2]17# Extract with command: cat lib* | grep "^#D-" | cut -c "4-"
18#==================================================
19
20#==================================================
21# Add high level verbosity
22typeset -i Verbosity=${Verbosity:=3}
23
24#==================================================
25# DEBUG_debug
26# Add low level verbosity
[1083]27DEBUG_debug=${DEBUG_debug:=false}
[2]28
[872]29#==================================================
30# GENERATE RANDOM ERROR ; only apply if ( ${DEBUG_debug} )
31typeset RandomError=false
32
[2]33#==================================================
34# NULL_STR
35# Default null string
[913]36typeset -r NULL_STR="_0_"
[2]37
38#==================================================
39# libIGCM_CurrentTag
40# Current libIGCM tag, check compatibilty with *.card
[915]41typeset -r libIGCM_CurrentTag="1.0"
[2]42
43#==================================================
44# Exit Flag (internal debug)
45# When true, end the master loop AFTER SAVES FILES
46ExitFlag=false
47
48#==================================================
49# Declare a stack of functions calls
[59]50unset IGCM_debug_Stack
51unset IGCM_debug_StackArgs
[913]52unset IGCM_debug_StackTiming
[54]53IGCM_debug_Stack[0]=${NULL_STR}
54IGCM_debug_StackArgs[0]=${NULL_STR}
[913]55IGCM_debug_StackTiming[0]=${NULL_STR}
[2]56IGCM_debug_LenStack=0
57
58#D-#==================================================================
[913]59#D-function IGCM_debug_getDate_ms
60#D- * Purpose: Give number of milliseconds since 01-jan-1970
61function IGCM_debug_getDate_ms
62{
[926]63  typeset nanosecs ms
[913]64  # nano secondes since 01-jan-1970
65  nanosecs=$( date +%s%N )
66
67  # truncate the last 6 digits to get milliseconds since 01-jan-1970
68  ms=${nanosecs:0:${#nanosecs}-6}
69
70  echo "$ms"
71}
72
73#D-#==================================================================
74#D-function IGCM_debug_sizeOfTabContent
75#D- * Purpose: Give sumed size of a list of files
[924]76#D- * Usage: IGCM_debug_sizeOfTabContent entityList destination
77#D- *        where entityList is a list of files or directory
78#D- *        where dest is either a directory or a file name
[913]79function IGCM_debug_sizeOfTabContent
80{
[924]81  typeset entityListe destination iEntity sizeKo sumSizeKo sumSizeMo
82
83  eval set +A entityListe \${${1}}
[941]84  destination=${2}
[924]85  sumSizeKo=0
86
87  # Here we will try to compute size (file or directory size) from local path and not from archive.
[941]88  for ((i = 0; i < ${#entityListe[*]}; i += 1)) ; do
89    if [ -f ${entityListe[$i]} ] ; then
90      # One file or a bunch of files has been copied without renaming from a visible filesystem
91      iEntity=${entityListe[$i]}
92    elif [ -f ${entityListe[$i]##/*/} ] ; then
93      # One file or a bunch of files has been copied without renaming from an non visible filesystem
[924]94      # remove path /home/login/../ from entityListe elements
95      iEntity=${entityListe[$i]##/*/}
96    elif [ -f ${destination} ] ; then
[941]97      # a file has been copied and renamed
[924]98      iEntity=${destination}
99    elif [ -f ${destination}/${entityListe[$i]##/*/} ] ; then
100      # a copy in a directory but not in ${PWD}
101      iEntity=${destination}/${entityListe[$i]##/*/}
102    elif [ -d ${entityListe[$i]} ] ; then
[941]103      # a directory has been copied from a non remote place
[924]104      iEntity=${entityListe[$i]}
105    elif [ -d ${destination}/${entityListe[$i]##/*/} ] ; then
[941]106      # a directory has been copied from a remote archive and not renamed
[924]107      iEntity=${destination}/${entityListe[$i]##/*/}
108    elif [ -d ${destination} ] ; then
[941]109      # a directory has been copied from a remote archive and renamed
[924]110      iEntity=${destination}
[917]111    fi
[1083]112    sizeKo=$( du --apparent-size -skL ${iEntity} | gawk '{print $1}' )
[924]113    sumSizeKo=$(( $sumSizeKo + $sizeKo ))
[913]114  done
[924]115  sumSizeMo=$( echo "scale=6;${sumSizeKo}/1024" | bc )
116  echo "${sumSizeKo}|${sumSizeMo}"
[913]117}
118
119#D-#==================================================================
[983]120#D-function IGCM_debug_send_AMQP_msg__MAILTUNNEL
121#D- * Purpose: Take over AMQP C client using mail as a message recipient
122#D- * One argument : base64 encoded message
[1051]123#D- * Attach encoded config.card when starting the simulation
124
[983]125function IGCM_debug_send_AMQP_msg__MAILTUNNEL {
126
[987]127  typeset b64_encoded_msg mail_recipient
[1076]128  typeset buffer send_messages mail_frequency
[987]129  typeset last_mail_date__file
130
[983]131  b64_encoded_msg=$1
132
[1072]133  mail_recipient="superviseur@ipsl.jussieu.fr"
[983]134  send_messages=0
135  mail_frequency=3600 # in seconds
136  # use to keep track when was last mail sent (maybe to be replaced with global variable)
[1150]137  last_mail_date__file=${R_BUF}/.stamp.${config_UserChoices_TagName}.${config_UserChoices_JobName}
138  # use to accumulate messages before sending them
139  buffer=${R_BUF}/.buffer.${config_UserChoices_TagName}.${config_UserChoices_JobName}
[983]140
141  # init
142  if [ ! -f "${buffer}" ]; then
[1150]143    touch ${buffer}
[983]144  fi
145
146  if [ ! -f "${last_mail_date__file}" ]; then
[1150]147    touch ${last_mail_date__file}
[983]148  else
[1150]149    # compute last time the file was changed (in seconds)
[983]150    seconds_since_last_mail=$(( $(date +%s) - $(stat -c %Y ${last_mail_date__file}) ))
[997]151    # send message when exceeding threshold
152    [ ${seconds_since_last_mail} -gt ${mail_frequency} ] && send_messages=1
[983]153  fi
154
[997]155  # queue messages in the buffer
156  echo ${b64_encoded_msg} >> ${buffer}
157
158  # send mail
[1051]159
[1053]160  if [ X${initBigBro} = Xtrue ] ; then
[1087]161    #echo $(date +"%Y-%m-%dT%H:%M:%S.%N%z") > ${SUBMIT_DIR}/mail.txt
[1051]162    mailx -s "[TEMPORARY AMQP CHANNEL]" -a ${SUBMIT_DIR}/config.card.base64 ${mail_recipient} < ${buffer} # send buffer
163    rm -f $buffer ; touch ${buffer}                                    # clear buffer
164    touch ${last_mail_date__file}                                      # memorize last mail date
165    initBigBro=false
[1150]166  elif [ ${send_messages} -eq 1 ] ; then
[1087]167    #echo $(date +"%Y-%m-%dT%H:%M:%S.%N%z") >> ${SUBMIT_DIR}/mail.txt
[1051]168    mailx -s "[TEMPORARY AMQP CHANNEL]" ${mail_recipient}  < ${buffer} # send buffer
[1150]169    rm -f ${buffer} ; touch ${buffer}                                  # flush the buffer
[1051]170    touch ${last_mail_date__file}                                      # memorize last mail date
[983]171  fi
[987]172
[1150]173  if [ X${FlushAMQP} = XTRUE ] ; then
174    mailx -s "[TEMPORARY AMQP CHANNEL]" ${mail_recipient}  < ${buffer} # send buffer
175    rm -f ${buffer}                                                    # cleaning behind us
176    rm -f ${last_mail_date__file}                                      # cleaning behind us
177  fi
178
[983]179  # Allways all good for now.
180  return 0
181}
182
183#D-#==================================================================
[913]184#D-function IGCM_debug_SendAMQP
185#D- * Purpose: Send body; encoded body and config.card to rabbitMQ
[1053]186function IGCM_debug_sendAMQP {
187
[913]188  typeset decal first additionnalOption encodedBody
189
190  # Encode message Body
191  encodedBody=$( echo "${Body}" | base64 -w 0 )
192
193  # Send config.card ?
194  if [ X${1} = Xactivate ] ; then
195    # Encode config.card
196    cat ${SUBMIT_DIR}/config.card | base64 -w 0 > ${SUBMIT_DIR}/config.card.base64
197    # Prepare additionnal option
198    additionnalOption="-f ${SUBMIT_DIR}/config.card.base64"
[1076]199    #
[1051]200    initBigBro=true
[913]201  else
202    additionnalOption=
[1051]203    #
204    initBigBro=false
[913]205  fi
206
207  # Only cosmetics : stack file
[1115]208  if [ X${ActivateStackFilling} = Xtrue ] ; then
209    decal=0
210    while [ ${decal} -lt ${IGCM_debug_LenStack} ]; do
211      printf ' ' >> ${StackFileLocation}/${StackFileName}
212      (( decal = decal + 1 ))
213    done
214    # Log to stack file using human readable format
215    echo "${Body}" >> ${StackFileLocation}/${StackFileName}
216  fi
[913]217
[983]218  # Log separately encoded AMQP message command for reuse in a mock up
[1120]219  #echo sendAMQPMsg -h localhost -p 5672 ${additionnalOption} -b ${encodedBody} >> ${RUN_DIR_PATH}/send.AMQP.${config_UserChoices_JobName}.${config_UserChoices_ExperimentName}.${config_UserChoices_SpaceName}.${config_UserChoices_TagName}.${CumulPeriod}.history.txt
[913]220
221  # Send the message
[983]222  if [ X${BigBrotherChannel} = XMAIL ] ; then
223    IGCM_debug_send_AMQP_msg__MAILTUNNEL "${encodedBody}"
224    status=$?
225  else
226    sendAMQPMsg -h localhost -p 5672 ${additionnalOption} -b ${encodedBody}
227    status=$?
228  fi
229
[913]230  if [ ${status} -gt 0 ] ; then
231    IGCM_debug_Print 2 "IGCM_debug_Push/PopStack/ActivateBigBro : command sendAMQPMsg failed error code ${status}"
[1051]232    echo sendAMQPMsg -h localhost -p 5672 -b "${Body}"
[1090]233    exit 1
[913]234  fi
235}
236
237#D-#==================================================================
[2]238#D-function IGCM_debug_CallStack
[913]239#D-* Purpose: Print the call stack tree from the oldest to the youngest (opposite of the display standard)
[2]240#D-
241function IGCM_debug_CallStack {
[544]242  if ( $DEBUG_debug ) ; then
[913]243    # Cosmetics
[544]244    typeset i decal
[823]245    i=0
[544]246    until [ $i -eq ${IGCM_debug_LenStack} ]; do
247      decal=0
248      until [ $decal -eq ${i} ]; do
[869]249        printf -- ' '
[823]250        (( decal = decal + 1 ))
[544]251      done
[869]252      echo "$i - ${IGCM_debug_Stack[$(( $IGCM_debug_LenStack-$i-1 ))]}" "(${IGCM_debug_StackArgs[$(( $IGCM_debug_LenStack-$i-1 ))]})"
[823]253      ((i = i + 1))
[544]254    done
255  fi
[2]256}
257
258#D-#==================================================================
259#D-function IGCM_debug_PushStack
260#D-* Purpose: Push a function name in the stack
261#D-
262function IGCM_debug_PushStack {
[544]263  if ( $DEBUG_debug ) ; then
[913]264    typeset decal inputs startTime_ms
265
266    # Only cosmetics : stack file
[1115]267    if [ X${ActivateStackFilling} = Xtrue ] ; then
268      echo >> ${StackFileLocation}/${StackFileName}
269      decal=0
270      while [ ${decal} -lt ${IGCM_debug_LenStack} ]; do
271        printf ' ' >> ${StackFileLocation}/${StackFileName}
272        (( decal = decal + 1 ))
273      done
[2]274
[1115]275      # Fill the stack file
276      echo "> ${IGCM_debug_LenStack} : ${@}" >> ${StackFileLocation}/${StackFileName}
277    fi
[926]278
[913]279    # Save input list in an indexed array
[823]280    INPUTS=( $@ )
[913]281
282    # Get timing information
283    startTime_ms=$( IGCM_debug_getDate_ms )
284
[544]285    # We add function call name on beginning of the stack
286    set +A IGCM_debug_Stack -- ${1} ${IGCM_debug_Stack[*]}
[2]287
[913]288    # Save timing in milliseconds in an indexed array
289    set +A IGCM_debug_StackTiming -- ${startTime_ms} ${IGCM_debug_StackTiming[*]}
290
[544]291    # We include the "null" Args in the beginning of the StackArgs
[913]292    set +A IGCM_debug_StackArgs ${NULL_STR} ${IGCM_debug_StackArgs[*]}
293
[544]294    # Then, we shift StackArgs tabular
[1065]295    # Replacing blank separated list by comma separated list of quoted elements (except the first and last element)
[913]296    if [ $# -gt 1 ]; then
[1065]297      IGCM_debug_StackArgs[0]=$(echo ${INPUTS[*]:1} | sed -e "s/\ /\",\"/g" )
[544]298    fi
[855]299
[1150]300    # Unplugged message 2000 handling for now. To ease downstream treatment.
301    #if [ X${ActivateBigBro} = Xtrue ] ; then
302    #  # RabbitMQ message code "PUSHSTACK"
303    #  code=2000
304    #  # RabbitMQ message body
305    #  Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"nesting\":\"${IGCM_debug_LenStack}\",\"command\":\"${IGCM_debug_Stack[0]}\",\"arguments\":[\"${IGCM_debug_StackArgs[0]}\"],\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
306    #  # Fill the rabbitMQ queue
307    #  IGCM_debug_sendAMQP
308    #fi
[855]309
310    # Increment LenStack
[544]311    (( IGCM_debug_LenStack = IGCM_debug_LenStack + 1 ))
[2]312
[869]313    #IGCM_debug_CallStack
[544]314  fi
[2]315}
316
317#D-#==================================================================
318#D-function IGCM_debug_PopStack
319#D-* Purpose: Pop a function name in the stack
320#D-
321function IGCM_debug_PopStack {
[544]322  if ( $DEBUG_debug ) ; then
[926]323    typeset i decal command arguments startTime_ms endTime_ms
[941]324    typeset instrumentation dest prefix
[926]325    # they are not typeset because they are send "by adress" to son functions
326    # we unset them to avoid "memory effect"
327    unset fileList source
[913]328
329    # INTRODUCE SIMPLE ERROR GENERATOR TO TEST SUPERVISOR
330    # PROBABILITY ERROR IS 0.0001 PER COMMAND OR FUNCTION CALL
331    # THERE ARE ~500 COMMAND OR FUNCTION CALL PER PERIOD
332    if ( ${RandomError} ) ; then
333      if [ $((RANDOM%10000)) -le 10 ] ; then
334        IGCM_debug_Print 1 "Random error has been triggered"
[1115]335        if [ X${ActivateStackFilling} = Xtrue ] ; then
336          echo "RANDOM ERROR" >> ${StackFileLocation}/${StackFileName}
337        fi
[913]338        ExitFlag=true
339      fi
340    fi
341
[544]342    if [ "${IGCM_debug_Stack[0]}" = "${1}" ]; then
[913]343      # Everything is cool
344
345      # Get timing information
346      endTime_ms=$( IGCM_debug_getDate_ms )
347
348      # Save Stack information before poping the stack
349      command=${IGCM_debug_Stack[0]}
350
[1084]351      # Go from comma separated list of quoted elements (except the first and the last element)
352      # to unquoted space separated elements in an array
[1083]353      set -A arguments -- $( echo ${IGCM_debug_StackArgs[0]} | sed -e "s/\",\"/\ /g" )
[913]354
355      # Save Stack information before poping the stack
356      startTime_ms=${IGCM_debug_StackTiming[0]}
357
358      # Pop the stack
[823]359      (( IGCM_debug_LenStack = IGCM_debug_LenStack - 1 ))
360      set -A IGCM_debug_Stack -- ${IGCM_debug_Stack[*]:1}
361      set -A IGCM_debug_StackArgs -- ${IGCM_debug_StackArgs[*]:1}
[913]362      set -A IGCM_debug_StackTiming -- ${IGCM_debug_StackTiming[*]:1}
[544]363    else
364      echo 'IGCM_debug_Exit : stack is corrupted ! LenStack =' ${IGCM_debug_LenStack}
365      IGCM_debug_Exit $@
366    fi
[913]367
[914]368    # Special actions depending on command to prepare IGCM_debug_PrintInfosActions call
[913]369    # We are interested in:
370    #  0. Which command performs the work
371    #  1. Size of entity we are working with
372    #  2. Where are we reading
373    #  3. Where are we writing
374    #  4. How long it took
375
[915]376    instrumentation=false
377
[913]378    case ${command} in
[925]379    # Classical copy (only files are given to IGCM_sys_Cp as options)
380    IGCM_sys_Cp)
381      instrumentation=true
382      # All but the latest
383      fileList=${arguments[*]:0:${#arguments[*]}-1}
384      # just need the first file to get the directory
385      source=${arguments[0]}
386      # Nothing but the latest
387      dest=${arguments[${#arguments[*]}-1]}
388      # Size of file whose name are stored in a list
389      entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
390      ;;
391
[913]392    # Copy from archive machine or from buffer
393    IGCM_sys_Get|IGCM_sys_GetBuffer)
[915]394      instrumentation=true
[913]395      if [ ${#arguments[*]} -eq 2 ] ; then
396        source=${arguments[0]}
397        dest=${arguments[1]}
398        # Size of file whose name are stored in a variable
[917]399        entitySize=$( IGCM_debug_sizeOfTabContent source ${dest} )
[913]400      elif ( [ ${#arguments[*]} -eq 3 ] && [ ${arguments[0]} = '/l' ] ) ; then
[936]401        # IGCM_sys_Get /l liste_file[*] /ccc/scratch/cont003/dsm/p86denv/RUN_DIR/985998_14754/
[913]402        # Keep the array name hosting the all list
[936]403        eval set +A fileList \${${arguments[1]}}
[913]404        # just need the first file to get the directory
[936]405        source=${fileList[0]}
[931]406        dest=${arguments[2]}
[934]407        # Size of file whose name are stored in a list
[936]408        entitySize=$( IGCM_debug_sizeOfTabContent fileList[*] ${dest} )
[913]409      elif [ [ ${#arguments[*]} -ge 3 ] ; then
410       # All but the latest
[916]411        fileList=${arguments[*]:0:${#arguments[*]}-1}
[913]412        # just need the first file to get the directory
413        source=${arguments[0]}
414        # Nothing but the latest
415        dest=${arguments[${#arguments[*]}-1]}
416        # Size of file whose name are stored in a list
[917]417        entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
[913]418      fi
419      ;;
420
[925]421    # Copy from compute node or copy to archive/buffer
422    IGCM_sys_Get_Master|IGCM_sys_Get_Dir|IGCM_sys_Put_Out|IGCM_sys_PutBuffer_Out)
[924]423      instrumentation=true
[916]424      source=${arguments[0]}
[924]425      dest=${arguments[1]}
426      # Size of file whose name are stored in a variable
427      entitySize=$( IGCM_debug_sizeOfTabContent source ${dest} )
[913]428      ;;
429
430    # Rebuild command
431    IGCM_sys_rebuild|IGCM_sys_rebuild_station)
[915]432      instrumentation=true
[913]433      # All but the first
434      fileList=${arguments[*]:1:${#arguments[*]}-1}
435      # just need a file to get the directory
436      source=${arguments[1]}
437      # Nothing but the first
438      dest=${arguments[0]}
439      # Size of file whose name are stored in a list
[917]440      entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
[913]441      ;;
[941]442
[926]443    # NCO commands
444    IGCM_sys_ncrcat|IGCM_sys_ncecat|IGCM_sys_ncra|IGCM_sys_ncks|IGCM_sys_cdo)
445      # Example of what we want to catch : only filenames in those command lines
446      # IGCM_sys_ncrcat -O -v ${list_var_final_ncrcat} ${OUT_SE[*]} ${RESULT_SE}
447      # IGCM_sys_ncrcat --hst -v ${liste_coord}${var} ${file1} ${liste_file_tmp[*]} ${file_out}
448      # IGCM_sys_ncrcat -p ${dir} ${liste_file_tmp} --output ${output}
449      # IGCM_sys_ncrcat -x -v ${list_var} -p ${dir} ${liste_file_tmp} --output ${output}
450      instrumentation=true
[941]451      keepGoing=true
452      prefix=.
[926]453      i=0
454      while ( ${keepGoing} ) ; do
[941]455        # the last one is not interesting
456        if [ ${i} -eq ${#arguments[*]}-1 ] ; then
457          keepGoing=false
458        # look after "-p" option. Path prefix is the following arguments
459        elif [ ${arguments[${i}]} = "-p" ] ; then
[926]460          ((i = i + 1))
[941]461          prefix=${arguments[${i}]}
462          ((i = i + 1))
463        elif [ ${i} -eq ${#arguments[*]}-1 ] ; then
[926]464          keepGoing=false
[941]465        # looking for files
466        elif [ -f ${prefix}/${arguments[${i}]} ] ; then
467          fileList="${fileList} ${prefix}/${arguments[${i}]}"
468          ((i = i + 1))
469        # other options are not interesting
[926]470        else
471          ((i = i + 1))
472        fi
473      done
[941]474
[926]475      # i value is at least 1
476      # just need one file to get the directory
[941]477      source=$( echo ${fileList} | gawk '{print $1}' )
[926]478      # Nothing but the latest
479      dest=${arguments[${#arguments[*]}-1]}
480      # Size of file whose name are stored in a list
481      entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
482      ;;
[913]483    esac
484
485    # Print information related to instrumentation
[915]486    ( ${instrumentation} ) && IGCM_debug_PrintInfosActions ${command} ${entitySize} ${startTime_ms} ${endTime_ms} ${dest} ${source}
[913]487
488    # Only cosmetics : stack file
[1115]489    if [ X${ActivateStackFilling} = Xtrue ] ; then
490      decal=0
491      while [ ${decal} -lt ${IGCM_debug_LenStack} ]; do
492        printf ' ' >> ${StackFileLocation}/${StackFileName}
493        (( decal = decal + 1 ))
494      done
495    fi
[2]496
[855]497    if ( ${ExitFlag} ) ; then
498      # Inform the stack file
[1115]499      if [ X${ActivateStackFilling} = Xtrue ] ; then
500        echo '!!! ExitFlag has been activated !!!' >> ${StackFileLocation}/${StackFileName}
501      fi
[874]502
[855]503      if [ X${ActivateBigBro} = Xtrue ] ; then
[1076]504        # RabbitMQ message code "ERROR HAS BEEN TRIGGERED"
[855]505        code=9000
[913]506        # RabbitMQ message body
[1065]507        Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"nesting\":\"${IGCM_debug_LenStack}\",\"command\":\"${command}\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[913]508        # Fill the rabbitMQ queue
509        IGCM_debug_sendAMQP
[855]510      fi
511    else
512      # Inform the stack file
[1115]513      if [ X${ActivateStackFilling} = Xtrue ] ; then
514        echo "< ${IGCM_debug_LenStack} : ${@}" >> ${StackFileLocation}/${StackFileName}
515      fi
516
[1150]517      # Unplugged message 3000 handling for now. To ease downstream treatment.
518      #if [ X${ActivateBigBro} = Xtrue ] ; then
519      #  # RabbitMQ message code "POPSTACK"
520      #  code=3000
521      #  # RabbitMQ message body
522      #  Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"nesting\":\"${IGCM_debug_LenStack}\",\"command\":\"${command}\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
523      #  # Fill the rabbitMQ queue
524      #  IGCM_debug_sendAMQP
525      #fi
[855]526    fi
527
[913]528    # Reset array if necessary
[544]529    if [ ${IGCM_debug_LenStack} = 0 ]; then
530      #echo
531      #IGCM_debug_Print 3 "Clean stack array"
532      #echo
533      unset IGCM_debug_Stack
534      unset IGCM_debug_StackArgs
[913]535      unset IGCM_debug_StackTiming
[544]536      IGCM_debug_Stack[0]=${NULL_STR}
537      IGCM_debug_StackArgs[0]=${NULL_STR}
[913]538      IGCM_debug_StackTiming[0]=${NULL_STR}
[2]539    fi
[544]540  fi
[869]541  #IGCM_debug_CallStack
[2]542}
543
544#D-#==================================================================
[855]545#D-function IGCM_debug_ActivateBigBro
546#D-* Purpose: switch rabbitMQ on
547#D-
548function IGCM_debug_ActivateBigBro {
549  IGCM_debug_PushStack "IGCM_debug_ActivateBigBro"
550
[1051]551# Message type standard fields:
552# https://github.com/Prodiguer/prodiguer-docs/wiki/MQ-Standard-Message-Fields
553
554# Message type dictionnary and custom fields:
555# https://github.com/Prodiguer/prodiguer-docs/wiki/Monitoring-Message-Dictionary
556
[868]557  if [ X${BigBrother} = Xtrue ] ; then
[1051]558    # create a unique ID for this specific job
559    jobuid=$(uuidgen)
[913]560
[855]561    if ( ${FirstInitialize} ) ; then
[1076]562      # RabbitMQ message code "BEGIN A SIMULATION"
[855]563      code=0000
[1051]564      # create and persist a unique id for this simulation
565      simuid=$(uuidgen)
566      IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration simuid ${simuid}
567      # Standard fields for the first message
568      genericSimulationID=$( echo "\"msgApplication\":\"monitoring\",\"msgProducer\":\"libigcm\",\"activity\":\"IPSL\",\"name\":\"${config_UserChoices_JobName}\",\"cumulPeriod\":\"${CumulPeriod}\",\"experiment\":\"${config_UserChoices_ExperimentName}\",\"space\":\"${config_UserChoices_SpaceName}\",\"model\":\"${config_UserChoices_TagName}\",\"startDate\":\"${config_UserChoices_DateBegin}\",\"endDate\":\"${config_UserChoices_DateEnd}\",\"login\":\"${LOGIN}\",\"centre\":\"${CENTER}\",\"machine\":\"${MASTER}\",\"simuid\":\"${simuid}\",\"jobuid\":\"${jobuid}\"" )
[1087]569      # RabbitMQ message body with specific fields associated message codes treated here
570      Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
571      # Fill the rabbitMQ queue (the config.card in use will be sent)
572      IGCM_debug_sendAMQP activate
[855]573    else
[1076]574      # RabbitMQ message code "A NEW JOB IS RUNNING PART OF A SIMULATION"
[855]575      code=1000
[1076]576      # retrieve this simulation's unique id
[1051]577      IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration simuid
[1086]578      simuid=${run_Configuration_simuid}
[1076]579      # Using standard fields for message others than the first one. Still subject to change
[1051]580      genericSimulationID=$( echo "\"msgApplication\":\"monitoring\",\"msgProducer\":\"libigcm\",\"cumulPeriod\":\"${CumulPeriod}\",\"simuid\":\"${simuid}\",\"jobuid\":\"${jobuid}\"" )
[1087]581      # RabbitMQ message body with specific fields associated message codes treated here
582      Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
583      # Fill the rabbitMQ queue
584      IGCM_debug_sendAMQP
[855]585    fi
[1051]586
[1076]587    # NOT VERY NICE BUT ... IT WORKS
588    # Be sure that the genericSimulationID will be small from now on
589    # Using standard fields for messages others than the first one. Still subject to change
590    genericSimulationID=$( echo "\"msgApplication\":\"monitoring\",\"msgProducer\":\"libigcm\",\"cumulPeriod\":\"${CumulPeriod}\",\"simuid\":\"${simuid}\",\"jobuid\":\"${jobuid}\"" )
591
[913]592    # Turn the flag on
[855]593    ActivateBigBro=true
594  fi
595  IGCM_debug_PopStack "IGCM_debug_ActivateBigBro"
596}
597
598#D-#==================================================================
[2]599#D-function IGCM_debug_Exit
600#D-* Purpose: Print Call Stack and set ExitFlag to true
601#D-
602function IGCM_debug_Exit {
[544]603  IGCM_debug_PushStack "IGCM_debug_Exit"
604  echo "IGCM_debug_Exit : " "${@}"
[913]605  echo
[894]606  echo "!!!!!!!!!!!!!!!!!!!!!!!!!!"
[913]607  echo "!!   ERROR TRIGGERED    !!"
608  echo "!!   EXIT FLAG SET      !!"
609  echo "!------------------------!"
610  echo
[894]611  IGCM_debug_CallStack
[544]612  ExitFlag=true
613  IGCM_debug_PopStack "IGCM_debug_Exit"
[2]614}
615
616#D-#==================================================
617#D-function IGCM_debug_Verif_Exit
618#D-* Purpose: exit with number 1 if ExitFlag is true
619#D-
620function IGCM_debug_Verif_Exit {
[544]621  if ( ${ExitFlag} ) ; then
622    # Plan to send an email here with IGCM_sys_SendMail
[775]623    if [ X${TaskType} != Xchecking ] ; then
624      IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Fatal"
[894]625      echo "IGCM_debug_Verif_Exit : Something wrong happened previously."
626      echo "IGCM_debug_Verif_Exit : ERROR and EXIT keyword will help find out where."
[775]627      echo "                        EXIT THE JOB."
628      echo
[869]629      IGCM_debug_CallStack
[775]630    fi
[874]631
[855]632    if [ X${ActivateBigBro} = Xtrue ] ; then
[1076]633      # RabbitMQ message code "EXIT THE JOBS BECAUSE ERROR(S) HAS BEEN TRIGGERED"
[855]634      code=9999
[913]635      # RabbitMQ message body
[1056]636      Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[1153]637      # To be sure we flush message buffer and clean up behind us before the end of the simulation
638      FlushAMQP=TRUE
[913]639      # Fill the rabbitMQ queue
640      IGCM_debug_sendAMQP
[855]641    fi
[874]642
[544]643    # Mail notification
644    IGCM_sys_SendMail
[913]645
[544]646    # And Good Bye
647    date
648    exit 1
649  fi
[2]650}
651
652#D-#==================================================
653#D-function IGCM_debug_Verif_Exit_Post
654#D-* Purpose: exit with number 1 if ExitFlag is true for Post-treatment
655#D-
656function IGCM_debug_Verif_Exit_Post {
[544]657  if ( ${ExitFlag} ) ; then
[765]658    echo "IGCM_debug_Verif_Exit_Post : Something wrong happened."
[544]659    # If SpaceName is PROD then we stop if post_processing fails
660    # Plan to send an email here with IGCM_sys_SendMail
[706]661    if [ X${config_UserChoices_SpaceName} = XPROD ] ; then
[544]662      echo "                        EXIT THE JOB."
663      echo
664      # Mail notification
665      #IGCM_sys_SendMailPost
666      # And Good Bye
667      date
668      exit 1
669    else
670      echo "Either inside config.card the variable SpaceName is not in PROD"
[765]671      echo "or inside the main Job the variable JobType is not in RUN mode"
[544]672      echo "              SO WE DO NOT EXIT THE JOB."
673      echo
674      date
[2]675    fi
[544]676  fi
[2]677}
678
679#D-#==================================================================
680#D-function IGCM_debug_Print
681#D-* Purpose: Print arguments according to a level of verbosity.
682#D-
683function IGCM_debug_Print
684{
[544]685  typeset level=$1
686  shift
687
688  if [ X"${1}" = X"-e" ]; then
689    typeset cmd_echo="echo -e"
[2]690    shift
[544]691  else
692    typeset cmd_echo="echo"
693  fi
[2]694
[544]695  if [ ${level} -le ${Verbosity} ] ; then
696    typeset i
697    case "${level}" in
698    1) for i in "$@" ; do
[734]699      ${cmd_echo} $(date +"%Y-%m-%d %T") "--Debug1-->" ${i}
[913]700      done ;;
[544]701    2) for i in "$@" ; do
[734]702      ${cmd_echo} $(date +"%Y-%m-%d %T") "--------Debug2-->" ${i}
[913]703      done ;;
[544]704    3) for i in "$@" ; do
[734]705      ${cmd_echo} $(date +"%Y-%m-%d %T") "--------------Debug3-->" ${i}
[913]706      done ;;
[544]707    esac
708  fi
[2]709}
710
711#D-#==================================================================
712#D-function IGCM_debug_PrintVariables
713#D-* Purpose: Print arguments when match a pattern
714#D-           according to a level of verbosity.
715function IGCM_debug_PrintVariables
716{
[544]717  typeset level=$1
718  shift
[2]719
[830]720  list=$( set | grep ^$1 | sed -e "s/'//g" )
[54]721
[544]722  if [ "X${list}" != X ]  ; then
723    IGCM_debug_Print ${level} ${list}
724  fi
[2]725}
726
727#D-#==================================================================
[914]728#D-function IGCM_debug_PrintInfosActions
[913]729#D-* Purpose: Print information related to instrumentation
730function IGCM_debug_PrintInfosActions
731{
732  typeset actionType=$1
733  typeset entitySize=$2
734  typeset start_ms=$3
735  typeset end_ms=$4
736
737  typeset dest=$5
738  typeset source=$6
739
740  typeset diff_ms entitySizeKo entitySizeMo flux_Ko_ms flux_Ko_s flux_Mo_s
[1090]741  typeset dirFrom dirTo
[913]742
743  diff_ms=$(( $end_ms - $start_ms ))
744  # echo "diff_ms=$diff_ms"
745
746  entitySizeKo=$( echo ${entitySize} | gawk -F"|" '{print $1}' )
747  # echo "entitySizeKo=$entitySizeKo"
748  entitySizeMo=$( echo ${entitySize} | gawk -F"|" '{print $2}' )
749
750  # flux en Ko / ms
751  flux_Ko_ms=$( echo "scale=6;${entitySizeKo}/${diff_ms}" | bc )
752  # echo "flux_Ko_ms=$flux_Ko_ms"
753
754  # flux en Ko / s
755  flux_Ko_s=$(( $flux_Ko_ms * 1000 ))
756  # echo "flux_Ko_s=$flux_Ko_s"
757
758  # flux en Mo / s
759  flux_Mo_s=$( echo "scale=6;${flux_Ko_s}/1024" | bc )
760  # echo "flux_Mo_s=$flux_Mo_s"
761
762  if [ -d $dest ] ; then
[1090]763    dirTo=$( readlink -f ${dest} )
[913]764  else
[1090]765    dirTo=$( readlink -f $( dirname ${dest} ) )
[913]766  fi
767
768  if [ -d $source ] ; then
[1090]769    dirFrom=$( readlink -f ${source} )
[913]770  else
[1090]771    dirFrom=$( readlink -f $( dirname ${source} ) )
[913]772  fi
773
[1094]774  instrumentationContent=$( echo "\"actionName\":\"${actionType}\",\"size_Mo\":\"${entitySizeMo}\",\"duration_ms\":\"${diff_ms}\",\"throughput_Mo_s\":\"${flux_Mo_s}\",\"dirFrom\":\"${dirFrom}\",\"dirTo\":\"${dirTo}\"" )
[1050]775
[1115]776  if [ X${ActivateStackFilling} = Xtrue ] ; then
777    echo "{${instrumentationContent}}" >> ${StackFileLocation}/${StackFileName}
778  fi
[1050]779
780  # Inform the rabbitMQ queue
781  if [ X${ActivateBigBro} = Xtrue ] ; then
782    # RabbitMQ message body
[1065]783    Body=$( echo "{${genericSimulationID},\"msgCode\":\"7000\",\"msgUID\":\"$(uuidgen)\",${instrumentationContent},\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[1050]784    # Fill the rabbitMQ queue
785    IGCM_debug_sendAMQP
786  fi
[913]787}
788
789#D-#==================================================================
[2]790#D-function IGCM_debug_Check
791#D- * Purpose: Check the present file by comparison with a reference file
792function IGCM_debug_Check
793{
[544]794  #---------------------
795  if [ ! -n "${libIGCM}" ] ; then
796    echo "Check libIGCM_debug ..........................................[ FAILED ]"
797    echo "--Error--> libIGCM variable is not defined"
798    exit 2
799  fi
[2]800
[544]801  #---------------------
802  if [ ! -n "${Verbosity}" ] ; then
803    echo "Check libIGCM_debug ..........................................[ FAILED ]"
804    echo "--Error--> Verbosity variable is not defined"
805    exit 3
806  fi
[2]807
[544]808  #---------------------
[1118]809  # Need to remove timestamps here
810  diff ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ref <(${libIGCM}/libIGCM_debug/IGCM_debug_Test.ksh | sed -e "s:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]\:[0-9][0-9]\:[0-9][0-9] ::g") > /dev/null 2>&1
[1106]811  status=$?
[2]812
[1118]813  if [ ${status} -eq 0 ] ; then
[544]814    echo "Check libIGCM_debug ..............................................[ OK ]"
815  else
816    echo "Check libIGCM_debug ..........................................[ FAILED ]"
817    echo "--Error--> Execution of ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ksh"
818    echo "           has produced the file IGCM_debug_Test.ref.failed"
819    echo "           Please analyse differences with the reference file by typing:"
820    echo "           diff IGCM_debug_Test.ref.failed ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ref"
821    echo "           Report errors to the author: Patrick.Brockmann@cea.fr"
[1118]822    diff ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ref <(${libIGCM}/libIGCM_debug/IGCM_debug_Test.ksh | sed -e "s:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]\:[0-9][0-9]\:[0-9][0-9] ::g")
[544]823    exit 4
824  fi
825  #---------------------
[2]826}
Note: See TracBrowser for help on using the repository browser.