Lately I've been working on creating a function in bash so that I can generically call MaxL scripts and process return codes from them so that I can do some error handling and possibly send a notification via email or SMS message depending on the situation. How the essbase_run_task function works is like this:
You call the function essbase_run_task and pass it two values. The first one is the name of the app and the second is an action, like export, import, or compact. Then in the $script_dir directory you have all your MaxL scripts that would be named like so: appname '_' action.mxl. So a Maxl script for example that was for exporting data for app1 would be named app1_export.mxl, etc ... So the essbase_run_task function will validate that the script actually exists before attempting to run it.
This is a simple MaxL script to perform an export and return an exit code depending on the situation.
app1_export.mxl
/*
$1 = script directory
$2 = logfile
$3 = errfile
*/
msh "$1/init.mxl";
set timestamp on;
set message level error;
spool stdout on to "$2";
spool stderr on to "$3";
login $USER $PASSWORD on $SERVER;
IfError 'loginErr';
echo "exporting app1.appDb"
alter system logout session on application app1;
alter application app1 disable connects;
alter system kill request on application app1;
shell sleep 40;
alter application app1 unload database appDb;
alter system unload application app1;
alter system load application app1;
alter application app1 load database appDb;
export database app1.appDb level0 data to data_file 'app1_export.txt';
IfError exportErr;
alter application app1 enable connects;
spool off;
exit 0;
Define Label 'loginErr';
echo "Error Logging in $USER to $SERVER";
spool off;
logout;
exit 2;
Define Label exportErr;
exit 1;
A few key features in this MaxL script is that when calling the script from the bash function I'm passing in three values. The directory the MaxL scripts are contained in, the STDOUT logfile location and the STDERR errfile log file location. The MaxL script first calls / loads the init.mxl script with contains the variables to login to the server. This makes the main scripts portable and only requires editing of one file when move the scripts from DEV -> QA/TEST->Production. The rest of the export piece is typical Essbase stuff. The important parts are the IfError statements. These set the exit code accordingly based on if any errors occured during the running of the MaxL script. Any errors are captured and processed then by the bash function.
essbase_run_task () {
# $1 = app
# $2 = action - to perform
automation_dir="/${EPMENV}/scripts/Automation"
script_dir="${automation_dir}/scripts"
logpath="${automation_dir}/logs"
maxl=${EPM_ORACLE_INSTANCE}/EssbaseServer/essbaseserver1/bin/startMaxl.sh
mxl_script="${script_dir}/$1_$2.mxl"
logfile="${logpath}/$(basename ${mxl_script} | cut -d. -f1).log"
errfile="${logpath}/$(basename ${mxl_script} | cut -d. -f1).err"
log "${FUNCNAME[0]}" "APP: $1 ACTION: $2"
# Verify mxl script and execute, return status code
if [ -e "${mxl_script}" ]
then
#log "${FUNCNAME[0]}" "${maxl} ${mxl_script} ${script_dir} ${logfile} ${errfile}"
# Arguments passed into MaxL script
# $1 = script_path
# $2 = logfile
# $3 = errfile
${maxl} ${mxl_script} ${script_dir} ${logfile} ${errfile}
mxlstatus=$?
else
echo "Error: ${mxl_script} does not exist."
exit 1
fi
#process mxl status
case ${mxlstatus} in
0)
#no errors
log "${FUNCNAME[0]}" "Completed Successfully. See ${logfile} for details."
;;
1|2)
#errors exist
log "${FUNCNAME[0]}" "Errors Occured: $(cat ${errfile})"
notify smtp "${RECIPIENTS}" "errors occured running $(basename ${mxl_script}) on ${HOSTNAME}" "${errfile}"
;;
esac
}
You call the function essbase_run_task and pass it two values. The first one is the name of the app and the second is an action, like export, import, or compact. Then in the $script_dir directory you have all your MaxL scripts that would be named like so: appname '_' action.mxl. So a Maxl script for example that was for exporting data for app1 would be named app1_export.mxl, etc ... So the essbase_run_task function will validate that the script actually exists before attempting to run it.
This is a simple MaxL script to perform an export and return an exit code depending on the situation.
app1_export.mxl
/*
$1 = script directory
$2 = logfile
$3 = errfile
*/
msh "$1/init.mxl";
set timestamp on;
set message level error;
spool stdout on to "$2";
spool stderr on to "$3";
login $USER $PASSWORD on $SERVER;
IfError 'loginErr';
echo "exporting app1.appDb"
alter system logout session on application app1;
alter application app1 disable connects;
alter system kill request on application app1;
shell sleep 40;
alter application app1 unload database appDb;
alter system unload application app1;
alter system load application app1;
alter application app1 load database appDb;
export database app1.appDb level0 data to data_file 'app1_export.txt';
IfError exportErr;
alter application app1 enable connects;
spool off;
exit 0;
Define Label 'loginErr';
echo "Error Logging in $USER to $SERVER";
spool off;
logout;
exit 2;
Define Label exportErr;
exit 1;
A few key features in this MaxL script is that when calling the script from the bash function I'm passing in three values. The directory the MaxL scripts are contained in, the STDOUT logfile location and the STDERR errfile log file location. The MaxL script first calls / loads the init.mxl script with contains the variables to login to the server. This makes the main scripts portable and only requires editing of one file when move the scripts from DEV -> QA/TEST->Production. The rest of the export piece is typical Essbase stuff. The important parts are the IfError statements. These set the exit code accordingly based on if any errors occured during the running of the MaxL script. Any errors are captured and processed then by the bash function.
essbase_run_task () {
# $1 = app
# $2 = action - to perform
automation_dir="/${EPMENV}/scripts/Automation"
script_dir="${automation_dir}/scripts"
logpath="${automation_dir}/logs"
maxl=${EPM_ORACLE_INSTANCE}/EssbaseServer/essbaseserver1/bin/startMaxl.sh
mxl_script="${script_dir}/$1_$2.mxl"
logfile="${logpath}/$(basename ${mxl_script} | cut -d. -f1).log"
errfile="${logpath}/$(basename ${mxl_script} | cut -d. -f1).err"
log "${FUNCNAME[0]}" "APP: $1 ACTION: $2"
# Verify mxl script and execute, return status code
if [ -e "${mxl_script}" ]
then
#log "${FUNCNAME[0]}" "${maxl} ${mxl_script} ${script_dir} ${logfile} ${errfile}"
# Arguments passed into MaxL script
# $1 = script_path
# $2 = logfile
# $3 = errfile
${maxl} ${mxl_script} ${script_dir} ${logfile} ${errfile}
mxlstatus=$?
else
echo "Error: ${mxl_script} does not exist."
exit 1
fi
#process mxl status
case ${mxlstatus} in
0)
#no errors
log "${FUNCNAME[0]}" "Completed Successfully. See ${logfile} for details."
;;
1|2)
#errors exist
log "${FUNCNAME[0]}" "Errors Occured: $(cat ${errfile})"
notify smtp "${RECIPIENTS}" "errors occured running $(basename ${mxl_script}) on ${HOSTNAME}" "${errfile}"
;;
esac
}
# notify is a wrapper function I created to send an email or sms message.
notify () {
# Send notification to recipients
# $1 protocol ( Valid values: smtp ) Can be extended for other ways to notify, possibly SMS
# $2 recipients
# $3 subject
# $4 message/attachment
case $1 in
"smtp")
if [ -e "$4" ]
then
log ${FUNCNAME[0]} "sending notification $(mail -s "$3" "$2" <"$4")"
else
log ${FUNCNAME[0]} "sending notification $(echo "$4" | mail -s "$3" "$2")"
fi
;;
esac
}
So that's all I have for now regarding MaxL script processing. --Enjoy!!
Comments
Post a Comment