2016/9/2編集 s/kuxuxun/tacogips/g
#何がしたい?
macがスリープしたり復帰したりした時刻を勝手に記録してほしい
#どうやる?
kernelと直接ごにょごにょやらなくてもOSXにはIOKitというものがあり、こいつでmacの起動イベントを受け取れる模様。
調べていくとIORegisterForSystemPower,IONotificationPortGetRunLoopSourceで起動時のハンドラの登録と監視を行うみたい感じらしい事はわかりつつも、意外にここらへんのドキュメントが少なくてちょっと時間かかりました。
最終的にこのページがざっくりわかりやすかったです(safariでしか見れません)
https://developer.apple.com/library/prerelease/mac/qa/qa1340/_index.html
新しいnotifierの構造体とコールバックを渡してイベント監視ループに混ぜてやれ、という事のようですね。
#書く
とりあえず、スリープを監視してgoの関数を呼び出すやつだけをcgo使って作ります
https://github.com/tacogips/mac_switch_watch
goのコード内にcを書くには、コメント内にCで書いて直後に
import "C"
cgoでgoからcのコードを呼び出す場合は
C.[cの関数名]()
その逆にcのコードからgoの関数を呼び出す場合は、goの関数コメントに//exportをつけるだけでOK。あら簡単
ただ、この時呼び出されるgo関数が呼び出すCのコードが書かれてるファイルと同じファイルに記述してあるとエラーになります。
cgoについてはyuroyoroさまのスライドがわかりやすいです
http://yuroyoro.net/trying_cgo/#/
#動かす
こいつを使ってスリープと起動した時に時刻をファイルに吐き出す代物をつくります
https://github.com/tacogips/log_mac_sleep
log_mac_sleep -watch
起動、スリープ、復帰のたびに下記のような時刻ログをホームディレクトリの下のファイルに吐き出しています。
start:2015-09-13 23_33_18
sleep:2015-09-13 23_38_40
wakeup:2015-09-13 23_40_08
sleep:2015-09-14 00_11_28
wakeup:2015-09-14 09_16_14
sleep:2015-09-14 09_44_14
デーモン化したければこんな感じのplistを書いて~/Library/LaunchAgents/にファイル置いてlaunchctl load /path/to/plistしてlaunchdに登録します。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>github.com.tacogips.log_mac_sleep</string>
<key>Disabled</key>
<false/>
<key>ProgramArguments</key>
<array>
<string>/path/to/log_mac_sleep</string>
<string>-watch</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
(ちなみにProgramArgumentsのパスに$GOPATH/bin/...とか書きたかったけど、環境変数をlaunchdに渡すのがうまくいかず断念してしまいました。。)
このログファイルでグラフ化すればどんだけ休憩とってるかが一目瞭然です
1日の開始と終業はコマンドで出せます。日報とか書く必要あるとかなら使えそう(実はこれするのが目的だったり)
log_mac_sleep -daily
6時間以上スリープしてたらその日の仕事は終わったぜということで