The situation is like that: Applications can use the syslog(3) API and the asl(3) API to log messages, other data logged can come from the kernel or from the network. All of these messages are handed over to the syslog Daemon: syslogd(8). The syslogd now outputs log messages both the BSD way (it writes stuff into various basic log files like /var/log) and into a unified log message store (/var/log/asl.log).
If you want certain log messages not to appear in your log files (eg. you read logs like system.log by selecting them in Console.app), you will need to configure syslog.conf(5) like chiggsy said. If you want messages not to be stored in the asl database, you will need to configure asl.conf(5).
If, for example, you do not longer want Bonjour's (mDNSResponders) Log messages to be stored in the ASL db, you will need to add the following line to /etc/asl.conf :
? [= Sender mDNSResponder] ignore
… and then "gently" restart the syslogd by:
sudo killall -HUP syslogd
Now, messages from mDNSResponder will no longer appear when you go into Console.app's "all messages", but still exist within your logfiles.
Lastly, if you call syslog(1) from the command line, it acts as a nice frontend for querying the ASL db - you could for example ask it to show all messages from the Time Machine Backup starter that were logged in the last two hours by running:
syslog -k Facility -k Sender com.apple.backupd-auto -k Time ge −2h
…which explains, why the ASL db is handy: you can search for log files simultaneously in "all log files".
The following script builds an array of Applications/Processes dynamically. This is an advantage in the sense that you do not need to "know" every process prior to its launch. However, it is important to note that due to this design as the number of processes grow the longer it will take to add a new process to the array. To compensate for this the script keeps the contents of the array cached so as to use them later preventing the need to re-add them to the array.
ALSO: If the Application/Process has not been dynamically loaded into the array prior to the process stopping the logger will leave the "Command" column empty. This will become less and less likely as your dynamically built array builds upon its cached information. Adding to the previous point. At times a "Command" may not be shown in the column yet it has already been added to the array. This is likely caused by the fact that certain process's like "sort" have been removed as they are used in the script and would be constantly starting and stopping (adding false positives to the logger). Currently the data will be put into the file /command_logger. This of course can be changed as you see fit. The config file /tmp/command_logger.plist can also be renamed/moved but remember that it holds the data to the growing App/Process array.
Please feel free to use and modify the following script as you see fit. Please remember to utilize a testing environment prior to running on your primary environment. Enjoy.
Tested on:
• 10.5.x
• 10.6.x
• 10.7.4
The output will include the following:
- STARTED/STOPPED
- Epoch (timestamp)
- Date/Time
- PID
- Application/Process
NOTE: The following script includes an internal loop.
DYNAMIC APP/PROCESS LOGGER
#!/bin/bash
On="true"
TMP="/tmp/command_logger"
LOG_CONFIG="/command_logger.plist"
LOG="/command_logger"
if [[ ! -e ${TMP} ]]; then
mkdir ${TMP}
if [[ ! -e ${TMP}${LOG_CONFIG} ]]; then
/usr/libexec/PlistBuddy -c "Add:Commands Dict" ${TMP}${LOG_CONFIG} > /dev/null 2>&1
fi
elif [[ -e ${TMP} ]]; then
if [[ ! -e ${TMP}${LOG_CONFIG} ]]; then
/usr/libexec/PlistBuddy -c "Add:Commands Dict" ${TMP}${LOG_CONFIG} > /dev/null 2>&1
find ${TMP} -type f ! -name '*.plist' -exec rm -f {} \;
elif [[ -e ${TMP}${LOG_CONFIG} ]]; then
find ${TMP} -type f ! -name '*.plist' -exec rm -f {} \;
fi
fi
if [[ ! -e ${LOG} ]]; then
echo -e "Status\tTimestamp\tDate/Time\t\tPID\tCommand\n" > ${LOG}
elif [[ -e ${LOG} ]]; then
TITLE=$(head -1 ${LOG} | awk '{print $1}')
if [[ ${TITLE} != "Status" ]]; then
echo -e "Status\tTimestamp\tDate/Time\t\tPID\tCommand\n" > ${LOG}
fi
fi
while [[ ${On} == "true" ]]; do
IFS=""
Live_Array=$(ps -Ac | sed 's/ /|/g' | sed 's/ /_/g' | sed 's/[[:digit:]]_.*[[:digit:]]_/ /g' | sed 's/:/!/' | sed 's/$/.comm/' | sed 's/^_//g' | sed 's/^|//g' | sed 's/^_//g' | sed 's/^|.*//g' | sed 's/ $//g' | sed 's/_$//g' | sed 's/|$//g' | sed 's/PID_TTY||.*//g' | awk '{print $2}' | sed 's/.*-sh.*//' | sed 's/.*CMD.*//' | sed 's/.*PID.*//' | sort -u | grep "[[:graph:]]" | tr -s "[\n]" "[,]")
Live_Array=$(echo ${Live_Array%\,})
IFS=","
Live_Array_2=( $Live_Array )
livarray=${#Live_Array_2[@]}
for (( liv=0; liv<${livarray}; liv++ ));
do
/usr/libexec/PlistBuddy -c "Add:Commands:${Live_Array_2[$liv]} bool true" ${TMP}${LOG_CONFIG} 2> /dev/null
Config_Array=$(/usr/libexec/PlistBuddy -c "Print:Commands" ${TMP}${LOG_CONFIG} | grep "=" | sed 's/=.*//' | sed 's/ //g' | sed 's/^.comm//' | sed 's/ $//g' | grep "[[:graph:]]" | tr -s "[\n]" "[,]")
Config_Array_2=( $Config_Array )
conarray=${#Config_Array_2[@]}
for (( con=0; con<${conarray}; con++ ));
do
STRING=$(ps -Ac | sed 's/ /|/g' | sed 's/ /_/g' | sed 's/[[:digit:]]_.*[[:digit:]]_/ /g' | sed 's/:/!/' | sed 's/$/.comm/' | sed 's/^_//g' | sed 's/^|//g' | sed 's/^_//g' | sed 's/^|.*//g' | sed 's/|_.comm/.comm/g' | sed 's/PID_TTY||.*//g' | awk '{print $2,$1}' | sed 's/.*-sh.*//' | sed 's/.*CMD.*//' | sed 's/.*PID.*//' | sort -u)
Launched_Command=$(echo ${STRING} | awk '{print $1}' | sort -u | awk "/${Config_Array_2[$con]}/")
PID=$(echo ${STRING} | sort -u | awk '{print $2,$1}' | awk "/${Config_Array_2[$con]}/" | sed 's/ .*//')
if [[ ${Launched_Command} != "" ]] && [[ ${PID} != "" ]]; then
DATE=$(date "+%m-%d-%Y %T")
EPOCH=$(date "+%s")
if [[ ${Launched_Command} == ${Config_Array_2[$con]} ]] && [[ ! -e ${TMP}/${Config_Array_2[$con]}-RUNNING ]]; then
echo -e "STARTED\t${EPOCH}\t${DATE}\t${PID}\t${Config_Array_2[$con]}" | sed 's/.comm$//g' | sed 's/_/ /g' | sed 's/.*sort.*//g' | sed 's/.*sed.*//g' | sed 's/awk//g'| awk '/STARTED/' >> ${LOG}
rm -f ${TMP}/${Config_Array_2[$con]}-STOPPED
touch ${TMP}/${Config_Array_2[$con]}-RUNNING
elif [[ ${Launched_Command} == ${Config_Array_2[$con]} ]] && [[ -e ${TMP}/${Config_Array_2[$con]}-RUNNING ]]; then
:
elif [[ ${Launched_Command} == ${Config_Array_2[$con]} ]] && [[ -e ${TMP}/${Config_Array_2[$con]}-RUNNING ]]; then
if [[ -e ${TMP}/${Config_Array_2[$con]}-STOPPED ]]; then
:
elif [[ ! -e ${TMP}/${Config_Array_2[$con]}-STOPPED ]]; then
echo -e "STOPPED\t${EPOCH}\t${DATE}\t${PID}\t${Config_Array_2[$con]}" | sed 's/.comm$//g' | sed 's/_/ /g' | sed 's/.*sort.*//g' | sed 's/.*sed.*//g' | sed 's/awk//g' | awk '/STOPPED/' >> ${LOG}
rm -f ${TMP}/${Config_Array_2[$con]}-RUNNING
touch ${TMP}/${Config_Array_2[$con]}-STOPPED
fi
fi
elif [[ ${Launched_Command} == "" ]] && [[ -e ${TMP}/${Config_Array_2[$con]}-RUNNING ]]; then
if [[ -e ${TMP}/${Config_Array_2[$con]}-STOPPED ]]; then
:
elif [[ ! -e ${TMP}/${Config_Array_2[$con]}-STOPPED ]]; then
echo -e "STOPPED\t${EPOCH}\t${DATE}\t${PID}\t${Config_Array_2[$con]}" | sed 's/.comm$//g' | sed 's/_/ /g' | sed 's/.*sort.*//g' | sed 's/.*sed.*//g' | sed 's/awk//g' | awk '/STOPPED/' >> ${LOG}
rm -f ${TMP}/${Config_Array_2[$con]}-RUNNING
touch ${TMP}/${Config_Array_2[$con]}-STOPPED
fi
fi
done
done
done
Best Answer
AirServer implements a basic AppleScript interface which can tell you if AirServer is in use by calling:
osascript -e "tell application \"AirServer\" to inUse"
Another approach is create a basic app which monitors AirServer's notifications using NSDistributedNotificationCenter:
com.airserverapp.MirroringDidStart, com.airserverapp.MirroringDidStop, com.airserverapp.AudioDidStart, com.airserverapp.AudioDidStop, com.airserverapp.VideoDidStart, com.airserverapp.VideoDidStop