-
Notifications
You must be signed in to change notification settings - Fork 49
Extensible payload handler #111
Changes from 10 commits
4fc5028
36e2c40
b405656
c5c38fb
02d1ed1
bf994b1
2110cdd
14af283
26c3bd3
d1f7649
1cf366d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ namespace Microsoft.ApplicationInsights.EventSourceListener.Implementation | |
using Microsoft.ApplicationInsights.DataContracts; | ||
using Microsoft.ApplicationInsights.TraceEvent.Shared.Utilities; | ||
|
||
internal static class EventDataExtensions | ||
public static class EventDataExtensions | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why making it public? Do you want to re-use certain methods from here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the PopulateStandardProperties method is very useful for outside creators who want to write their own payload readers but make still use of the rest of the properties. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps the callback may be called after telemetry got initialized then? My worry is that if you use this method you probably relying on the implementation too much. It feel you want a callback to "add" information, not to replace. Is it correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps I am not the standard consumer here but it works exactly as I would expect it to work and it handles the job of that I would just end up implementing myself if it wasn't there. For my scenario, I call:
This gives me a TraceTelemetry with all of the "boilerplate" fields populated from the EventWrittenEventArgs and then I add my own payload onto that. Of course you need not call any of these methods if you don't want to, but I find them convenient. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thank you! I appreciate you taking time to submit this PR and have this conversation. It definitely helps to form the opinion on how analogous generic API should look like. |
||
{ | ||
private static Lazy<Random> random = new Lazy<Random>(); | ||
|
||
|
@@ -30,30 +30,35 @@ internal static class EventDataExtensions | |
}; | ||
|
||
/// <summary> | ||
/// Creates a TraceTelemetry out of an EventSource event and tracks it using the supplied client. | ||
/// Creates a TraceTelemetry out of an EventSource event. | ||
/// </summary> | ||
/// <param name="eventSourceEvent">The source for the telemetry data.</param> | ||
/// <param name="client">Client to track the data with.</param> | ||
public static void Track(this EventWrittenEventArgs eventSourceEvent, TelemetryClient client) | ||
public static TraceTelemetry CreateTraceTelementry(this EventWrittenEventArgs eventSourceEvent) | ||
{ | ||
Debug.Assert(client != null, "Should always receive a valid client"); | ||
|
||
string formattedMessage = null; | ||
if (eventSourceEvent.Message != null) | ||
{ | ||
try | ||
{ | ||
// If the event has a badly formatted manifest, message formatting might fail | ||
formattedMessage = string.Format(CultureInfo.InvariantCulture, eventSourceEvent.Message, eventSourceEvent.Payload.ToArray()); | ||
formattedMessage = string.Format(CultureInfo.InvariantCulture, eventSourceEvent.Message, | ||
eventSourceEvent.Payload.ToArray()); | ||
} | ||
catch | ||
{ | ||
} | ||
} | ||
TraceTelemetry telemetry = new TraceTelemetry(formattedMessage, eventLevelToSeverityLevel[(int)eventSourceEvent.Level]); | ||
|
||
eventSourceEvent.ExtractPayloadData(telemetry); | ||
return new TraceTelemetry(formattedMessage, | ||
eventLevelToSeverityLevel[(int) eventSourceEvent.Level]); | ||
} | ||
|
||
/// <summary> | ||
/// Populates a standard set of properties on the <see cref="TraceTelemetry"/> with values from the a given EventSource event. | ||
/// </summary> | ||
/// <param name="telemetry">Telemetry item to populate with properties.</param> | ||
/// <param name="eventSourceEvent">Event to extract values from.</param> | ||
public static TraceTelemetry PopulateStandardProperties(this TraceTelemetry telemetry, EventWrittenEventArgs eventSourceEvent) | ||
{ | ||
telemetry.AddProperty(nameof(EventWrittenEventArgs.EventId), eventSourceEvent.EventId.ToString(CultureInfo.InvariantCulture)); | ||
telemetry.AddProperty(nameof(EventWrittenEventArgs.EventName), eventSourceEvent.EventName); | ||
if (eventSourceEvent.ActivityId != default(Guid)) | ||
|
@@ -76,21 +81,37 @@ public static void Track(this EventWrittenEventArgs eventSourceEvent, TelemetryC | |
telemetry.AddProperty(nameof(EventWrittenEventArgs.Task), GetHexRepresentation((int)eventSourceEvent.Task)); | ||
} | ||
|
||
client.Track(telemetry); | ||
return telemetry; | ||
} | ||
|
||
/// <summary> | ||
/// Extracts payload properties from a given EventSource event and populates the telemetry properties with values found. | ||
/// Creates a TraceTelemetry out of an EventSource event and tracks it using the supplied client. | ||
/// </summary> | ||
/// <param name="eventSourceEvent">The source for the telemetry data.</param> | ||
/// <param name="client">Client to track the data with.</param> | ||
internal static void Track(this EventWrittenEventArgs eventSourceEvent, TelemetryClient client) | ||
{ | ||
Debug.Assert(client != null, "Should always receive a valid client"); | ||
|
||
var telemetry = eventSourceEvent.CreateTraceTelementry() | ||
.PopulatePayloadProperties(eventSourceEvent) | ||
.PopulateStandardProperties(eventSourceEvent); | ||
|
||
client.Track(telemetry); | ||
} | ||
|
||
/// <summary> | ||
/// Populates properties on the <see cref="TraceTelemetry"/> with values from the Payload of a given EventSource event. | ||
/// </summary> | ||
/// <param name="eventSourceEvent">Event to extract values from.</param> | ||
/// <param name="telemetry">Telemetry item to populate with properties.</param> | ||
private static void ExtractPayloadData(this EventWrittenEventArgs eventSourceEvent, TraceTelemetry telemetry) | ||
/// <param name="eventSourceEvent">Event to extract values from.</param> | ||
public static TraceTelemetry PopulatePayloadProperties(this TraceTelemetry telemetry, EventWrittenEventArgs eventSourceEvent) | ||
{ | ||
Debug.Assert(telemetry != null, "Should have received a valid TraceTelemetry object"); | ||
|
||
if (eventSourceEvent.Payload == null || eventSourceEvent.PayloadNames == null) | ||
{ | ||
return; | ||
return telemetry; | ||
} | ||
|
||
IDictionary<string, string> payloadData = telemetry.Properties; | ||
|
@@ -105,6 +126,8 @@ private static void ExtractPayloadData(this EventWrittenEventArgs eventSourceEve | |
payloadData.Add(payloadNamesEnunmerator.Current, payloadEnumerator.Current.ToString()); | ||
} | ||
} | ||
|
||
return telemetry; | ||
} | ||
|
||
/// <summary> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put try catch around it as it is an external code you are calling