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

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