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

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

We need a timestamp formatted like this 2014-09-22T19:05:14.880462898+0200

  • 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.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
[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
[913]312    if [ $# -gt 1 ]; then
313      IGCM_debug_StackArgs[0]=$(echo ${INPUTS[*]:1} | sed -e "s/\ /,/g" )
[544]314    fi
[855]315
316    if [ X${ActivateBigBro} = Xtrue ] ; then
[913]317      # RabbitMQ message code
[855]318      code=2000
[913]319      # RabbitMQ message body
[1056]320      Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"nesting\":\"${IGCM_debug_LenStack}\",\"command\":\"${INPUTS[*]}\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[913]321      # Fill the rabbitMQ queue
322      IGCM_debug_sendAMQP
[855]323    fi
324
325    # Increment LenStack
[544]326    (( IGCM_debug_LenStack = IGCM_debug_LenStack + 1 ))
[2]327
[869]328    #IGCM_debug_CallStack
[544]329  fi
[2]330}
331
332#D-#==================================================================
333#D-function IGCM_debug_PopStack
334#D-* Purpose: Pop a function name in the stack
335#D-
336function IGCM_debug_PopStack {
[544]337  if ( $DEBUG_debug ) ; then
[926]338    typeset i decal command arguments startTime_ms endTime_ms
[941]339    typeset instrumentation dest prefix
[926]340    # they are not typeset because they are send "by adress" to son functions
341    # we unset them to avoid "memory effect"
342    unset fileList source
[913]343
344    # INTRODUCE SIMPLE ERROR GENERATOR TO TEST SUPERVISOR
345    # PROBABILITY ERROR IS 0.0001 PER COMMAND OR FUNCTION CALL
346    # THERE ARE ~500 COMMAND OR FUNCTION CALL PER PERIOD
347    if ( ${RandomError} ) ; then
348      if [ $((RANDOM%10000)) -le 10 ] ; then
349        IGCM_debug_Print 1 "Random error has been triggered"
[926]350        echo "RANDOM ERROR" >> ${StackFileLocation}/${StackFileName}
[913]351        ExitFlag=true
352      fi
353    fi
354
[544]355    if [ "${IGCM_debug_Stack[0]}" = "${1}" ]; then
[913]356      # Everything is cool
357
358      # Get timing information
359      endTime_ms=$( IGCM_debug_getDate_ms )
360
361      # Save Stack information before poping the stack
362      command=${IGCM_debug_Stack[0]}
363
364      # Go from comma separated (list) to space separated in an array
365      set -A arguments $( echo ${IGCM_debug_StackArgs[0]} | sed -e "s/,/\ /g" )
366
367      # Save Stack information before poping the stack
368      startTime_ms=${IGCM_debug_StackTiming[0]}
369
370      # Pop the stack
[823]371      (( IGCM_debug_LenStack = IGCM_debug_LenStack - 1 ))
372      set -A IGCM_debug_Stack -- ${IGCM_debug_Stack[*]:1}
373      set -A IGCM_debug_StackArgs -- ${IGCM_debug_StackArgs[*]:1}
[913]374      set -A IGCM_debug_StackTiming -- ${IGCM_debug_StackTiming[*]:1}
[544]375    else
376      echo 'IGCM_debug_Exit : stack is corrupted ! LenStack =' ${IGCM_debug_LenStack}
377      IGCM_debug_Exit $@
378    fi
[913]379
[914]380    # Special actions depending on command to prepare IGCM_debug_PrintInfosActions call
[913]381    # We are interested in:
382    #  0. Which command performs the work
383    #  1. Size of entity we are working with
384    #  2. Where are we reading
385    #  3. Where are we writing
386    #  4. How long it took
387
[915]388    instrumentation=false
389
[913]390    case ${command} in
[925]391    # Classical copy (only files are given to IGCM_sys_Cp as options)
392    IGCM_sys_Cp)
393      instrumentation=true
394      # All but the latest
395      fileList=${arguments[*]:0:${#arguments[*]}-1}
396      # just need the first file to get the directory
397      source=${arguments[0]}
398      # Nothing but the latest
399      dest=${arguments[${#arguments[*]}-1]}
400      # Size of file whose name are stored in a list
401      entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
402      ;;
403
[913]404    # Copy from archive machine or from buffer
405    IGCM_sys_Get|IGCM_sys_GetBuffer)
[915]406      instrumentation=true
[913]407      if [ ${#arguments[*]} -eq 2 ] ; then
408        source=${arguments[0]}
409        dest=${arguments[1]}
410        # Size of file whose name are stored in a variable
[917]411        entitySize=$( IGCM_debug_sizeOfTabContent source ${dest} )
[913]412      elif ( [ ${#arguments[*]} -eq 3 ] && [ ${arguments[0]} = '/l' ] ) ; then
[936]413        # IGCM_sys_Get /l liste_file[*] /ccc/scratch/cont003/dsm/p86denv/RUN_DIR/985998_14754/
[913]414        # Keep the array name hosting the all list
[936]415        eval set +A fileList \${${arguments[1]}}
[913]416        # just need the first file to get the directory
[936]417        source=${fileList[0]}
[931]418        dest=${arguments[2]}
[934]419        # Size of file whose name are stored in a list
[936]420        entitySize=$( IGCM_debug_sizeOfTabContent fileList[*] ${dest} )
[913]421      elif [ [ ${#arguments[*]} -ge 3 ] ; then
422       # All but the latest
[916]423        fileList=${arguments[*]:0:${#arguments[*]}-1}
[913]424        # just need the first file to get the directory
425        source=${arguments[0]}
426        # Nothing but the latest
427        dest=${arguments[${#arguments[*]}-1]}
428        # Size of file whose name are stored in a list
[917]429        entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
[913]430      fi
431      ;;
432
[925]433    # Copy from compute node or copy to archive/buffer
434    IGCM_sys_Get_Master|IGCM_sys_Get_Dir|IGCM_sys_Put_Out|IGCM_sys_PutBuffer_Out)
[924]435      instrumentation=true
[916]436      source=${arguments[0]}
[924]437      dest=${arguments[1]}
438      # Size of file whose name are stored in a variable
439      entitySize=$( IGCM_debug_sizeOfTabContent source ${dest} )
[913]440      ;;
441
442    # Rebuild command
443    IGCM_sys_rebuild|IGCM_sys_rebuild_station)
[915]444      instrumentation=true
[913]445      # All but the first
446      fileList=${arguments[*]:1:${#arguments[*]}-1}
447      # just need a file to get the directory
448      source=${arguments[1]}
449      # Nothing but the first
450      dest=${arguments[0]}
451      # Size of file whose name are stored in a list
[917]452      entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
[913]453      ;;
[941]454
[926]455    # NCO commands
456    IGCM_sys_ncrcat|IGCM_sys_ncecat|IGCM_sys_ncra|IGCM_sys_ncks|IGCM_sys_cdo)
457      # Example of what we want to catch : only filenames in those command lines
458      # IGCM_sys_ncrcat -O -v ${list_var_final_ncrcat} ${OUT_SE[*]} ${RESULT_SE}
459      # IGCM_sys_ncrcat --hst -v ${liste_coord}${var} ${file1} ${liste_file_tmp[*]} ${file_out}
460      # IGCM_sys_ncrcat -p ${dir} ${liste_file_tmp} --output ${output}
461      # IGCM_sys_ncrcat -x -v ${list_var} -p ${dir} ${liste_file_tmp} --output ${output}
462      instrumentation=true
[941]463      keepGoing=true
464      prefix=.
[926]465      i=0
466      while ( ${keepGoing} ) ; do
[941]467        # the last one is not interesting
468        if [ ${i} -eq ${#arguments[*]}-1 ] ; then
469          keepGoing=false
470        # look after "-p" option. Path prefix is the following arguments
471        elif [ ${arguments[${i}]} = "-p" ] ; then
[926]472          ((i = i + 1))
[941]473          prefix=${arguments[${i}]}
474          ((i = i + 1))
475        elif [ ${i} -eq ${#arguments[*]}-1 ] ; then
[926]476          keepGoing=false
[941]477        # looking for files
478        elif [ -f ${prefix}/${arguments[${i}]} ] ; then
479          fileList="${fileList} ${prefix}/${arguments[${i}]}"
480          ((i = i + 1))
481        # other options are not interesting
[926]482        else
483          ((i = i + 1))
484        fi
485      done
[941]486
[926]487      # i value is at least 1
488      # just need one file to get the directory
[941]489      source=$( echo ${fileList} | gawk '{print $1}' )
[926]490      # Nothing but the latest
491      dest=${arguments[${#arguments[*]}-1]}
492      # Size of file whose name are stored in a list
493      entitySize=$( IGCM_debug_sizeOfTabContent fileList ${dest} )
494      ;;
[913]495    esac
496
497    # Print information related to instrumentation
[915]498    ( ${instrumentation} ) && IGCM_debug_PrintInfosActions ${command} ${entitySize} ${startTime_ms} ${endTime_ms} ${dest} ${source}
[913]499
500    # Only cosmetics : stack file
[823]501    decal=0
502    while [ ${decal} -lt ${IGCM_debug_LenStack} ]; do
[926]503      printf ' ' >> ${StackFileLocation}/${StackFileName}
[823]504      (( decal = decal + 1 ))
[544]505    done
[2]506
[855]507    if ( ${ExitFlag} ) ; then
508      # Inform the stack file
[926]509      echo '!!! ExitFlag has been activated !!!' >> ${StackFileLocation}/${StackFileName}
[874]510
[855]511      if [ X${ActivateBigBro} = Xtrue ] ; then
[913]512        # RabbitMQ message code
[855]513        code=9000
[913]514        # RabbitMQ message body
[1056]515        Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"nesting\":\"${IGCM_debug_LenStack}\",\"command\":\"${INPUTS[*]}\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[913]516        # Fill the rabbitMQ queue
517        IGCM_debug_sendAMQP
[855]518      fi
519    else
520      # Inform the stack file
[926]521      echo "< ${IGCM_debug_LenStack} : ${@}" >> ${StackFileLocation}/${StackFileName}
[855]522      if [ X${ActivateBigBro} = Xtrue ] ; then
[913]523        # RabbitMQ message code
[855]524        code=3000
[913]525        # RabbitMQ message body
[1056]526        Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"nesting\":\"${IGCM_debug_LenStack}\",\"command\":\"${INPUTS[*]}\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[913]527        # Fill the rabbitMQ queue
528        IGCM_debug_sendAMQP
[855]529      fi
530    fi
531
[913]532    # Reset array if necessary
[544]533    if [ ${IGCM_debug_LenStack} = 0 ]; then
534      #echo
535      #IGCM_debug_Print 3 "Clean stack array"
536      #echo
537      unset IGCM_debug_Stack
538      unset IGCM_debug_StackArgs
[913]539      unset IGCM_debug_StackTiming
[544]540      IGCM_debug_Stack[0]=${NULL_STR}
541      IGCM_debug_StackArgs[0]=${NULL_STR}
[913]542      IGCM_debug_StackTiming[0]=${NULL_STR}
[2]543    fi
[544]544  fi
[869]545  #IGCM_debug_CallStack
[2]546}
547
548#D-#==================================================================
[855]549#D-function IGCM_debug_ActivateBigBro
550#D-* Purpose: switch rabbitMQ on
551#D-
552function IGCM_debug_ActivateBigBro {
553  IGCM_debug_PushStack "IGCM_debug_ActivateBigBro"
554
[1051]555# Message type standard fields:
556# https://github.com/Prodiguer/prodiguer-docs/wiki/MQ-Standard-Message-Fields
557
558# Message type dictionnary and custom fields:
559# https://github.com/Prodiguer/prodiguer-docs/wiki/Monitoring-Message-Dictionary
560
[868]561  if [ X${BigBrother} = Xtrue ] ; then
[1051]562    # create a unique ID for this specific job
563    jobuid=$(uuidgen)
[913]564
565    # RabbitMQ message code
[855]566    if ( ${FirstInitialize} ) ; then
567      code=0000
[1051]568      # create and persist a unique id for this simulation
569      simuid=$(uuidgen)
570      IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration simuid ${simuid}
571
572      # Standard fields for the first message
573      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]574    else
575      code=1000
[1051]576      #
577      # retrieve this simulation's unique id
578      IGCM_card_DefineVariableFromOption ${SUBMIT_DIR}/run.card Configuration simuid
579      simuid=${config_Configuration_simuid}
580
581      # Standard fields for message others than the first one. Still subject to change
582      genericSimulationID=$( echo "\"msgApplication\":\"monitoring\",\"msgProducer\":\"libigcm\",\"cumulPeriod\":\"${CumulPeriod}\",\"simuid\":\"${simuid}\",\"jobuid\":\"${jobuid}\"" )
[855]583    fi
[1051]584
585    # RabbitMQ message body with specific fields associated message codes treated here
[1056]586    Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[913]587    # Fill the rabbitMQ queue (specifying config.card must be send)
588    IGCM_debug_sendAMQP activate
589
590    # Turn the flag on
[855]591    ActivateBigBro=true
592  fi
593  IGCM_debug_PopStack "IGCM_debug_ActivateBigBro"
594}
595
596#D-#==================================================================
[2]597#D-function IGCM_debug_Exit
598#D-* Purpose: Print Call Stack and set ExitFlag to true
599#D-
600function IGCM_debug_Exit {
[544]601  IGCM_debug_PushStack "IGCM_debug_Exit"
602  echo "IGCM_debug_Exit : " "${@}"
[913]603  echo
[894]604  echo "!!!!!!!!!!!!!!!!!!!!!!!!!!"
[913]605  echo "!!   ERROR TRIGGERED    !!"
606  echo "!!   EXIT FLAG SET      !!"
607  echo "!------------------------!"
608  echo
[894]609  IGCM_debug_CallStack
[544]610  ExitFlag=true
611  IGCM_debug_PopStack "IGCM_debug_Exit"
[2]612}
613
614#D-#==================================================
615#D-function IGCM_debug_Verif_Exit
616#D-* Purpose: exit with number 1 if ExitFlag is true
617#D-
618function IGCM_debug_Verif_Exit {
[544]619  if ( ${ExitFlag} ) ; then
620    # Plan to send an email here with IGCM_sys_SendMail
[775]621    if [ X${TaskType} != Xchecking ] ; then
622      IGCM_card_WriteOption ${SUBMIT_DIR}/run.card Configuration PeriodState "Fatal"
[894]623      echo "IGCM_debug_Verif_Exit : Something wrong happened previously."
624      echo "IGCM_debug_Verif_Exit : ERROR and EXIT keyword will help find out where."
[775]625      echo "                        EXIT THE JOB."
626      echo
[869]627      IGCM_debug_CallStack
[775]628    fi
[874]629
[855]630    if [ X${ActivateBigBro} = Xtrue ] ; then
[913]631      # RabbitMQ message code
[855]632      code=9999
[913]633      # RabbitMQ message body
[1056]634      Body=$( echo "{${genericSimulationID},\"msgCode\":\"${code}\",\"msgUID\":\"$(uuidgen)\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[913]635      # Fill the rabbitMQ queue
636      IGCM_debug_sendAMQP
[855]637    fi
[874]638
[913]639    # Not sure about that one ...
640    if ( $DEBUG_debug ) ; then
641      echo "Your files on ${R_OUT} :"
642      IGCM_sys_Tree ${R_SAVE}
643      echo
644    fi
[874]645
[544]646    # Mail notification
647    IGCM_sys_SendMail
[913]648
[544]649    # And Good Bye
650    date
651    exit 1
652  fi
[2]653}
654
655#D-#==================================================
656#D-function IGCM_debug_Verif_Exit_Post
657#D-* Purpose: exit with number 1 if ExitFlag is true for Post-treatment
658#D-
659function IGCM_debug_Verif_Exit_Post {
[544]660  if ( ${ExitFlag} ) ; then
[765]661    echo "IGCM_debug_Verif_Exit_Post : Something wrong happened."
[544]662    # If SpaceName is PROD then we stop if post_processing fails
663    # Plan to send an email here with IGCM_sys_SendMail
[706]664    if [ X${config_UserChoices_SpaceName} = XPROD ] ; then
[544]665      echo "                        EXIT THE JOB."
666      echo
667      # Mail notification
668      #IGCM_sys_SendMailPost
669      # And Good Bye
670      date
671      exit 1
672    else
673      echo "Either inside config.card the variable SpaceName is not in PROD"
[765]674      echo "or inside the main Job the variable JobType is not in RUN mode"
[544]675      echo "              SO WE DO NOT EXIT THE JOB."
676      echo
677      date
[2]678    fi
[544]679  fi
[2]680}
681
682#D-#==================================================================
683#D-function IGCM_debug_Print
684#D-* Purpose: Print arguments according to a level of verbosity.
685#D-
686function IGCM_debug_Print
687{
[544]688  typeset level=$1
689  shift
690
691  if [ X"${1}" = X"-e" ]; then
692    typeset cmd_echo="echo -e"
[2]693    shift
[544]694  else
695    typeset cmd_echo="echo"
696  fi
[2]697
[544]698  if [ ${level} -le ${Verbosity} ] ; then
699    typeset i
700    case "${level}" in
701    1) for i in "$@" ; do
[734]702      ${cmd_echo} $(date +"%Y-%m-%d %T") "--Debug1-->" ${i}
[913]703      done ;;
[544]704    2) for i in "$@" ; do
[734]705      ${cmd_echo} $(date +"%Y-%m-%d %T") "--------Debug2-->" ${i}
[913]706      done ;;
[544]707    3) for i in "$@" ; do
[734]708      ${cmd_echo} $(date +"%Y-%m-%d %T") "--------------Debug3-->" ${i}
[913]709      done ;;
[544]710    esac
711  fi
[2]712}
713
714#D-#==================================================================
715#D-function IGCM_debug_PrintVariables
716#D-* Purpose: Print arguments when match a pattern
717#D-           according to a level of verbosity.
718function IGCM_debug_PrintVariables
719{
[544]720  typeset level=$1
721  shift
[2]722
[830]723  list=$( set | grep ^$1 | sed -e "s/'//g" )
[54]724
[544]725  if [ "X${list}" != X ]  ; then
726    IGCM_debug_Print ${level} ${list}
727  fi
[2]728}
729
730#D-#==================================================================
[914]731#D-function IGCM_debug_PrintInfosActions
[913]732#D-* Purpose: Print information related to instrumentation
733function IGCM_debug_PrintInfosActions
734{
735  typeset actionType=$1
736  typeset entitySize=$2
737  typeset start_ms=$3
738  typeset end_ms=$4
739
740  typeset dest=$5
741  typeset source=$6
742
743  typeset diff_ms entitySizeKo entitySizeMo flux_Ko_ms flux_Ko_s flux_Mo_s
744  typeset name dirOut dirSource
745
746  name="doNotKnow"
747
748  diff_ms=$(( $end_ms - $start_ms ))
749  # echo "diff_ms=$diff_ms"
750
751  entitySizeKo=$( echo ${entitySize} | gawk -F"|" '{print $1}' )
752  # echo "entitySizeKo=$entitySizeKo"
753  entitySizeMo=$( echo ${entitySize} | gawk -F"|" '{print $2}' )
754
755  # flux en Ko / ms
756  flux_Ko_ms=$( echo "scale=6;${entitySizeKo}/${diff_ms}" | bc )
757  # echo "flux_Ko_ms=$flux_Ko_ms"
758
759  # flux en Ko / s
760  flux_Ko_s=$(( $flux_Ko_ms * 1000 ))
761  # echo "flux_Ko_s=$flux_Ko_s"
762
763  # flux en Mo / s
764  flux_Mo_s=$( echo "scale=6;${flux_Ko_s}/1024" | bc )
765  # echo "flux_Mo_s=$flux_Mo_s"
766
767  if [ -d $dest ] ; then
768    dirOut=$( readlink -f ${dest} )
769  else
770    dirOut=$( readlink -f $( dirname ${dest} ) )
771  fi
772
773  if [ -d $source ] ; then
774    dirSource=$( readlink -f ${source} )
775  else
[914]776    dirSource=$( readlink -f $( dirname ${source} ) )
[913]777  fi
778
[1050]779  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}\"" )
780
781  #echo "==>act:${actionType}|sz:${entitySizeMo}|ms:${diff_ms}|fx(ko):${flux_Ko_s}|fx(mo):${flux_Mo_s}|nm:${name}|dirSource:${dirSource}|dirOut:${dirOut}"
782
783  echo ${instrumentationContent}
784
785  # Inform the rabbitMQ queue
786  if [ X${ActivateBigBro} = Xtrue ] ; then
787    # RabbitMQ message body
[1056]788    Body=$( echo "{${genericSimulationID},${instrumentationContent},\"msgCode\":\"7000\",\"msgUID\":\"$(uuidgen)\",\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
[1050]789    # Fill the rabbitMQ queue
790    IGCM_debug_sendAMQP
791  fi
[913]792}
793
794#D-#==================================================================
[2]795#D-function IGCM_debug_Check
796#D- * Purpose: Check the present file by comparison with a reference file
797function IGCM_debug_Check
798{
[544]799  #---------------------
800  if [ ! -n "${libIGCM}" ] ; then
801    echo "Check libIGCM_debug ..........................................[ FAILED ]"
802    echo "--Error--> libIGCM variable is not defined"
803    exit 2
804  fi
[2]805
[544]806  #---------------------
807  if [ ! -n "${Verbosity}" ] ; then
808    echo "Check libIGCM_debug ..........................................[ FAILED ]"
809    echo "--Error--> Verbosity variable is not defined"
810    exit 3
811  fi
[2]812
[544]813  #---------------------
[931]814  ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ksh > /tmp/IGCM_debug_Test.$$.ref.failed 2>&1
[544]815  sleep 2
[2]816
[772]817  # Remove date stamp.
[931]818  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
819  mv /tmp/IGCM_debug_Test.$$.ref.failed.nodate /tmp/IGCM_debug_Test.$$.ref.failed
[772]820
[931]821  if diff /tmp/IGCM_debug_Test.$$.ref.failed ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ref > /dev/null 2>&1 ; then
[544]822    echo "Check libIGCM_debug ..............................................[ OK ]"
[931]823    rm -f /tmp/IGCM_debug_Test.$$.ref.failed
[544]824  else
825    echo "Check libIGCM_debug ..........................................[ FAILED ]"
826    echo "--Error--> Execution of ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ksh"
827    echo "           has produced the file IGCM_debug_Test.ref.failed"
828    echo "           Please analyse differences with the reference file by typing:"
829    echo "           diff IGCM_debug_Test.ref.failed ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ref"
830    echo "           Report errors to the author: Patrick.Brockmann@cea.fr"
[931]831    cat /tmp/IGCM_debug_Test.$$.ref.failed
[544]832    exit 4
833  fi
834  #---------------------
[2]835}
Note: See TracBrowser for help on using the repository browser.