プロセスの開始と停止を監視/記録するアプリまたはスクリプト?


5

アプリまたはスクリプトを起動し、数時間実行したままにしてから、戻ってきて、その時間に開始および停止したプロセスのログを確認できるようにしたいのです。これは、「ライブ」ビューのみを表示するアクティビティモニターまたはトップとは異なります。

たとえば、次のようなものです。

<timestamp> <pid> Safari started
<timestamp> <pid> ssh started
<timestamp> <pid> ssh stopped
<timestamp> <pid> Safari stopped

推奨事項はありますか?

編集して明確にします-監視したいプロセスの名前がまだわかりません-どのプロセスが開始/停止しているかを知りたいです。


元の回答を編集して、動的なソリューションを提供しました。名前を知らなくても、すべてのアプリケーション/プロセスをログに記録できるようになります。
E1Suave

回答:


3

次のスクリプトは、アプリケーション/プロセスの配列を動的に構築します。これは、起動前にすべてのプロセスを「知る」必要がないという意味で利点です。ただし、プロセスの数が増えるにつれてこの設計のために、新しいプロセスをアレイに追加するのに時間がかかることに注意することが重要です。これを補うために、スクリプトはアレイの内容をキャッシュに保存して、後で使用できるようにアレイに再度追加する必要を防ぎます。

また、プロセスが停止する前にアプリケーション/プロセスがアレイに動的にロードされていない場合、ロガーは「コマンド」列を空のままにします。これは、キャッシュされた情報に基づいて動的に構築されたアレイが構築されるにつれて、ますます少なくなります。前のポイントに追加します。列に「コマンド」が表示されない場合がありますが、アレイにすでに追加されています。これは、スクリプトで使用される「ソート」などの特定のプロセスが削除され、絶えず開始および停止する(ロガーに誤検知を追加する)ために発生する可能性があります。現在、データはファイル/ command_loggerに格納されます。もちろん、これは必要に応じて変更できます。構成ファイル/tmp/command_logger.plist 名前を変更したり移動したりすることもできますが、成長するApp / Process配列にデータを保持することに注意してください。

必要に応じて、次のスクリプトを自由に使用および変更してください。プライマリ環境で実行する前に、テスト環境を使用することを忘れないでください。楽しい。

テスト済み:

   10.5.x
   10.6.x
   10.7.4

出力には以下が含まれます。

  • 開始/停止
  • エポック(タイムスタンプ)
  • 日付時刻
  • PID
  • アプリケーションプロセス

command_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

こんにちは、それは素晴らしく、いくつかのアイデアが与えられました。ただし、開始するプロセスについてはスクリプトに通知してもらいたいのですが、監視するプロセス名はまだわかりません。
snowcrash09

@ snowcrash09ええ、それは少し異なります。配列に10、20、30の異なるプロセス/アプリケーションを含める場合、上記のスクリプトはまだ機能すると思います。特定のプロセス/アプリケーションを正確に「知らない」という点を理解していますが、意図が完全に未知のプロセス/アプリケーションを監視しない限り、必要なことを実行できます。
E1Suave

@ snowcrash09元の回答を編集して、動的なソリューションを提供しました。名前を知らなくても、すべてのアプリケーション/プロセスをログに記録できるようになります。
E1Suave

@ snowcrash09新しいスクリプトに幸運はありましたか?
E1Suave

はい、ありがとうございます!既存のプロセスを開始時として誤ってログに記録するようですが、ここから取得できます。
snowcrash09

1

あなたは見たことがありfseventerを

これにより、ファイルシステムのアクティビティをグラフィカルに表示できます。また、必要以上に多くの処理を実行できますが、アプリケーションの起動と終了もリストできます(フィルタリングして、他の不要なイベントを削除できます)。必要)。


0

事実上、トップが行っているのはプロセスマネージャーのサンプリングです。プロセスマネージャには、UnixレベルのC API、CocoaレベルのObj-C API、およびもちろんコマンドPSおよびTOPがあります。

あなたが探しているのは、スクリプトよりももう少しプログラミングが必要だと思います。また、そのような獣が存在するかどうか(確信はありませんが)、Macアプリケーションを無料で見つけることはできないと思います。

「プロセスロガー」を探し回ると、オープンソースコミュニティ(Google Code、Gitなど)で見つけることができるかもしれません。

独自のスピンを考えている場合。ここではなくStackOverflowについて尋ねることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.