source: tags/libIGCM_v2.7/libIGCM_debug/libIGCM_debug.ksh @ 1265

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