source: tags/libIGCM_v2.4/libIGCM_debug/libIGCM_debug.ksh @ 1435

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