source: tags/libIGCM_v2.2/libIGCM_debug/libIGCM_debug.ksh

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

Tag libIGCM_v2.2 is mainly a release dedicated to IPSLCM6 transition

  • netcdf4 support on Curie
  • can activate BigBrother?, will also be use to transport metric results
  • bug fixes
  • code cleanup

Tickets solved:
https://forge.ipsl.jussieu.fr/libigcm/query?status=closed&group=resolution&milestone=libIGCM_v2.2+metrics

Full changelog:
https://forge.ipsl.jussieu.fr/libigcm/log/trunk/libIGCM?action=stop_on_copy&mode=stop_on_copy&rev=997&stop_rev=951&limit=100&verbose=on

Next release will continue to focus on metrics. Tickets can be inspected there : http://forge.ipsl.jussieu.fr/libigcm/query?milestone=libIGCM_v2.3+metrics&group=status&order=priority

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