Refactor beam_stats_state
[beam_stats.git] / src / beam_stats_state.erl
1 -module(beam_stats_state).
2
3 -include("include/beam_stats.hrl").
4
5 -export_type(
6 [ t/0
7 ]).
8
9 -export(
10 [ new/0
11 , update/1
12 , export/1
13 ]).
14
15 -record(snapshots,
16 { memory :: [{atom(), non_neg_integer()}]
17 , run_queue :: non_neg_integer()
18 }).
19
20 -type snapshots() ::
21 #snapshots{}.
22
23 -record(deltas,
24 { reductions :: non_neg_integer()
25 }).
26
27 -type deltas() ::
28 #deltas{}.
29
30 -record(totals,
31 { io_bytes_in :: non_neg_integer()
32 , io_bytes_out :: non_neg_integer()
33 , context_switches :: non_neg_integer()
34 }).
35
36 -type totals() ::
37 #totals{}.
38
39 -record(?MODULE,
40 { timestamp :: erlang:timestamp()
41 , node_id :: atom()
42 , snapshots :: snapshots() % Current state
43 , deltas :: deltas() % Accumulated since last check
44 , totals_previous :: totals() % Accumulated since VM start, as of last state
45 , totals_current :: totals() % Accumulated since VM start, as of this state
46 }).
47
48 -define(T, #?MODULE).
49
50 -opaque t() ::
51 ?T{}.
52
53 -spec new() ->
54 t().
55 new() ->
56 TotalsPrevious = totals_empty(),
57 new(TotalsPrevious).
58
59 -spec new(TotalsPrevious :: totals()) ->
60 t().
61 new(#totals{}=TotalsPrevious) ->
62 ?T
63 { timestamp = os:timestamp()
64 , node_id = erlang:node()
65 , snapshots = snapshots_new()
66 , deltas = deltas_new()
67 , totals_previous = TotalsPrevious
68 , totals_current = totals_new()
69 }.
70
71 -spec update(t()) ->
72 t().
73 update(?T{totals_current=TotalsPrevious}) ->
74 new(TotalsPrevious).
75
76 -spec export(t()) ->
77 beam_stats:t().
78 export(
79 ?T
80 { timestamp = Timestamp
81 , node_id = NodeID
82 , snapshots =
83 #snapshots
84 { memory = Memory
85 , run_queue = RunQueue
86 }
87 , deltas =
88 #deltas
89 { reductions = Reductions
90 }
91 , totals_previous =
92 #totals
93 { io_bytes_in = PreviousIOBytesIn
94 , io_bytes_out = PreviousIOBytesOut
95 , context_switches = PreviousContextSwitches
96 }
97 , totals_current =
98 #totals
99 { io_bytes_in = CurrentIOBytesIn
100 , io_bytes_out = CurrentIOBytesOut
101 , context_switches = CurrentContextSwitches
102 }
103 }
104 ) ->
105 #beam_stats
106 { timestamp = Timestamp
107 , node_id = NodeID
108 , memory = Memory
109 , io_bytes_in = CurrentIOBytesIn - PreviousIOBytesIn
110 , io_bytes_out = CurrentIOBytesOut - PreviousIOBytesOut
111 , context_switches = CurrentContextSwitches - PreviousContextSwitches
112 , reductions = Reductions
113 , run_queue = RunQueue
114 }.
115
116 snapshots_new() ->
117 #snapshots
118 { memory = erlang:memory()
119 , run_queue = erlang:statistics(run_queue)
120 }.
121
122 deltas_new() ->
123 {_ReductionsTotal, ReductionsDelta} = erlang:statistics(reductions),
124 #deltas
125 { reductions = ReductionsDelta
126 }.
127
128 totals_new() ->
129 { {input , IOBytesIn}
130 , {output , IOBytesOut}
131 } = erlang:statistics(io),
132 {ContextSwitches, 0} = erlang:statistics(context_switches),
133 #totals
134 { io_bytes_in = IOBytesIn
135 , io_bytes_out = IOBytesOut
136 , context_switches = ContextSwitches
137 }.
138
139 totals_empty() ->
140 #totals
141 { io_bytes_in = 0
142 , io_bytes_out = 0
143 , context_switches = 0
144 }.
This page took 0.061773 seconds and 4 git commands to generate.