/
http_cache_store_native_stats.erl
86 lines (68 loc) · 2.64 KB
/
http_cache_store_native_stats.erl
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
%% @private
-module(http_cache_store_native_stats).
-include("http_cache_store_native.hrl").
-behaviour(gen_server).
-export([allocated_memory_used/0, set_limit_reached/1, is_limit_reached/0]).
-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2]).
-define(DEFAULT_INTERVAL, 1000).
-define(DEFAULT_LIMIT, 0.9).
set_limit_reached(IsReached) ->
ets:insert(?CONFIG_TABLE, {limit_reached, IsReached}),
ok.
is_limit_reached() ->
[{_, IsReached}] = ets:lookup(?CONFIG_TABLE, limit_reached),
IsReached.
allocated_memory_used() ->
MemoryLimit = application:get_env(http_cache_store_native, memory_limit, ?DEFAULT_LIMIT),
allocated_memory_used(MemoryLimit).
allocated_memory_used(Ratio) when is_float(Ratio) ->
system_memory_use() / Ratio;
allocated_memory_used(MaxSize) when is_integer(MaxSize) ->
(table_memory_used(?OBJECT_TABLE) + table_memory_used(?LRU_TABLE)) / MaxSize.
system_memory_use() ->
system_memory_use(maps:from_list(
memsup:get_system_memory_data())).
system_memory_use(#{available_memory := Available, system_total_memory := Total}) ->
1 - Available / Total;
system_memory_use(MemData) ->
Cached = map_get(cached_memory, MemData),
Buffered = map_get(buffered_memory, MemData),
Free = map_get(free_memory, MemData),
Total = map_get(system_total_memory, MemData),
1 - (Cached + Buffered + Free) / Total.
table_memory_used(Table) ->
WordSize = persistent_term:get(os_word_size),
ets:info(Table, memory) * WordSize.
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
init(_) ->
WordSize = memsup:get_os_wordsize() div 8,
persistent_term:put(os_word_size, WordSize),
schedule_collect(),
{ok,
#{total_mem => 0,
objects_mem => 0,
objects_count => 0,
lru_mem => 0}}.
handle_call(stats, _From, Stats) ->
{reply, Stats, Stats}.
handle_cast({}, Stats) ->
{noreply, Stats}.
handle_info(collect_stats, _Stats) ->
ObjectsMem = table_memory_used(?OBJECT_TABLE),
ObjectsCount = ets:info(?OBJECT_TABLE, size),
LRUMem = table_memory_used(?LRU_TABLE),
Stats =
#{total_mem => ObjectsMem + LRUMem,
objects_mem => ObjectsMem,
objects_count => ObjectsCount,
lru_mem => LRUMem},
telemetry:execute([http_cache_store_native, memory], Stats, #{}),
schedule_collect(),
{noreply, Stats}.
schedule_collect() ->
erlang:send_after(collect_interval(), self(), collect_stats).
collect_interval() ->
application:get_env(http_cache_store_native,
pull_table_stats_interval,
?DEFAULT_INTERVAL).