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

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

use specific mail subject. Will be automatically consume to feed supervisor database

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