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