Exemple #1
0
func (s *sender) sendMetrics(reader spool.MetricReader) error {
	batches, err := reader.Read()
	if err != nil {
		return errors.Annotate(err, "failed to open the metric reader")
	}
	var sendBatches []params.MetricBatchParam
	for _, batch := range batches {
		sendBatches = append(sendBatches, spool.APIMetricBatch(batch))
	}
	results, err := s.client.AddMetricBatches(sendBatches)
	if err != nil {
		return errors.Annotate(err, "could not send metrics")
	}
	for batchUUID, resultErr := range results {
		// if we fail to send any metric batch we log a warning with the assumption that
		// the unsent metric batches remain in the spool directory and will be sent to the
		// controller when the network partition is restored.
		if _, ok := resultErr.(*params.Error); ok || params.IsCodeAlreadyExists(resultErr) {
			err := reader.Remove(batchUUID)
			if err != nil {
				logger.Errorf("could not remove batch %q from spool: %v", batchUUID, err)
			}
		} else {
			logger.Errorf("failed to send batch %q: %v", batchUUID, resultErr)
		}
	}
	return nil
}
Exemple #2
0
// Do sends metrics from the metric spool to the
// state server via an api call.
func (s *sender) Do(stop <-chan struct{}) error {
	reader, err := s.factory.Reader()
	if err != nil {
		return errors.Trace(err)
	}
	batches, err := reader.Read()
	if err != nil {
		logger.Warningf("failed to open the metric reader: %v", err)
		return errors.Trace(err)
	}
	defer reader.Close()
	var sendBatches []params.MetricBatchParam
	for _, batch := range batches {
		sendBatches = append(sendBatches, spool.APIMetricBatch(batch))
	}
	results, err := s.client.AddMetricBatches(sendBatches)
	if err != nil {
		logger.Warningf("could not send metrics: %v", err)
		return errors.Trace(err)
	}
	for batchUUID, resultErr := range results {
		// if we fail to send any metric batch we log a warning with the assumption that
		// the unsent metric batches remain in the spool directory and will be sent to the
		// state server when the network partition is restored.
		if _, ok := resultErr.(*params.Error); ok || params.IsCodeAlreadyExists(resultErr) {
			err = reader.Remove(batchUUID)
			if err != nil {
				logger.Warningf("could not remove batch %q from spool: %v", batchUUID, err)
			}
		} else {
			logger.Warningf("failed to send batch %q: %v", batchUUID, resultErr)
		}
	}
	return nil
}
Exemple #3
0
func (s *metricsBatchSuite) TestAPIMetricBatch(c *gc.C) {
	batches := []spool.MetricBatch{{
		CharmURL: "local:trusty/test-charm",
		UUID:     "test-uuid",
		Created:  time.Now(),
		Metrics: []jujuc.Metric{
			{
				Key:   "test-key-1",
				Value: "test-value-1",
				Time:  time.Now(),
			}, {
				Key:   "test-key-2",
				Value: "test-value-2",
				Time:  time.Now(),
			},
		},
	}, {
		CharmURL: "local:trusty/test-charm",
		UUID:     "test-uuid",
		Created:  time.Now(),
		Metrics:  []jujuc.Metric{},
	},
	}
	for _, batch := range batches {
		apiBatch := spool.APIMetricBatch(batch)
		c.Assert(apiBatch.Batch.UUID, gc.DeepEquals, batch.UUID)
		c.Assert(apiBatch.Batch.CharmURL, gc.DeepEquals, batch.CharmURL)
		c.Assert(apiBatch.Batch.Created, gc.DeepEquals, batch.Created)
		c.Assert(len(apiBatch.Batch.Metrics), gc.Equals, len(batch.Metrics))
		for i, metric := range batch.Metrics {
			c.Assert(metric.Key, gc.DeepEquals, apiBatch.Batch.Metrics[i].Key)
			c.Assert(metric.Value, gc.DeepEquals, apiBatch.Batch.Metrics[i].Value)
			c.Assert(metric.Time, gc.DeepEquals, apiBatch.Batch.Metrics[i].Time)
		}
	}
}