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

Last change on this file since 1094 was 1094, checked in by sdipsl, 10 years ago

Change attribute names related to instrumentation

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