Hello.
–UPDATE: added contextual menuitem for inserting an try error block with logger statement within.
WHAT IT IS – README.txt
This is a solution which enables you to easily log the activity of a script to a separate
file to during debugging and experimenting to a predefined folder of your choice.
Copy the logger script object to the end of your script, create the global error handler AFTER the
put in logger statements where appropriate and off you go logging to a file which pops up
when the script is done, provided that you have installed a folder action on the logfile folder.
“EXAMPLE SKELETON THAT USES THE LOGGER SCRIPT WITHOUT THE ACTUAL SCRIPT”
tell logger to run -- MUST BE INCLUDED BEFORE YOUR MAIN ERROR HANDLER
try -- MAIN ERROR HANDLER
logger's logThis("Starting my script")
--
-- Your normal program is here.
--
logger's logThis("Last regular statement of the script has been executed")
logger's flushLogFile()
on error e number n
display dialog " " & e & " Number : " & n
logger's flushLogFile()
end try
– the logger script object is place somewere here.
There is also a separate installer version which when installed can be reached from the context menu of the AppleScriptEditor which inserts the logger script object into your source file on a blank line,
together with the initial run statement. There are alose menu items for logger statments and flushLogFile. Even an alternative logger statement which writes to the file directly, -for those low
on memory.
Everything can easily be removed when the initial debugging of the script is finished. Or just let be if it was just an experiment.
WHAT IT CONSISTS OF
“README” - Description of the whole solution.
"INSTALLATION" - Installation instructions.
"VANILLA LOGGER SCRIPT" - A script object for manually insertion into your script.
"APPLE SCRIPT LOGGER MENUITEM" - The same script but for installation into
AppleScript Editor's contextual menu.
"LOGGER STATEMENT" - Script to be installed into AppleScript Editor's contextual
menu. To insert a logger statement in your script.
"CLEANUP STATEMENT" - Script to be installed into AppleScript Editor's contextual
menu. To insert a flushLogFile statement in your on error block.
"ALTERNATIVE LOGGER STATEMENT" - For those who don't whish to use the folder action.
Or runs low on memory. -They must call showLogfile explicitly.
"ALTERNATIVE CLEANUP STATEMENT"
"CONTEXT MENU ITEM FOR INSERTING AND TRY ON ERROR BLOCK WITH LOG STATEMENT"
"REFERENCES"
HOW IT WORKS
Requirements
A logger scriptobject must be inserted into your script and run.
A Global error handler that calls the logger's flushLogFile handler.
Insertion of a flushLogFile handler in every error handler.
A call to the flushLogFile handler as the last statement in your script.
Preparations
A script object must be is inserted into your script together with logging statements.
The logger scriptobject must be run, and logger statement must be inserted at the places
you want to keep track of stuff; stuff must be converted to text before passed to the
logger handler.
You must insert logger statements in order to log various informations into the log file.
You must insert a flushLogFile statement in order to close the file when you encounter a
runtime error, this implies that you have to have a global runtime hander around your whole
script or in the run handler of your script.
Runtime:
The logger script object makes up the log file name of the name of script it resides in.
It then creates/overwrites any file with a similiar name in the log file folder. *NOTES
It then outputs log statements you have inserted into the logfile when the script is finished.
NOTES
Cleanup: I tend to use a centralized handler which I stuff with everything that needs to be done before
I can exit both normally and abnormally.
Runtime:
If you want to compare the output of different versions of the script just name the scripts differently.
ex:
The different versions of the same script:
myscript.scptd myscript01.scptd myscript02.scptd myscript03.scptd
will be store in your log directory as:
myscript.txt myscript01.txt myscript02.txt myscript03.txt
This makes it easy to compare the different results of the different versions if you either
use some commandline tool like diff from a terminal window, or if you choose to use filemerge
which can be found in the xcode developer tools. There are also some applescripts out there
which can be used for comparing text files.
The log files are stored as text files for easy access,and shows up autmagically in TextEdit
when the script is done.
REFERENCES
The basis where stolen from AppleScript Guidebook of Bill Cheesman.
Some subroutines reworked from AS the definitive Guide by Matt Neburg.
Some subroutines was looted from AS Sdk.
The Idea of making contextual menui tems in the AppleScript Editor was stolen from
AppleScript Developer Kit from scripts by Sal Sohoigan.
The basics where learnt by:
AppleScript the definitive Guide By Matt Neuburg.
The Applescript Language Guide
The Applescript Scripting Additions guide.
The Applescript Finder Guide
– EOF README
INSTALLATION
Create the folder to store the logger files in
( I have chosen to create one in my documents folder and create an alias to that folder onto
my Desktop for easy access ).
The vanilla script for logging which you must manually insert into your script
Copy "VANILLALOGGERSCRIPT" further below of this post and paste it into your editor.
Save it somewhere you can easily find it.
Edit the script and edit the path to the logfile in it.This is done by finding the text LOGPATH in
the script and replace it whith the path to your logfiles folder.
Simply remove "LOGPATH and just drag the Folder from finder into the script. Choose
alias when prompted if you want to paste the entire contents.
This script is later used as template and you will copy its contents into the script you currently
want to log.
The AppleScriptEditorMenuEditorItem
Copy "APPLESCRIPTLOGGERMENUITEM" further below of this post and paste it into your editor.
While using the AppleScript editor you can access the context menu by rightc clicking, select
the menuitem for this script and get the script inserted into your current script by pasting the
clipboard.
Edit the AppleScriptEditorMenuEditorItem
Find the text LOGPATH in the script, and store this script in "/Library/Scripts/Script Editor
Scripts/" where ever you find it natural within this domain, so so that you can just right click in
the current script file to copy the script into the clipboard to ease installing the script.
The logger statement
Copy the "LOGGER STATEMENT" from below into your editor and save it where ever you find it
natural within the "/Library/Scripts/Script Editor Scripts/" domain.
Save it with the name LoggerStatement.
This is so that you can just right click in the current script to insert the logger statement onto
the clipboard which you then can paste into your script.
The flushLogFile statement
Copy the "FLUSH STATEMENT" from below into your editor and save it where ever you find it
natural within the "/Library/Scripts/Script Editor Scripts/" domain.
Save it with the name CleanupStatement.
This is so that you can just right click in the current script to insert the flushLogFile statement onto
the clipboard which you then can paste into your script.
If you have followed the steps you found neccesary you are now good to go!
– EOF INSTALLATION
“VANILLALOGGERSCRIPT”
– see README in the post for explanation. If no copyright is mentioned it is mine
– but put in the public domain. Use it as you will but if you republish anything with
– explicit copyright notice over it; please keep the copyright notice .
tell logger to run -- MUST BE INCLUDED BEFORE YOUR MAIN ERROR HANDLER
script logger
property logFolderPath : "LOGPATH" -- posixpath
on run
global logList, logFileName
set myName to my internal's myShortName()
set pxLogfileName to logFolderPath & "/" & myName & ".txt"
set mydata to "This is all my data so far\n\t\t and so be it"
if my internal's posixPathExist(pxLogfileName) then
if not my internal's deletePosixFile(pxLogfileName) then
display alert "Logger: Couldn't delete " & pxLogfileName & " hmm. exiting"
error number -128
end if
end if
set logFileName to my internal's macStylePathName(pxLogfileName)
set logFileName to the logFileName as text
-- prep of the list to store data in
set logList to {}
-- :)
end run
on logThis(theStatement) -- ex: logger's logThis(" a has now a value of : " & a )
set theStatement to theStatement & "\n"
set end of my logList to theStatement
end logThis
on logThisDirectly(theStatement) -- for those low on memory
set theStatement to theStatement & "\n"
try
set the open_target_file to open for access the file (my logFileName) with write permission
write this_data to the open_target_file starting at eof
close access the open_target_file
return true
on error
try
close access the open_target_file
display alert "Logger: IOerror in " & pxLogfileName & "While trying to close the file exiting"
error number -128
end try
return false
end try
end logThisDirectly
on flushLogFile() -- flushes the log into logfile on disk. ( the flushLogFile )
try
set the open_target_file to open for access the file (my logFileName) with write permission
set eof of the open_target_file to 0 --> remove this line if you want written data appended to existing data
repeat with aLogStatement in my logList
write aLogStatement to the open_target_file starting at eof
end repeat
close access the open_target_file
on error
try
close access the open_target_file
display alert "Logger: IOerror in " & pxLogfileName & "While trying to close the file exiting"
end try
return false
end try
my showLogFile()
end flushLogFile
on showLogFile() -- intended to be used with logThisDirectly
tell application "Finder" to open my logFileName as alias
end showLogFile
script internal
on macStylePathName(posixStylePathName)
return (POSIX file posixStylePathName as Unicode text)
end macStylePathName
on deletePosixFile(posixFn)
local fRef, success
if not posixPathExist(posixFn) then return missing value
set success to true
set fRef to a reference to POSIX file posixFn as alias
tell application "Finder"
try
delete file fRef as alias
on error
set success to false
end try
end tell
return success
end deletePosixFile
on posixPathExist(s)
try
POSIX file s as alias
on error
return false
end try
return true
end posixPathExist
on myShortName()
local myNameShort
set myNameShort to my extract_shortname_from(extract_filename_from(path to me as Unicode text))
log myNameShort
return myNameShort
end myShortName
(* Sal Soghoian ©1998 Apple Computer *)
on extract_filename_from(the_filepath)
set the_filepath to the_filepath as text
set x to the offset of ":" in (the reverse of every character of the_filepath) as string
return ((characters -(x - 1) thru -1 of the_filepath) as text)
end extract_filename_from
(* Sal Soghoian ©1998 Apple Computer *)
on extract_shortname_from(the_filepath)
set the_filepath to the_filepath as text
set x to the offset of "." in (the reverse of every character of the_filepath) as string
-- return ((characters -(x - 1) thru -1 of the_filepath) as text)
return ((characters 1 thru -(x + 1) of the_filepath) as text)
end extract_shortname_from
end script
end script
EOF “VANILLALOGGERSCRIPT”
“APPLE SCRIPT LOGGER MENUITEM”
set the clipboard to "tell logger to run" -- MUST BE INCLUDED BEFORE YOUR MAIN ERROR HANDLER
script logger
property logFolderPath : \"LOGPATH\" -- posixpath
on run
global logList, logFileName
set myName to my internal's myShortName()
set pxLogfileName to logFolderPath & \"/\" & myName & \".txt\"
set mydata to \"This is all my data so far\n\t\t and so be it\"
if my internal's posixPathExist(pxLogfileName) then
if not my internal's deletePosixFile(pxLogfileName) then
display alert \"Logger: Couldn't delete \" & pxLogfileName & \" hmm. exiting\"
error number -128
end if
end if
set logFileName to my internal's macStylePathName(pxLogfileName)
set logFileName to the logFileName as text
-- prep of the list to store data in
set logList to {}
end run
on logThis(theStatement) -- ex: logger's logThis(\" a has now a value of : \" & a )
set theStatement to theStatement & \"\n\"
set end of my logList to theStatement
end logThis
on logThisDirectly(theStatement) -- for those low on memory
set theStatement to theStatement & \"\n\"
try
set the open_target_file to open for access the file (my logFileName) with write permission
write this_data to the open_target_file starting at eof
close access the open_target_file
return true
on error
try
close access the open_target_file
display alert \"Logger: IOerror in \" & pxLogfileName & \"While trying to close the file exiting\"
error number -128
end try
return false
end try
end logThisDirectly
on flushLogFile() -- flushes the log into logfile on disk. ( the flushLogFile )
try
set the open_target_file to open for access the file (my logFileName) with write permission
set eof of the open_target_file to 0 --> remove this line if you want written data appended to existing data
repeat with aLogStatement in my logList
write aLogStatement to the open_target_file starting at eof
end repeat
close access the open_target_file
on error
try
close access the open_target_file
display alert \"Logger: IOerror in \" & pxLogfileName & \"While trying to close the file exiting\"
end try
return false
end try
my showLogFile()
end flushLogFile
on showLogFile() -- intended to be used with logThisDirectly
tell application \"Finder\" to open my logFileName as alias
end showLogFile
script internal
on macStylePathName(posixStylePathName)
return (POSIX file posixStylePathName as Unicode text)
end macStylePathName
on deletePosixFile(posixFn)
local fRef, success
if not posixPathExist(posixFn) then return missing value
set success to true
set fRef to a reference to POSIX file posixFn as alias
tell application \"Finder\"
try
delete file fRef as alias
on error
set success to false
end try
end tell
return success
end deletePosixFile
on posixPathExist(s)
try
POSIX file s as alias
on error
return false
end try
return true
end posixPathExist
on myShortName()
local myNameShort
set myNameShort to my extract_shortname_from(extract_filename_from(path to me as Unicode text))
log myNameShort
return myNameShort
end myShortName
(* Sal Soghoian ©1998 Apple Computer *)
on extract_filename_from(the_filepath)
set the_filepath to the_filepath as text
set x to the offset of \":\" in (the reverse of every character of the_filepath) as string
return ((characters -(x - 1) thru -1 of the_filepath) as text)
end extract_filename_from
(* Sal Soghoian ©1998 Apple Computer *)
on extract_shortname_from(the_filepath)
set the_filepath to the_filepath as text
set x to the offset of \".\" in (the reverse of every character of the_filepath) as string
-- return ((characters -(x - 1) thru -1 of the_filepath) as text)
return ((characters 1 thru -(x + 1) of the_filepath) as text)
end extract_shortname_from
end script
end script"
EOF “APPLE SCRIPT LOGGER MENUITEM”
“LOGGER STATEMENT”
set the clipboard to "logger's logThis(\"\")"
EOF “LOGGER STATEMENT”
“CLEANUP STATEMENT”
set the clipboard to "logger's flushLogFile()"
EOF “CLEANUP STATEMENT”
“ALTERNATIVE LOGGER STATEMENT”
set the clipbard to "logger's logThisDirectly(\"\")"
EOF “ALTERNATIVE LOGGER STATEMENT”
“ALTERNATIVE CLEANUP STATEMENT”
set the clipbard to "logger's showLogFile()"
EOF “ALTERNATIVE CLEANUP STATEMENT”
“CONTEXT MENU ITEM FOR INSERTING AND TRY ON ERROR BLOCK WITH LOG STATEMENT”
(*
Message and OK
Copyright © 2001“2007 Apple Inc.
You may incorporate this Apple sample code into your program(s) without
restriction. This Apple sample code has been provided "AS IS" and the
responsibility for its operation is yours. You are not permitted to
redistribute this Apple sample code as "Apple sample code" after having
made changes. If you're going to redistribute the code, we require
that you make it clear that the code was descended from Apple sample
code, but that you've made changes.
------------------------------------------------------------------------------
This script was originally created by apple but are modified to me in order to
insert an error handler with a logger statement. into a try errror block.
Save it in the Machines Script Editor Scripts 's Error handlers and name it
To use it, select som code you'd like to wrap an error handler block about
and run the script by right clicking. - or using it from the scripts menu.
-------------------------------------------------------------------------------
*)
set CR to ASCII character 13
set NL to ASCII character 10
tell application "AppleScript Editor"
tell front document
set the target_string to "--XXXX"
set the selected_text to contents of selection
if the selected_text is "" then
set the selected_text to the target_string
set the script_text to ""
set the script_text to the script_text & "try" & return
set the script_text to the script_text & tab & the target_string & return
set the script_text to the script_text & "on error the error_message number the error_number" & return
set the script_text to the script_text & tab & "-- display dialog \"Error: \" & the error_number & \". \" & the error_message buttons {\"OK\"} default button 1" & return
set the script_text to the script_text & tab & "logger's logThis(\"Error: \" & the error_number & \". \" & the error_message)" & return
set the script_text to the script_text & "end try" & return
set the replacement_string to "-- insert actions here"
else
set the script_text to ""
set the script_text to the script_text & "try" & return
if last character of selected_text is in {CR, NL} then
set the script_text to the script_text & tab & the selected_text
else
set the script_text to the script_text & tab & the selected_text & CR
end if
set the script_text to the script_text & tab & "--display dialog \"Error: \" & the error_number & \". \" & the error_message buttons {\"OK\"} default button 1" & return
set the script_text to the script_text & "on error the error_message number the error_number" & return
set the script_text to the script_text & tab & "logger's logThis(\"Error: \" & the error_number & \". \" & the error_message)" & return
set the script_text to the script_text & "end try" & the target_string & return
set the replacement_string to ""
end if
set contents of selection to script_text
try
check syntax
end try
my replace_and_select(target_string, replacement_string)
try
check syntax
end try
end tell
end tell
on replace_and_select(target_string, replacement_string)
tell application "AppleScript Editor"
tell the front document
set this_text to the contents
set this_offset to the offset of the target_string in this_text
if this_offset is not 0 then
set selection to characters this_offset thru (this_offset + (length of the target_string) - 1)
set the contents of the selection to the replacement_string
end if
end tell
end tell
end replace_and_select
EOF “CONTEXT MENU ITEM FOR INSERTING AND TRY ON ERROR BLOCK WITH LOG STATEMENT”