def metricDataBatchWrite(log): """ Context manager for sending metric data samples more efficiently using batches. :param log: logger object for logging On entry, it yields a callable putSample for putting metric data samples: putSample(metricName, value, epochTimestamp) The user calls putSample for each metricDataSample that it wants to send; putSample accumulates incoming samples into a batch and sends each batch to Taurus server when optimal batch size is reached. At normal exit, the context manager sends remaining samples, if any Usage example: with metricDataBatchWrite() as putSample: putSample(metricName1, value1, epochTimestamp1) putSample(metricName2, value2, epochTimestamp2) . . . putSample(metricNameX, valueX, epochTimestampX) """ # __enter__ part begins here: batch = [] bus = message_bus_connector.MessageBusConnector() def sendBatch(): try: msg = json.dumps(dict(protocol="plain", data=batch)) bus.publish(mqName="taurus.metric.custom.data", body=msg, persistent=True) log.info("Published numSamples=%d: first=%r; last=%r", len(batch), str(batch[0]), str(batch[-1])) finally: del batch[:] def putSample(metricName, value, epochTimestamp): # NOTE: we use %r for value to avoid loss of accuracy in floats; # NOTE: we cast value to float to deal with values like the long 72001L that # would fail the parsing back to float in the receiver. batch.append("%s %r %d" % (metricName, float(value), epochTimestamp)) if len(batch) >= _METRIC_DATA_BATCH_WRITE_SIZE: sendBatch() with bus: yield putSample # __exit__ part begins here: # Send remnants, if any if batch: sendBatch()
import time import psutil from nta.utils import message_bus_connector from nta.utils.config import Config appConfig = Config("application.conf", os.environ["APPLICATION_CONFIG_PATH"]) MESSAGE_QUEUE_NAME = appConfig.get("metric_listener", "queue_name") def sendSample(bus, metricName, value, epochTimestamp): singleDataPoint = "%s %r %d" % (metricName, float(value), epochTimestamp) msg = json.dumps(dict(protocol="plain", data=[singleDataPoint])) bus.publish(mqName=MESSAGE_QUEUE_NAME, body=msg, persistent=True) if __name__ == "__main__": bus = message_bus_connector.MessageBusConnector() metricName = "cpu_percent" print "Sending CPU percent samples to `%s`..." % metricName # Send cpu percent every 5 seconds, indefinitely... while True: sample = psutil.cpu_percent(interval=5) ts = int(time.time()) sendSample(bus, metricName=metricName, value=sample, epochTimestamp=ts) print "Sent %f @ %d" % (sample, ts) sys.stdout.flush()