add support for (de)serialization of both implementations of IMetric

As part of breaking up all of the kafka-related changes into smaller chunks.

This adds functionality for JSON serialization and deserialization of both implementations of `IMetric`. 

PreaggregatedMetric looks like this when serialized:

```json
[
  {
    "class": "preaggregated",
    "collectionTime": 12345,
    "tenantId": "gone",
    "metricName": "in",
    "metricValue": {
      "type": "counter",
      "count": 1,
      "rate": 0.066666666666667,
      "sampleCount": 0
    },
    "ttlInSeconds": 60
  },
  {
    "class": "preaggregated",
    "collectionTime": 12345,
    "tenantId": "gone",
    "metricName": "in",
    "metricValue": {
      "type": "gauge",
      "count": 1,
      "timestamp": 1389211230,
      "latestNumericValue": 397,
      "mean": 397,
      "var": 0,
      "min": 397,
      "max": 397
    },
    "ttlInSeconds": 60
  },
  {
    "class": "preaggregated",
    "collectionTime": 12345,
    "tenantId": "gone",
    "metricName": "in",
    "metricValue": {
      "type": "set",
      "hashes": [
        746007989,
        1875251108,
        98262,
        103159993,
        1727114331,
        -1034140067,
        98699,
        1062516268,
        99644
      ],
      "count": 9
    },
    "ttlInSeconds": 60
  },
  {
    "class": "preaggregated",
    "collectionTime": 12345,
    "tenantId": "gone",
    "metricName": "in",
    "metricValue": {
      "type": "timer",
      "sum": 214,
      "count": 1,
      "rate": 0.066666666666667,
      "sampleCount": 1,
      "min": 214,
      "max": 214,
      "average": 214,
      "variance": 0,
      "percentiles": {
        "98": 214,
        "99": 214,
        "75": 214,
        "999": 214,
        "50": 214
      }
    },
    "ttlInSeconds": 60
  }
]
```