Class: Vector::Function::FlexibleDownScaling
- Inherits:
-
Object
- Object
- Vector::Function::FlexibleDownScaling
- Includes:
- HLogger
- Defined in:
- lib/vector/functions/flexible_down_scaling.rb
Instance Method Summary collapse
-
#initialize(options) ⇒ FlexibleDownScaling
constructor
A new instance of FlexibleDownScaling.
- #run_for(group, ps_check_procs) ⇒ Object
Methods included from HLogger
enable, #hlog, #hlog_ctx, #hlog_ctx_string
Constructor Details
#initialize(options) ⇒ FlexibleDownScaling
Returns a new instance of FlexibleDownScaling.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/vector/functions/flexible_down_scaling.rb', line 8 def initialize() @cloudwatch = [:cloudwatch] @dry_run = [:dry_run] @up_down_cooldown = [:up_down_cooldown] @down_down_cooldown = [:down_down_cooldown] @max_sunk_cost = [:max_sunk_cost] @variable_thresholds = [:variable_thresholds] @n_low = [:n_low] @n_high = [:n_high] @m = [:m] @g_low = [:g_low] @g_high = [:g_high] @debug_variable_thresholds = [:print_variable_thresholds] end |
Instance Method Details
#run_for(group, ps_check_procs) ⇒ Object
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 |
# File 'lib/vector/functions/flexible_down_scaling.rb', line 23 def run_for(group, ps_check_procs) result = { :triggered => false } hlog_ctx("fds") do hlog_ctx("group:#{group.name}") do # don't check if no config was specified if @up_down_cooldown.nil? && @down_down_cooldown.nil? hlog("No cooldown periods specified, exiting") return result end # don't bother checking for a scaledown if desired capacity is # already at the minimum size... if group.desired_capacity == group.min_size hlog("Group is already at minimum size, exiting") return result end scaledown_policies = group.scaling_policies.select do |policy| policy.scaling_adjustment < 0 end scaledown_policies.each do |policy| hlog_ctx("policy:#{policy.name}") do # TODO: support adjustment types other than ChangeInCapacity here if policy.adjustment_type == "ChangeInCapacity" && ps_check_procs && ps_check_procs.any? {|ps_check_proc| ps_check_proc.call(group.desired_capacity + policy.scaling_adjustment, self) } hlog("Predictive scaleup would trigger a scaleup if group were shrunk") next end alarms = policy.alarms.keys.map do |alarm_name| @cloudwatch.alarms[alarm_name] end # only consider disabled alarms (enabled alarms will trigger # the policy automatically) disabled_alarms = alarms.select do |alarm| !alarm.enabled? end # Do this logic first in case the user is just trying to print out # the thresholds. if @variable_thresholds # variable_thresholds currently requires a CPUUtilization alarm to function vt_cpu_alarm = disabled_alarms.find {|alarm| alarm.metric_name == "CPUUtilization" } # remove this alarm from the check, since we're not checking its alarm status # below. disabled_alarms.delete(vt_cpu_alarm) unless vt_cpu_alarm hlog("Variable thresholds requires an alarm on CPUUtilization, skipping") next end @n_low ||= group.min_size + 1 @n_high ||= group.max_size @m ||= vt_cpu_alarm.threshold / 100 if @g_low == @g_high hlog("g_low == g_high (#{@g_low}), not attempting to use flexible thresholds.") next end if @n_low == @n_high hlog("n_low == n_high (#{@n_low}), not attempting to use flexible thresholds.") next end if @debug_variable_thresholds puts " n_low: #{@n_low}" puts " n_high: #{@n_high}" puts " m: #{@m}" puts " g_low: #{@g_low}" puts " g_high: #{@g_high}" puts puts " N Threshold" ([@n_low, group.min_size].min + 1).upto([@n_high, group.max_size].max) do |i| puts " %2d %.1f%%" % [i, (variable_threshold(i, @n_low, @n_high, @m, @g_low, @g_high) * 100)] end next end end unless disabled_alarms.all? {|alarm| alarm.state_value == "ALARM" } hlog("Not all alarms are in ALARM state") next end if @variable_thresholds threshold = variable_threshold(group.desired_capacity, @n_low, @n_high, @m, @g_low, @g_high) stats = vt_cpu_alarm.metric.statistics( :start_time => Time.now - (vt_cpu_alarm.period * vt_cpu_alarm.evaluation_periods), :end_time => Time.now, :statistics => [ vt_cpu_alarm.statistic ], :period => vt_cpu_alarm.period) if stats.datapoints.length < vt_cpu_alarm.evaluation_periods hlog("Could not get enough datapoints for checking variable threshold"); next end if stats.datapoints.any? {|dp| dp[vt_cpu_alarm.statistic.downcase.to_sym] > (threshold * 100) } hlog("Not all datapoints are beneath the variable threshold #{(threshold * 100).to_i}: #{stats.datapoints}") next end hlog("Variable threshold: #{(threshold * 100).to_i}, #{group.desired_capacity} nodes") end unless outside_cooldown_period(group) hlog("Group is not outside the specified cooldown periods") next end unless has_eligible_scaledown_instance(group) hlog("Group does not have an instance eligible for scaledown due to max_sunk_cost") next end if @dry_run hlog("Executing policy (DRY RUN)") else hlog("Executing policy") policy.execute(:honor_cooldown => true) end result[:triggered] = true # no need to evaluate other scaledown policies return result end end end end result end |