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

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