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

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