esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% debug_log_file.mac
#%NAME%
#  
#%CATEGORY% debugging
#%DESCRIPTION%
#  Open a log file. At eache prompt, check the size of the log
#  file. If size exceed the limit, the file is copied to another file
#  with a .X extention.  X in 1..N.
#
#  You can define the number of files to use. if set to -1, files will
#  not be deleted.
#
#
#%EXAMPLE%
#
#
#%SETUP%
#%DL%
#%DT% To put in your spec session setup:
#%DL%
# %DT%  #    5 files of 1MB each
# %DT%  dlf_setup("/buffer/mufid2.esrf.fr1/cyril/lll.dlog", 1000000, 5)
# %DT%
# %DT%  # re init at each fresh restart
# %DT%  if ( FRESH && !NOT_FIRST_SETUP_FRESH) {
# %DT%     dlf_init()
# %DT%  }
#%XDL%

#
#%XDL%
#%END%


global DLF_PAR[]
# DLF_PAR["on"]           : int 0/1 : 0=off 1=on
# DLF_PAR["file_name"]    : string  : path+file name (use .dlog to catch debug 192)
# DLF_PAR["nb_of_files"]  : integer : number of already generated log files.
# DLF_PAR["max_files"]    : integer : maximum number of log files to keep.
# DLF_PAR["max_size"]     : float   : shifts log file when this limit is reached.



#%UU% (<file_name>, <max_size_in_Bytes>, <number_of_files>)
#%MDESC%
# - <file_name>      : string  : path + file name
# - <max_size_in_MB> : number  : shifts log file when this limit is reached.
# - <max_files>      : integer : -1  : do not delete files.
#                                N>0 : use N files : { f , f.1, f.2, ... , f.N-1}
def dlf_setup(file_name, max_size, max_files) '{

    dlf_msg(sprintf("Debug log file setup"))

    #### FILE NAME
    DLF_PAR["file_name"] = file_name
    dlf_msg(sprintf("File Name : %s", DLF_PAR["file_name"]))

    #### MAXIMUM NUMBER OF FILES
    DLF_PAR["max_files"] = max_files
    dlf_msg(sprintf("Maximum number of log files : %d", DLF_PAR["max_files"]))


    #### SIZE
    if(max_size > 1){
        DLF_PAR["max_size"] = max_size
    }
    else{
        DLF_PAR["max_size"] = 10000000
    }
    dlf_msg(sprintf("Max size of one file set to %s Bytes.", DLF_PAR["max_size"]))

    #### hooked macro.
    cdef ("prompt_mac" , "\n dlf_test_log_file() \n" , "_dlf_key_")

}'


#%IU% ()
#%MDESC%
#    To put in real fresh restart ?
def dlf_init() '{

    dlf_on
    DLF_PAR["nb_of_files"] = 1

}'


#%IU%
#%MDESC%
#    Remove all globals used and hiiked functions.
def dlf_unsetup '{
    dlf_off
    cdef ("prompt_mac" , "" , "_dlf_key_", "delete")
    unglobal DLF_PAR
}'


#%UU%
#%MDESC%
#    Enables log recording.
def dlf_on '{
    DLF_PAR["on"] = 1
    on(DLF_PAR["file_name"])
}'


#%UU%
#%MDESC%
#    Disables log recording.
def dlf_off '{
    DLF_PAR["on"] = 0
    off(DLF_PAR["file_name"])
}'




#%UU% ()
#%MDESC%
#    Makes a copy of current log file for post-mortem analysis.
def dlf_timestamp_current_logfile() '{
    local _cmd _tstamp

     _tstamp = date("%Y-%m-%d_%T.%.6")
     _cmd = sprintf("cp %s %s-%s" , DLF_PAR["file_name"], DLF_PAR["file_name"], _tstamp)
     dlf_msg(sprintf("Making a timestamped copy of current logfile : %s-%s ", DLF_PAR["file_name"], _tstamp))
     unix(_cmd)

}'



