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

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