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

Last change on this file since 1153 was 1153, checked in by sdipsl, 9 years ago
  • r1150 missed this bit. Need to flush messages when something wrong happened. See #242
  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

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