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

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

We need a timestamp formatted like this 2014-09-22T19:05:14.880462898+0200

  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

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