#%IU% ()
#%MDESC%
#    Function called at each prompt to check the size of log file and
# shift it if needed.
def dlf_test_log_file() '{
    local _cmd _cmdh _size _sizeh  _file ii

    _file = DLF_PAR["file_name"]

    if (DLF_PAR["on"] == 0){
        return
    }

    if(file_info(_file, "-f")){
        _cmd  = sprintf("ls -al %s   | gawk \'\{print \$5\}\'", DLF_PAR["file_name"])
        _cmdh = sprintf("ls -alh %s  | gawk \'\{print \$5\}\'", DLF_PAR["file_name"])

        unix(_cmdh, _sizeh)
        unix(_cmd, _size)

        _size = removeEndingChar(_size, "\n")
        _sizeh = removeEndingChar(_sizeh, "\n")


        print "log file name : " DLF_PAR["file_name"]
        print "log file size : " _sizeh
    }
    else{
        dlf_err(sprintf("File \"%s\" does not exist.", _file))
    }


    if (_size >  DLF_PAR["max_size"]) {
        local _new_logfile_name

        dlf_dbg(printf ("oh oh, THE LOG FILE : %s is too big : %s \n", DLF_PAR["file_name"] , _sizeh))


        # Deletes the oldetst file (if needed).
        if (  (DLF_PAR["nb_of_files"] >= DLF_PAR["max_files"])  &&  \
              (DLF_PAR["max_files"]>0)                              \
            ) {
            _rm_cmd = sprintf("rm -f %s.%d", DLF_PAR["file_name"], DLF_PAR["nb_of_files"]-1)
            dlf_dbg(sprintf("I will do \"%s\" \n", _rm_cmd))
            unix(_rm_cmd)

            DLF_PAR["nb_of_files"] = DLF_PAR["nb_of_files"] - 1
        }
        else{
            dlf_dbg("No old file to delete")
        }

        # Shifts the files.
        # .3->.4 .2->.3  .1->.2
        for (ii = DLF_PAR["nb_of_files"]-1 ; ii >= 1 ; ii--){
            _mv_cmd = sprintf("mv %s.%d %s.%d",               \
                              DLF_PAR["file_name"], ii,       \
                              DLF_PAR["file_name"], ii+1)
            dlf_dbg(sprintf("I will do (shift files) )\"%s\" \n", _mv_cmd))
            unix(_mv_cmd)
        }


        # current -> .1
        close(DLF_PAR["file_name"])
        _mv_cmd = sprintf("mv %s %s.1", DLF_PAR["file_name"], DLF_PAR["file_name"])
        dlf_msg(sprintf("I will change current log file \"%s\" \n", _mv_cmd))
        unix(_mv_cmd)


        # re-open current file.
        on(DLF_PAR["file_name"])

        if (  (DLF_PAR["nb_of_files"] < DLF_PAR["max_files"]) ||        \
              (DLF_PAR["max_files"] == -1)   )  {
            DLF_PAR["nb_of_files"] = DLF_PAR["nb_of_files"] + 1
            dlf_dbg(sprintf("Now %d log files", DLF_PAR["nb_of_files"]))
        }

   }
    else{
        print "ok file not too big (", _sizeh, ")"
    }
}'



###############################################################
####################                            ###############
####################   DEBUG AND INFO MESSAGES  ###############
####################                            ###############
###############################################################

need spec_utils

#%IU% (<msg>)
#%MDESC%
#    Prints a message in green.
def dlf_msg(msg) '{
    cprint(sprintf ("[dl]--%s\n", msg), 2)
}'


#%IU% (<debug_msg>, <level>)
#%MDESC%
#     Prints a debug message if debug level is activated.
def dlf_dbg(debug_msg, level) '{

    # level 1 = ?
    # level 2 = ?

    if (dlf_PAR["debug"] >= level) {

        if (level == 1){
            #                                                            3 = orange
            cprint(sprintf ("[dl]--DEBUG[%d]--%s\n", level, debug_msg), 3)
        }
        else if (level == 2){
            #                                                            3 0 1 = bold yellow
            cprint(sprintf ("[dl]--DEBUG[%d]--%s\n", level, debug_msg), 3,0,1)
        }
        else if(level >2){
            #                                                            7 0 1 = bold
            cprint(sprintf ("[dl]--DEBUG[%d]--%s\n", level, debug_msg), 7,0,1)
        }
    }
}'



#%UU% [<debug_level>]
#%MDESC%
#    Activates or desactivates the printing of debug messages.
def dlf_debug '{
    global dlf_PAR[]

    _nb_param = $#

    if(_nb_param){
        dlf_PAR["debug"] = $1>2 ? 2 : $1
        printf("[dl]--debug level : ")
        cprint(dlf_PAR["debug"], 1,0,1)
    }
    else{
        printf("[dl]--debug level : ")
        cprint(dlf_PAR["debug"], 1,0,1)
        print "\nusage : $0 [ <debug level (in 0..2)> ]"
        print ""
    }
}'




#%IU% (<err_msg>)
#%MDESC%
#    
def dlf_err(err_msg) '{
    cprint(sprintf ("[dl-ERROR]--%s\n", err_msg), 1)
}'




#%MACROS%
#%IMACROS%
#%TOC%
#%DEPENDENCIES%
#%AUTHOR% 
#%END%