diff --git a/salt/beacons/load.py b/salt/beacons/load.py index cd05ce2a61..5c2ff509dc 100644 --- a/salt/beacons/load.py +++ b/salt/beacons/load.py @@ -18,6 +18,8 @@ log = logging.getLogger(__name__) __virtualname__ = 'load' +LAST_STATUS = {} + def __virtual__(): if salt.utils.is_windows(): @@ -47,7 +49,7 @@ def validate(config): 'contain 1m, 5m and 15m items.') return False - for item in config_item: + for item in ['1m', '5m', '15m']: if not isinstance(config_item[item], list): log.info('Configuration for load beacon: ' '1m, 5m and 15m items must be ' @@ -70,6 +72,15 @@ def beacon(config): and only emit a beacon if any of them are exceeded. + `onchangeonly`: when `onchangeonly` is True the beacon will fire + events only when the load average pass one threshold. Otherwise, it will fire an + event at each beacon interval. The default is False. + + `emitatstartup`: when `emitatstartup` is False the beacon will not fire + event when the minion is reload. Applicable only when `onchangeonly` is True. + The default is True. + + .. code-block:: yaml beacons: @@ -83,9 +94,17 @@ def beacon(config): 15m: - 0.1 - 1.0 + emitatstartup: True + onchangeonly: False ''' log.trace('load beacon starting') + + if 'emitatstartup' not in config: + config['emitatstartup'] = True + if 'onchangeonly' not in config: + config['onchangeonly'] = False + ret = [] if not os.path.isfile('/proc/loadavg'): return ret @@ -93,12 +112,42 @@ def beacon(config): avgs = fp_.read().split()[:3] avg_keys = ['1m', '5m', '15m'] avg_dict = dict(zip(avg_keys, avgs)) + + if config['onchangeonly']: + if not LAST_STATUS: + for k in ['1m', '5m', '15m']: + LAST_STATUS[k] = avg_dict[k] + if not config['emitatstartup']: + return ret + + + send_beacon = False + # Check each entry for threshold - if float(avgs[0]) < float(config['1m'][0]) or \ - float(avgs[0]) > float(config['1m'][1]) or \ - float(avgs[1]) < float(config['5m'][0]) or \ - float(avgs[1]) > float(config['5m'][1]) or \ - float(avgs[2]) < float(config['15m'][0]) or \ - float(avgs[2]) > float(config['15m'][1]): + for k in ['1m', '5m', '15m']: + if k in config: + if config['onchangeonly']: + # Emit if current is more that threshold and old value less that threshold + # Emit if current is less that threshold and old value more that threshold + if float(avg_dict[k]) > float(config[k][1]) and float(LAST_STATUS[k]) < float(config[k][1]): + send_beacon = True + break + if float(avg_dict[k]) < float(config[k][0]) and float(LAST_STATUS[k]) > float(config[k][0]): + send_beacon = True + break + else: + # Emit no matter LAST_STATUS + if float(avg_dict[k]) < float(config[k][0]) or \ + float(avg_dict[k]) > float(config[k][1]): + send_beacon = True + break + + + if config['onchangeonly']: + for k in ['1m', '5m', '15m']: + LAST_STATUS[k] = avg_dict[k] + + if send_beacon: ret.append(avg_dict) + return ret