public void GlobalSetup() { _noopCollector = new NoopCollector(); const int dataPointsPerMsg = 10; _dataPointUploadMessage = new DataPointUploadMessage(); for (int i = 0; i < dataPointsPerMsg; ++i) { var dp = new DataPoint { metric = "benchmark" + i, value = new Datum { intValue = i }, metricType = MetricType.COUNTER, }; dp.dimensions.Add(new Dimension { key = "test0", value = "benchmark" }); dp.dimensions.Add(new Dimension { key = "test1", value = "benchmark" }); _dataPointUploadMessage.datapoints.Add(dp); } }
private void ProcessDatapoints(TypeDatapoint[] typeDatapoints) { _triggerBatchTimer.Change(_config.MaxTimeBetweenBatches, _config.MaxTimeBetweenBatches); var msg = new DataPointUploadMessage(); foreach (var typeDatapoint in typeDatapoints) { msg.datapoints.Add(typeDatapoint.toDataPoint(_config.DefaultDimensions, _config.DefaultSource)); } _reporter.Send(msg); /* * * _retryPolicy.ExecuteAction(() => * { * var result = _client.Execute(request); * if (result.StatusCode == HttpStatusCode.Unauthorized) * { * throw new UnauthorizedAccessException("SignalFuse reports that your access is not authorised. Is your API key correct?"); * } * else if (result.StatusCode != HttpStatusCode.OK) * { * _log.Warn(String.Format("Request could not be processed. Server said {0}", result.StatusCode.ToString())); * } * }); */ }
protected virtual void Add(Datum value, string name, com.signalfuse.metrics.protobuf.MetricType metricType, MetricTags tags) { IDictionary <string, string> dimensions = ParseTagsToDimensions(tags); DataPoint dataPoint = new DataPoint(); dataPoint.value = value; string metricName = dimensions.ContainsKey(METRIC_DIMENSION) ? dimensions[METRIC_DIMENSION] : name; string sourceName = dimensions.ContainsKey(SOURCE_DIMENSION) ? dimensions[SOURCE_DIMENSION] : defaultSource; dataPoint.metric = metricName; dataPoint.metricType = metricType; if (!String.IsNullOrEmpty(sourceDimension) && !dimensions.ContainsKey(sourceDimension)) { AddDimension(dataPoint, sourceDimension, sourceName); } AddDimensions(dataPoint, defaultDimensions); AddDimensions(dataPoint, dimensions); uploadMessage.datapoints.Add(dataPoint); if (++datapointsAdded >= maxDatapointsPerMessage) { this.sender.Send(uploadMessage); datapointsAdded = 0; this.uploadMessage = new DataPointUploadMessage(); } }
protected internal void sendMetric(DataPoint dp) { // send the metric AddDimensions(dp, defaultDimensions); DataPointUploadMessage msg = new DataPointUploadMessage(); msg.datapoints.Add(dp); reporter.Send(msg); }
internal async Task <HttpResponseMessage> PostDataPointsAsync(IEnumerable <DataPoint> dataPoints) { var dataPointUploadMessage = new DataPointUploadMessage(); dataPointUploadMessage.datapoints.AddRange(dataPoints); using (var httpContent = NewHttpContent(dataPointUploadMessage)) { return(await _httpClient.PostAsync(Config.DataPointIngestPath, httpContent)); } }
public void Send(DataPointUploadMessage msg) { if (msg?.datapoints == null || msg.datapoints.Count < 1) { return; } var attemptNumber = 1; while (true) { try { var webRequest = WebRequest.CreateHttp(_metricsEndpointAddress); webRequest.ContentType = "application/x-protobuf"; webRequest.Method = "POST"; webRequest.Headers.Add(CommonHttpHeaderNames.TracingEnabled, "false"); if (!string.IsNullOrWhiteSpace(_apiToken)) { webRequest.Headers.Add("X-Sf-Token", _apiToken); } webRequest.Timeout = _webRequestTimeoutMs; using (var requestStream = webRequest.GetRequestStream()) { Serializer.Serialize(requestStream, msg); requestStream.Flush(); } using var webResponse = (HttpWebResponse)webRequest.GetResponse(); // if request failed (statusCode < 200 || statusCode >= 300), exception will be thrown Log.Debug($"Sent {msg.datapoints.Count} metric data points to: {_metricsEndpointAddress}."); return; } catch (Exception ex) { if (attemptNumber >= MaxAttempts || !IsTransient(ex)) { Log.Error(ex, $"Dropping metrics after {attemptNumber} unsuccessful attempt(s) sending to: {_metricsEndpointAddress}."); return; } Log.Debug(ex, "Transient exception encountered. Retrying sending metric data."); } attemptNumber++; // short wait before retrying Thread.Sleep(_waitBeforeRetries); } }
private static HttpContent NewHttpContent(DataPointUploadMessage dataPointUploadMessage) { var memoryStream = new MemoryStream(); Serializer.Serialize(memoryStream, dataPointUploadMessage); memoryStream.Flush(); memoryStream.Seek(0, SeekOrigin.Begin); HttpContent httpContent = new StreamContent(memoryStream); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-protobuf"); httpContent.Headers.Add(Config.AuthTokenHeaderName, Config.AuthToken); return(httpContent); }
internal BufferingWorker(ISignalFxMetricExporter exporter, int maxItems, Func <DataPointUploadMessage> uploadMessageFactory) { _exporter = exporter ?? throw new ArgumentNullException(nameof(exporter)); if (uploadMessageFactory == null) { throw new ArgumentNullException(nameof(uploadMessageFactory)); } // The same _uploadMessage instance is used on all export messages. _uploadMessage = uploadMessageFactory(); if (maxItems < 1) { throw new ArgumentOutOfRangeException(nameof(maxItems), "MaxItems has to be greater or equal to 1"); } _maxBufferSize = maxItems; // idle period similar to trace exporter _idlePeriod = TimeSpan.FromSeconds(1); }
public void Send(DataPointUploadMessage msg) { try { var request = _requestor.GetRequestor(); using (var rs = request.GetWriteStream()) { Serializer.Serialize(rs, msg); // flush the message before disposing rs.Flush(); } try { using (request.Send()) { } } catch (SecurityException) { LambdaLogger.Log("API token for sending metrics to SignalFx is invalid"); throw; } } catch (Exception ex) { if (ex is WebException) { var webex = ex as WebException; using (var exresp = webex.Response) { if (exresp != null) { var stream2 = exresp.GetResponseStream(); var reader2 = new StreamReader(stream2); var errorStr = reader2.ReadToEnd(); LambdaLogger.Log(errorStr); } } } throw; } }
public void Dispose() { //end stopwatch and send duration var elapsedMs = _watch.ElapsedMilliseconds; Datum timer = new Datum(); timer.doubleValue = elapsedMs; AddMetric(METRIC_NAME_DURATION, MetricType.GAUGE, timer); var msg = new DataPointUploadMessage(); msg.datapoints.AddRange(_metricsBatch); try { _reporter.Send(msg); } catch (Exception ex) { LambdaLogger.Log($"[ERR] Failed to send metrics: {ex.Message}{Environment.NewLine}"); } }
public void RecommendedUsage(bool throwException) { var context = ContextUtils.FromJsonFile("./SampleContexts/lambda-context.json"); var mockSender = new Mock <ISignalFxReporter>(); DataPointUploadMessage actualDataPointMsg = null; mockSender.Setup(m => m.Send(It.IsNotNull <DataPointUploadMessage>())) .Callback <DataPointUploadMessage>(msg => actualDataPointMsg = msg); using (var wrapper = new MetricWrapper(context, mockSender.Object)) { // Add a custom data point. DataPoint dp = new DataPoint(); dp.metric = "custom.gauge"; dp.metricType = MetricType.GAUGE; dp.value = new Datum { intValue = 1 }; dp.timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); wrapper.AddDataPoint(dp); try { if (throwException) { throw new ApplicationException("test"); } } catch (Exception) { wrapper.Error(); } } Assert.NotNull(actualDataPointMsg); var expectedDimensions = new Dictionary <string, string> { { "aws_execution_env", "" }, // Expected to be empty since the env var is not defined. { "aws_function_name", "sample-lambda-functions" }, { "aws_function_version", "$LATEST" }, { "aws_region", "us-west-2" }, { "aws_account_id", "123456789012" }, { "lambda_arn", "arn:aws:lambda:us-west-2:123456789012:function:sample-lambda-functions:$LATEST" }, // { "function_wrapper_version", "signalfx_lambda_3.0.1.0" }, { "metric_source", "lambda_wrapper" }, }; // It is hard to control for cold starts, it is exists check for the dimensions and remove it. var coldStartMetric = actualDataPointMsg.datapoints.FirstOrDefault(dp => dp.metric == "function.cold_starts"); if (coldStartMetric != null) { AssertDimensions(coldStartMetric, expectedDimensions); actualDataPointMsg.datapoints.Remove(coldStartMetric); } var expectedMetrics = new List <dynamic> { new { Name = "function.invocations", MetricType = MetricType.COUNTER }, new { Name = "function.duration", MetricType = MetricType.GAUGE }, new { Name = "custom.gauge", MetricType = MetricType.GAUGE }, }; if (throwException) { expectedMetrics.Add(new { Name = "function.errors", MetricType = MetricType.COUNTER }); } Assert.Equal(actualDataPointMsg.datapoints.Count, expectedMetrics.Count); foreach (var expectedMetric in expectedMetrics) { var actualMetric = actualDataPointMsg.datapoints.FirstOrDefault(dp => dp.metric == expectedMetric.Name); Assert.True(actualMetric != null, $"Expected metric {expectedMetric.Name} was not found."); Assert.Equal(expectedMetric.MetricType, actualMetric.metricType); AssertDimensions(actualMetric, expectedDimensions); } void AssertDimensions(DataPoint actualMetric, dynamic expectedDimensions) { Assert.Equal(actualMetric.dimensions.Count, expectedDimensions.Count); foreach (var expectedDimension in expectedDimensions) { var actualDimension = actualMetric.dimensions.FirstOrDefault(dim => dim.key == expectedDimension.Key); Assert.True(actualDimension != null, $"Expected dimension {expectedDimension.Key} was not found."); Assert.Equal(expectedDimension.Value, actualDimension.value); } } }
protected override void StartReport(string contextName) { this.uploadMessage = new DataPointUploadMessage(); base.StartReport(contextName); }
public void GlobalCleanup() { _noopCollector.Dispose(); _dataPointUploadMessage = null; }