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

Last change on this file since 1072 was 1072, checked in by sdipsl, 10 years ago

a small change ... :)

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