Rust でネストが深くなったけど未解決
前に行った into_iter() は無事動きました。何だったんだ。
今はこんな感じです。
perf_client/pdh_wrapper.rs at master · ROki1988/perf_client · GitHub
impl PdhController { pub fn new(path: Vec<PdhCounterPathElement>) -> Option<PdhController> { pdh_open_query() .map(|q| { let cs = path.into_iter() .filter_map(|e| { pdh_make_counter_path(&e) .and_then(|p| pdh_add_counter(q, p.as_str())) .map(|c| { PdhCollectionItem { element: e, hcounter: c, } }) .ok() }) .collect::<Vec<_>>(); PdhController { hquery: q, hcounters: cs, } }) .ok() } }
ふかい! ふかいんだよ…
依存があるのはそうだからしかたないけど、どうにかしたい。
do 記法とか for 内包表記とかにあたるものがあれば、まだましになるはず?
相変わらず PdhController
返してるあたりが胡散臭いけど、またあと。
Rust で Windows のパフォーマンスカウンターをとってみる
前回作った車輪の再発明!! 言い訳はしない!
色々頑張った結果…
fn main() { let path_list = vec!["\\Memory\\Available Mbytes"]; if let Some(pdhc) = PdhController::new(path_list) { let m = pdhc.current_values(); println!("{:?}", m); } }
main 関数がこうなりました。だーいぶ隠せたかな?
大まかな流れ
とりたいメトリクスの PATH 配列を入力として、カウンター取得のための構造体を作成。
current_values() を呼び出すたびにそのタイミングでの値が Vec で返ってくる寸法。
PDH_HQUERY の開放も、 PdhController がスコープ外になって消えるタイミングでやるように trait を実装。
改善すべき点
- 一番最初の HCOUNTER 取得から PdhController 生成の部分が胡散臭い。
- PATH の部分を文字列でなく PDH_COUNTER_PATH_ELEMENTS の wrapper なりにすれば、もうちょい使いやすくなるかも。
- 値を返すのでなく、値を順繰りとれる iter は実装中。
iter ができたら、送信部分つくってみるかー
OOP の勉強がてら Windows の Graphite クライアント書いた
動機
Windows のパフォーマンス計測をしたかったのです。
で、クライアントの計測なので、ランタイムインストールはよけたい所でもあったのです。
インストールする物が多かったり大きかったりすると、協力して貰いにくく…
C# 製の↓のがあったんで展開してみたわけです。
CryptonZylog/carbonator: Windows service that collects performance counters and reports metrics to a Graphite server
結果、CPU 使用率が 5% とかで、思った以上にくってたんですよ。
OOP とか色々勉強したけど、素振りばっかだなーってこともあったので、書きました。
ROki1988/PerfSrv
お仕事の環境と同じ、Delphi で書きました。
Rust で書こうとも思ったんですが、まず Windows の API 定義からだったので、とりあえず後回し。
何かちょうど良い感じのブログ
があったので、ここで計測していた23個のメトリクスで負荷計測。
取得周期は 1 秒毎。
結果
- CPU 使用率: 0.05%
- メモリ使用量(ワーキングセット): 15MB
- ディスク IO: 0
- ネットワークIO: 1KB/s
ディスクは書いてないですからね。そらそうだ。
結構かるい? と思ってます。
この辺は Rust や Golang の勉強を兼ねて作ってみて、比較できるようにしたいです。
需要が何処にあるかは定かでないですが。
動作確認等々
ローカルの動作確認では、下のアプリを使用しました。
Packet Sender - The Free UDP and TCP Network Test Utility
で、本番との接続は下のサービスを使用しました。
Hosted Graphite - Graphite and StatsD as a service, Grafana and Alertinghttps://t.co/Upk5uKZOm6
— rohki (@r_ohki) September 3, 2016
ここであそんでる
環境もっかい構築とか苦行ですし。
ただ…
社内で動かないという・・・
どーもネットワーク関係っぽいんですが、特定には至らず。
Hosted Graphite に繋がってよっしゃーとおもったらこのざまですよ。
(追記)Graphite の UDP 受信がデフォルト OFF のままだっただけでした orz
上は特定して直すとして、さらに色々粗々なので、直します。名前とか、設定ファイルとか。
OOP 的にもっと整理できそうですし、テストコードとかもちゃんと書かないとです。
OOP の話
は、土曜日にとっときます。話すネタがなくなる!!
Rust + Windows でウィンドウタイトルとかとってみる
なにしてんねん
社会人生活4年目で、Windows に染まりきってしまいました・・・
ShellScript で GCC ビルドをしていたあの頃にはもう・・・
さて
Rust をこのごろ触ってます。
で、Windows でも API がちょろっとあったので、試しにやってみました。
で、僕的に おー と思ったのが、この部分。
let mut title = vec![ 0u16; (length + 1) as usize ]; unsafe { user32::GetWindowTextW(whdl, title.as_mut_ptr(), length + 1); }
unsafe 何ていうから malloc/free なのかなーなんて思ってたんですが、するっと確保出来ました。
言われてみれば、たしかになー。頭固かった。
mut vec!
の as_mut_ptr()
を返せば、変更可能なメモリ領域ですよ。
僕みたいな API べたべた触る人間にはありがたい限りです。
つぎー
構造体がサンプルの哲学者ぐらいでしか書いてないので、そろそろちゃんと書きます。
trait とかもまだ。
構造体配列をとってきてとかも面白そうですね。
Lifetime? HAHAHA!
参考 URL
トラックボール生活 -1週目-
Bash on Windows の流行にのれてない rohki です。
試す時間が・・・
ELECOM マウス トラックボール 有線 6ボタン ブラック M-XT3URBK
- 出版社/メーカー: エレコム
- 発売日: 2015/10/17
- メディア: Personal Computers
- この商品を含むブログを見る
さて、使っていたマウスがなにやら不良になってきたので、上のトラックボールを購入してみました。
ので、使用感等々を書いてみます。
良かった点
- 肘がいたくならない
- 握りが良い感じ
- ボール転がすって結構気持ちいい
下2つについては、メリットというより感覚ですけど、こと毎日使う道具だからこの辺の直感は大事な気がします。
悪かった点
- 細かい操作に慣れるまで大変
- 戻るボタンが押しづらい
- 1週間たってボールが引っかかるようになった
細かい操作については、慣れの問題ですから良いんです。どうにかなってきました。
が、1番下がきつい・・・
さっきの感覚の話で言うなら、操作したのにカーソルが動いてくれないので、イラッとするんです。
ボールを代えるなり何なりで対策する予定。
ボールの引っかかりがどうにかなれば、おおむねよい買い物でした。
どうにかせねば。
ややこしい COM とスレッドの初期化(?)をコードにする
Windows に相も変わらずどっぷりの rohki です。
Windows には COM という便利な、便利な仕組みがあります。
この COM とスレッドが絡むと、アパートメントという仕組みが出てきます。
COM ライブラリを初期化する (Windows)
上記を参照すると、以下のように使い分けるとよい、とのこと。
- スレッドでウィンドウを作成するなら、アパートメント スレッド(COINIT_APARTMENTTHREADED)
- 持たないなら、マルチスレッド(COINIT_MULTITHREADED)
まぁ、だいたいはマルチスレッドでしょう。*1
この切り替えは、スレッドに対して CoInitializeEx
で設定します。*2
で、これ設定したら CoUninitialize
で解除しなきゃなんですが、いちいち気にしたくないです。
なんで、以下のようなクラスを作ってみるとよいかなーって考えてます。
TThread.Execute は final
でこのクラス以降で override
出来ないようにして、実質的な処理をかく関数を別に用意する形です。
こうすると利用する人はいちいち気にしなくても良いことになります。
Create
に CoInitializeEx
を書けば、って僕も一番最初思ったんですが、この設定は先ほどもあげたようにスレッドに対してする必要があるんです。
Create
処理を行うのは当然呼び出し元スレッドなので、生成されたスレッドに設定が適用されないままとなります。
だからわざわざこんなことしてます。
あー、ややこし。
プロセスごとの Disk IO がパフォーマンスカウンターの Process からじゃあとれない悲しみ
パフォーマンスカウンターでの性能計測は、テストや開発で行います…よね?
そこでタイトルの話ですよ。