forked from uwiger/jobs
/
jobs_sampler_cpu.erl
87 lines (74 loc) · 2.74 KB
/
jobs_sampler_cpu.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
87
%%==============================================================================
%% Copyright 2010 Erlang Solutions Ltd.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%==============================================================================
%%-------------------------------------------------------------------
%% File : jobs_sampler_cpu.erl
%% @author : Ulf Wiger <ulf.wiger@erlang-solutions.com>
%% @end
%% Description :
%%
%% Created : 15 Jan 2010 by Ulf Wiger <ulf.wiger@erlang-solutions.com>
%%-------------------------------------------------------------------
-module(jobs_sampler_cpu).
-behaviour(jobs_sampler).
-export([init/2,
sample/2,
handle_msg/3,
calc/2]).
-record(st, {levels = []}).
default_levels() -> [{80,1},{90,2},{100,3}].
init(_Name, Opts) ->
cpu_sup:util([per_cpu]), % first return value is rubbish, per the docs
Levels = proplists:get_value(levels, Opts, default_levels()),
{ok, #st{levels = Levels}}.
handle_msg(_Msg, _Timestamp, ModS) ->
{ignore, ModS}.
sample(_Timestamp, #st{} = S) ->
Result =
case cpu_sup:util([per_cpu]) of
Info when is_list(Info) ->
Utils = [U || {_,U,_,_} <- Info],
case Utils of
[U] ->
%% only one cpu
U;
[_,_|_] ->
%% This is a form of ad-hoc averaging, which tries to
%% account for the possibility that the application
%% loads the cores unevenly.
calc_avg_util(Utils)
end;
_ ->
undefined
end,
{Result, S}.
calc_avg_util(Utils) ->
case minmax(Utils) of
{A,B} when B-A > 50 ->
%% very uneven load
High = [U || U <- Utils,
B-U > 20],
lists:sum(High)/length(High);
{Low,High} ->
High+Low/2
end.
minmax([H|T]) ->
lists:foldl(
fun(X, {Min,Max}) ->
{erlang:min(X,Min), erlang:max(X,Max)}
end, {H,H}, T).
calc(History, #st{levels = Levels} = St) ->
L = jobs_sampler:calc(value, Levels, History),
{[{cpu,L}], St}.