diff --git a/.gitignore b/.gitignore index 5fb81ac..26a1bca 100755 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.swp *.iml +.DS_Store .cache .classpath .idea diff --git a/pom.xml b/pom.xml index 1a47dbf..e70cd62 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.0.0 ${versionNumber}-SNAPSHOT 1.0.0.280 - 1.0.0.108 + 1.0.0.134 0.6.1 true diff --git a/src/main/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImpl.java b/src/main/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImpl.java index 41a7a4f..9dd9309 100644 --- a/src/main/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImpl.java +++ b/src/main/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImpl.java @@ -13,7 +13,6 @@ import com.hpcloud.maas.common.model.alarm.AggregateFunction; import com.hpcloud.maas.common.model.alarm.AlarmOperator; import com.hpcloud.maas.common.model.alarm.AlarmState; import com.hpcloud.maas.common.model.alarm.AlarmSubExpression; -import com.hpcloud.maas.common.model.metric.CollectdMetrics; import com.hpcloud.maas.common.model.metric.MetricDefinition; import com.hpcloud.maas.domain.model.Alarm; import com.hpcloud.maas.domain.model.SubAlarm; @@ -50,10 +49,9 @@ public class AlarmDAOImpl implements AlarmDAO { String subAlarmId = (String) row.get("id"); Map dimensions = findDimensionsById(handle, subAlarmId); AggregateFunction function = AggregateFunction.valueOf((String) row.get("function")); - MetricDefinition metricDef = new MetricDefinition((String) row.get("namespace"), - (String) row.get("metric_type"), (String) row.get("metric_subject"), dimensions); + MetricDefinition metricDef = new MetricDefinition((String) row.get("namespace"), dimensions); // TODO remove later when collectd supports all dimensions - CollectdMetrics.removeUnsupportedDimensions(metricDef); + // CollectdMetrics.removeUnsupportedDimensions(metricDef); AlarmOperator operator = AlarmOperator.valueOf((String) row.get("operator")); AlarmSubExpression subExpression = new AlarmSubExpression(function, metricDef, operator, (Double) row.get("threshold"), (Integer) row.get("period"), (Integer) row.get("periods")); diff --git a/src/main/java/com/hpcloud/maas/infrastructure/persistence/MetricDefinitionDAOImpl.java b/src/main/java/com/hpcloud/maas/infrastructure/persistence/MetricDefinitionDAOImpl.java index b8ae88b..f3a7dda 100644 --- a/src/main/java/com/hpcloud/maas/infrastructure/persistence/MetricDefinitionDAOImpl.java +++ b/src/main/java/com/hpcloud/maas/infrastructure/persistence/MetricDefinitionDAOImpl.java @@ -20,7 +20,7 @@ import com.hpcloud.maas.domain.service.MetricDefinitionDAO; * @author Jonathan Halterman */ public class MetricDefinitionDAOImpl implements MetricDefinitionDAO { - private static final String METRIC_DEF_SQL = "select sa.namespace, sa.metric_type, sa.metric_subject, sad.dimensions from sub_alarm as sa " + private static final String METRIC_DEF_SQL = "select sa.namespace, sad.dimensions from sub_alarm as sa " + "left join (select sub_alarm_id, group_concat(dimension_name, '=', value) as dimensions from sub_alarm_dimension group by sub_alarm_id) as sad on sa.id = sad.sub_alarm_id"; private final DBI db; @@ -40,8 +40,6 @@ public class MetricDefinitionDAOImpl implements MetricDefinitionDAO { List metricDefs = new ArrayList(rows.size()); for (Map row : rows) { String namespace = (String) row.get("namespace"); - String type = (String) row.get("metric_type"); - String subject = (String) row.get("metric_subject"); String dimensionSet = (String) row.get("dimensions"); Map dimensions = null; @@ -57,7 +55,7 @@ public class MetricDefinitionDAOImpl implements MetricDefinitionDAO { } } - metricDefs.add(new MetricDefinition(namespace, type, subject, dimensions)); + metricDefs.add(new MetricDefinition(namespace, dimensions)); } return metricDefs; diff --git a/src/main/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImpl.java b/src/main/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImpl.java index e53ee41..854cda4 100644 --- a/src/main/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImpl.java +++ b/src/main/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImpl.java @@ -31,10 +31,10 @@ public class SubAlarmDAOImpl implements SubAlarmDAO { */ private static final String FIND_BY_METRIC_DEF_SQL = "select sa.* from sub_alarm sa, sub_alarm_dimension d " + "join (%s) v on d.dimension_name = v.dimension_name and d.value = v.value " - + "where sa.id = d.sub_alarm_id and sa.namespace = :namespace and sa.metric_type = :metricType and sa.metric_subject %s " + + "where sa.id = d.sub_alarm_id and sa.namespace = :namespace " + "group by d.sub_alarm_id having count(d.sub_alarm_id) = %s"; private static final String FIND_BY_METRIC_DEF_NO_DIMS_SQL = "select * from sub_alarm sa where sa.namespace = :namespace " - + "and sa.metric_type = :metricType and sa.metric_subject %s and (select count(*) from sub_alarm_dimension where sub_alarm_id = sa.id) = 0"; + + "and (select count(*) from sub_alarm_dimension where sub_alarm_id = sa.id) = 0"; private final DBI db; @@ -49,21 +49,17 @@ public class SubAlarmDAOImpl implements SubAlarmDAO { try { String sql = null; - String subjectSql = metricDefinition.subject == null ? "is null" : "= :metricSubject"; if (metricDefinition.dimensions == null || metricDefinition.dimensions.isEmpty()) - sql = String.format(FIND_BY_METRIC_DEF_NO_DIMS_SQL, subjectSql); + sql = FIND_BY_METRIC_DEF_NO_DIMS_SQL; else { String unionAllStatement = SqlStatements.unionAllStatementFor(metricDefinition.dimensions, "dimension_name", "value"); - sql = String.format(FIND_BY_METRIC_DEF_SQL, unionAllStatement, subjectSql, + sql = String.format(FIND_BY_METRIC_DEF_SQL, unionAllStatement, metricDefinition.dimensions.size()); } - Query> query = h.createQuery(sql) - .bind("namespace", metricDefinition.namespace) - .bind("metricType", metricDefinition.type); - if (metricDefinition.subject != null) - query.bind("metricSubject", metricDefinition.subject); + Query> query = h.createQuery(sql).bind("namespace", + metricDefinition.namespace); List> rows = query.list(); List subAlarms = new ArrayList(rows.size()); @@ -75,7 +71,7 @@ public class SubAlarmDAOImpl implements SubAlarmDAO { operator, (Double) row.get("threshold"), (Integer) row.get("period"), (Integer) row.get("periods")); SubAlarm subAlarm = new SubAlarm(subAlarmId, (String) row.get("alarm_id"), subExpression); - + subAlarms.add(subAlarm); } diff --git a/src/main/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializer.java b/src/main/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializer.java index 880e850..8620715 100644 --- a/src/main/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializer.java +++ b/src/main/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializer.java @@ -33,7 +33,7 @@ public class CollectdMetricDeserializer implements TupleDeserializer, Serializab List> results = new ArrayList>(metrics.size()); for (Metric metric : metrics) { // TODO remove in the future - CollectdMetrics.removeUnsupportedDimensions(metric.definition); +// CollectdMetrics.removeUnsupportedDimensions(metric.definition); results.add(Arrays.asList(metric.definition, metric)); } return results; diff --git a/src/test/java/com/hpcloud/maas/domain/model/AlarmTest.java b/src/test/java/com/hpcloud/maas/domain/model/AlarmTest.java index 7b10098..30a4671 100644 --- a/src/test/java/com/hpcloud/maas/domain/model/AlarmTest.java +++ b/src/test/java/com/hpcloud/maas/domain/model/AlarmTest.java @@ -19,7 +19,7 @@ import com.hpcloud.maas.common.model.alarm.AlarmState; public class AlarmTest { public void shouldBeUndeterminedIfAnySubAlarmIsUndetermined() { AlarmExpression expr = new AlarmExpression( - "avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 AND avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3"); + "avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 AND avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3"); SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0), AlarmState.UNDETERMINED); SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1), AlarmState.ALARM); @@ -32,7 +32,7 @@ public class AlarmTest { public void shouldEvaluateExpressionWithBooleanAnd() { AlarmExpression expr = new AlarmExpression( - "avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 AND avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3"); + "avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 AND avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3"); SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0)); SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1)); @@ -66,7 +66,7 @@ public class AlarmTest { public void shouldEvaluateExpressionWithBooleanOr() { AlarmExpression expr = new AlarmExpression( - "avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 OR avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3"); + "avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 OR avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3"); SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0)); SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1)); @@ -103,7 +103,7 @@ public class AlarmTest { public void shouldBuiltStateChangeReason() { AlarmExpression expr = new AlarmExpression( - "avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5 times 3 OR avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4 times 3"); + "avg(hpcs.compute{instance_id=5,metric_name=cpu,device=1}, 1) > 5 times 3 OR avg(hpcs.compute{flavor_id=3,metric_name=mem}, 2) < 4 times 3"); SubAlarm subAlarm1 = new SubAlarm("123", "1", expr.getSubExpressions().get(0)); SubAlarm subAlarm2 = new SubAlarm("456", "1", expr.getSubExpressions().get(1)); List expressions = Arrays.asList(subAlarm1.getExpression().toString(), @@ -111,10 +111,10 @@ public class AlarmTest { assertEquals( Alarm.buildStateChangeReason(AlarmState.UNDETERMINED, expressions), - "No data was present for the sub-alarms: [avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4.0 times 3]"); + "No data was present for the sub-alarms: [avg(hpcs.compute:{device=1, metric_name=cpu, instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:{flavor_id=3, metric_name=mem}, 2) < 4.0 times 3]"); assertEquals( Alarm.buildStateChangeReason(AlarmState.ALARM, expressions), - "Thresholds were exceeded for the sub-alarms: [avg(hpcs.compute:cpu:1:{instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:mem:{flavor_id=3}, 2) < 4.0 times 3]"); + "Thresholds were exceeded for the sub-alarms: [avg(hpcs.compute:{device=1, metric_name=cpu, instance_id=5}, 1) > 5.0 times 3, avg(hpcs.compute:{flavor_id=3, metric_name=mem}, 2) < 4.0 times 3]"); } } diff --git a/src/test/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImplTest.java b/src/test/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImplTest.java index ee7720c..8e5b4c8 100644 --- a/src/test/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImplTest.java +++ b/src/test/java/com/hpcloud/maas/infrastructure/persistence/AlarmDAOImplTest.java @@ -50,17 +50,18 @@ public class AlarmDAOImplTest { handle.execute("truncate table alarm_action"); handle.execute("insert into alarm (id, tenant_id, name, expression, state, created_at, updated_at) " - + "values ('123', 'bob', '90% CPU', 'avg(hpcs.compute:cpu:{flavor_id=777, image_id=888}) > 10', 'UNDETERMINED', NOW(), NOW())"); - handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) " - + "values ('111', '123', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())"); + + "values ('123', 'bob', '90% CPU', 'avg(hpcs.compute{flavor_id=777, image_id=888, metric_name=cpu}) > 10', 'UNDETERMINED', NOW(), NOW())"); + handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) " + + "values ('111', '123', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())"); handle.execute("insert into sub_alarm_dimension values ('111', 'flavor_id', '777')"); handle.execute("insert into sub_alarm_dimension values ('111', 'image_id', '888')"); + handle.execute("insert into sub_alarm_dimension values ('111', 'metric_name', 'cpu')"); handle.execute("insert into alarm_action values ('123', '29387234')"); handle.execute("insert into alarm_action values ('123', '77778687')"); } public void shouldFindById() { - String expr = "avg(hpcs.compute:cpu) > 10"; + String expr = "avg(hpcs.compute{flavor_id=777, image_id=888, metric_name=cpu}) > 10"; Alarm expected = new Alarm("123", "bob", "90% CPU", AlarmExpression.of(expr), Arrays.asList(new SubAlarm("111", "123", AlarmSubExpression.of(expr))), AlarmState.UNDETERMINED); diff --git a/src/test/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImplTest.java b/src/test/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImplTest.java index b614a4b..94fa71a 100644 --- a/src/test/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImplTest.java +++ b/src/test/java/com/hpcloud/maas/infrastructure/persistence/SubAlarmDAOImplTest.java @@ -1,6 +1,7 @@ package com.hpcloud.maas.infrastructure.persistence; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; import java.nio.charset.Charset; import java.util.Arrays; @@ -47,54 +48,61 @@ public class SubAlarmDAOImplTest { handle.execute("truncate table sub_alarm"); handle.execute("truncate table sub_alarm_dimension"); - handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) " - + "values ('111', '123', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())"); + handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) " + + "values ('111', '123', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())"); handle.execute("insert into sub_alarm_dimension values ('111', 'instance_id', '555')"); handle.execute("insert into sub_alarm_dimension values ('111', 'az', '1')"); handle.execute("insert into sub_alarm_dimension values ('111', 'instance_uuid', '555')"); + handle.execute("insert into sub_alarm_dimension values ('111', 'metric_name', 'cpu')"); - handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) " - + "values ('222', '234', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())"); + handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) " + + "values ('222', '234', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())"); handle.execute("insert into sub_alarm_dimension values ('222', 'instance_id', '666')"); handle.execute("insert into sub_alarm_dimension values ('222', 'az', '1')"); handle.execute("insert into sub_alarm_dimension values ('222', 'instance_uuid', '666')"); + handle.execute("insert into sub_alarm_dimension values ('222', 'metric_name', 'cpu')"); - handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) " - + "values ('333', '345', 'AVG', 'hpcs.compute', 'disk', 'vda', 'GT', 10, 60, 1, NOW(), NOW())"); + handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) " + + "values ('333', '345', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())"); handle.execute("insert into sub_alarm_dimension values ('333', 'instance_id', '777')"); handle.execute("insert into sub_alarm_dimension values ('333', 'az', '1')"); handle.execute("insert into sub_alarm_dimension values ('333', 'instance_uuid', '777')"); + handle.execute("insert into sub_alarm_dimension values ('333', 'metric_name', 'disk')"); + handle.execute("insert into sub_alarm_dimension values ('333', 'device', 'vda')"); - handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, metric_type, metric_subject, operator, threshold, period, periods, created_at, updated_at) " - + "values ('444', '456', 'AVG', 'hpcs.compute', 'cpu', null, 'GT', 10, 60, 1, NOW(), NOW())"); + handle.execute("insert into sub_alarm (id, alarm_id, function, namespace, operator, threshold, period, periods, created_at, updated_at) " + + "values ('444', '456', 'AVG', 'hpcs.compute', 'GT', 10, 60, 1, NOW(), NOW())"); + handle.execute("insert into sub_alarm_dimension values ('444', 'metric_name', 'cpu')"); } public void shouldFind() { List expected = Arrays.asList(new SubAlarm("111", "123", - AlarmSubExpression.of("avg(hpcs.compute:cpu:{instance_id=555,az=1}) > 10"), + AlarmSubExpression.of("avg(hpcs.compute{instance_id=555,az=1,metric_name=cpu}) > 10"), AlarmState.UNDETERMINED)); List subAlarms = dao.find(expected.get(0).getExpression().getMetricDefinition()); assertEquals(subAlarms, expected); expected = Arrays.asList(new SubAlarm("222", "234", - AlarmSubExpression.of("avg(hpcs.compute:cpu:{instance_id=666,az=1}) > 10"), + AlarmSubExpression.of("avg(hpcs.compute{instance_id=666,az=1,metric_name=cpu}) > 10"), AlarmState.UNDETERMINED)); subAlarms = dao.find(expected.get(0).getExpression().getMetricDefinition()); assertEquals(subAlarms, expected); } public void shouldFindWithSubject() { - List expected = Arrays.asList(new SubAlarm("333", "345", - AlarmSubExpression.of("avg(hpcs.compute:disk:vda:{instance_id=777,az=1}) > 10"), + List expected = Arrays.asList(new SubAlarm( + "333", + "345", + AlarmSubExpression.of("avg(hpcs.compute{instance_id=777,az=1,metric_name=disk,device=vda}) > 10"), AlarmState.UNDETERMINED)); List subAlarms = dao.find(expected.get(0).getExpression().getMetricDefinition()); assertEquals(subAlarms, expected); } - public void shouldFindForNullDimensions() { + public void shouldFailFindForNullDimensions() { List expected = Arrays.asList(new SubAlarm("444", "456", - AlarmSubExpression.of("avg(hpcs.compute:cpu) > 10"), AlarmState.UNDETERMINED)); + AlarmSubExpression.of("avg(hpcs.compute{metric_name=cpu}) > 10"), AlarmState.UNDETERMINED)); List subAlarms = dao.find(new MetricDefinition("hpcs.compute", "cpu", null, null)); - assertEquals(subAlarms, expected); + assertNotEquals(subAlarms, expected); } } diff --git a/src/test/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializerTest.java b/src/test/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializerTest.java index f2939b8..098c662 100644 --- a/src/test/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializerTest.java +++ b/src/test/java/com/hpcloud/maas/infrastructure/thresholding/deserializer/CollectdMetricDeserializerTest.java @@ -24,12 +24,18 @@ public class CollectdMetricDeserializerTest { String metric = "{\"putval\":{\"values\":[36184,51182963],\"dstypes\":[\"derive\",\"derive\"],\"dsnames\":[\"read\",\"write\"],\"time\":1365802618.809,\"interval\":60.000,\"host\":\"instance-000d65f3\",\"plugin\":\"libvirt\",\"plugin_instance\":\"\",\"type\":\"disk_ops\",\"type_instance\":\"vda\"}}"; List> metrics = deserializer.deserialize(metric.getBytes()); - Metric expected1 = new Metric(new MetricDefinition("hpcs.compute", "disk_read_ops_count", "vda", - ImmutableMap.builder().put("instance_id", "878067").build()), 1365802618, - 36184); - Metric expected2 = new Metric(new MetricDefinition("hpcs.compute", "disk_write_ops_count", "vda", - ImmutableMap.builder().put("instance_id", "878067").build()), 1365802618, - 51182963); + Metric expected1 = new Metric(new MetricDefinition("hpcs.compute", + ImmutableMap.builder() + .put("device", "vda") + .put("metric_name", "disk_read_ops_count") + .put("instance_id", "878067") + .build()), 1365802618, 36184); + Metric expected2 = new Metric(new MetricDefinition("hpcs.compute", + ImmutableMap.builder() + .put("device", "vda") + .put("metric_name", "disk_write_ops_count") + .put("instance_id", "878067") + .build()), 1365802618, 51182963); assertEquals( metrics, Arrays.asList(Arrays.asList(expected1.definition, expected1), diff --git a/src/test/resources/com/hpcloud/maas/infrastructure/persistence/alarm.sql b/src/test/resources/com/hpcloud/maas/infrastructure/persistence/alarm.sql index 3dca776..63a430b 100644 --- a/src/test/resources/com/hpcloud/maas/infrastructure/persistence/alarm.sql +++ b/src/test/resources/com/hpcloud/maas/infrastructure/persistence/alarm.sql @@ -14,8 +14,6 @@ CREATE TABLE `sub_alarm` ( `alarm_id` varchar(36) NOT NULL, `function` varchar(10) NOT NULL, `namespace` varchar(100) NOT NULL, - `metric_type` varchar(100) NOT NULL, - `metric_subject` varchar(50) DEFAULT NULL, `operator` varchar(5) NOT NULL, `threshold` double NOT NULL, `period` int(11) NOT NULL,