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

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