public virtual async Task SendBatchMetricsAsync(IEnumerable<DataPoint> dataPoints)
        {
            var msg = new CustomMetricsMessage(dataPoints);
            var result = await Client.PostAsync(DefaultEndpointUrl, PrepareContent(msg.ToJson())).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.Created && _failureCallback != null)
            {
                // the normal response is a 201. For any other response code, log the code and the response body (which will hopefully say 
                // what StackDriver didn't like with the request.
                var body = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
                _failureCallback.HandleMetricPostFailure(null, result.StatusCode, body);
            }
        }
        public virtual async Task SendBatchMetricsAsync(IEnumerable <DataPoint> dataPoints)
        {
            var msg    = new CustomMetricsMessage(dataPoints);
            var result = await Client.PostAsync(DefaultEndpointUrl, PrepareContent(msg.ToJson())).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.Created && _failureCallback != null)
            {
                // the normal response is a 201. For any other response code, log the code and the response body (which will hopefully say
                // what StackDriver didn't like with the request.
                var body = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                _failureCallback.HandleMetricPostFailure(null, result.StatusCode, body);
            }
        }
        public virtual async Task SendMetricAsync(string name, object value, DateTime? collectedAt = null, string instanceId = null)
        {
            var sendCollectedAt = collectedAt.HasValue ? collectedAt.Value : DateTime.UtcNow;
            var sendInstanceId = instanceId ?? InstanceId;

            var msg = new CustomMetricsMessage(new DataPoint(name, value, sendCollectedAt, sendInstanceId));
            var result = await Client.PostAsync(DefaultEndpointUrl, PrepareContent(msg.ToJson())).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.Created && _failureCallback != null)
            {
                // the normal response is a 201. For any other response code, log the code and the response body (which will hopefully say 
                // what StackDriver didn't like with the request.
                var body = await result.Content.ReadAsStringAsync().ConfigureAwait(false);
                _failureCallback.HandleMetricPostFailure(name, result.StatusCode, body);
            }
        }
        public virtual async Task SendMetricAsync(string name, object value, DateTime?collectedAt = null, string instanceId = null)
        {
            var sendCollectedAt = collectedAt.HasValue ? collectedAt.Value : DateTime.UtcNow;
            var sendInstanceId  = instanceId ?? InstanceId;

            var msg    = new CustomMetricsMessage(new DataPoint(name, value, sendCollectedAt, sendInstanceId));
            var result = await Client.PostAsync(DefaultEndpointUrl, PrepareContent(msg.ToJson())).ConfigureAwait(false);

            if (result.StatusCode != HttpStatusCode.Created && _failureCallback != null)
            {
                // the normal response is a 201. For any other response code, log the code and the response body (which will hopefully say
                // what StackDriver didn't like with the request.
                var body = await result.Content.ReadAsStringAsync().ConfigureAwait(false);

                _failureCallback.HandleMetricPostFailure(name, result.StatusCode, body);
            }
        }