added rackspace maas format (#28)

Signed-off-by: Kevin Carter <kevin.carter@rackspace.com>
This commit is contained in:
Kevin Carter 2017-03-19 09:03:06 -05:00 committed by Major Hayden
parent 775f034a78
commit a61786d4e1
3 changed files with 190 additions and 9 deletions

View File

@ -82,7 +82,8 @@ class MonitorStackCLI(click.MultiCommand):
VALID_OUTPUT_FORMATS = [
'json',
'line',
'telegraf'
'telegraf',
'rax-maas'
]
@ -107,7 +108,7 @@ def cli(ctx, output_format, verbose):
def process_result(result, output_format, verbose):
"""Render the output into the proper format."""
module_name = 'monitorstack.common.formatters'
method_name = 'write_{}'.format(output_format)
method_name = 'write_{}'.format(output_format.replace('-', '_'))
output_formatter = getattr(
importlib.import_module(module_name),
method_name

View File

@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Output methods."""
import json
import time
@ -38,18 +39,62 @@ def _current_time():
return int(time.time() * 1000000000)
def _get_value_types(value, measurement_type=None):
"""Return the value and the measurement type.
This method will evaluate a given value and cast it to the
appropriate type. If the parameter `measurement_type` is
not provided the method will assign the type based on the
key set in the types list.
:param value: item to evaluate.
:param measurement_type: name of the measurement
"""
def _check_value(c_type, c_value):
try:
c_value = c_type(c_value)
except ValueError:
return False, c_value
else:
return True, c_value
success = False
if isinstance(value, str) and '.' in value:
success, value = _check_value(
c_type=float,
c_value=value
)
elif isinstance(value, float):
success = True
if success:
_measurement_type = 'float'
else:
_, value = _check_value(
c_type=int,
c_value=value
)
if isinstance(value, int):
if value > 2147483647:
_measurement_type = 'int64'
else:
_measurement_type = 'int32'
else:
_measurement_type = 'string'
if not measurement_type:
measurement_type = _measurement_type
return value, measurement_type
def _telegraf_line_format(sets, quote=False):
"""Return a comma separated string."""
store = list()
for k, v in sets.items():
k = k.replace(' ', '_')
for v_type in [int, float]:
try:
v = v_type(v)
except ValueError:
pass # v was not a int, float, or long
else:
break
v, _ = _get_value_types(value=v)
if not isinstance(v, (int, float, bool)) and quote:
store.append('{}="{}"'.format(k, v))
else:
@ -72,3 +117,27 @@ def write_telegraf(result):
click.echo(' '.join(resultant))
return True
def write_rax_maas(result):
"""Output in Rackspace Monitoring as a Service format."""
status = ['status']
if result['exit_code'] == 0:
status.append('okay')
else:
status.append('error')
status.append(result['message'])
click.echo(' '.join(status))
for key, value in result['variables'].items():
value, measurement_type = _get_value_types(
value=value,
measurement_type=result.get('measurement_type')
)
metric = ['metric', key, measurement_type, str(value)]
if 'measurement_units' in result:
metric.append(result['measurement_units'])
click.echo(' '.join(metric))
return True

View File

@ -28,6 +28,40 @@ SAMPLE_RESULT = {
}
}
SAMPLE_RESULT_ERROR = {
'exit_code': 1,
'message': 'uptime failed',
'measurement_name': 'system_uptime',
'meta': {},
'variables': {}
}
SAMPLE_RESULT_MEASUREMENT_TYPE = {
'exit_code': 0,
'message': 'uptime is ok',
'measurement_name': 'system_uptime',
'measurement_type': 'testType',
'meta': {
'platform': 'example_platform',
},
'variables': {
'uptime': '29587.75'
}
}
SAMPLE_RESULT_MEASUREMENT_UNITS = {
'exit_code': 0,
'message': 'uptime is ok',
'measurement_name': 'system_uptime',
'measurement_units': 'testUnits',
'meta': {
'platform': 'example_platform',
},
'variables': {
'uptime': '29587.75'
}
}
SAMPLE_RESULT_NO_META = {
'exit_code': 0,
'message': 'uptime is ok',
@ -56,6 +90,54 @@ class TestFormatters(object):
assert isinstance(result, int)
assert result > 0
def test__get_value_types_int32(self):
"""Test _get_value_types() with int."""
value, m_type = formatters._get_value_types(1)
assert value == 1
assert m_type == 'int32'
def test__get_value_types_int32_str(self):
"""Test _get_value_types() with int."""
value, m_type = formatters._get_value_types('1')
assert value == 1
assert m_type == 'int32'
def test__get_value_types_int64(self):
"""Test _get_value_types() with int."""
value, m_type = formatters._get_value_types(9999999999)
assert value == 9999999999
assert m_type == 'int64'
def test__get_value_types_int64_str(self):
"""Test _get_value_types() with int."""
value, m_type = formatters._get_value_types('9999999999')
assert value == 9999999999
assert m_type == 'int64'
def test__get_value_types_float(self):
"""Test _get_value_types() with float."""
value, m_type = formatters._get_value_types(1.1)
assert value == 1.1
assert m_type == 'float'
def test__get_value_types_float_str(self):
"""Test _get_value_types() with float."""
value, m_type = formatters._get_value_types('1.1')
assert value == 1.1
assert m_type == 'float'
def test__get_value_types_set_m_type(self):
"""Test _get_value_types() with float."""
value, m_type = formatters._get_value_types('1.1', 'double')
assert value == 1.1
assert m_type == 'double'
def test__get_value_types_string(self):
"""Test _get_value_types() with str."""
value, m_type = formatters._get_value_types('TestString')
assert value == 'TestString'
assert m_type == 'string'
def test_write_json(self, capsys):
"""Test write_json() module."""
formatters.write_json(SAMPLE_RESULT)
@ -95,3 +177,32 @@ class TestFormatters(object):
assert isinstance(result, str)
assert 'othervar=3' in result
assert 'platform="example_platform"' in result
def test_write_rax_maas(self, capsys):
"""Test write_telegraf() module."""
formatters.write_rax_maas(SAMPLE_RESULT)
out, err = capsys.readouterr()
assert SAMPLE_RESULT['message'] in out
assert 'metric uptime float 29587.75' in out
def test_write_rax_maas_with_types(self, capsys):
"""Test write_telegraf() module."""
formatters.write_rax_maas(SAMPLE_RESULT_MEASUREMENT_TYPE)
out, err = capsys.readouterr()
assert SAMPLE_RESULT['message'] in out
assert 'metric uptime testType 29587.75' in out
def test_write_rax_maas_with_units(self, capsys):
"""Test write_telegraf() module."""
formatters.write_rax_maas(SAMPLE_RESULT_MEASUREMENT_UNITS)
out, err = capsys.readouterr()
out_split = out.splitlines()
assert [i for i in out_split if SAMPLE_RESULT['message'] in i]
assert 'metric uptime float 29587.75 testUnits' in out_split
def test_write_rax_maas_with_error(self, capsys):
"""Test write_telegraf() module."""
formatters.write_rax_maas(SAMPLE_RESULT_ERROR)
out, err = capsys.readouterr()
out_split = out.splitlines()
assert [i for i in out_split if 'status error' in i]