source: tags/libIGCM_v2.6/libIGCM_debug/libIGCM_debug.ksh @ 1267

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