forked from heroku/erlang-in-anger
-
Notifications
You must be signed in to change notification settings - Fork 9
/
105-runtime-metrics-ja.tex
743 lines (601 loc) · 73.2 KB
/
105-runtime-metrics-ja.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
%\chapter{Runtime Metrics}
\chapter{ランタイムメトリクス}
\label{chap:runtime-metrics}
%One of the best selling points of the Erlang VM for production use is how transparent it can be for all kinds of introspection, debugging, profiling, and analysis at run time.
実運用を考えた際、Erlang VMで最も良いセールスポイントの一つとして、ありとあらゆる内部調査やデバッグ、プロファイリング、実行時分析の透過性が挙げられます。
%The advantage of having these runtime metrics accessible programmatically is that building tools relying on them is easy, and building automation for some tasks or watchdogs is equally simple\footnote{Making sure your automated processes don't run away and go overboard with whatever corrective actions they take is more complex}.
プログラム上で取得できるランタイムメトリクスがある利点として、これらメトリクスに依存したツールを作ることも簡単ですし、何らかのタスクや監視を自動化するのも同じように単純です
\footnote{自動化プロセスが何かしら是正措置を行おうとして、暴走したり、やり過ぎたりしないか保証するほうが、より一層複雑です}。
%Then, in times of need, it's also possible to bypass the tools and go direct to the VM for information.
それに、必要であれば、ツールを介さずにVMから直接情報を受け取ることも可能です。
%A practical approach to growing a system and keeping it healthy in production is to make sure all angles are observable: in the large, and in the small.
システムを健全に保ちつつ成長させる実用的な方法は、すべての角度から―大域的にも、局所的にも―監視できるようにしておくことです。
%There's no generic recipe to tell in advance what is going to be normal or not.
将来起きることが通常の挙動なのか否かを先んじて知らせる一般的な方法はありません。
%You want to keep a lot of data and to look at it from time to time to form an idea about what your system looks like under normal circumstances.
あなたのシステムが通常の状況下でどのように見えているのか。考えを形にするには、多くのデータを保持して、それらをことあるごとに観察したくなるでしょう。
%The day something goes awry, you will have all these angles you've grown to know, and it will be simpler to find what is off and needs fixing.
何かがうまく行かなくなったその日、あなたがこれまで培ってきたすべての観察方法を使えば、どこが不調で何を修正すべきかを簡単に見つけだせます。
%For this chapter (and most of those that follow), most of the concepts or features to be shown are accessible through code in the standard library, part of the regular OTP distribution.
この章(また、このあとの章のほとんど)では、紹介する概念や機能のほとんどは、標準ライブラリ---正規OTPディストリビューションの一部---に含まれるコードからアクセス可能です。
%However, these features aren't all in one place, and can make it too easy to shoot yourself in the foot within a production system.
しかしながら、これら機能は一箇所にまとまっているわけではありませんし、システムの中で自らの足を撃ちぬくことも非常に簡単にできてしまいます。
%They also tend to be closer to building blocks than usable tools.
これらは便利ツールというより、基本的な構成要素に近いものにもなりがちです。
%Therefore, to make the text lighter and to be more usable, common operations have been regrouped in the \otpapp{recon}\footnote{\href{http://ferd.github.io/recon/}{http://ferd.github.io/recon/}} library, and are generally production-safe.
したがって、本書をより軽く、利用しやすくするために、
よく使う操作は、実運用で利用しても安全な\otpapp{recon}\footnote{\href{http://ferd.github.io/recon/}{http://ferd.github.io/recon/}}ライブラリにまとめ直されています。
%\section{Global View}
\section{グローバルビュー}
\label{sec:global-view}
% For a view of the VM in the large, it's useful to track statistics and metrics general to the VM, regardless of the code running on it.
大域的にVMを見るなら、どんなコードが動いているかはさておき、VMの一般的なメトリクスの統計情報を監視すると役に立ちます。
%Moreover, you should aim for a solution that allows long-term views of each metric — some problems show up as a very long accumulation over weeks that couldn't be detected over small time windows.
更に言うなら、各メトリクスを長期的に見るソリューションをめざすべきです --- 一部の問題は幾週にも渡る非常に長い蓄積で発生しますし、これを短期間の情報表示画面から検知するのは不可能です。
%Good examples for issues exposed by a long-term view include memory or process leaks, but also could be regular or irregular spikes in activities relative to the time of the day or week, which can often require having months of data to be sure about it.
長期的に見ることで問題が明るみになる良い例にはメモリやプロセスのリークがありますが、
それだけでなく、一日もしくは一週間のうちの特定時刻に関連する活動の中で、周期的または不定期に発生するスパイクも良い例です。
確証を持つためには、何ヶ月ものデータがしばしば必要になります。
%For these cases, using existing Erlang metrics applications is useful. Common options are:
このようなケースにおいて、 既存のErlang メトリクス アプリケーションは有用です。
一般的な選択肢としては、以下のようなものがあります。
\begin{itemize*}
%\item \otpapp{folsom}\footnote{\href{https://github.com/boundary/folsom}{https://github.com/boundary/folsom}} to store metrics in memory within the VM, whether global or app-specific..
\item \otpapp{folsom}\footnote{\href{https://github.com/boundary/folsom}{https://github.com/boundary/folsom}}。メトリクスをVM内のメモリに保存する。グローバル領域、アプリケーション領域のどちらも可能。
%\item \otpapp{vmstats}\footnote{\href{https://github.com/ferd/vmstats}{https://github.com/ferd/vmstats}} and \otpapp{statsderl}\footnote{\href{https://github.com/lpgauth/statsderl}{https://github.com/lpgauth/statsderl}}, sending node metrics over to graphite through \app{statsd}\footnote{\href{https://github.com/etsy/statsd/}{https://github.com/etsy/statsd/}}.
\item \otpapp{vmstats}\footnote{\href{https://github.com/ferd/vmstats}{https://github.com/ferd/vmstats}} と \otpapp{statsderl}\footnote{\href{https://github.com/lpgauth/statsderl}{https://github.com/lpgauth/statsderl}}。 \app{statsd}\footnote{\href{https://github.com/etsy/statsd/}{https://github.com/etsy/statsd/}}を通じてノードメトリクスをgraphiteに送る。
%\item \otpapp{exometer}\footnote{\href{https://github.com/Feuerlabs/exometer}{https://github.com/Feuerlabs/exometer}}, a fancy-pants metrics system that can integrate with \otpapp{folsom} (among other things), and a variety of back-ends (graphite, collectd, \app{statsd}, Riak, SNMP, etc.). It's the newest player in town
\item \otpapp{exometer}\footnote{\href{https://github.com/Feuerlabs/exometer}{https://github.com/Feuerlabs/exometer}}。気取ったメトリクスシステムで、(とりわけ)\otpapp{folsom}と統合できる他、多くのバックエンド(graphite、collectd、\app{statsd}、Riak、SNMPなど)とも統合できます。この島では新参者ですね。
%\item \otpapp{ehmon}\footnote{\href{https://github.com/heroku/ehmon}{https://github.com/heroku/ehmon}} for output done directly to standard output, to be grabbed later through specific agents, splunk, and so on.
\item \otpapp{ehmon}\footnote{\href{https://github.com/heroku/ehmon}{https://github.com/heroku/ehmon}}は直接標準出力に書き出すときに使います。出力結果は専用のエージェントなり、splunkなどで取得します。
%\item custom hand-rolled solutions, generally using ETS tables and processes periodically dumping the data.\footnote{Common patterns may fit the \otpapp{ectr} application, at \href{https://github.com/heroku/ectr}{https://github.com/heroku/ectr}}
\item お手製のカスタムソリューション。一般的には、ETSテーブルと定期的にデータをダンプするプロセスを使います。
\footnote{よくあるパターンでは、\otpapp{ectr}アプリケーションが適しています。 \href{https://github.com/heroku/ectr}{https://github.com/heroku/ectr} を参照してください。}
%\item or if you have nothing and are in trouble, a function printing stuff in a loop in a shell\footnote{The \otpapp{recon} application has the function \function{\href{http://ferd.github.io/recon/recon.html\#node\_stats\_print-2}{recon:node\_stats\_print/2}} to do this if you're in a pinch}.
\item もし何も用意がない状態で障害になったら、シェルループで諸々の出力を行う関数\footnote{あなたがピンチの時にも諸々の出力ができるよう、\otpapp{recon}アプリケーションは関数 \function{\href{http://ferd.github.io/recon/recon.html\#node\_stats\_print-2}{recon:node\_stats\_print/2}}を備えています}。
\end{itemize*}
%It is generally a good idea to explore them a bit, pick one, and get a persistence layer that will let you look through your metrics over time.
これらを少し調べてみて、どれか一つを使い、あなたの興味あるメトリクスを刻々と見せてくれる永続レイヤーを用意するのが、一般的には良い方法です。
%\subsection{Memory}
\subsection{メモリ}
%The memory reported by the Erlang VM in most tools will be a variant of what is reported by \expression{erlang:memory()}:
大抵のツールでErlang VMから受けているメモリの情報は、\expression{erlang:memory()} から取られる変数です。
\begin{VerbatimEshell}
1> erlang:memory().
[{total,13772400},
{processes,4390232},
{processes_used,4390112},
{system,9382168},
{atom,194289},
{atom_used,173419},
{binary,979264},
{code,4026603},
{ets,305920}]
\end{VerbatimEshell}
%This requires some explaining.
これは説明が必要ですね。
%First of all, all the values returned are in bytes, and they represent memory \emph{allocated} (memory actively used by the Erlang VM, not the memory set aside by the operating system for the Erlang VM).
まず第一に、すべての返り値はbyte単位の値となっていて、メモリの\emph{割り当てられた}量(Erlang VMが実際に使用しているメモリ量のことで、OSがErlang VMのために確保した量ではありません)を表します。
%It will sooner or later look much smaller than what the operating system reports.
遅かれ早かれ、OSが示す値よりはるかに少ない値だとわかるはずです。
%The \expression{total} field contains the sum of the memory used for \expression{processes} and \expression{system} (which is incomplete, unless the VM is instrumented!).
\expression{total}の項には、\expression{processes} と \expression{system} で利用してるメモリ量の和が入ります(instrumentモジュールを有効にして\footnote{訳註:例えば\expression{erl -instr}などで有効化できます。}VMを実行しないかぎり、完璧な和にはなりません!)。
%\expression{processes} is the memory used by Erlang processes, their stacks and heaps.
\expression{processes}の項は、スタックやヒープとしてErlangプロセスが使用するメモリ量です。
%\expression{system} is the rest: memory used by ETS tables, atoms in the VM, refc binaries\footnote{See Section \ref{sec:binaries}}, and some of the hidden data I mentioned was missing.
\expression{system}の項は残りです。つまり、ETSテーブルや、VMの中で使われるアトムや、refcバイナリ\footnote{リファレンスカウントされたバイナリ(reference-counted binary)。プロセスヒープ外に保持するバイナリオブジェクト(実データ及び参照カウンタ)と、プロセスヒープ内に保持するProcBinオブジェクト(バイナリオブジェクトを参照するオブジェクト)から構成されるバイナリのこと。\ref{sec:binaries}節参照}。先述の通り、instrumentモジュールを使わない限り一部データは失われます。
%If you want the total amount of memory owned by the virtual machine, as in the amount that will trip system limits (\app{ulimit}), this value is more difficult to get from within the VM.
システム限界(\app{ulimit})を突破する時などに仮想マシンが保有する総メモリ量を知りたいなら、VM内部から取得するのはより困難です。
%If you want the data without calling \app{top} or \app{htop}, you have to dig down into the VM's memory allocators to find things out.\footnote{See Section \ref{subsec:erlang-memory-model}}
もし\app{top}や\app{htop}を使うことなしにこのデータが欲しければ、あなたはVMのメモリアロケータを深堀して見つけ出すしかありません\footnote{詳しくは\ref{subsec:erlang-memory-model}節を見てください}。
%Fortunately, recon has the function \function{recon\_alloc:memory/1} to figure it out, where the argument is:
運が良いことに、この値を取るために reconは関数 \function{recon\_alloc:memory/1} を用意しています。
引数には以下のようなものがあります。
\begin{itemize*}
% \item \expression{used} reports the memory that is actively used for allocated Erlang data;
\item \expression{used}。 使用中のErlangデータが割り当てられているメモリの総量
% \item \expression{allocated} reports the memory that is reserved by the VM. It includes the memory used, but also the memory yet-to-be-used but still given by the OS. This is the amount you want if you're dealing with \app{ulimit} and OS-reported values.
\item \expression{allocated}。 VMにより予約されているメモリ量。使用中のメモリ量だけでなく、OSから与えられた未使用な領域も含む。あなたが\app{ulimit}やOSの示す値を取り扱うなら、この値がほしい値でしょう。
%\item \expression{unused} reports the amount of memory reserved by the VM that is not being allocated. Equivalent to \expression{allocated - used}.
\item \expression{unused}。VMにより予約されているがまだ割り当てられていない容量。\expression{allocated - used}と等価です。
%\item \expression{usage} returns a percentage (0.0 .. 1.0) of used over allocated memory ratios.
\item \expression{usage}。割当てられたメモリ量に対する使用中のメモリ量の割合(0.0から1.0)。
\end{itemize*}
%There are additional options available, but you'll likely only need them when investigating memory leaks in chapter \ref{chap:memory-leaks}
利用可能なオプションは他にもありますが、\ref{chap:memory-leaks}の章でメモリリークの調査を行うにはこのくらいで十分でしょう。
%\subsection{CPU}
\subsection{CPU}
\label{subsec:global-cpu}
%Unfortunately for Erlang developers, CPU is very hard to profile. There are a few reasons for this:
Erlang 開発者にとって残念なことに、CPUの統計データを取ることは非常に困難です。
それには少し理由があります。
\begin{itemize*}
%\item The VM does a lot of work unrelated to processes when it comes to scheduling — high scheduling work and high amounts of work done by the Erlang processes are hard to characterize.
\item VMはスケジューリングの際にプロセスとは無関係のタスクをたくさん行っています。高度なスケジューリングタスクとErlangプロセスによる大量のタスクは、特徴付けすることが難しいのです。
%\item The VM internally uses a model based on \emph{reductions}, which represent an arbitrary number of work actions. Every function call, including BIFs, will increment a process reduction counter. After a given number of reductions, the process gets descheduled.
\item VMは内部で \emph{リダクション} に基づくモデルを使っています。このモデルは任意の数のタスクで表せます。すべての(BIFを含む)関数呼び出しでプロセスリダクション数がインクリメントされ、所与のリダクション数に到達すると、プロセスがスケジューラ上の実行中から外れます。
%\item To avoid going to sleep when work is low, the threads that control the Erlang schedulers will do busy looping. This ensures the lowest latency possible for sudden load spikes. The VM flag \command{+sbwt none|very\_short|short|medium|long|very\_long} can be used to change this value.
\item 負荷の低いスケジューラスレッドがすぐスリープ状態にならないように、Erlangスケジューラの扱うスレッドはしばらくビジーウェイト状態になります。これは、突然負荷が上がるケースでも遅延が大きくなり過ぎないための配慮です。この値を変更するには、VMフラグ (\command{+sbwt none|very\_short|short|medium|long|very\_long}) が使えます。
\end{itemize*}
%These factors combine to make it fairly hard to find a good absolute measure of how busy your CPU is actually running Erlang code.
これらの要素が組み合わさっているため、実行中のErlangコードによるCPU使用量をしっかりと測る方法を見つけるのは大変です。
%It will be common for Erlang nodes in production to do a moderate amount of work and use a lot of CPU, but to actually fit a lot of work in the remaining place when the workload gets higher.
Erlangノードは実運用において、ほどほどのタスクでもCPUを大量に使用するようによく見えますが、これは負荷が上がっても残りのCPUリソースで多くのタスクをこなせるよう適合させているのです。
%The most accurate representation for this data is the scheduler wall time.
このデータを最も適切に表現するのは、スケジューラの総経過時間です。
%It's an optional metric that needs to be turned on by hand on a node, and polled at regular intervals.
これは標準では無効のメトリクスで、ノードごとに手動で有効に設定して一定間隔で取得させる必要があります。
%It will reveal the time percentage a scheduler has been running processes and normal Erlang code, NIFs, BIFs, garbage collection, and so on, versus the amount of time it has spent idling or trying to schedule processes.
取得される値からわかるのは、スケジューラがプロセス、普通のErlangコード、NIF、BIF、ガベージコレクションなどを走らせる時間と、スケジューラがプロセススケジュールを試みているか、アイドル状態になっている時間の割合です。
%The value here represents \emph{scheduler utilization} rather than CPU utilization.
これはCPU使用率というより、どちらかといえば\emph{スケジューラ使用率}を表すものです。
%The higher the ratio, the higher the workload.
高い値であるほど、高い負荷がかかっていることを表します。
%While the basic usage is explained in the Erlang/OTP reference manual\footnote{\href{http://www.erlang.org/doc/man/erlang.html\#statistics\_scheduler\_wall\_time}{http://www.erlang.org/doc/man/erlang.html\#statistics\_scheduler\_wall\_time}}, the value can be obtained by calling recon:
基本的な使い方はErlang/OTPのリファレンスマニュアル\footnote{\href{http://www.erlang.org/doc/man/erlang.html\#statistics\_scheduler\_wall\_time}{http://www.erlang.org/doc/man/erlang.html\#statistics\_scheduler\_wall\_time}}に記載されていますが、reconを使ってもこの値は取得できます。
\begin{VerbatimEshell}
1> recon:scheduler_usage(1000).
[{1,0.9919596133421669},
{2,0.9369579039389054},
{3,1.9294092120138725e-5},
{4,1.2087551402238991e-5}]
\end{VerbatimEshell}
%The function \function{recon:scheduler\_usage(N)} will poll for \var{N} milliseconds (here, 1 second) and output the value of each scheduler.
関数\function{recon:scheduler\_usage(N)}は\var{N} ミリ秒(ここでは1秒) 調査を行い、各スケジューラの値を出力します。
%In this case, the VM has two very loaded schedulers (at 99.2\% and 93.7\% repectively), and two mostly unused ones at far below 1\%.
今回の場合は、VMは高負荷なスケジューラが2つ (それぞれ99.2\%と93.7\%)と、1\%にも満たないくらいほとんど使われていないスケジューラが2つありますね。
%Yet, a tool like \app{htop} would report something closer to this for each core:
しかし、\app{htop}などのツールはCPUコアごとにこれと似たような値を出力してくれました。
\begin{VerbatimText}
[||||||||||||||||||||||||| 70.4%]
[||||||| 20.6%]
[|||||||||||||||||||||||||||||100.0%]
[|||||||||||||||| 40.2%]
\end{VerbatimText}
%The result being that there is a decent chunk of CPU usage that would be mostly free for scheduling actual Erlang work (assuming the schedulers are busy waiting more than trying to select tasks to run), but is being reported as busy by the OS.
結果として、(スケジューラが実行タスクを選択する状態でなく、ビジーウェイト状態だとを想定すると) Erlangのタスクスケジューリングでほとんど使っていないCPU領域があっても、OSからは高い使用率を表示されます。
%Another interesting behaviour possible is that the scheduler usage may show a higher rate (1.0) than what the OS will report.
もうひとつの面白い挙動として、スケジューラはOSが示す値よりも高い割合(1.0)を表示することもありえます。
%Schedulers waiting for os resources are considered utilized as they cannot handle more work.
スケジューラがOSリソースを待っている場合、それ以上のタスクを扱えないことから使用状態と認識される場合がその一例です。
%If the OS itself is holding up on non-CPU tasks it is still possible for Erlang's schedulers not to be able to do more work and report a full ratio.
他にも、OS自身がCPU以外のタスクで詰まっている場合にも、Erlangスケジューラも仕事を行えないことから、1.0の割合が表示されることになります。
%These behaviours may especially be important to consider when doing capacity planning, and can be better indicators of headroom than looking at CPU usage or load.
これらのふるまいに関する考察は容量計画を行う際には特に大事で、CPU使用率や負荷を見る以上に余力をみる良い指標になるでしょう。
%% 08:37 #erlounge: <+garazdawi> MononcQc: There is a cost when not doing work. The way it works is that when starting/stopping to do work it checks the time, but if the
%% scheduler has something to do the entire time then there is no overhead. So you might see a slight cpu increase if the schedulers run out of
%% work often, but it will (should) not affect the maximum possible throughput of the system.
%\subsection{Processes}
\subsection{プロセス}
\label{subsec:global-procs}
%Trying to get a global view of processes is helpful when trying to assess how much work is being done in the VM in terms of \emph{tasks}.
プロセスに関するグローバルビューがあると、\emph{タスク}の観点でVMはがどのくらいの仕事を完了したか知るのに役立ちます。
%A general good practice in Erlang is to use processes for truly concurrent activities — on web servers, you will usually get one process per request or connection, and on stateful systems, you may add one process per-user — and therefore the number of processes on a node can be used as a metric for load.
Erlangにおいて一般的に良い方法となるのは、真に同時実行されているプロセスを用いることです --- Webサーバでは普段、1リクエストもしくは1接続ごとに1プロセスを持つでしょうし、状態を持つシステムであれば、ユーザごとに1つのプロセスを追加しているかもしれません --- したがって、1ノード中に存在するプロセス数がメトリクスとして利用できます。
%Most tools mentioned in section \ref{sec:global-view} will track them in one way or another, but if the process count needs to be done manually, calling the following expression is enough:
\ref{sec:global-view}の章で説明するツールのほとんどが、何らかの方法でプロセス数を監視していますが、自前でプロセスカウントが必要であれば、以下のようにすれば十分です。
\begin{VerbatimEshell}
1> length(processes()).
56535
\end{VerbatimEshell}
% Tracking this value over time can be extremely helpful to try and characterize load or detect process leaks, along with other metrics you may have around.
この値を刻々と監視することは、どんなメトリクスよりも、負荷を特徴づけたり、プロセスリークを発見するのに非常に役立ちます。
%\subsection{Ports}
\subsection{ポート}
\label{subsec:global-ports}
%In a manner similar to processes, \emph{Ports} should be considered.
プロセスと似たような理由で、\emph{ポート}も監視すべきです。
%Ports are a datatype that encompasses all kinds of connections and sockets opened to the outside world: TCP sockets, UDP sockets, SCTP sockets, file descriptors, and so on.
ポートはありとあらゆる種類のコネクションや、外部に開いているソケット--- TCPソケット、UDPソケット、SCTPソケット、ファイルディスクリプタなど --- を包含するデータ型です。
%There is a general function (again, similar to processes) to count them: \expression{length(erlang:ports())}.
これをカウントする一般的な関数として、\expression{length(erlang:ports())} があります(この関数が用意されているところも、プロセスの時の話と似ていますね)。
%However, this function merges in all types of ports into a single entity.
しかしながら、この関数では全種類のポートをひとつのエンティティにまとめてしまっています。
%Instead, one can use \otpapp{recon} to get them sorted by type:
ポートの種類ごとに値を取りたければ、この関数の代わりに \otpapp{recon} が使えます。
\begin{VerbatimEshell}
1> recon:port_types().
[{"tcp_inet",21480},
{"efile",2},
{"udp_inet",2},
{"0/1",1},
{"2/2",1},
{"inet_gethost 4 ",1}]
\end{VerbatimEshell}
%This list contains the types and the count for each type of port.
このリストはポートの種類ごとに、タイプ名と数値を格納しています。
%The type name is a string and is defined by the Erlang VM itself.
タイプ名はErlang VM自身によって定義されている文字列です。
%All the \expression{*\_inet} ports are usually sockets, where the prefix is the protocol used (TCP, UDP, SCTP).
普通、すべての\expression{*\_inet}ポートはソケットで、接頭語が使用プロトコル(TCP, UDP, SCTP)を表します。
%The \expression{efile} type is for files, while \expression{"0/1"} and \expression{"2/2"} are file descriptors for standard I/O channels (\emph{stdin} and \emph{stdout}) and standard error channels (\emph{stderr}), respectively.
\expression{efile}タイプはファイルのためのもので、\expression{"0/1"}と\expression{"2/2"}はそれぞれ、標準入出力チャンネル (\emph{stdin}と\emph{stdout})と標準エラー出力チャンネル(\emph{stderror})へのファイルディスクリプタを表します。
%Most other types will be given names of the driver they're talking to, and will be examples of \emph{port programs}\footnote{\href{http://www.erlang.org/doc/tutorial/c\_port.html}{http://www.erlang.org/doc/tutorial/c\_port.html}} or \emph{port drivers}\footnote{\href{http://www.erlang.org/doc/tutorial/c\_portdriver.html}{http://www.erlang.org/doc/tutorial/c\_portdriver.html}}.
その他のタイプのほとんどは、ポートがやり取りしているドライバ名が入ります。例としては\emph{port programs}\footnote{\href{http://www.erlang.org/doc/tutorial/c\_port.html}{http://www.erlang.org/doc/tutorial/c\_port.html}}や\emph{port drivers}\footnote{\href{http://www.erlang.org/doc/tutorial/c\_portdriver.html}{http://www.erlang.org/doc/tutorial/c\_portdriver.html}}などです。
%Again, tracking these can be useful to assess load or usage of a system, detect leaks, and so on.
繰り返しになりますが、これらの値を監視することはシステム使用率や負荷を見たり、リークを見たり、その他いろいろなことに役立ちます。
%\section{Digging In}
\section{内部分析}
\label{sec:digging-in}
%Whenever some 'in the large' view (or logging, maybe) has pointed you towards a potential cause for an issue you're having, it starts being interesting to dig around with a purpose. Is a process in a weird state? Maybe it needs tracing\footnote{See Chapter \ref{chap:tracing}}! Tracing is great whenever you have a specific function call or input or output to watch for, but often, before getting there, a lot more digging is required.
大規模なビュー(または、ロギング)が問題の潜在的な原因を示す時は大抵、目的を持って内部状態を分析する事が面白くなってきます。プロセスの状態はおかしいですか? 多分トレーシングが必要になるでしょう\footnote{Chapter \ref{chap:tracing} 参照}! 特定の関数の呼び出しや入出力を監視する時はいつでも、トレーシングが有効ですが、多くの場合、監視前に多くの内部分析が必要になります。
%Outside of memory leaks, which often need their own specific techniques and are discussed in Chapter \ref{chap:memory-leaks}, the most common tasks are related to processes, and ports (file descriptors and sockets).
Chaptere \ref{chap:memory-leaks} で議論する特定のテクニックが必要なメモリリークを除けば、最も共通するタスクはプロセスとポート(ファイルディスクリプタとソケット)に関連しています。
%\subsection{Processes}
\subsection{プロセス}
\label{subsec:digging-procs}
%By all means, processes are an important part of a running Erlang system. And because they're so central to everything that goes on, there's a lot to want to know about them. Fortunately, the VM makes a lot of information available, some of which is safe to use, and some of which is unsafe to use in production (because they can return data sets large enough that the amount of memory copied to the shell process and used to print it can kill the node).
どんな事があろうとも、プロセスは実行中のErlangシステムの重要な部分です。そして、プロセスは動作中のすべてのものの中心にあるので、プロセスについて知りたい事が沢山あります。幸いにも、VMは多くの情報を提供しており、そのうちのいくつかは安全に使用できますが、一部は安全ではありません(シェルプロセスにコピーされ表示するのに使用するメモリ量が、ノードを強制終了させる程大きいデータセットを返す事ができるからです)。
%All the values can be obtained by calling \expression{process\_info(Pid, Key)} or \newline \expression{process\_info(Pid, [Keys])}\footnote{In cases where processes contain sensitive information, data can be forced to be kept private by calling \expression{process\_flag(sensitive, true)}}. Here are the commonly used keys\footnote{For \emph{all} options, look at \href{http://www.erlang.org/doc/man/erlang.html\#process\_info-2}{http://www.erlang.org/doc/man/erlang.html\#process\_info-2}:
全ての値は、\expression{process\_info(Pid, Key)}か\newline \expression{process\_info(Pid, [Keys])}を呼び出して取得する事ができます\footnote{プロセスに機密情報が含まれている場合、\expression{process\_flag(sensitive, true)}を呼び出す事でデータを非公開にする事ができます}。よく使われるキーはこちらになります\footnote{\emph{全ての}オプションは \href{http://www.erlang.org/doc/man/erlang.html\#process\_info-2}{http://www.erlang.org/doc/man/erlang.html\#process\_info-2}を参照してください}:
\begin{description*}
\item[Meta] \hfill
\begin{description}
% \item[\expression{dictionary}] returns all the entries in the process dictionary\footnote{See \href{http://www.erlang.org/course/advanced.html\#dict}{http://www.erlang.org/course/advanced.html\#dict} and \href{http://ferd.ca/on-the-use-of-the-process-dictionary-in-erlang.html}{http://ferd.ca/on-the-use-of-the-process-dictionary-in-erlang.html}}. Generally safe to use, because people shouldn't be storing gigabytes of arbitrary data in there.
\item[\expression{dictionary}] プロセス辞書の全てのエントリを返します\footnote{\href{http://www.erlang.org/course/advanced.html\#dict}{http://www.erlang.org/course/advanced.html\#dict} と \href{http://ferd.ca/on-the-use-of-the-process-dictionary-in-erlang.html}{http://ferd.ca/on-the-use-of-the-process-dictionary-in-erlang.html} 参照}。ギガバイトもする任意のデータをそこに格納する事はまず無いので、一般的には安全です。
% \item[\expression{group\_leader}] the group leader of a process defines where IO (files, output of \function{io:format/1-3}) goes.\footnote{See \href{http://learnyousomeerlang.com/building-otp-applications\#the-application-behaviour}{http://learnyousomeerlang.com/building-otp-applications\#the-application-behaviour} and \href{http://erlang.org/doc/apps/stdlib/io\_protocol.html}{http://erlang.org/doc/apps/stdlib/io\_protocol.html} for more details.}
\item[\expression{group\_leader}] プロセスのグループリーダーはIO(ファイル、\function{io:format/1-3}の出力)をどこに向けるかを定義します。\footnote{詳細は\href{http://learnyousomeerlang.com/building-otp-applications\#the-application-behaviour}{http://learnyousomeerlang.com/building-otp-applications\#the-application-behaviour} と \href{http://erlang.org/doc/apps/stdlib/io\_protocol.html}{http://erlang.org/doc/apps/stdlib/io\_protocol.html} を参照。}
% \item[\expression{registered\_name}] if the process has a name (as registered with \function{erlang:register/2}), it is given here.
\item[\expression{registered\_name}] もしプロセスが名前(\function{erlang:register/2}で登録)を持っているなら、それを取得します。
% \item[\expression{status}] the nature of the process as seen by the scheduler. The possible values are:
\item[\expression{status}] スケジューラーによって参照できるプロセスの特性。取りうる値は以下となります。
\begin{description*}
% \item[\expression{exiting}] the process is done, but not fully cleared yet;
\item[\expression{exiting}] プロセスは終了していますが、まだクリアされていません
% \item[\expression{waiting}] the process is waiting in a \expression{receive ... end};
\item[\expression{waiting}] プロセスは\expression{receive ... end}によって待機中です
% \item[\expression{running}] self-descriptive;
\item[\expression{running}] 実行中
% \item[\expression{runnable}] ready to run, but not scheduled yet because another process is running;
\item[\expression{runnable}] 実行の準備は整っていますが、他のプロセスが実行中の為、まだスケジューリングされていません
% \item[\expression{garbage\_collecting}] self-descriptive;
\item[\expression{garbage\_collecting}] GC中
% \item[\expression{suspended}] whenever it is suspended by a BIF, or as a back-pressure mechanism because a socket or port buffer is full. The process only becomes runnable again once the port is no longer busy.
\item[\expression{suspended}] BIF、またソケットやポートのバッファがいっぱいになる事によるバックプレッシャーのメカニズムによって停止された時はいつでも。ポートがビジーでなくなったら、プロセスは再びrunnableになります。
\end{description*}
\end{description}
\item[Signals] \hfill
\begin{description}
% \item[\expression{links}] will show a list of all the links a process has towards other processes and also ports (sockets, file descriptors). Generally safe to call, but to be used with care on large supervisors that may return thousands and thousands of entries.
\item[\expression{links}] 他のプロセスやポート(ソケット、ファイルディスクリプタ)に対する全てのリンクのリストを表示します。
% \item[\expression{monitored\_by}] gives a list of processes that are monitoring the current process (through the use of \function{erlang:monitor/2}).
\item[\expression{monitored\_by}] (\function{erlang:monitor/2}を使って)現プロセスをモニタしているプロセスのリストを表示します。
% \item[\expression{monitors}] kind of the opposite of \expression{monitored\_by}; it gives a list of all the processes being monitored by the one polled here.
\item[\expression{monitors}] \expression{monitored\_by}の反対。モニタされている全てのプロセスのリストを取得します。
% \item[\expression{trap\_exit}] has the value \expression{true} if the process is trapping exits, \expression{false} otherwise.
\item[\expression{trap\_exit}] プロセスが終了(exits)メッセージを補足する場合は\expression{true} 、そうでない場合は\expression{false} となります。
\end{description}
\item[Location] \hfill
\begin{description}
% \item[\expression{current\_function}] displays the current running function, as a tuple of the form \expression{\{Mod, Fun, Arity\}}.
\item[\expression{current\_function}] \expression{\{Mod, Fun, Arity\}}の形式のタプルで、現在実行中の関数を表示します。
% \item[\expression{current\_location}] displays the current location within a module, as a tuple of the form \expression{\{Mod, Fun, Arity, [\{File, FileName\}, \{line, Num\}]\}}.
\item[\expression{current\_location}] \expression{\{Mod, Fun, Arity, [\{File, FileName\}, \{line, Num\}]\}}形式のタプルで、モジュールの現在のロケーションを表示します。
% \item[\expression{current\_stacktrace}] more verbose form of the preceding option; displays the current stacktrace as a list of 'current locations'.
\item[\expression{current\_stacktrace}] 前述のオプションよりも詳細な形式、'current location'のリストで現在のスタックトレースを表示します。
% \item[\expression{initial\_call}] shows the function that the process was running when spawned, of the form \expression{\{Mod, Fun, Arity\}}. This may help identify what the process was spawned as, rather than what it's running right now.
\item[\expression{initial\_call}] プロセス生成時に実行されていた関数を\expression{\{Mod, Fun, Arity\}}形式で表示します。これは現在実行中のプロセスが何かというより、プロセスがどう生成されたかの特定に役立ちます。
\end{description}
\item[Memory Used] \hfill
\begin{description}
% \item[\expression{binary}] Displays the all the references to refc binaries\footnote{See Section \ref{sec:binaries}} along with their size. Can be unsafe to use if a process has a lot of them allocated.
\item[\expression{binary}] Refcバイナリ\footnote{Section \ref{sec:binaries} 参照}への参照をそのサイズと一緒に表示します。プロセスへの割り当て数が大きい場合、使用するのは危険です。
% \item[\expression{garbage\_collection}] contains information regarding garbage collection in the process. The content is documented as 'subject to change' and should be treated as such. The information tends to contains entries such as the number of garbage collections the process has went through, options for full-sweep garbage collections, and heap sizes.
\item[\expression{garbage\_collection}] プロセスのガベージコレクションに関する情報が含まれています。その情報は'予告なしに変更がある'内容となるでしょう。この情報は、プロセスが実行したガベージコレクションの回数、フルスワップガベージコレクションのオプション、ヒープサイズといったエントリが含みます。
% \item[\expression{heap\_size}] A typical Erlang process contains an 'old' heap and a 'new' heap, and goes through generational garbage collection. This entry shows the process' heap size for the newest generation, and it usually includes the stack size. The value returned is in \emph{words}.
\item[\expression{heap\_size}] 典型的なErlangプロセスは、'古い'ヒープと'新しい'ヒープを含み、世代別ガベージコレクションが行われます。このエントリは最新世代のプロセスのヒープサイズを示し、通常はスタックサイズが含まれます。値は\emph{words}単位で返します。
% \item[\expression{memory}] Returns, in \emph{bytes}, the size of the process, including the call stack, the heaps, and internal structures used by the VM that are part of a process.
\item[\expression{memory}] コールスタック、ヒープ、プロセスの一部であるVMによって使用される内部構造、これらを含むプロセスのサイズを\emph{bytes}単位で返します。
% \item[\expression{message\_queue\_len}] Tells you how many messages are waiting in the mailbox of a process.
\item[\expression{message\_queue\_len}] プロセスのメールボックスで待機中のメッセージ数を返します。
% \item[\expression{messages}] Returns all of the messages in a process' mailbox. This attribute is \emph{extremely} dangerous to request in production because mailboxes can hold millions of messages if you're debugging a process that managed to get locked up. \emph{Always} call for the \expression{message\_queue\_len} first to make sure it's safe to use.
\item[\expression{messages}] プロセスのメールボックス内の全てのメッセージを返します。もしロック状態になっているプロセスをデバッグしているのなら、メールボックスは何百万ものメッセージを保持できるので、この属性を本番環境で取得するのは\emph{非常に}危険です。安全に使用できる事を確認する為、\emph{常に}\expression{message\_queue\_len}を最初に呼び出してください。
% \item[\expression{total\_heap\_size}] Similar to \expression{heap\_size}, but also contains all other fragments of the heap, including the old one. The value returned is in \emph{words}.
\item[\expression{total\_heap\_size}] \expression{heap\_size}と似ていますが、最新世代のヒープだけでなく、それ以外の全ての断片、つまり旧世代のヒープを含みます。値は\emph{words}単位で返されます。
\end{description}
\item[Work] \hfill
\begin{description}
% \item[\expression{reductions}] The Erlang VM does scheduling based on \emph{reductions}, an arbitrary unit of work that allows rather portable implementations of scheduling (time-based scheduling is usually hard to make work efficiently on as many OSes as Erlang runs on). The higher the reductions, the more work, in terms of CPU and function calls, a process is doing.
\item[\expression{reductions}] ErlangVMは、スケジューリング実装の移植性を高める任意の作業単位である\emph{reductions}に基づいてスケジューリングを行います(時間ベースのスケジューリングは通常、Erlangが動作する多くのOSで効率的に実行させるのが難しいです)。reductionsが大きいほど、CPUと関数呼び出しの面で、より多くの仕事をこなしています。
\end{description}
\end{description*}
%Fortunately, for all the common ones that are also safe, recon contains the \expression{recon:info/1} function to help:
幸いなことに、全ての安全な共通の属性を取得するのに、reconが\expression{recon:info/1}関数を提供しています。
\begin{VerbatimEshell}
1> recon:info("<0.12.0>").
[{meta,[{registered_name,rex},
{dictionary,[{'$ancestors',[kernel_sup,<0.10.0>]},
{'$initial_call',{rpc,init,1}}]},
{group_leader,<0.9.0>},
{status,waiting}]},
{signals,[{links,[<0.11.0>]},
{monitors,[]},
{monitored_by,[]},
{trap_exit,true}]},
{location,[{initial_call,{proc_lib,init_p,5}},
{current_stacktrace,[{gen_server,loop,6,
[{file,"gen_server.erl"},{line,358}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,239}]}]}]},
{memory_used,[{memory,2808},
{message_queue_len,0},
{heap_size,233},
{total_heap_size,233},
{garbage_collection,[{min_bin_vheap_size,46422},
{min_heap_size,233},
{fullsweep_after,65535},
{minor_gcs,0}]}]},
{work,[{reductions,35}]}]
\end{VerbatimEshell}
%For the sake of convenience, \expression{recon:info/1} will accept any pid-like first argument and handle it: literal pids, strings (\expression{"<0.12.0>"}), registered atoms, global names (\expression{\{global, Atom\}}), names registered with a third-party registry (e.g. with \otpapp{gproc}: \expression{\{via, gproc, Name\}}), or tuples (\expression{\{0,12,0\}}). The process just needs to be local to the node you're debugging.
使用しやすいよう、\expression{recon:info/1}はプロセスid、文字列\expression{"<0.12.0>"}、名前として登録されたアトム、グローバルネーム\expression{\{global, Atom\}}、サードパーティーのレジストリで登録された名前(例えば\otpapp{gproc}による\expression{\{via, gproc, Name\}})、タプル\expression{\{0,12,0\}}といったpidライクな最初の引数を受け取ってそれを処理します。このプロセスはデバッグ対象のノードにある必要があります。
%If only a category of information is wanted, the category can be used directly:
カテゴリの情報だけ欲しいのであれば、カテゴリを直接指定できます。
\begin{VerbatimEshell}
2> recon:info(self(), work).
{work,[{reductions,11035}]}
\end{VerbatimEshell}
%or can be used in exactly the same way as \function{process\_info/2}:
また、\function{process\_info/2}と全く同じ方法で使用できます。
\begin{VerbatimEshell}
3> recon:info(self(), [memory, status]).
[{memory,10600},{status,running}]
\end{VerbatimEshell}
%This latter form can be used to fetch unsafe information.
後者の方式は、安全でない情報を取得する方法です。
%With all this data, it's possible to find out all we need to debug a system. The challenge then is often to figure out, between this per-process data, and the global one, which process(es) should be targeted.
これらの全てのデータを使って、システムをデバッグする為に必要なものを全て見つける事ができます。難しいのは、プロセス単位のデータとグローバルなプロセス間で、どのプロセスをターゲットにするかを把握する事です。
%When looking for high memory usage, for example it's interesting to be able to list all of a node's processes and find the top \var{N} consumers. Using the attributes above and the \function{recon:proc\_count(Attribute, N)} function, we can get these results:
メモリ使用量が高い箇所を探している時、例えばノードの全てのプロセスをリストアップして上位\var{N}個の使用量が高いプロセスを見つける事ができるのは興味深いです。この情報と\function{recon:proc\_count(Attribute, N)}関数を使って、次の結果を得る事ができます。
\begin{VerbatimEshell}
4> recon:proc_count(memory, 3).
[{<0.26.0>,831448,
[{current_function,{group,server_loop,3}},
{initial_call,{group,server,3}}]},
{<0.25.0>,372440,
[user,
{current_function,{group,server_loop,3}},
{initial_call,{group,server,3}}]},
{<0.20.0>,372312,
[code_server,
{current_function,{code_server,loop,1}},
{initial_call,{erlang,apply,2}}]}]
\end{VerbatimEshell}
%Any of the attributes mentioned earlier can work, and for nodes with long-lived processes that can cause problems, it's a fairly useful function.
前述の属性のいくつかが作用して、問題を引き起こす可能性のある長時間生存しているプロセスを持つノードだった場合、これはかなり有用な関数です。
%There is however a problem when most processes are short-lived, usually too short to inspect through other tools, or when a moving window is what we need (for example, what processes are busy accumulating memory or running code \emph{right now}).
しかし、ほとんどのプロセスが短命で、通常は他のツールで調べるには短すぎる場合や、(例えば、\emph{今この瞬間}、どのプロセスがメモリを積んでいるのか、またコードを実行中なのかといった)必要な情報が検査対象の区間から移動している場合、問題があります。
%For this use case, Recon has the \function{recon:proc\_window(Attribute, Num, Milliseconds)} function.
このようなケースの為、Reconは\function{recon:proc\_window(Attribute, Num, Milliseconds)}関数を持っています。
%It is important to see this function as a snapshot over a sliding window. A program's timeline during sampling might look like this:
この関数をスライドする区間上のスナップショットとして見る事が重要です。サンプリング中のプログラムのタイムラインは以下の様になります。
\begin{Verbatim}
--w---- [Sample1] ---x-------------y----- [Sample2] ---z--->
\end{Verbatim}
%The function will take two samples at an interval defined by \var{Milliseconds}.
この関数は\var{ミリ秒}単位で指定する間隔で2つのサンプルをとります。
%Some processes will live between \var{w} and die at \var{x}, some between \var{y} and \var{z}, and some between \var{x} and \var{y}. These samples will not be too significant as they're incomplete.
いくつかのプロセスは\var{w}から\var{x}の間で、いくつかは\var{y}から\var{z}の間で、またいくつかは\var{x}から\var{y}の間で生存してから死にます。これらのサンプルは(どちらか、または両方が欠けていて)不完全なので、重要ではなくなるでしょう。
%If the majority of your processes run between a time interval \var{x} to \var{y} (in absolute terms), you should make sure that your sampling time is smaller than this so that for many processes, their lifetime spans the equivalent of \var{w} and \var{z}. Not doing this can skew the results: long-lived processes that have 10 times the time to accumulate data (say reductions) will look like huge consumers when they're not one.\footnote{Warning: this function depends on data gathered at two snapshots, and then building a dictionary with entries to differentiate them. This can take a heavy toll on memory when you have many tens of thousands of processes, and a little bit of time.}
プロセスの大半が(絶対値で)\var{x}から\var{y}の間隔の中で実行されるのであれば、それらのプロセスの寿命は\var{w}から\var{z}の時間に相当するので、サンプリング時間をこれより短くする必要があります。でなければ、結果を歪めてしまいます。データを蓄積する時間(reductionsとも言います)の10倍の長寿命のプロセスは、大きなボトルネックのように見えます。\footnote{注意: この関数は、2つのスナップショットで収集されたデータに依存し、それらを区別するためのエントリを持つ辞書を構築します。数十万ものプロセスがある時、短い時間にメモリに大きな負担をかける可能性があります。}
%The function, once running gives results like follows:
この関数が実行されると、次の様な結果が得られます。
\begin{VerbatimEshell}
5> recon:proc_window(reductions, 3, 500).
[{<0.46.0>,51728,
[{current_function,{queue,in,2}},
{initial_call,{erlang,apply,2}}]},
{<0.49.0>,5728,
[{current_function,{dict,new,0}},
{initial_call,{erlang,apply,2}}]},
{<0.43.0>,650,
[{current_function,{timer,sleep,1}},
{initial_call,{erlang,apply,2}}]}]
\end{VerbatimEshell}
%With these two functions, it becomes possible to hone in on a specific process that is causing issues or misbehaving.
これらの2つの関数によって、問題を引き起こしたり、振る舞いのおかしい特定のプロセスに対処する事ができるようになります。
%\subsection{OTP Processes}
\subsection{OTPプロセス}
%When processes in question are OTP processes (most of the processes in a production system should definitely be OTP processes), you instantly win more tools to inspect them.
対象のプロセスがOTPプロセスの場合(本番環境のほとんどのプロセスはおそらくOTPプロセスです)、それらのプロセスを調査するための多くのツールをすぐに見つけられます。
%In general the \module{sys} module\footnote{\href{http://www.erlang.org/doc/man/sys.html}{http://www.erlang.org/doc/man/sys.html}} is what you want to look into. Read the documentation on it and you'll discover why it's so useful. It contains the following features for any OTP process:
通常は \module{sys}\footnote{\href{http://www.erlang.org/doc/man/sys.html}{http://www.erlang.org/doc/man/sys.html}}が知りたいツールでしょう。\module{sys}モジュールのドキュメントを読めば、なぜそんなに便利なのかがわかるはずです。OTPプロセスに対する下記のような機能を持っています。
\begin{itemize*}
%\item logging of all messages and state transitions, both to the shell or to a file, or even in an internal buffer to be queried;
\item 全てのメッセージと状態遷移を、シェルやファイルまたは参照可能な内部バッファにすらロギングできます
%\item statistics (reductions, message counts, time, and so on);
\item 統計情報(リダクション、メッセージ数、時間など)
%\item fetching the status of a process (metadata including the state);
\item プロセスの状態(状態などのメタデータ)
%\item fetching the state of a process (as in the \expression{\#state\{\}} record);
\item (\expression{\#state\{\}} レコードに)プロセスの状態を取得
%\item replacing that state
\item 状態の書き換え
%\item custom debugging functions to be used as callbacks
\item コールバックとして使えるようにデバッグ関数をカスタマイズ
\end{itemize*}
%It also provides functionality to suspend or resume process execution.
また、プロセスの実行を中断、再開する機能も提供します。
%I won't go into a lot of details about these functions, but be aware that they exist.
これらの機能の詳細は割愛しますが、それらの機能が存在しているということは認識しておいてください。
%\subsection{Ports}
\subsection{ポート}
%Similarly to processes, Erlang ports allow a lot of introspection. The info can be accessed by calling \function{erlang:port\_info(Port, Key)}, and more info is available through the \module{inet} module. Most of it has been regrouped by the \function{recon:port\_info/1-2} functions, which work using a somewhat similar interface to their process-related counterparts.
プロセスと同様に、Erlangのポートは沢山の内省する機会を与えてくれます。ポートの情報へは \function{erlang:port\_info(Port, Key)} を呼ぶことによってアクセスでき、それ以上の情報は \module{inet} モジュールを通して取得できます。それらのほとんどは、 \function{recon:port\_info/1-2} によって再編成され、それはプロセス関連の同等の関数のインターフェースとやや似ているものを使っています。
\begin{description*}
%\item[Meta] \hfill
\item[メタ情報] \hfill
\begin{description}
%\item[\expression{id}] internal index of a port. Of no particular use except to differentiate ports.
\item[\expression{id}] ポートの内部インデックス。ポートを区別すること以外に用途はありません。
%\item[\expression{name}] type of the port — with names such as \expression{"tcp\_inet"}, \expression{"udp\_inet"}, or \expression{"efile"}, for example.
\item[\expression{name}] ポートのタイプです。例えば、\expression{"tcp\_inet"}、\expression{"udp\_inet"}、\expression{"efile"}などの名前で表します。
%\item[\expression{os\_pid}] if the port is not an inet socket, but rather represents an external process or program, this value contains the os pid related to the said external program.
\item[\expression{os\_pid}] もしもポートがinetソケットではなく、プログラムの外のプロセスを表しているのであれば、このポートの値は先述した外部プログラムに関連するOSのpidを含んでいます。
\end{description}
%\item[Signals] \hfill
\item[シグナル] \hfill
\begin{description}
%\item[\expression{connected}] Each port has a controlling process in charge of it, and this process' pid is the \expression{connected} one.
\item[\expression{connected}] 各ポートは、その責務として controlling process の機能を持っており、このプロセスの pid は \expression{connected} となります。
%\item[\expression{links}] ports can be linked with processes, much like other processes can be. The list of linked processes is contained here. Unless the process has been owned by or manually linked to a lot of processes, this should be safe to use.
\item[\expression{links}] ポートは、他のプロセスと同様にプロセスとリンクできます。この値にリンクされたプロセスのリストが含まれます。このプロセスが獲得されてしまったり、手作業によりプロセスとリンクされない限り、この値の使用は安全です。
%\item[\expression{monitors}] ports that represent external programs can have these programs end up monitoring Erlang processes. These processes are listed here.
\item[\expression{monitors}] 外部プログラムを表すポートは、それらのプログラムの情報を持ち、最終的にErlangのプロセスをモニターします。これらのプロセスはここで列挙されています。
\end{description}
\item[IO] \hfill
\begin{description}
%\item[\expression{input}] the number of bytes read from the port.
\item[\expression{input}] ポートに読み込まれたバイト数です。
%\item[\expression{output}] the number of bytes written to the port.
\item[\expression{output}] ポートに書き込まれたバイト数です。
\end{description}
%\item[Memory Used] \hfill
\item[メモリ使用量] \hfill
\begin{description}
%\item[\expression{memory}] this is the memory (in bytes) allocated by the runtime system for the port. This number tends to be small-ish and excludes space allocated by the port itself.
\item[\expression{memory}] これは、ポートのランタイムシステムによって割り当てられたメモリ(バイト単位)です。この数値は小さくなる傾向があり、そのポート自身によって割り当てられたスペースは除外しています。
%\item[\expression{queue\_size}] Port programs have a specific queue, called the driver queue\footnote{The driver queue is available to queue output from the emulator to the driver (data from the driver to the emulator is queued by the emulator in normal Erlang message queues). This can be useful if the driver has to wait for slow devices etc, and wants to yield back to the emulator.}. This return the size of this queue, in bytes.
\item[\expression{queue\_size}] ポートのプログラムは、ドライバキューと呼ばれる特別なキューを持っています\footnote{ドライバキューはエミュレータからドライバ(ドライバからエミュレータへのデータは通常のErlangのメッセージキューにキューイングされます。)へ出力をキューイングするのに使えます。}。これはドライバが遅いデバイスを待ったり、エミュレータに処理を返却するのに便利です。
\end{description}
%\item[Type-Specific] \hfill
\item[タイプ特有の情報] \hfill
\begin{description}
%\item[Inet Ports] Returns inet-specific data, including statistics\footnote{\href{http://www.erlang.org/doc/man/inet.html\#getstat-1}{http://www.erlang.org/doc/man/inet.html\#getstat-1}}, the local address and port number for the socket (\expression{sockname}), and the inet options used\footnote{\href{http://www.erlang.org/doc/man/inet.html\#setopts-2}{http://www.erlang.org/doc/man/inet.html\#setopts-2}}
\item[inet ポート] inet に関するデータを返却します。このデータは統計情報\footnote{\href{http://www.erlang.org/doc/man/inet.html\#getstat-1}{http://www.erlang.org/doc/man/inet.html\#getstat-1}}、ソケット (\expression{sockname}) のローカルアドレスとポート番号、そして 使われている inet オプション\footnote{\href{http://www.erlang.org/doc/man/inet.html\#setopts-2}{http://www.erlang.org/doc/man/inet.html\#setopts-2}}を含んでいます。
%\item[Others] currently no other form than inet ports are supported in recon, and an empty list is returned.
\item[その他] 現在のところ、 recon では inet ポート以外の形式はサポートされておらず、空のリストが返却されます。
\end{description}
\end{description*}
%The list can be obtained as follows:
次のようなリストが取得されます:
\begin{VerbatimEshell}
1> recon:port_info("#Port<0.818>").
[{meta,[{id,6544},{name,"tcp_inet"},{os_pid,undefined}]},
{signals,[{connected,<0.56.0>},
{links,[<0.56.0>]},
{monitors,[]}]},
{io,[{input,0},{output,0}]},
{memory_used,[{memory,40},{queue_size,0}]},
{type,[{statistics,[{recv_oct,0},
{recv_cnt,0},
{recv_max,0},
{recv_avg,0},
{recv_dvi,...},
{...}|...]},
{peername,{{50,19,218,110},80}},
{sockname,{{97,107,140,172},39337}},
{options,[{active,true},
{broadcast,false},
{buffer,1460},
{delay_send,...},
{...}|...]}]}]
\end{VerbatimEshell}
%On top of this, functions to find out specific problematic ports exist the way they do for processes. The gotcha is that so far, recon only supports them for inet ports and with restricted attributes: the number of octets (bytes) sent, received, or both (\expression{send\_oct}, \expression{recv\_oct}, \expression{oct}, respectively), or the number of packets sent, received, or both (\expression{send\_cnt}, \expression{recv\_cnt}, \expression{cnt}, respectively).
この例の一番上に、特定の、プロセスに関与している問題のあるポートを見つけ出す関数があります。これまででわかることは、 recon は inet ポートと限定された属性についてサポートするのみということです: 送信、受信、そして両者のオクテット(バイト)数(それぞれ\expression{send\_oct}、 \expression{recv\_oct}、\expression{oct})か、送信、受信、そして両者のパケット数(それぞれ\expression{send\_cnt}、\expression{recv\_cnt}、\expression{cnt})です。
%So for the cumulative total, which can help find out who is slowly but surely eating up all your bandwidth:
ここまでの累積合計量は、どのポートが遅い一方で確かに帯域を食いつぶしているかを見つけるのに役立ちます:
\begin{VerbatimEshell}
2> recon:inet_count(oct, 3).
[{#Port<0.6821166>,15828716661,
[{recv_oct,15828716661},{send_oct,0}]},
{#Port<0.6757848>,15762095249,
[{recv_oct,15762095249},{send_oct,0}]},
{#Port<0.6718690>,15630954707,
[{recv_oct,15630954707},{send_oct,0}]}]
\end{VerbatimEshell}
%Which suggest some ports are doing only input and eating lots of bytes. You can then use \function{recon:port\_info("\#Port<0.6821166>")} to dig in and find who owns that socket, and what is going on with it.
これは、いくつかのポートがただ受信しているだけで沢山のバイトを食い荒らしていることを示してします。そして\function{recon:port\_info("\#Port<0.6821166>")} を使って深掘り、誰がそのソケットを所有しているか、何が起こっているかを見つけることができます。
%Or in any other case, we can look at what is sending the most data within any time window\footnote{See the explanations for the \function{recon:proc\_window/3} in the preceding subsection} with the \function{recon:inet\_window(Attribute, Count, Milliseconds)} function:
もしくはその他のケースで、\function{recon:inet\_window(Attribute, Count, Milliseconds)}を使って、あるタイムウィンドウの間で何がほとんどのデータを送信しているのか\footnote{前小節の\function{recon:proc\_window/3}の説明を見てください}を見ることができます:
\begin{VerbatimEshell}
3> recon:inet_window(send_oct, 3, 5000).
[{#Port<0.11976746>,2986216,[{send_oct,4421857688}]},
{#Port<0.11704865>,1881957,[{send_oct,1476456967}]},
{#Port<0.12518151>,1214051,[{send_oct,600070031}]}]
\end{VerbatimEshell}
%For this one, the value in the middle of the tuple is what \expression{send\_oct} was worth (or any chosen attribute for each call) during the specific time interval chosen (5 seconds here).
この例では、中ほどのタプルの値は設定した特定の時間の間(ここでは5秒間) \expression{send\_oct} どのような値だったか(もしくは呼び出し時に設定した属性に対応するもの)を表しています。
%There is still some manual work involved into properly linking a misbehaving port to a process (and then possibly to a specific user or customer), but all the tools are in place.
依然、正しくプロセス(と、もしかしたら特定のユーザや顧客)にリンクされた行儀の悪いポートの巻き添えになった手作業がありますが、これらすべてのツールはちゃんとしています。
%%%
%\section{Exercises}
\section{演習}
%\subsection*{Review Questions}
\subsection*{復習問題}
\begin{enumerate}
%\item What kind of values are reported for Erlang's memory?
\item Erlangのメモリではどのような値が報告されますか。
%\item What's a valuable process-related metric for a global view?
\item グローバルビュー向けのプロセス関連で有益なメトリクスはなんでしょう。
%\item What's a port, and how should it be monitored globally?
\item ポートとはどんなもので、グローバルではどのように監視されているでしょう。
%\item Why can't you trust \app{top} or \app{htop} for CPU usage with Erlang systems? What's the alternative?
\item Erlangシステムにおいてなぜ\app{top}や\app{htop}が信頼できないのでしょうか。代替手段はなんでしょうか。
%\item Name two types of signal-related information available for processes
\item プロセス用に得られる2種類のシグナル関係の情報を挙げてください。
%\item How can you find what code a specific process is running?
\item 特定のプロセスがどのコードを動かしているかをどうやって見つけられるでしょうか。
%\item What are the different kinds of memory information available for a specific process?
\item 特定のプロセスのメモリ関連の情報にはどのような種類があるでしょうか。
%\item How can you know if a process is doing a lot of work?
\item プロセスが大量の処理をしているかどうかをどうやって見極めますか。
%\item Name a few of the values that are dangerous to fetch when inspecting processes in a production system.
\item 本番システム内のプロセスを調査する際に取得すると危険な値を2つ、3つ挙げてください。
%\item What are some features provided to OTP processes through the sys module?
\item sysモジュール経由でOTPプロセスに提供されるいくつかの機能はなんでしょうか。
%\item What kind of values are available when inspecting inet ports?
\item inetポートを調査しているときに得られる値にはどんなものがあるでしょうか。
%\item How can you find the type of a port (Files, TCP, UDP)?
\item ポートの種類(ファイル、TCP、UDP)はどのように見つけられるでしょうか。
\end{enumerate}
%\subsection*{Open-ended Questions}
\subsection*{自由回答問題}
\begin{enumerate}
%\item Why do you want a long time window available on global metrics?
\item グローバルメトリクス内で利用できる長時間のウィンドウが欲しくなる理由はなんでしょうか。
%\item Which would be more appropriate between \function{recon:proc\_count/2} and \function{recon:proc\_window/3} to find issues with:
\item 次の問題を見つけるときに使うべき関数は\function{recon:proc\_count/2}と\function{recon:proc\_window/3}のどちらでしょうか。
\item
\begin{enumerate*}
%\item Reductions
\item リダクション
%\item Message queue length
\item メッセージキューの長さ
%\item Memory
\item メモリ
\end{enumerate*}
%\item How can you find information about who is the supervisor of a given process?
\item あるプロセスのスーパーバイザーがどれかに関する情報はどうやって見つけますか。
%\item When should you use \function{recon:inet\_count/2}? \function{recon:inet\_window/3}?
\item \function{recon:inet\_count/2} や \function{recon:inet\_window/3} はそれぞれいつ使うべきでしょう。
%\item What could explain the difference in memory reported by the operating system and the memory functions in Erlang?
\item OSから報告されたメモリとErlangのmemory関数から報告されるメモリの違いを説明してください。
%\item Why is it that Erlang can sometimes look very busy even when it isn't?
\item ときどきErlangが実際にはさほど稼働していないのに、非常に稼働率が上がっているように見えるのはなぜでしょうか。
%\item How can you find what proportion of processes on a node are ready to run, but can't be scheduled right away?
\item あるノード上のプロセスの何割が実行可能だがすぐにはスケジュールできない状況になっているかを調べる方法を教えてください。
\end{enumerate}
%\subsection*{Hands-On}
\subsection*{ハンズオン}
次のコードを使って回答してください。 \href{https://github.com/ferd/recon\_demo}{https://github.com/ferd/recon\_demo}:
\begin{enumerate}
%\item What's the system memory?
\item システムメモリとはなんですか。
%\item Is the node using a lot of CPU resources?
\item ノードは多くのCPUリソースを使っていますか。
%\item Is any process mailbox overflowing?
\item メールボックスが溢れいているプロセスはありますか。
%\item Which chatty process (\module{council\_member}) takes the most memory?
\item どのchattyプロセス(\module{council\_member})が一番メモリを使っていますか。
%\item Which chatty process is eating the most CPU?
\item どのchattyプロセスが一番CPUを使用していますか。
%\item Which chatty process is consuming the most bandwidth?
\item どのchattyプロセスが一番帯域を消費していますか。
%\item Which chatty process sends the most messages over TCP? The least?
\item どのchattyプロセスがTCPで一番メッセージを送っていますか。また一番メッセージを送っていないものも答えてください。
%\item Can you find out if a specific process tends to hold multiple connections or file descriptors open at the same time on a node?
\item ノード上のあるプロセスが複数の接続やファイルディスクリプタを同時に保持しがちかどうか、どのように判断しますか。
%\item Can you find out which function is being called by the most processes at once on the node right now?
\item 今現在あるノード上でほとんどのプロセスから同時に呼ばれている関数を見つけられますか。
\end{enumerate}