internal override void WritePayload(float intervalSec) { lock (MyLock) { float value = 0; try { value = _getMetricFunction(); } catch (Exception ex) { ReportOutOfBandMessage($"ERROR: Exception during EventCounter {_name} getMetricFunction callback: " + ex.Message); } CounterPayload payload = new CounterPayload(); payload.Name = _name; payload.DisplayName = (DisplayName == null) ? "" : DisplayName; payload.Count = 1; // NOTE: These dumb-looking statistics is intentional payload.IntervalSec = intervalSec; payload.Mean = value; payload.Max = value; payload.Min = value; payload.StandardDeviation = 0; _lastVal = value; _eventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new PollingPayloadType(payload)); } }
public static ICounterPayload GenerateCounterPayload( bool isIncrementingCounter, string counterName, double counterValue, int displayRateTimeScaleSeconds = 0, string displayName = "", string displayUnits = "") { if (isIncrementingCounter) { Dictionary <string, object> payloadFields = new Dictionary <string, object>() { { "Name", counterName }, { "Increment", counterValue }, { "DisplayName", displayName }, { "DisplayRateTimeScale", displayRateTimeScaleSeconds == 0 ? "" : TimeSpan.FromSeconds(displayRateTimeScaleSeconds).ToString() }, { "DisplayUnits", displayUnits }, }; ICounterPayload payload = new IncrementingCounterPayload(payloadFields, 1); return(payload); } else { Dictionary <string, object> payloadFields = new Dictionary <string, object>() { { "Name", counterName }, { "Mean", counterValue }, { "DisplayName", displayName }, { "DisplayUnits", displayUnits }, }; ICounterPayload payload = new CounterPayload(payloadFields); return(payload); } }
internal override void WritePayload(float intervalSec) { lock (MyLock) { Flush(); CounterPayload payload = new CounterPayload(); payload.Count = _count; payload.IntervalSec = intervalSec; if (0 < _count) { payload.Mean = _sum / _count; payload.StandardDeviation = Math.Sqrt(_sumSquared / _count - _sum * _sum / _count / _count); } else { payload.Mean = 0; payload.StandardDeviation = 0; } payload.Min = _min; payload.Max = _max; payload.Metadata = GetMetadataString(); payload.DisplayName = DisplayName; payload.Name = Name; ResetStatistics(); EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new CounterPayloadType(payload)); } }
public IDisposable Attach(EventPipeEventSource source, ReplicaInfo replicaInfo) { var store = replicaInfo.Metrics; source.Dynamic.All += traceEvent => { try { // Metrics if (traceEvent.EventName.Equals("EventCounters")) { var value = (IDictionary <string, object>)traceEvent.PayloadValue(0); var eventPayload = (IDictionary <string, object>)value["Payload"]; var payload = CounterPayload.FromPayload(eventPayload); store[traceEvent.ProviderName + "/" + payload.Name] = payload.Value; } } catch (Exception ex) { _logger.LogError(ex, "Error processing counter for {ProviderName}:{EventName}", traceEvent.ProviderName, traceEvent.EventName); } }; return(new NullDisposable()); }
internal override void WritePayload(float intervalSec, int pollingIntervalMillisec) { lock (this) { double value = 0; try { value = _metricProvider(); } catch (Exception ex) { ReportOutOfBandMessage($"ERROR: Exception during EventCounter {Name} metricProvider callback: " + ex.Message); } CounterPayload payload = new CounterPayload(); payload.Name = Name; payload.DisplayName = DisplayName ?? ""; payload.Count = 1; // NOTE: These dumb-looking statistics is intentional payload.IntervalSec = intervalSec; payload.Series = $"Interval={pollingIntervalMillisec}"; // TODO: This may need to change when we support multi-session payload.CounterType = "Mean"; payload.Mean = value; payload.Max = value; payload.Min = value; payload.Metadata = GetMetadataString(); payload.StandardDeviation = 0; payload.DisplayUnits = DisplayUnits ?? ""; _lastVal = value; EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new PollingPayloadType(payload)); } }
private void ProcessEvents(TraceEvent eventData) { if (eventData.EventName.Equals("EventCounters")) { try { IDictionary <string, object> payloadVal = (IDictionary <string, object>)eventData.PayloadValue(0); IDictionary <string, object> payloadFields = (IDictionary <string, object>)payloadVal["Payload"]; var payload = CounterPayload.GetFromKvPairs(payloadFields); OnNewCounterData(payload); } catch (Exception ex) { _logger.Error(ex.ToString()); } } else { try { OnNewEventData(eventData); } catch (Exception ex) { _logger.Error(ex.ToString()); } } }
internal override void WritePayload(float intervalSec, int pollingIntervalMillisec) { lock (this) { Flush(); CounterPayload payload = new CounterPayload(); payload.Count = _count; payload.IntervalSec = intervalSec; if (0 < _count) { payload.Mean = _sum / _count; payload.StandardDeviation = Math.Sqrt(_sumSquared / _count - _sum * _sum / _count / _count); } else { payload.Mean = 0; payload.StandardDeviation = 0; } payload.Min = _min; payload.Max = _max; payload.Series = $"Interval={pollingIntervalMillisec}"; // TODO: This may need to change when we support multi-session payload.CounterType = "Mean"; payload.Metadata = GetMetadataString(); payload.DisplayName = DisplayName ?? ""; payload.DisplayUnits = DisplayUnits ?? ""; payload.Name = Name; ResetStatistics(); EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new CounterPayloadType(payload)); } }
internal override void WritePayload(float intervalSec) { lock (MyLock) { double value = 0; try { value = _metricProvider(); } catch (Exception ex) { ReportOutOfBandMessage($"ERROR: Exception during EventCounter {Name} metricProvider callback: " + ex.Message); } CounterPayload payload = new CounterPayload(); payload.Name = Name; payload.DisplayName = DisplayName ?? ""; payload.Count = 1; // NOTE: These dumb-looking statistics is intentional payload.IntervalSec = intervalSec; payload.Mean = value; payload.Max = value; payload.Min = value; payload.Metadata = GetMetadataString(); payload.StandardDeviation = 0; _lastVal = value; EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new PollingPayloadType(payload)); } }
private bool TryMapCounterPayload(BaseParseResult result, CounterPayload payload, out CounterData counterData) { counterData = null; if (payload.Value == ulong.MaxValue) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. The payload value equals maximum ulong", _context.Mini.SerialNumber); return(false); } if ((payload is R21CounterPayload) && !(payload as R21CounterPayload).IsValid) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. The payload is of type R21CounterPayload but not valid for counter '{InternalNr}'", _context.Mini.SerialNumber, payload.InternalNr); return(false); } if (ClientNotConnected()) { // No connection with client, payload is last measured value and not the real value. First real value will be spread out over missing values _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. There is no connection with client, data not saved", _context.Mini.SerialNumber); return(false); } if (!MapCounterId(payload, _context.Mini)) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. Mapping the counter {InternalNr} failed", _context.Mini.SerialNumber, payload.InternalNr); return(false); } // store the data in the payload into the corresponding counter var counter = FindCounter(payload); if (counter == null) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. Received value for unknown counter: {InternalNr}", _context.Mini.SerialNumber, payload.InternalNr); return(false); } if (!(result is MiniParseResult parseResult)) { _logger.LogWarning("TryMapCounterPayload failed for '{SerialNumber}'. The _result is not of type MiniParseResult", _context.Mini.SerialNumber); return(false); } // Counter is valid, set the LastDataReceived _context.Mini.QboxStatus.LastDataReceived = _dateTimeService.UtcNow; // Counter is valid, define a valid CounterData object counterData = new CounterData { SerialNumber = _context.Mini.SerialNumber, MeasureTime = parseResult.Model.MeasurementTime.ToUniversalTime(), // .ToAmsterdam(), // Change to Dutch Timezone CounterId = payload.InternalNr, PulseValue = Convert.ToInt32(payload.Value) }; return(true); }
private void OnNewCounterData(CounterPayload data) { var subscribers = NewCounterData; if (subscribers != null) { subscribers(this, data); } }
/// <summary> /// Process the payload /// </summary> /// <param name="ioPayload">Payload, InternalNr will be mapped to the actual internal number used to store the data.</param> public void Accept(CounterPayload ioPayload) { try { if (ioPayload.Value == ulong.MaxValue) { return; } if ((ioPayload is R21CounterPayload) && !(ioPayload as R21CounterPayload).IsValid) { Log.Debug("Invalid value for counter {0} / {1}", ioPayload.InternalNr, _context.Mini.SerialNumber); return; } if (ClientNotConnected()) { // No connection with client, payload is last measured value and not the real value. First real value will be spread out over missing values Log.Debug("No connection with client, data not saved"); return; } if (!MapCounterId(ioPayload, _context.Mini)) { return; } // store the data in the payload into the corresponding counter var counter = FindCounter(ioPayload); if (counter == null) { Log.Warn(string.Format("Recieved value for unknown counter: {0} / {1}", ioPayload.InternalNr, _context.Mini.SerialNumber)); return; //todo: investigate if exception would be better } var parseResult = _result as MiniParseResult; if (parseResult == null) { return; } counter.SetValue(parseResult.Model.MeasurementTime, ioPayload.Value, _context.Mini.QboxStatus); _context.Mini.QboxStatus.LastDataReceived = DateTime.UtcNow; } catch (Exception e) { Log.Error(e, e.Message); } }
public void CounterPayloadReceived(CounterPayload payload, bool _) { lock (_lock) { if (builder.Length > flushLength) { File.AppendAllText(_output, builder.ToString()); builder.Clear(); } builder .Append("{ \"timestamp\": \"").Append(DateTime.Now.ToString("u")).Append("\", ") .Append(" \"provider\": \"").Append(JsonEscape(payload.ProviderName)).Append("\", ") .Append(" \"name\": \"").Append(JsonEscape(payload.DisplayName)).Append("\", ") .Append(" \"tags\": \"").Append(JsonEscape(payload.Tags)).Append("\", ") .Append(" \"counterType\": \"").Append(JsonEscape(payload.CounterType)).Append("\", ") .Append(" \"value\": ").Append(payload.Value.ToString(CultureInfo.InvariantCulture)).Append(" },"); } }
private CounterPoco FindCounter(CounterPayload payload) { if (payload is CounterWithSourcePayload) { var pl = payload as CounterWithSourcePayload; var counter = _context.Mini.Counters.SingleOrDefault(s => s.CounterId == payload.InternalNr && s.Secondary != pl.PrimaryMeter && s.GroupId == pl.Source); if (counter != null) { return(counter); } // No specific counter found, try to find counter with only internalNr } // Down grading firmware could lead to find multiple counters. InternalId is not unique from firmware revision 39 return(_context.Mini.Counters.SingleOrDefault(s => s.CounterId == payload.InternalNr)); }
/// <summary> /// Change the InternalId (CounterId) of the payload to the value that will be used to store and retrieve the measurements. /// </summary> /// <returns>false if the mapping could not be done (for example when the secondary meter type of a duo is not an S0 meter).</returns> private bool MapCounterId(CounterPayload ioPayload, Mini inMini) { Dictionary <int, int> mapping = null; var counterWithSourcePayload = ioPayload as CounterWithSourcePayload; if (counterWithSourcePayload == null || counterWithSourcePayload.PrimaryMeter) { // Firmware A34, Smart Meter and soladin measured on client reports counters instead of specific message: if (inMini.Clients.Any(d => d.MeterType == DeviceMeterType.Smart_Meter_E || d.MeterType == DeviceMeterType.Smart_Meter_EG)) { mapping = SmartMeterIdMapping; } else if (inMini.Clients.Any(d => d.MeterType == DeviceMeterType.Soladin_600)) { mapping = SoladinIdMapping; } } if (counterWithSourcePayload != null && !counterWithSourcePayload.PrimaryMeter) { // At the moment we only support S0 as secondary meter type, so log an error when we find a different meter type. var clientsWithUnsupportedSecondaryMeterTypes = inMini.Clients.Where(c => c.SecondaryMeterType != DeviceMeterType.None && c.SecondaryMeterType != DeviceMeterType.SO_Pulse).ToList(); if (clientsWithUnsupportedSecondaryMeterTypes.Count > 0) { _logger.LogError("Qbox {SerialNumber} has counter for unsupported secondary meter type {SecondaryMeterType}", inMini.SerialNumber, clientsWithUnsupportedSecondaryMeterTypes[0].SecondaryMeterType); return(false); } // S0 as secondary meter type does not need to be mapped. } if (mapping != null && mapping.ContainsKey(ioPayload.InternalNr)) { ioPayload.InternalNr = mapping[ioPayload.InternalNr]; } return(true); }
public void CounterPayloadReceived(CounterPayload payload, bool _) { lock (_lock) { if (builder.Length > flushLength) { File.AppendAllText(_output, builder.ToString()); builder.Clear(); } builder .Append(payload.Timestamp.ToString()).Append(',') .Append(payload.ProviderName).Append(',') .Append(payload.DisplayName); if (!string.IsNullOrEmpty(payload.Tags)) { builder.Append('[').Append(payload.Tags.Replace(',', ';')).Append(']'); } builder.Append(',') .Append(payload.CounterType).Append(',') .Append(payload.Value.ToString(CultureInfo.InvariantCulture)).Append('\n'); } }
public PollingPayloadType(CounterPayload payload) { Payload = payload; }
public void Accept(CounterPayload payload) { throw new NotSupportedException(); }
public void ProcessEvents(string applicationName, string serviceName, int processId, string replicaName, ReplicaStatus replica, CancellationToken cancellationToken) { var hasEventPipe = false; for (int i = 0; i < 10; ++i) { if (DiagnosticsClient.GetPublishedProcesses().Contains(processId)) { hasEventPipe = true; break; } if (cancellationToken.IsCancellationRequested) { return; } Thread.Sleep(500); } if (!hasEventPipe) { _logger.LogInformation("Process id {PID}, does not support event pipe", processId); return; } _logger.LogInformation("Listening for event pipe events for {ServiceName} on process id {PID}", replicaName, processId); // Create the logger factory for this replica using var loggerFactory = LoggerFactory.Create(builder => ConfigureLogging(serviceName, replicaName, builder)); var processor = new SimpleSpanProcessor(CreateSpanExporter(serviceName, replicaName)); var providers = new List <EventPipeProvider>() { // Runtime Metrics new EventPipeProvider( SystemRuntimeEventSourceName, EventLevel.Informational, (long)ClrTraceEventParser.Keywords.None, new Dictionary <string, string>() { { "EventCounterIntervalSec", "1" } } ), new EventPipeProvider( MicrosoftAspNetCoreHostingEventSourceName, EventLevel.Informational, (long)ClrTraceEventParser.Keywords.None, new Dictionary <string, string>() { { "EventCounterIntervalSec", "1" } } ), new EventPipeProvider( GrpcAspNetCoreServer, EventLevel.Informational, (long)ClrTraceEventParser.Keywords.None, new Dictionary <string, string>() { { "EventCounterIntervalSec", "1" } } ), // Application Metrics new EventPipeProvider( applicationName, EventLevel.Informational, (long)ClrTraceEventParser.Keywords.None, new Dictionary <string, string>() { { "EventCounterIntervalSec", "1" } } ), // Logging new EventPipeProvider( MicrosoftExtensionsLoggingProviderName, EventLevel.LogAlways, (long)(LoggingEventSource.Keywords.JsonMessage | LoggingEventSource.Keywords.FormattedMessage) ), // Distributed Tracing // Activity correlation new EventPipeProvider(TplEventSource, keywords: 0x80, eventLevel: EventLevel.LogAlways), // Diagnostic source events new EventPipeProvider(DiagnosticSourceEventSource, keywords: 0x1 | 0x2, eventLevel: EventLevel.Verbose, arguments: new Dictionary <string, string> { { "FilterAndPayloadSpecs", DiagnosticFilterString } }) }; while (!cancellationToken.IsCancellationRequested) { EventPipeSession session = null; var client = new DiagnosticsClient(processId); try { session = client.StartEventPipeSession(providers); } catch (EndOfStreamException) { break; } catch (Exception ex) { if (!cancellationToken.IsCancellationRequested) { _logger.LogDebug(0, ex, "Failed to start the event pipe session"); } // We can't even start the session, wait until the process boots up again to start another metrics thread break; } void StopSession() { try { session.Stop(); } catch (EndOfStreamException) { // If the app we're monitoring exits abruptly, this may throw in which case we just swallow the exception and exit gracefully. } // We may time out if the process ended before we sent StopTracing command. We can just exit in that case. catch (TimeoutException) { } // On Unix platforms, we may actually get a PNSE since the pipe is gone with the process, and Runtime Client Library // does not know how to distinguish a situation where there is no pipe to begin with, or where the process has exited // before dotnet-counters and got rid of a pipe that once existed. // Since we are catching this in StopMonitor() we know that the pipe once existed (otherwise the exception would've // been thrown in StartMonitor directly) catch (PlatformNotSupportedException) { } } using var _ = cancellationToken.Register(() => StopSession()); try { var source = new EventPipeEventSource(session.EventStream); var activities = new Dictionary <string, ActivityItem>(); source.Dynamic.All += traceEvent => { try { // Uncomment to debug the diagnostics source event source //if (traceEvent.EventName == "Message") //{ // _logger.LogTrace("[" + replicaName + "]:" + traceEvent.PayloadValue(0)); //} //// Distributed tracing // else if (traceEvent.EventName == "Activity1Start/Start") { var listenerEventName = (string)traceEvent.PayloadByName("EventName"); if (traceEvent.PayloadByName("Arguments") is IDictionary <string, object>[] arguments) { string activityId = null; string parentId = null; string operationName = null; string httpMethod = null; string path = null; string spanId = null; string parentSpanId = null; string traceId = null; DateTime startTime = default; ActivityIdFormat idFormat = default; foreach (var arg in arguments) { var key = (string)arg["Key"]; var value = (string)arg["Value"]; if (key == "ActivityId") { activityId = value; } else if (key == "ActivityParentId") { parentId = value; } else if (key == "ActivityOperationName") { operationName = value; } else if (key == "ActivitySpanId") { spanId = value; } else if (key == "ActivityTraceId") { traceId = value; } else if (key == "ActivityParentSpanId") { parentSpanId = value; } else if (key == "Method") { httpMethod = value; } else if (key == "Path") { path = value; } else if (key == "ActivityStartTime") { startTime = new DateTime(long.Parse(value), DateTimeKind.Utc); } else if (key == "ActivityIdFormat") { idFormat = Enum.Parse <ActivityIdFormat>(value); } } if (string.IsNullOrEmpty(activityId)) { // Not a 3.1 application (we can detect this earlier) return; } if (idFormat == ActivityIdFormat.Hierarchical) { // We need W3C to make it work return; } // This is what open telemetry currently does // https://github.com/open-telemetry/opentelemetry-dotnet/blob/4ba732af062ddc2759c02aebbc91335aaa3f7173/src/OpenTelemetry.Collector.AspNetCore/Implementation/HttpInListener.cs#L65-L92 var item = new ActivityItem() { Name = path, SpanId = ActivitySpanId.CreateFromString(spanId), TraceId = ActivityTraceId.CreateFromString(traceId), ParentSpanId = parentSpanId == "0000000000000000" ? default : ActivitySpanId.CreateFromString(parentSpanId), StartTime = startTime, }; item.Attributes[SpanAttributeConstants.HttpMethodKey] = httpMethod; item.Attributes[SpanAttributeConstants.HttpPathKey] = path; activities[activityId] = item; } } else if (traceEvent.EventName == "Activity1Stop/Stop") { var listenerEventName = (string)traceEvent.PayloadByName("EventName"); if (traceEvent.PayloadByName("Arguments") is IDictionary <string, object>[] arguments) { string activityId = null; TimeSpan duration = default; int statusCode = 0; foreach (var arg in arguments) { var key = (string)arg["Key"]; var value = (string)arg["Value"]; if (key == "ActivityId") { activityId = value; } else if (key == "StatusCode") { statusCode = int.Parse(value); } else if (key == "ActivityDuration") { duration = new TimeSpan(long.Parse(value)); } } if (string.IsNullOrEmpty(activityId)) { // Not a 3.1 application (we can detect this earlier) return; } if (activities.TryGetValue(activityId, out var item)) { item.Attributes[SpanAttributeConstants.HttpStatusCodeKey] = statusCode; item.EndTime = item.StartTime + duration; var spanData = new SpanData(item.Name, new SpanContext(item.TraceId, item.SpanId, ActivityTraceFlags.Recorded), item.ParentSpanId, SpanKind.Server, item.StartTime, item.Attributes, Enumerable.Empty <Event>(), Enumerable.Empty <Link>(), null, Status.Ok, item.EndTime); processor.OnEnd(spanData); activities.Remove(activityId); } } } else if (traceEvent.EventName == "Activity2Start/Start") { var listenerEventName = (string)traceEvent.PayloadByName("EventName"); _logger.LogDebug("[" + replicaName + "]: " + listenerEventName + " fired"); } else if (traceEvent.EventName == "Activity2Stop/Stop") { var listenerEventName = (string)traceEvent.PayloadByName("EventName"); _logger.LogDebug("[" + replicaName + "]: " + listenerEventName + " fired"); } // Metrics else if (traceEvent.EventName.Equals("EventCounters")) { var payloadVal = (IDictionary <string, object>)traceEvent.PayloadValue(0); var eventPayload = (IDictionary <string, object>)payloadVal["Payload"]; ICounterPayload payload = CounterPayload.FromPayload(eventPayload); replica.Metrics[traceEvent.ProviderName + "/" + payload.Name] = payload.Value; } } catch (Exception ex) { _logger.LogError(ex, "Error processing counter for {ProviderName}:{EventName}", traceEvent.ProviderName, traceEvent.EventName); } }; // Logging string lastFormattedMessage = ""; var logActivities = new Dictionary <Guid, LogActivityItem>(); var stack = new Stack <Guid>(); source.Dynamic.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProviderName, "ActivityJsonStart/Start", (traceEvent) => { var factoryId = (int)traceEvent.PayloadByName("FactoryID"); var categoryName = (string)traceEvent.PayloadByName("LoggerName"); var argsJson = (string)traceEvent.PayloadByName("ArgumentsJson"); // TODO: Store this information by logger factory id var item = new LogActivityItem { ActivityID = traceEvent.ActivityID, ScopedObject = new LogObject(JsonDocument.Parse(argsJson).RootElement), }; if (stack.TryPeek(out var parentId) && logActivities.TryGetValue(parentId, out var parentItem)) { item.Parent = parentItem; } stack.Push(traceEvent.ActivityID); logActivities[traceEvent.ActivityID] = item; }); source.Dynamic.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProviderName, "ActivityJsonStop/Stop", (traceEvent) => { var factoryId = (int)traceEvent.PayloadByName("FactoryID"); var categoryName = (string)traceEvent.PayloadByName("LoggerName"); stack.Pop(); logActivities.Remove(traceEvent.ActivityID); }); source.Dynamic.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProviderName, "MessageJson", (traceEvent) => { // Level, FactoryID, LoggerName, EventID, EventName, ExceptionJson, ArgumentsJson var logLevel = (LogLevel)traceEvent.PayloadByName("Level"); var factoryId = (int)traceEvent.PayloadByName("FactoryID"); var categoryName = (string)traceEvent.PayloadByName("LoggerName"); var eventId = (int)traceEvent.PayloadByName("EventId"); var eventName = (string)traceEvent.PayloadByName("EventName"); var exceptionJson = (string)traceEvent.PayloadByName("ExceptionJson"); var argsJson = (string)traceEvent.PayloadByName("ArgumentsJson"); // There's a bug that causes some of the columns to get mixed up if (eventName.StartsWith("{")) { argsJson = exceptionJson; exceptionJson = eventName; eventName = null; } if (string.IsNullOrEmpty(argsJson)) { return; } Exception exception = null; var logger = loggerFactory.CreateLogger(categoryName); var scopes = new List <IDisposable>(); if (logActivities.TryGetValue(traceEvent.ActivityID, out var logActivityItem)) { // REVIEW: Does order matter here? We're combining everything anyways. while (logActivityItem != null) { scopes.Add(logger.BeginScope(logActivityItem.ScopedObject)); logActivityItem = logActivityItem.Parent; } } try { if (exceptionJson != "{}") { var exceptionMessage = JsonSerializer.Deserialize <JsonElement>(exceptionJson); exception = new LoggerException(exceptionMessage); } var message = JsonSerializer.Deserialize <JsonElement>(argsJson); if (message.TryGetProperty("{OriginalFormat}", out var formatElement)) { var formatString = formatElement.GetString(); var formatter = new LogValuesFormatter(formatString); object[] args = new object[formatter.ValueNames.Count]; for (int i = 0; i < args.Length; i++) { args[i] = message.GetProperty(formatter.ValueNames[i]).GetString(); } logger.Log(logLevel, new EventId(eventId, eventName), exception, formatString, args); } else { var obj = new LogObject(message, lastFormattedMessage); logger.Log(logLevel, new EventId(eventId, eventName), obj, exception, LogObject.Callback); } } catch (Exception ex) { _logger.LogDebug(ex, "Error processing log entry for {ServiceName}", replicaName); } finally { scopes.ForEach(d => d.Dispose()); } }); source.Dynamic.AddCallbackForProviderEvent(MicrosoftExtensionsLoggingProviderName, "FormattedMessage", (traceEvent) => { // Level, FactoryID, LoggerName, EventID, EventName, FormattedMessage var logLevel = (LogLevel)traceEvent.PayloadByName("Level"); var factoryId = (int)traceEvent.PayloadByName("FactoryID"); var categoryName = (string)traceEvent.PayloadByName("LoggerName"); var eventId = (int)traceEvent.PayloadByName("EventId"); var eventName = (string)traceEvent.PayloadByName("EventName"); var formattedMessage = (string)traceEvent.PayloadByName("FormattedMessage"); if (string.IsNullOrEmpty(formattedMessage)) { formattedMessage = eventName; eventName = ""; } lastFormattedMessage = formattedMessage; }); source.Process(); }
/// <summary> /// Обработчик собьытия, выводит данные на конссоль /// </summary> /// <param name="sender">Кем сгенерировано событие</param> /// <param name="data">Данные счётчика</param> public void OnNewCounterData(object sender, CounterPayload data) { Console.WriteLine($"{data.DisplayName}: {data.Value} {data.DisplayUnits}"); }
public CounterPayloadType(CounterPayload payload) { Payload = payload; }