private void WriteEvent(string eventName, EventLevel level, Keywords keywords, EventMetadata metadata, EventOpcode opcode) { string jsonPayload = metadata != null?JsonConvert.SerializeObject(metadata) : null; if (this.isDisposed) { throw new ObjectDisposedException(nameof(JsonTracer)); } var message = new TraceEventMessage { EventName = eventName, ActivityId = this.activityId, ParentActivityId = this.parentActivityId, Level = level, Keywords = keywords, Opcode = opcode, Payload = jsonPayload }; // Iterating over the bag is thread-safe as the enumerator returned here // is of a snapshot of the bag. foreach (EventListener listener in this.listeners) { listener.RecordMessage(message); } }
private void LogMessageToNonFailedListeners(TraceEventMessage message) { foreach (EventListener listener in this.listeners.Except(this.failedListeners.Keys)) { // To prevent infinitely recursive failures, we won't try and log that we failed to log that a listener failed :) listener.TryRecordMessage(message, out _); } }
public void AddEventListener(EventListener listener) { this.listeners.Add(listener); // Tell the new listener about others who have previously failed foreach (KeyValuePair <EventListener, string> kvp in this.failedListeners) { TraceEventMessage failureMessage = CreateListenerFailureMessage(kvp.Key, kvp.Value); listener.TryRecordMessage(failureMessage, out _); } }
protected override void RecordMessageInternal(TraceEventMessage message) { string pipeMessage = this.CreatePipeMessage(message); bool dropped = !this.pipeWriter.TryEnqueue(pipeMessage); if (dropped) { this.RaiseListenerFailure("Pipe delivery queue is full. Message was dropped."); } }
private void MarkAndLogListenerFailure(EventListener failedListener, string errorMessage) { if (!this.failedListeners.TryAdd(failedListener, errorMessage)) { // We've already logged that this listener has failed so there is no need to do it again return; } TraceEventMessage message = CreateListenerFailureMessage(failedListener, errorMessage); this.LogMessageToNonFailedListeners(message); }
public void RecordMessage(TraceEventMessage message) { if (this.IsEnabled(message.Level, message.Keywords)) { try { this.RecordMessageInternal(message); } catch (Exception ex) { this.RaiseListenerFailure(ex.ToString()); } } }
public void AddEventListener(EventListener listener) { if (this.isDisposed) { throw new ObjectDisposedException(nameof(JsonTracer)); } this.listeners.Add(listener); // Tell the new listener about others who have previously failed foreach (KeyValuePair <EventListener, string> kvp in this.failedListeners) { TraceEventMessage failureMessage = CreateListenerFailureMessage(kvp.Key, kvp.Value); listener.RecordMessage(failureMessage); } }
private void MarkAndLogListenerRecovery(EventListener recoveredListener) { // Check ContainsKey first (rather than always calling TryRemove) because ContainsKey // is lock-free and recoveredListener should rarely be in failedListeners if (!this.failedListeners.ContainsKey(recoveredListener)) { // This listener has not failed since the last time it was called, so no need to log recovery return; } if (this.failedListeners.TryRemove(recoveredListener, out _)) { TraceEventMessage message = CreateListenerRecoveryMessage(recoveredListener); this.LogMessageToNonFailedListeners(message); } }
protected override void RecordMessageInternal(TraceEventMessage message) { if (string.IsNullOrEmpty(message.Payload)) { return; } ConsoleOutputPayload payload = JsonConvert.DeserializeObject <ConsoleOutputPayload>(message.Payload); if (string.IsNullOrEmpty(payload.ErrorMessage)) { return; } // It's necessary to do a lock here because this can be called in a multi-threaded // environment and we want to make sure that ForegroundColor is restored correctly. lock (consoleLock) { ConsoleColor prevColor = Console.ForegroundColor; string prefix; switch (message.Level) { case EventLevel.Critical: case EventLevel.Error: case EventLevel.LogAlways: prefix = "Error"; Console.ForegroundColor = ConsoleColor.Red; break; case EventLevel.Warning: prefix = "Warning"; Console.ForegroundColor = ConsoleColor.Yellow; break; default: prefix = "Info"; break; } // The leading \r interacts with the spinner, which always leaves the // cursor at the end of the line, rather than the start. Console.WriteLine($"\r{prefix}: {payload.ErrorMessage}"); Console.ForegroundColor = prevColor; } }
private void MarkAndLogListenerRecovery(EventListener recoveredListener) { if (!this.failedListeners.ContainsKey(recoveredListener)) { // This listener has not failed since the last time it was called, so no need to do anything return; } this.failedListeners.Remove(recoveredListener); TraceEventMessage message = CreateListenerRecoveryMessage(recoveredListener); // Only log that the listener has recovered to the other good listeners foreach (EventListener listener in this.listeners.Except(this.failedListeners.Keys)) { listener.TryRecordMessage(message, out _); } }
private void MarkAndLogListenerFailure(EventListener failedListener, string errorMessage) { if (this.failedListeners.ContainsKey(failedListener)) { // We've already logged that this listener has failed so there is no need to do it again return; } this.failedListeners.Add(failedListener, errorMessage); TraceEventMessage message = CreateListenerFailureMessage(failedListener, errorMessage); // Only log the failure to listeners that have not failed themselves foreach (EventListener listener in this.listeners.Except(this.failedListeners.Keys)) { // To prevent infinitely recursive failures, we won't try and log that we failed to log that a listener failed :) listener.TryRecordMessage(message, out _); } }
private void WriteEvent(string eventName, EventLevel level, Keywords keywords, EventMetadata metadata, EventOpcode opcode) { string jsonPayload = metadata != null?JsonConvert.SerializeObject(metadata) : null; if (this.disposed) { Console.WriteLine("Writing to disposed tracer"); Console.WriteLine(jsonPayload); throw new ObjectDisposedException(nameof(JsonTracer)); } var message = new TraceEventMessage { EventName = eventName, ActivityId = this.activityId, ParentActivityId = this.parentActivityId, Level = level, Keywords = keywords, Opcode = opcode, Payload = jsonPayload }; foreach (EventListener listener in this.listeners) { string errorMessage; bool? success = listener.TryRecordMessage(message, out errorMessage); // Try to mark success or failure for this listener only if it was enabled for this message type if (success.HasValue) { if (success == true) { this.MarkAndLogListenerRecovery(listener); } else { this.MarkAndLogListenerFailure(listener, errorMessage); } } } }
public bool?TryRecordMessage(TraceEventMessage message, out string errorMessage) { if (this.IsEnabled(message.Level, message.Keywords)) { try { this.RecordMessageInternal(message); errorMessage = null; return(true); } catch (Exception ex) { errorMessage = ex.ToString(); return(false); } } errorMessage = null; return(null); }
private string SerializeMessage(TraceEventMessage message) { var pipeMessage = new TelemetryMessage { Version = this.vfsVersion, ProviderName = this.providerName, EventName = message.EventName, EventLevel = message.Level, EventOpcode = message.Opcode, Payload = new TelemetryMessage.TelemetryMessagePayload { EnlistmentId = this.enlistmentId, MountId = this.mountId, Json = message.Payload }, // Other TraceEventMessage properties are not used }; return(pipeMessage.ToJson()); }
protected override void RecordMessageInternal(TraceEventMessage message) { string json = this.SerializeMessage(message); this.SendMessage(json); }
protected abstract void RecordMessageInternal(TraceEventMessage message);
protected override void RecordMessageInternal(TraceEventMessage message) { this.writer.WriteLine(this.GetLogString(message.EventName, message.Opcode, message.Payload)); this.writer.Flush(); }