source: tags/libIGCM_v2.4/libIGCM_debug/libIGCM_debug.ksh @ 1331

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