/// <summary> /// Creates the file listener. /// </summary> /// <param name="providerGuid">The provider unique identifier.</param> /// <param name="etlFileName">Name of the etl file.</param> /// <param name="metricProducedAction">The metric produced action.</param> /// <param name="eventIdFilter">The event identifier filter.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>A <see cref="RawListener"/> instance.</returns> private static RawListener CreateFileListener( Guid providerGuid, string etlFileName, Action <ILocalAggregatedMetric> metricProducedAction, int eventIdFilter, CancellationToken cancellationToken) { return(RawListener.CreateEtlFileListener( new[] { etlFileName }, eventRecord => { if (eventRecord->EventHeader.ProviderId == providerGuid && eventRecord->EventHeader.Id == eventIdFilter) { metricProducedAction(LocalAggregatedMetric.ConvertToMetricData(eventRecord)); } }, eventTraceLog => { Logger.Log( LoggerLevel.Info, LogId, "CreateFileListener", "LocalAggregatedMetric, cancelled = {0}", cancellationToken.IsCancellationRequested); return !cancellationToken.IsCancellationRequested; })); }
/// <summary> /// Converts content of the ETW event published by ME to a <see cref="LocalAggregatedMetric"/> /// </summary> /// <param name="etwMetricData">Object containing information about metric data sample.</param> /// <returns>A MetricData object representing a locally aggregated metric.</returns> internal static unsafe LocalAggregatedMetric ConvertToMetricData(NativeMethods.EventRecord *etwMetricData) { var metricData = new LocalAggregatedMetric(); IntPtr pointerInPayload = etwMetricData->UserData; metricData.MonitoringAccount = EtwPayloadManipulationUtils.ReadString(ref pointerInPayload); metricData.MetricNamespace = EtwPayloadManipulationUtils.ReadString(ref pointerInPayload); metricData.MetricName = EtwPayloadManipulationUtils.ReadString(ref pointerInPayload); long timestamp = *((long *)pointerInPayload); metricData.MetricTimeUtc = DateTime.FromFileTimeUtc(timestamp); pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(long)); // Read the dimension name and values and split them out. var dimensionNames = EtwPayloadManipulationUtils.ReadString(ref pointerInPayload); var dimensionValues = EtwPayloadManipulationUtils.ReadString(ref pointerInPayload); if (!string.IsNullOrWhiteSpace(dimensionNames) && !string.IsNullOrWhiteSpace(dimensionValues)) { var splitDimensionNames = dimensionNames.Split(EtwListSeparatorChar, StringSplitOptions.None); var splitDimensionValues = dimensionValues.Split(EtwListSeparatorChar, StringSplitOptions.None); // Expected that both lengths be the same since they are written this way. for (var x = 0; x < splitDimensionNames.Length && x < splitDimensionValues.Length; ++x) { metricData.dimensions[splitDimensionNames[x]] = splitDimensionValues[x]; } } var scalingFactor = *((float *)pointerInPayload); pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(float)); metricData.ScalingFactor = scalingFactor; var samplingTypes = (SamplingTypes)(*((int *)pointerInPayload)); pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(int)); if ((samplingTypes & SamplingTypes.Min) != 0) { metricData.Min = *((ulong *)pointerInPayload); metricData.ScaledMin = metricData.Min / scalingFactor; } pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(ulong)); if ((samplingTypes & SamplingTypes.Max) != 0) { metricData.Max = *((ulong *)pointerInPayload); metricData.ScaledMax = metricData.Max / scalingFactor; } pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(ulong)); if ((samplingTypes & SamplingTypes.Sum) != 0) { metricData.Sum = *((ulong *)pointerInPayload); metricData.ScaledSum = metricData.Sum / scalingFactor; } pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(ulong)); pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(float)); if ((samplingTypes & SamplingTypes.Count) != 0) { metricData.Count = *((uint *)pointerInPayload); } pointerInPayload = EtwPayloadManipulationUtils.Shift(pointerInPayload, sizeof(uint)); return(metricData); }