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

Last change on this file since 1150 was 1150, checked in by sdipsl, 9 years ago

adressing #242
message 2000 and 3000 (pushstack and popstack) has been turned off for the moment to ease downstream processing

  • 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.3 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      # Fill the rabbitMQ queue
638      IGCM_debug_sendAMQP
639    fi
640
641    # Mail notification
642    IGCM_sys_SendMail
643
644    # And Good Bye
645    date
646    exit 1
647  fi
648}
649
650#D-#==================================================
651#D-function IGCM_debug_Verif_Exit_Post
652#D-* Purpose: exit with number 1 if ExitFlag is true for Post-treatment
653#D-
654function IGCM_debug_Verif_Exit_Post {
655  if ( ${ExitFlag} ) ; then
656    echo "IGCM_debug_Verif_Exit_Post : Something wrong happened."
657    # If SpaceName is PROD then we stop if post_processing fails
658    # Plan to send an email here with IGCM_sys_SendMail
659    if [ X${config_UserChoices_SpaceName} = XPROD ] ; then
660      echo "                        EXIT THE JOB."
661      echo
662      # Mail notification
663      #IGCM_sys_SendMailPost
664      # And Good Bye
665      date
666      exit 1
667    else
668      echo "Either inside config.card the variable SpaceName is not in PROD"
669      echo "or inside the main Job the variable JobType is not in RUN mode"
670      echo "              SO WE DO NOT EXIT THE JOB."
671      echo
672      date
673    fi
674  fi
675}
676
677#D-#==================================================================
678#D-function IGCM_debug_Print
679#D-* Purpose: Print arguments according to a level of verbosity.
680#D-
681function IGCM_debug_Print
682{
683  typeset level=$1
684  shift
685
686  if [ X"${1}" = X"-e" ]; then
687    typeset cmd_echo="echo -e"
688    shift
689  else
690    typeset cmd_echo="echo"
691  fi
692
693  if [ ${level} -le ${Verbosity} ] ; then
694    typeset i
695    case "${level}" in
696    1) for i in "$@" ; do
697      ${cmd_echo} $(date +"%Y-%m-%d %T") "--Debug1-->" ${i}
698      done ;;
699    2) for i in "$@" ; do
700      ${cmd_echo} $(date +"%Y-%m-%d %T") "--------Debug2-->" ${i}
701      done ;;
702    3) for i in "$@" ; do
703      ${cmd_echo} $(date +"%Y-%m-%d %T") "--------------Debug3-->" ${i}
704      done ;;
705    esac
706  fi
707}
708
709#D-#==================================================================
710#D-function IGCM_debug_PrintVariables
711#D-* Purpose: Print arguments when match a pattern
712#D-           according to a level of verbosity.
713function IGCM_debug_PrintVariables
714{
715  typeset level=$1
716  shift
717
718  list=$( set | grep ^$1 | sed -e "s/'//g" )
719
720  if [ "X${list}" != X ]  ; then
721    IGCM_debug_Print ${level} ${list}
722  fi
723}
724
725#D-#==================================================================
726#D-function IGCM_debug_PrintInfosActions
727#D-* Purpose: Print information related to instrumentation
728function IGCM_debug_PrintInfosActions
729{
730  typeset actionType=$1
731  typeset entitySize=$2
732  typeset start_ms=$3
733  typeset end_ms=$4
734
735  typeset dest=$5
736  typeset source=$6
737
738  typeset diff_ms entitySizeKo entitySizeMo flux_Ko_ms flux_Ko_s flux_Mo_s
739  typeset dirFrom dirTo
740
741  diff_ms=$(( $end_ms - $start_ms ))
742  # echo "diff_ms=$diff_ms"
743
744  entitySizeKo=$( echo ${entitySize} | gawk -F"|" '{print $1}' )
745  # echo "entitySizeKo=$entitySizeKo"
746  entitySizeMo=$( echo ${entitySize} | gawk -F"|" '{print $2}' )
747
748  # flux en Ko / ms
749  flux_Ko_ms=$( echo "scale=6;${entitySizeKo}/${diff_ms}" | bc )
750  # echo "flux_Ko_ms=$flux_Ko_ms"
751
752  # flux en Ko / s
753  flux_Ko_s=$(( $flux_Ko_ms * 1000 ))
754  # echo "flux_Ko_s=$flux_Ko_s"
755
756  # flux en Mo / s
757  flux_Mo_s=$( echo "scale=6;${flux_Ko_s}/1024" | bc )
758  # echo "flux_Mo_s=$flux_Mo_s"
759
760  if [ -d $dest ] ; then
761    dirTo=$( readlink -f ${dest} )
762  else
763    dirTo=$( readlink -f $( dirname ${dest} ) )
764  fi
765
766  if [ -d $source ] ; then
767    dirFrom=$( readlink -f ${source} )
768  else
769    dirFrom=$( readlink -f $( dirname ${source} ) )
770  fi
771
772  instrumentationContent=$( echo "\"actionName\":\"${actionType}\",\"size_Mo\":\"${entitySizeMo}\",\"duration_ms\":\"${diff_ms}\",\"throughput_Mo_s\":\"${flux_Mo_s}\",\"dirFrom\":\"${dirFrom}\",\"dirTo\":\"${dirTo}\"" )
773
774  if [ X${ActivateStackFilling} = Xtrue ] ; then
775    echo "{${instrumentationContent}}" >> ${StackFileLocation}/${StackFileName}
776  fi
777
778  # Inform the rabbitMQ queue
779  if [ X${ActivateBigBro} = Xtrue ] ; then
780    # RabbitMQ message body
781    Body=$( echo "{${genericSimulationID},\"msgCode\":\"7000\",\"msgUID\":\"$(uuidgen)\",${instrumentationContent},\"msgTimestamp\":\"$( date +"%Y-%m-%dT%H:%M:%S.%N%z" )\"}" )
782    # Fill the rabbitMQ queue
783    IGCM_debug_sendAMQP
784  fi
785}
786
787#D-#==================================================================
788#D-function IGCM_debug_Check
789#D- * Purpose: Check the present file by comparison with a reference file
790function IGCM_debug_Check
791{
792  #---------------------
793  if [ ! -n "${libIGCM}" ] ; then
794    echo "Check libIGCM_debug ..........................................[ FAILED ]"
795    echo "--Error--> libIGCM variable is not defined"
796    exit 2
797  fi
798
799  #---------------------
800  if [ ! -n "${Verbosity}" ] ; then
801    echo "Check libIGCM_debug ..........................................[ FAILED ]"
802    echo "--Error--> Verbosity variable is not defined"
803    exit 3
804  fi
805
806  #---------------------
807  # Need to remove timestamps here
808  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
809  status=$?
810
811  if [ ${status} -eq 0 ] ; then
812    echo "Check libIGCM_debug ..............................................[ OK ]"
813  else
814    echo "Check libIGCM_debug ..........................................[ FAILED ]"
815    echo "--Error--> Execution of ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ksh"
816    echo "           has produced the file IGCM_debug_Test.ref.failed"
817    echo "           Please analyse differences with the reference file by typing:"
818    echo "           diff IGCM_debug_Test.ref.failed ${libIGCM}/libIGCM_debug/IGCM_debug_Test.ref"
819    echo "           Report errors to the author: Patrick.Brockmann@cea.fr"
820    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")
821    exit 4
822  fi
823  #---------------------
824}
Note: See TracBrowser for help on using the repository browser.