diff --git a/.vsts/linux-build.yml b/.vsts/linux-build.yml
index da01572659..3df2f59681 100644
--- a/.vsts/linux-build.yml
+++ b/.vsts/linux-build.yml
@@ -20,7 +20,7 @@ steps:
inputs:
command: "test"
projects: "Test/**/*netcoreapp20*.csproj"
- arguments: "--configuration Release --filter TestCategory!=WindowsOnly"
+ arguments: "--configuration Release -l trx --filter TestCategory!=WindowsOnly"
- task: DotNetCoreInstaller@0
inputs:
@@ -30,9 +30,12 @@ steps:
inputs:
command: "test"
projects: "Test/**/*netcoreapp11*.csproj"
- arguments: "--configuration Release --filter TestCategory!=WindowsOnly"
+ arguments: "--configuration Release -l trx --filter TestCategory!=WindowsOnly"
- task: PublishTestResults@2
+ inputs:
+ testRunner: "VSTest"
+ testResultsFiles: "**/*.trx"
- task: DotNetCoreCLI@1
inputs:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b52e1095d7..06bea0aa95 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,20 @@
This changelog will be used to generate documentation on [release notes page](http://azure.microsoft.com/documentation/articles/app-insights-release-notes-dotnet/).
+## Version 2.8.0-beta1
+- [Add a new distict properties collection, GlobalProperties, on TelemetryContext, and obsolete the Properties on TelemetryContext.](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/820)
+- [Added support for strongly typed extensibility for Telemetry types using IExtension.](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/871)
+- [New method SerializeData(ISerializationWriter writer) defined in ITelemetry. All existing types implement this method to emit information about it's fields to channels who can serialize this data]
+ (continuation of https://github.com/Microsoft/ApplicationInsights-dotnet/issues/871)
+- [Allow to track PageViewPerformance data type](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/673).
+- Added method `ExceptionDetailsInfoList` on `ExceptionTelemetry` class that gives control to user to update exception
+message and exception type of underlying `System.Exception` object that user wants to send to telemetry. Related discussion is [here](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/498).
+- Added an option of creating ExceptionTelemetry object off of custom exception information rather than a System.Exception object.
+- [Add support for hex values in config](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/551)
+
+## Version 2.7.0
+- Metrics: Renamed TryTrackValue(..) into TrackValue(..).
+- Metrics: Removed some superfluous public constants.
## Version 2.7.0
- Metrics: Renamed TryTrackValue(..) into TrackValue(..).
@@ -10,7 +24,7 @@ This changelog will be used to generate documentation on [release notes page](ht
## Version 2.7.0-beta3
- [Allow to set flags on event](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/844). It will be used in conjunction with the feature that will allow to keep IP addresses.
- [Fix: SerializationException resolving Activity in cross app-domain calls](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/613)
-- [Make HttpClient instance static to avoid re-creating with every transmission. This had caused connection/memory leaks in .net core 2.1] (https://github.com/Microsoft/ApplicationInsights-dotnet/issues/594)
+- [Make HttpClient instance static to avoid re-creating with every transmission. This had caused connection/memory leaks in .net core 2.1](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/594)
Related: (https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/690)
## Version 2.7.0-beta2
@@ -57,7 +71,7 @@ This changelog will be used to generate documentation on [release notes page](ht
- Remove calculation of sampling-score based on Context.User.Id [Issue #625](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/625)
- New sdk-driven "heartbeat" functionality added which sends health status at pre-configured intervals. See [extending heartbeat properties doc for more information](./docs/ExtendingHeartbeatProperties.md)
- Fixes a bug in ServerTelemetryChannel which caused application to crash on non-windows platforms.
- [Details on fix and workaround #654] (https://github.com/Microsoft/ApplicationInsights-dotnet/issues/654)
+ [Details on fix and workaround #654](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/654)
Original issue (https://github.com/Microsoft/ApplicationInsights-aspnetcore/issues/551)
- [Fixed a bug with the `AdaptiveSamplingTelemetryProcessor` that would cause starvation over time. Issue #756 (dotnet-server)](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/756)
- Updated solution to build on Mac!
@@ -101,7 +115,7 @@ This changelog will be used to generate documentation on [release notes page](ht
- [Fixed a bug which caused SDK to stop sending telemetry.](https://github.com/Microsoft/ApplicationInsights-dotnet-server/issues/480)
## Version 2.3.0-beta3
-- [Added overloads of TelemetryClientExtensions.StartOperation.] (https://github.com/Microsoft/ApplicationInsights-dotnet/issues/163)
+- [Added overloads of TelemetryClientExtensions.StartOperation.](https://github.com/Microsoft/ApplicationInsights-dotnet/issues/163)
- Fire new ETW events for Operation Start/Stop.
## Version 2.3.0-beta2
diff --git a/GlobalStaticVersion.props b/GlobalStaticVersion.props
index 29078572dd..348586b4b6 100644
--- a/GlobalStaticVersion.props
+++ b/GlobalStaticVersion.props
@@ -6,10 +6,10 @@
Update for every public release.
-->
2
- 7
- 2
+ 8
+ 0
-
+ beta1
- 2018-05-21
+ 2018-08-01
$([MSBuild]::Divide($([System.DateTime]::Now.Subtract($([System.DateTime]::Parse($(SemanticVersionDate)))).TotalMinutes), 5).ToString('F0'))
diff --git a/Microsoft.ApplicationInsights.sln b/Microsoft.ApplicationInsights.sln
index 7eea38ca81..80e7ce1b31 100644
--- a/Microsoft.ApplicationInsights.sln
+++ b/Microsoft.ApplicationInsights.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26430.16
+VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.ApplicationInsights.Tests", "Microsoft.ApplicationInsights.Tests", "{C2FEEDE5-8CAE-41A4-8932-42D284A86EA7}"
EndProject
diff --git a/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Shipped.txt b/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Shipped.txt
index 916d1e920e..8007a9f1fd 100644
--- a/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Shipped.txt
+++ b/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Shipped.txt
@@ -99,6 +99,14 @@ Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.Platform = 2 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.Unhandled = 0 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.UserCode = 1 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.ExceptionDetailsInfo(int id, int outerId, string typeName, string message, bool hasFullStack, string stack, System.Collections.Generic.IEnumerable parsedStack) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.TypeName.get -> string
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.TypeName.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.Message.get -> string
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.Message.set -> void
+Microsoft.ApplicationInsights.DataContracts.StackFrame
+Microsoft.ApplicationInsights.DataContracts.StackFrame.StackFrame(string assembly, string fileName, int level, int line, string method) -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Context.get -> Microsoft.ApplicationInsights.DataContracts.TelemetryContext
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.DeepClone() -> Microsoft.ApplicationInsights.Channel.ITelemetry
@@ -106,8 +114,10 @@ Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Exception.get ->
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Exception.set -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry() -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry(System.Exception exception) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry(System.Collections.Generic.IEnumerable exceptionDetailsInfoList, Microsoft.ApplicationInsights.DataContracts.SeverityLevel? severityLevel, string problemId, System.Collections.Generic.IDictionary properties, System.Collections.Generic.IDictionary measurements) -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.HandledAt.get -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.HandledAt.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionDetailsInfoList.get -> System.Collections.Generic.IReadOnlyList
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Message.get -> string
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Message.set -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Metrics.get -> System.Collections.Generic.IDictionary
@@ -244,6 +254,7 @@ Microsoft.ApplicationInsights.DataContracts.TelemetryContext.InstrumentationKey.
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Location.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.LocationContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Operation.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.OperationContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Properties.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.TelemetryContext.GlobalProperties.get -> System.Collections.Generic.IDictionary
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Session.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.SessionContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.TelemetryContext() -> void
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.User.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.UserContext
diff --git a/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Unshipped.txt b/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Unshipped.txt
index be2d45c507..35653d4cce 100644
--- a/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Unshipped.txt
+++ b/PublicAPI/Microsoft.ApplicationInsights.dll/net45/PublicAPI.Unshipped.txt
@@ -1,3 +1,32 @@
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Id.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Id.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Context.get -> Microsoft.ApplicationInsights.DataContracts.TelemetryContext
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DeepClone() -> Microsoft.ApplicationInsights.Channel.ITelemetry
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DomProcessing.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DomProcessing.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Duration.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Duration.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Metrics.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Name.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Name.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.NetworkConnect.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.NetworkConnect.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PageViewPerformanceTelemetry() -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PageViewPerformanceTelemetry(string pageName) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PerfTotal.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PerfTotal.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Properties.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.ReceivedResponse.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.ReceivedResponse.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SentRequest.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SentRequest.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Sequence.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Sequence.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Timestamp.get -> System.DateTimeOffset
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Timestamp.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.get -> System.Uri
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.set -> void
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricNamespace.get -> string
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricNamespace.set -> void
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricTelemetry(string metricNamespace, string name, int count, double sum, double min, double max, double standardDeviation) -> void
@@ -264,4 +293,63 @@ static readonly Microsoft.ApplicationInsights.MetricConfigurations.Common -> Mic
virtual Microsoft.ApplicationInsights.Metrics.MetricConfiguration.Equals(Microsoft.ApplicationInsights.Metrics.MetricConfiguration other) -> bool
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Flags.get -> long
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Flags.set -> void
-const Microsoft.ApplicationInsights.DataContracts.TelemetryContext.FlagDropIdentifiers = 2097152 -> long
\ No newline at end of file
+const Microsoft.ApplicationInsights.DataContracts.TelemetryContext.FlagDropIdentifiers = 2097152 -> long
+Microsoft.ApplicationInsights.Channel.ITelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Channel.ITelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.Channel.ITelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.Extension.set -> void
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Extension.set -> void
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.Extension.set -> void
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter
+Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter.Serialize(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Extensibility.IExtension.DeepClone() -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, string value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, double? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, int? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, bool? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.TimeSpan? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.DateTimeOffset? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IList items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IList items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IDictionary items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IDictionary items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteStartObject(string name) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteStartObject() -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteEndObject() -> void
\ No newline at end of file
diff --git a/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Shipped.txt b/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Shipped.txt
index 916d1e920e..8007a9f1fd 100644
--- a/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Shipped.txt
+++ b/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Shipped.txt
@@ -99,6 +99,14 @@ Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.Platform = 2 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.Unhandled = 0 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.UserCode = 1 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.ExceptionDetailsInfo(int id, int outerId, string typeName, string message, bool hasFullStack, string stack, System.Collections.Generic.IEnumerable parsedStack) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.TypeName.get -> string
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.TypeName.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.Message.get -> string
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.Message.set -> void
+Microsoft.ApplicationInsights.DataContracts.StackFrame
+Microsoft.ApplicationInsights.DataContracts.StackFrame.StackFrame(string assembly, string fileName, int level, int line, string method) -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Context.get -> Microsoft.ApplicationInsights.DataContracts.TelemetryContext
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.DeepClone() -> Microsoft.ApplicationInsights.Channel.ITelemetry
@@ -106,8 +114,10 @@ Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Exception.get ->
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Exception.set -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry() -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry(System.Exception exception) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry(System.Collections.Generic.IEnumerable exceptionDetailsInfoList, Microsoft.ApplicationInsights.DataContracts.SeverityLevel? severityLevel, string problemId, System.Collections.Generic.IDictionary properties, System.Collections.Generic.IDictionary measurements) -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.HandledAt.get -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.HandledAt.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionDetailsInfoList.get -> System.Collections.Generic.IReadOnlyList
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Message.get -> string
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Message.set -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Metrics.get -> System.Collections.Generic.IDictionary
@@ -244,6 +254,7 @@ Microsoft.ApplicationInsights.DataContracts.TelemetryContext.InstrumentationKey.
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Location.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.LocationContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Operation.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.OperationContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Properties.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.TelemetryContext.GlobalProperties.get -> System.Collections.Generic.IDictionary
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Session.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.SessionContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.TelemetryContext() -> void
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.User.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.UserContext
diff --git a/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt b/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt
index be2d45c507..35653d4cce 100644
--- a/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt
+++ b/PublicAPI/Microsoft.ApplicationInsights.dll/net46/PublicAPI.Unshipped.txt
@@ -1,3 +1,32 @@
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Id.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Id.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Context.get -> Microsoft.ApplicationInsights.DataContracts.TelemetryContext
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DeepClone() -> Microsoft.ApplicationInsights.Channel.ITelemetry
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DomProcessing.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DomProcessing.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Duration.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Duration.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Metrics.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Name.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Name.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.NetworkConnect.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.NetworkConnect.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PageViewPerformanceTelemetry() -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PageViewPerformanceTelemetry(string pageName) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PerfTotal.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PerfTotal.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Properties.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.ReceivedResponse.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.ReceivedResponse.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SentRequest.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SentRequest.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Sequence.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Sequence.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Timestamp.get -> System.DateTimeOffset
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Timestamp.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.get -> System.Uri
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.set -> void
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricNamespace.get -> string
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricNamespace.set -> void
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricTelemetry(string metricNamespace, string name, int count, double sum, double min, double max, double standardDeviation) -> void
@@ -264,4 +293,63 @@ static readonly Microsoft.ApplicationInsights.MetricConfigurations.Common -> Mic
virtual Microsoft.ApplicationInsights.Metrics.MetricConfiguration.Equals(Microsoft.ApplicationInsights.Metrics.MetricConfiguration other) -> bool
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Flags.get -> long
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Flags.set -> void
-const Microsoft.ApplicationInsights.DataContracts.TelemetryContext.FlagDropIdentifiers = 2097152 -> long
\ No newline at end of file
+const Microsoft.ApplicationInsights.DataContracts.TelemetryContext.FlagDropIdentifiers = 2097152 -> long
+Microsoft.ApplicationInsights.Channel.ITelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Channel.ITelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.Channel.ITelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.Extension.set -> void
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Extension.set -> void
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.Extension.set -> void
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter
+Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter.Serialize(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Extensibility.IExtension.DeepClone() -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, string value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, double? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, int? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, bool? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.TimeSpan? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.DateTimeOffset? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IList items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IList items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IDictionary items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IDictionary items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteStartObject(string name) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteStartObject() -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteEndObject() -> void
\ No newline at end of file
diff --git a/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Shipped.txt b/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Shipped.txt
index 0994669abc..8f5b72affe 100644
--- a/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Shipped.txt
+++ b/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Shipped.txt
@@ -99,6 +99,14 @@ Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.Platform = 2 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.Unhandled = 0 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt.UserCode = 1 -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.ExceptionDetailsInfo(int id, int outerId, string typeName, string message, bool hasFullStack, string stack, System.Collections.Generic.IEnumerable parsedStack) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.TypeName.get -> string
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.TypeName.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.Message.get -> string
+Microsoft.ApplicationInsights.DataContracts.ExceptionDetailsInfo.Message.set -> void
+Microsoft.ApplicationInsights.DataContracts.StackFrame
+Microsoft.ApplicationInsights.DataContracts.StackFrame.StackFrame(string assembly, string fileName, int level, int line, string method) -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Context.get -> Microsoft.ApplicationInsights.DataContracts.TelemetryContext
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.DeepClone() -> Microsoft.ApplicationInsights.Channel.ITelemetry
@@ -106,8 +114,10 @@ Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Exception.get ->
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Exception.set -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry() -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry(System.Exception exception) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionTelemetry(System.Collections.Generic.IEnumerable exceptionDetailsInfoList, Microsoft.ApplicationInsights.DataContracts.SeverityLevel? severityLevel, string problemId, System.Collections.Generic.IDictionary properties, System.Collections.Generic.IDictionary measurements) -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.HandledAt.get -> Microsoft.ApplicationInsights.DataContracts.ExceptionHandledAt
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.HandledAt.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.ExceptionDetailsInfoList.get -> System.Collections.Generic.IReadOnlyList
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Message.get -> string
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Message.set -> void
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Metrics.get -> System.Collections.Generic.IDictionary
@@ -243,6 +253,7 @@ Microsoft.ApplicationInsights.DataContracts.TelemetryContext.InstrumentationKey.
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Location.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.LocationContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Operation.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.OperationContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Properties.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.TelemetryContext.GlobalProperties.get -> System.Collections.Generic.IDictionary
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Session.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.SessionContext
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.TelemetryContext() -> void
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.User.get -> Microsoft.ApplicationInsights.Extensibility.Implementation.UserContext
diff --git a/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Unshipped.txt b/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Unshipped.txt
index 031af31ff3..19c24ee0d5 100644
--- a/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Unshipped.txt
+++ b/PublicAPI/Microsoft.ApplicationInsights.dll/netstandard1.3/PublicAPI.Unshipped.txt
@@ -1,3 +1,32 @@
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Id.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Id.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Context.get -> Microsoft.ApplicationInsights.DataContracts.TelemetryContext
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DeepClone() -> Microsoft.ApplicationInsights.Channel.ITelemetry
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DomProcessing.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.DomProcessing.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Duration.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Duration.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Metrics.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Name.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Name.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.NetworkConnect.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.NetworkConnect.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PageViewPerformanceTelemetry() -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PageViewPerformanceTelemetry(string pageName) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PerfTotal.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.PerfTotal.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Properties.get -> System.Collections.Generic.IDictionary
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.ReceivedResponse.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.ReceivedResponse.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SentRequest.get -> System.TimeSpan
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SentRequest.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Sequence.get -> string
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Sequence.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Timestamp.get -> System.DateTimeOffset
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Timestamp.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.get -> System.Uri
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Url.set -> void
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricNamespace.get -> string
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricNamespace.set -> void
Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.MetricTelemetry(string metricNamespace, string name, int count, double sum, double min, double max, double standardDeviation) -> void
@@ -265,4 +294,63 @@ virtual Microsoft.ApplicationInsights.Metrics.MetricConfiguration.Equals(Microso
Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.SetParsedStack(System.Diagnostics.StackFrame[] frames) -> void
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Flags.get -> long
Microsoft.ApplicationInsights.DataContracts.TelemetryContext.Flags.set -> void
-const Microsoft.ApplicationInsights.DataContracts.TelemetryContext.FlagDropIdentifiers = 2097152 -> long
\ No newline at end of file
+const Microsoft.ApplicationInsights.DataContracts.TelemetryContext.FlagDropIdentifiers = 2097152 -> long
+Microsoft.ApplicationInsights.Channel.ITelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Channel.ITelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.Channel.ITelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.AvailabilityTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.EventTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.ExceptionTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.MetricTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewPerformanceTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PageViewTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.PerformanceCounterTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.SessionStateTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.Extension.set -> void
+Microsoft.ApplicationInsights.DataContracts.TraceTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.Extension.set -> void
+override Microsoft.ApplicationInsights.DataContracts.DependencyTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.Extension.set -> void
+override Microsoft.ApplicationInsights.DataContracts.RequestTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.Extension.get -> Microsoft.ApplicationInsights.Extensibility.IExtension
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.Extension.set -> void
+abstract Microsoft.ApplicationInsights.Extensibility.Implementation.OperationTelemetry.SerializeData(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter
+Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter.Serialize(Microsoft.ApplicationInsights.Extensibility.ISerializationWriter serializationWriter) -> void
+Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Extensibility.IExtension.DeepClone() -> Microsoft.ApplicationInsights.Extensibility.IExtension
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, string value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, double? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, int? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, bool? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.TimeSpan? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.DateTimeOffset? value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(Microsoft.ApplicationInsights.Extensibility.ISerializableWithWriter value) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IList items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IList items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IDictionary items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteProperty(string name, System.Collections.Generic.IDictionary items) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteStartObject(string name) -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteStartObject() -> void
+Microsoft.ApplicationInsights.Extensibility.ISerializationWriter.WriteEndObject() -> void
\ No newline at end of file
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Channel/ITelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/Channel/ITelemetryTest.cs
index 536871a9c5..623ec6152b 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/Channel/ITelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Channel/ITelemetryTest.cs
@@ -6,6 +6,8 @@
using Microsoft.ApplicationInsights.DataContracts;
using AI;
using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
internal class ITelemetryTest
where TTelemetry : ITelemetry, new()
@@ -18,6 +20,7 @@ public void Run()
this.ClassShouldHaveParameterizedConstructorToSimplifyCreationOfValidTelemetryInstancesInUserCode();
this.ClassShouldImplementISupportCustomPropertiesIfItDefinesPropertiesProperty();
this.TestProperties();
+ this.TestExtension();
this.SerializeWritesTimestampAsExpectedByEndpoint();
this.SerializeWritesSequenceAsExpectedByEndpoint();
this.SerializeWritesInstrumentationKeyAsExpectedByEndpoint();
@@ -25,6 +28,22 @@ public void Run()
this.SerializeWritesDataBaseTypeAsExpectedByEndpoint();
}
+ private void TestExtension()
+ {
+ // Extention field exists
+ var extensionField = typeof(TTelemetry).GetRuntimeProperties().Any(p => p.Name == "Extension");
+ Assert.IsNotNull(extensionField);
+
+ TTelemetry tel = new TTelemetry();
+ Assert.IsNull(tel.Extension, "Extension should be null by default");
+
+ // Set extension
+ var myExt = new MyTestExtension();
+ tel.Extension = myExt;
+
+ Assert.AreSame(myExt, tel.Extension, "Extension should be assignable.");
+ }
+
private void TestProperties()
{
foreach (PropertyInfo property in typeof(TTelemetry).GetRuntimeProperties())
@@ -215,6 +234,11 @@ private string ExtractTelemetryNameFromType(Type telemetryType)
// handle TraceTelemetry separately
result = "Message";
}
+ else if (telemetryType == typeof(DependencyTelemetry))
+ {
+ // handle DeppendencyTelemetry separately
+ result = "RemoteDependency";
+ }
#pragma warning disable 618
else if (telemetryType == typeof(SessionStateTelemetry))
{
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/AvailabilityTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/AvailabilityTelemetryTest.cs
index 0da956a2a7..a6917e163d 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/AvailabilityTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/AvailabilityTelemetryTest.cs
@@ -147,6 +147,15 @@ public void AvailabilityTelemetryDeepCloneCopiesAllProperties()
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+ [TestMethod]
+ public void AvailabilityTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new AvailabilityTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
+
private AvailabilityTelemetry CreateAvailabilityTelemetry()
{
AvailabilityTelemetry item = new AvailabilityTelemetry
@@ -161,7 +170,7 @@ private AvailabilityTelemetry CreateAvailabilityTelemetry()
item.Properties.Add("TestProperty", "TestValue");
item.Context.GlobalProperties.Add("TestPropertyGlobal", "TestValue");
item.Sequence = "12";
-
+ item.Extension = new MyTestExtension();
return item;
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/DependencyTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/DependencyTelemetryTest.cs
index 246bbe16c5..4334d1575e 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/DependencyTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/DependencyTelemetryTest.cs
@@ -2,6 +2,8 @@
{
using System;
using System.Collections.Generic;
+ using System.Globalization;
+ using System.IO;
using System.Linq;
using KellermanSoftware.CompareNetObjects;
using Microsoft.ApplicationInsights.Channel;
@@ -23,6 +25,12 @@ public void VerifyExpectedDefaultValue()
Assert.AreEqual(true, defaultDependencyTelemetry.Success, "Success is expected to be true");
}
+ [TestMethod]
+ public void DependencyTelemetryITelemetryContractConsistentlyWithOtherTelemetryTypes()
+ {
+ new ITelemetryTest().Run();
+ }
+
[TestMethod]
public void DependencyTelemetryPropertiesFromContextAndItemSerializesToPropertiesInJson()
{
@@ -80,6 +88,24 @@ public void SerializeWritesNullValuesAsExpectedByEndpoint()
Assert.AreEqual(2, item.data.baseData.ver);
}
+ [TestMethod]
+ public void SerializePopulatesRequiredFieldsOfDependencyTelemetry()
+ {
+ using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture))
+ {
+ var depTelemetry = new DependencyTelemetry();
+ depTelemetry.Context.InstrumentationKey = Guid.NewGuid().ToString();
+ ((ITelemetry)depTelemetry).Sanitize();
+ var item = TelemetryItemTestHelper.SerializeDeserializeTelemetryItem(depTelemetry);
+
+ Assert.AreEqual(2, item.data.baseData.ver);
+ Assert.IsNotNull(item.data.baseData.id);
+ Assert.IsNotNull(item.time);
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.duration));
+ Assert.IsTrue(item.data.baseData.success);
+ }
+ }
+
[TestMethod]
public void RemoteDependencyTelemetrySerializesStructuredIKeyToJsonCorrectlyPreservingPrefixCasing()
{
@@ -218,7 +244,6 @@ public void DependencyTelemetryGetUnsetOperationDetail()
telemetry.ClearOperationDetails();
}
-#if !NETCOREAPP1_1
[TestMethod]
public void DependencyTelemetryDeepCloneCopiesAllProperties()
{
@@ -231,7 +256,15 @@ public void DependencyTelemetryDeepCloneCopiesAllProperties()
ComparisonResult result = deepComparator.Compare(telemetry, other);
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
-#endif
+
+ [TestMethod]
+ public void DependencyTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new DependencyTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
private DependencyTelemetry CreateRemoteDependencyTelemetry()
{
@@ -249,7 +282,7 @@ private DependencyTelemetry CreateRemoteDependencyTelemetry()
item.Context.InstrumentationKey = Guid.NewGuid().ToString();
item.Properties.Add("TestProperty", "TestValue");
item.Context.GlobalProperties.Add("TestPropertyGlobal", "TestValue");
-
+ item.Extension = new MyTestExtension();
return item;
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/EventTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/EventTelemetryTest.cs
index 6014c5a47b..137393da17 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/EventTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/EventTelemetryTest.cs
@@ -153,6 +153,7 @@ public void EventTelemetryDeepCloneCopiesAllProperties()
eventTelemetry.Name = "Test Event";
eventTelemetry.Properties["Test Property"] = "Test Value";
eventTelemetry.Metrics["Test Property"] = 4.2;
+ eventTelemetry.Extension = new MyTestExtension();
EventTelemetry other = (EventTelemetry)eventTelemetry.DeepClone();
CompareLogic deepComparator = new CompareLogic();
@@ -161,6 +162,15 @@ public void EventTelemetryDeepCloneCopiesAllProperties()
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+ [TestMethod]
+ public void EventTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new EventTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
+
[TestMethod]
public void EventTelemetryHasCorrectValueOfSamplingPercentageAfterSerialization()
{
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/ExceptionTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/ExceptionTelemetryTest.cs
index ebe4bb9f6e..2ac3483b1e 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/ExceptionTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/ExceptionTelemetryTest.cs
@@ -39,6 +39,122 @@ public void ExceptionTelemetryReturnsNonNullContext()
Assert.IsNotNull(item.Context);
}
+ [TestMethod]
+ public void ExceptionTelemetryCreatedBasedOnCustomData()
+ {
+ // ARRANGE
+ var topLevelexceptionDetails = new ExceptionDetailsInfo(1, -1, "TopLevelException", "Top level exception",
+ true, "Top level exception stack", new[]
+ {
+ new StackFrame("Some.Assembly", "SomeFile.dll", 3, 33, "TopLevelMethod"),
+ new StackFrame("Some.Assembly", "SomeOtherFile.dll", 2, 22, "LowerLevelMethod"),
+ new StackFrame("Some.Assembly", "YetAnotherFile.dll", 1, 11, "LowLevelMethod")
+ });
+
+ var innerExceptionDetails = new ExceptionDetailsInfo(2, 1, "InnerException", "Inner exception", false,
+ "Inner exception stack", new[]
+ {
+ new StackFrame("Some.Assembly", "ImportantFile.dll", 2, 22, "InnerMethod"),
+ new StackFrame("Some.Assembly", "LessImportantFile.dll", 1, 11, "DeeperInnerMethod")
+ });
+
+ // ACT
+ ExceptionTelemetry item = new ExceptionTelemetry(new[] {topLevelexceptionDetails, innerExceptionDetails},
+ SeverityLevel.Error, "ProblemId",
+ new Dictionary() {["property1"] = "value1", ["property2"] = "value2"},
+ new Dictionary() {["property1"] = 1, ["property2"] = 2});
+
+ item.ExceptionDetailsInfoList[1].Message = "Inner exception modified";
+ item.ProblemId = "ProblemId modified";
+
+ // ASSERT
+ // use internal fields to validate
+ Assert.AreEqual(item.Data.Data.ver, 2);
+ Assert.AreEqual(item.Data.Data.problemId, "ProblemId modified");
+ Assert.AreEqual(item.Data.Data.severityLevel, Extensibility.Implementation.External.SeverityLevel.Error);
+
+ Assert.AreEqual(item.Data.Data.properties.Count, 2);
+ Assert.IsTrue(item.Data.Data.properties.Keys.Contains("property1"));
+ Assert.IsTrue(item.Data.Data.properties.Keys.Contains("property2"));
+ Assert.IsTrue(item.Data.Data.properties.Values.Contains("value1"));
+ Assert.IsTrue(item.Data.Data.properties.Values.Contains("value2"));
+
+ Assert.AreEqual(item.Data.Data.measurements.Count, 2);
+ Assert.IsTrue(item.Data.Data.measurements.Keys.Contains("property1"));
+ Assert.IsTrue(item.Data.Data.measurements.Keys.Contains("property2"));
+ Assert.IsTrue(item.Data.Data.measurements.Values.Contains(1));
+ Assert.IsTrue(item.Data.Data.measurements.Values.Contains(2));
+
+ Assert.AreEqual(item.Data.Data.exceptions.Count, 2);
+
+ Assert.AreEqual(item.Data.Data.exceptions.First().id, 1);
+ Assert.AreEqual(item.Data.Data.exceptions.First().outerId, -1);
+ Assert.AreEqual(item.Data.Data.exceptions.First().typeName, "TopLevelException");
+ Assert.AreEqual(item.Data.Data.exceptions.First().message, "Top level exception");
+ Assert.AreEqual(item.Data.Data.exceptions.First().hasFullStack, true);
+ Assert.AreEqual(item.Data.Data.exceptions.First().stack, "Top level exception stack");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack.Count, 3);
+
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[0].assembly, "Some.Assembly");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[0].fileName, "SomeFile.dll");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[0].level, 3);
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[0].line, 33);
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[0].method, "TopLevelMethod");
+
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[1].assembly, "Some.Assembly");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[1].fileName, "SomeOtherFile.dll");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[1].level, 2);
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[1].line, 22);
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[1].method, "LowerLevelMethod");
+
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[2].assembly, "Some.Assembly");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[2].fileName, "YetAnotherFile.dll");
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[2].level, 1);
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[2].line, 11);
+ Assert.AreEqual(item.Data.Data.exceptions.First().parsedStack[2].method, "LowLevelMethod");
+
+ Assert.AreEqual(item.Data.Data.exceptions.Last().id, 2);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().outerId, 1);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().typeName, "InnerException");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().message, "Inner exception modified");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().hasFullStack, false);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().stack, "Inner exception stack");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack.Count, 2);
+
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[0].assembly, "Some.Assembly");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[0].fileName, "ImportantFile.dll");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[0].level, 2);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[0].line, 22);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[0].method, "InnerMethod");
+
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[1].assembly, "Some.Assembly");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[1].fileName, "LessImportantFile.dll");
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[1].level, 1);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[1].line, 11);
+ Assert.AreEqual(item.Data.Data.exceptions.Last().parsedStack[1].method, "DeeperInnerMethod");
+ }
+
+ [TestMethod]
+ public void ExceptionTelemetryExceptionDetailsUpdate()
+ {
+ // ARRANGE
+ var exception = new AggregateException("Test Exception", new Exception());
+ ExceptionTelemetry item = new ExceptionTelemetry(exception);
+
+ // ACT
+ IReadOnlyList newExceptionDetails = item.ExceptionDetailsInfoList;
+
+ string modifiedMessage = "Modified Message";
+ string modifiedTypeName = "Modified TypeName";
+
+ newExceptionDetails[0].Message = modifiedMessage;
+ newExceptionDetails[0].TypeName = modifiedTypeName;
+
+ // ASSERT
+ Assert.AreEqual(modifiedMessage, item.Exceptions[0].message);
+ Assert.AreEqual(modifiedTypeName, item.Exceptions[0].typeName);
+ }
+
[TestMethod]
public void ExceptionsPropertyIsInternalUntilWeSortOutPublicInterface()
{
@@ -53,6 +169,7 @@ public void ConstructorAddsExceptionToExceptionPropertyAndExceptionsCollectionPr
Assert.AreSame(constructorException, testExceptionTelemetry.Exception);
Assert.AreEqual(constructorException.Message, testExceptionTelemetry.Exceptions.First().message);
+ Assert.AreEqual(constructorException.Message, testExceptionTelemetry.ExceptionDetailsInfoList.First().Message);
}
[TestMethod]
@@ -66,6 +183,7 @@ public void ExceptionPropertySetterReplacesExceptionDetailsInExceptionsCollectio
Assert.AreSame(nextException, testExceptionTelemetry.Exception);
Assert.AreEqual(nextException.Message, testExceptionTelemetry.Exceptions.First().message);
+ Assert.AreEqual(nextException.Message, testExceptionTelemetry.ExceptionDetailsInfoList.First().Message);
}
#pragma warning disable 618
@@ -344,9 +462,12 @@ public void ExceptionPropertySetterHandlesAggregateExceptionsWithMultipleNestedE
};
Assert.AreEqual(expectedSequence.Length, telemetry.Exceptions.Count);
- int counter = 0;
- foreach (ExceptionDetails details in telemetry.Exceptions)
+ Assert.AreEqual(expectedSequence.Length, telemetry.ExceptionDetailsInfoList.Count);
+ for(int counter = 0; counter < expectedSequence.Length; counter++)
{
+ ExceptionDetails details = telemetry.Exceptions[counter];
+ ExceptionDetailsInfo newExceptionDetails = telemetry.ExceptionDetailsInfoList[counter];
+ Assert.IsTrue(ReferenceEquals(details, newExceptionDetails.InternalExceptionDetails));
if (details.typeName == "System.AggregateException")
{
AssertEx.StartsWith(expectedSequence[counter], details.message);
@@ -355,7 +476,6 @@ public void ExceptionPropertySetterHandlesAggregateExceptionsWithMultipleNestedE
{
Assert.AreEqual(expectedSequence[counter], details.message);
}
- counter++;
}
}
@@ -374,9 +494,12 @@ public void ExceptionPropertySetterHandlesAggregateExceptionsWithMultipleNestedE
ExceptionTelemetry telemetry = new ExceptionTelemetry { Exception = rootLevelException };
Assert.AreEqual(Constants.MaxExceptionCountToSave + 1, telemetry.Exceptions.Count);
- int counter = 0;
- foreach (ExceptionDetails details in telemetry.Exceptions.Take(Constants.MaxExceptionCountToSave))
+ Assert.AreEqual(Constants.MaxExceptionCountToSave + 1, telemetry.ExceptionDetailsInfoList.Count);
+ for(int counter = 0; counter < Constants.MaxExceptionCountToSave; counter++)
{
+ ExceptionDetails details = telemetry.Exceptions[counter];
+ ExceptionDetailsInfo newExceptionDetails = telemetry.ExceptionDetailsInfoList[counter];
+ Assert.IsTrue(ReferenceEquals(details, newExceptionDetails.InternalExceptionDetails));
if (details.typeName == "System.AggregateException")
{
AssertEx.StartsWith(counter.ToString(CultureInfo.InvariantCulture), details.message);
@@ -385,7 +508,6 @@ public void ExceptionPropertySetterHandlesAggregateExceptionsWithMultipleNestedE
{
Assert.AreEqual(counter.ToString(CultureInfo.InvariantCulture), details.message);
}
- counter++;
}
ExceptionDetails first = telemetry.Exceptions.First();
@@ -465,6 +587,15 @@ public void ExceptionTelemetryDeepCloneCopiesAllProperties()
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+ [TestMethod]
+ public void ExceptionTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new ExceptionTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
+
[TestMethod]
public void ExceptionTelemetryPropertiesFromContextAndItemSerializesToPropertiesInJson()
{
@@ -508,6 +639,7 @@ private static ExceptionTelemetry CreateExceptionTelemetry(Exception exception =
output.Context.GlobalProperties.Add("TestPropertyGlobal", "contextpropvalue");
output.Context.InstrumentationKey = "required";
output.Properties.Add("TestProperty", "TestPropertyValue");
+ output.Extension = new MyTestExtension();
return output;
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/MetricTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/MetricTelemetryTest.cs
index b04132e065..82213c309f 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/MetricTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/MetricTelemetryTest.cs
@@ -27,7 +27,7 @@ public void MetricTelemetryImplementsITelemetryContract()
}
[TestMethod]
- public void EventTelemetryReturnsNonNullContext()
+ public void MetricTelemetryReturnsNonNullContext()
{
MetricTelemetry item = new MetricTelemetry();
Assert.IsNotNull(item.Context);
@@ -355,12 +355,21 @@ public void MetricTelemetryDeepCloneCopiesAllProperties()
metric.Max = 6.4;
metric.StandardDeviation = 0.5;
metric.Properties.Add("Property1", "Value1");
-
+ metric.Extension = new MyTestExtension();
MetricTelemetry other = (MetricTelemetry)metric.DeepClone();
CompareLogic deepComparator = new CompareLogic();
var comparisonResult = deepComparator.Compare(metric, other);
Assert.IsTrue(comparisonResult.AreEqual, comparisonResult.DifferencesString);
}
+
+ [TestMethod]
+ public void MetricTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new MetricTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewPerformanceTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewPerformanceTelemetryTest.cs
new file mode 100644
index 0000000000..cd668cbe5a
--- /dev/null
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewPerformanceTelemetryTest.cs
@@ -0,0 +1,209 @@
+namespace Microsoft.ApplicationInsights.DataContracts
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Reflection;
+ using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
+ using Microsoft.ApplicationInsights.TestFramework;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using CompareLogic = KellermanSoftware.CompareNetObjects.CompareLogic;
+
+
+ [TestClass]
+ public class PageViewPerformanceTelemetryTest
+ {
+ [TestMethod]
+ public void PageViewImplementsITelemetryContractConsistentlyWithOtherTelemetryTypes()
+ {
+ new ITelemetryTest().Run();
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryIsPublic()
+ {
+ Assert.IsTrue(typeof(PageViewPerformanceTelemetry).GetTypeInfo().IsPublic);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryReturnsNonNullContext()
+ {
+ PageViewPerformanceTelemetry item = new PageViewPerformanceTelemetry();
+ Assert.IsNotNull(item.Context);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetrySuppliesConstructorThatTakesNameParameter()
+ {
+ string expectedPageName = "My page view";
+ var instance = new PageViewPerformanceTelemetry(expectedPageName);
+ Assert.AreEqual(expectedPageName, instance.Name);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryReturnsDefaultDurationAsTimespanZero()
+ {
+ PageViewPerformanceTelemetry item = new PageViewPerformanceTelemetry();
+ Assert.AreEqual(TimeSpan.Zero, item.Duration);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetrySerializesToJsonCorrectly()
+ {
+ var expected = new PageViewPerformanceTelemetry("My Page");
+ expected.Url = new Uri("http://temp.org/page1");
+ expected.Duration = TimeSpan.FromSeconds(123);
+ expected.Metrics.Add("Metric1", 30);
+ expected.Properties.Add("Property1", "Value1");
+
+ var item = TelemetryItemTestHelper.SerializeDeserializeTelemetryItem(expected);
+
+ // NOTE: It's correct that we use the v1 name here, and therefore we test against it.
+ Assert.AreEqual(item.name, AI.ItemType.PageViewPerformance);
+
+ Assert.AreEqual(PageViewPerformanceTelemetry.BaseType, item.data.baseType);
+ Assert.AreEqual(2, item.data.baseData.ver);
+ Assert.AreEqual(expected.Name, item.data.baseData.name);
+ Assert.AreEqual(expected.Duration, TimeSpan.Parse(item.data.baseData.duration));
+ Assert.AreEqual(expected.Url.ToString(), item.data.baseData.url);
+
+ AssertEx.AreEqual(expected.Properties.ToArray(), item.data.baseData.properties.ToArray());
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryTelemetryPropertiesFromContextAndItemSerializesToPropertiesInJson()
+ {
+ var expected = new PageViewPerformanceTelemetry();
+ expected.Context.GlobalProperties.Add("TestPropertyGlobal", "contextpropvalue");
+ expected.Properties.Add("TestProperty", "TestPropertyValue");
+ ((ITelemetry)expected).Sanitize();
+
+ Assert.AreEqual(1, expected.Properties.Count);
+ Assert.AreEqual(1, expected.Context.GlobalProperties.Count);
+
+ Assert.IsTrue(expected.Properties.ContainsKey("TestProperty"));
+ Assert.IsTrue(expected.Context.GlobalProperties.ContainsKey("TestPropertyGlobal"));
+
+ var item = TelemetryItemTestHelper.SerializeDeserializeTelemetryItem(expected);
+
+ // Items added to both PageViewPerformanceTelemetry.Properties, and PageViewPerformanceTelemetry.Context.GlobalProperties are serialized to properties.
+ Assert.AreEqual(2, item.data.baseData.properties.Count);
+ Assert.IsTrue(item.data.baseData.properties.ContainsKey("TestPropertyGlobal"));
+ Assert.IsTrue(item.data.baseData.properties.ContainsKey("TestProperty"));
+ }
+
+ [TestMethod]
+ public void SerializePopulatesRequiredFieldsOfPageViewPerfTelemetry()
+ {
+ using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture))
+ {
+ var pvTelemetry = new PageViewPerformanceTelemetry();
+ pvTelemetry.Context.InstrumentationKey = Guid.NewGuid().ToString();
+ ((ITelemetry)pvTelemetry).Sanitize();
+ var item = TelemetryItemTestHelper.SerializeDeserializeTelemetryItem(pvTelemetry);
+
+ Assert.AreEqual(2, item.data.baseData.ver);
+ Assert.IsNotNull(item.data.baseData.id);
+ Assert.IsNotNull(item.time);
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.duration));
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.domProcessing));
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.networkConnect));
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.perfTotal));
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.receivedResponse));
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.sentRequest));
+ }
+ }
+
+
+ [TestMethod]
+ public void SanitizeWillTrimAppropriateFields()
+ {
+ PageViewPerformanceTelemetry telemetry = new PageViewPerformanceTelemetry();
+ telemetry.Name = new string('Z', Property.MaxNameLength + 1);
+ telemetry.Properties.Add(new string('X', Property.MaxDictionaryNameLength) + 'X', new string('X', Property.MaxValueLength + 1));
+ telemetry.Properties.Add(new string('X', Property.MaxDictionaryNameLength) + 'Y', new string('X', Property.MaxValueLength + 1));
+ telemetry.Metrics.Add(new string('Y', Property.MaxDictionaryNameLength) + 'X', 42.0);
+ telemetry.Metrics.Add(new string('Y', Property.MaxDictionaryNameLength) + 'Y', 42.0);
+ telemetry.Url = new Uri("http://foo.com/" + new string('Y', Property.MaxUrlLength + 1));
+
+ ((ITelemetry)telemetry).Sanitize();
+
+ Assert.AreEqual(new string('Z', Property.MaxNameLength), telemetry.Name);
+
+ Assert.AreEqual(2, telemetry.Properties.Count);
+ string[] keys = telemetry.Properties.Keys.OrderBy(s => s).ToArray();
+ string[] values = telemetry.Properties.Values.OrderBy(s => s).ToArray();
+ Assert.AreEqual(new string('X', Property.MaxDictionaryNameLength), keys[1]);
+ Assert.AreEqual(new string('X', Property.MaxValueLength), values[1]);
+ Assert.AreEqual(new string('X', Property.MaxDictionaryNameLength - 3) + "1", keys[0]);
+ Assert.AreEqual(new string('X', Property.MaxValueLength), values[0]);
+
+ Assert.AreEqual(2, telemetry.Metrics.Count);
+ keys = telemetry.Metrics.Keys.OrderBy(s => s).ToArray();
+ Assert.AreEqual(new string('Y', Property.MaxDictionaryNameLength), keys[1]);
+ Assert.AreEqual(new string('Y', Property.MaxDictionaryNameLength - 3) + "1", keys[0]);
+
+ Assert.AreEqual(new Uri("http://foo.com/" + new string('Y', Property.MaxUrlLength - 15)), telemetry.Url);
+ }
+
+ [TestMethod]
+ public void SanitizePopulatesNameWithErrorBecauseItIsRequiredByEndpoint()
+ {
+ var telemetry = new PageViewPerformanceTelemetry { Name = null };
+
+ ((ITelemetry)telemetry).Sanitize();
+
+ Assert.AreEqual("n/a", telemetry.Name);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryImplementsISupportSamplingContract()
+ {
+ var telemetry = new PageViewPerformanceTelemetry();
+
+ Assert.IsNotNull(telemetry as ISupportSampling);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryHasCorrectValueOfSamplingPercentageAfterSerialization()
+ {
+ var telemetry = new PageViewPerformanceTelemetry("my page view");
+ ((ISupportSampling)telemetry).SamplingPercentage = 10;
+
+ var item = TelemetryItemTestHelper.SerializeDeserializeTelemetryItem(telemetry);
+
+ Assert.AreEqual(10, item.sampleRate);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryDeepCloneCopiesAllProperties()
+ {
+ var pageView = new PageViewPerformanceTelemetry("My Page");
+ pageView.Url = new Uri("http://temp.org/page1");
+ pageView.Duration = TimeSpan.FromSeconds(123);
+ pageView.Metrics.Add("Metric1", 30);
+ pageView.Properties.Add("Property1", "Value1");
+ pageView.Extension = new MyTestExtension();
+
+
+ PageViewPerformanceTelemetry other = (PageViewPerformanceTelemetry)pageView.DeepClone();
+
+ CompareLogic deepComparator = new CompareLogic();
+ var result = deepComparator.Compare(pageView, other);
+ Assert.IsTrue(result.AreEqual, result.DifferencesString);
+ }
+
+ [TestMethod]
+ public void PageViewPerformanceTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new PageViewPerformanceTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
+ }
+}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewTelemetryTest.cs
index 4e53611e31..fa671beb86 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PageViewTelemetryTest.cs
@@ -96,6 +96,23 @@ public void PageViewTelemetryTelemetryPropertiesFromContextAndItemSerializesToPr
Assert.IsTrue(item.data.baseData.properties.ContainsKey("TestProperty"));
}
+ [TestMethod]
+ public void SerializePopulatesRequiredFieldsOfPageViewTelemetry()
+ {
+ using (StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture))
+ {
+ var pvTelemetry = new PageViewTelemetry();
+ pvTelemetry.Context.InstrumentationKey = Guid.NewGuid().ToString();
+ ((ITelemetry)pvTelemetry).Sanitize();
+ var item = TelemetryItemTestHelper.SerializeDeserializeTelemetryItem(pvTelemetry);
+
+ Assert.AreEqual(2, item.data.baseData.ver);
+ Assert.IsNotNull(item.data.baseData.id);
+ Assert.IsNotNull(item.time);
+ Assert.AreEqual(new TimeSpan(), TimeSpan.Parse(item.data.baseData.duration));
+ }
+ }
+
[TestMethod]
public void SanitizeWillTrimAppropriateFields()
{
@@ -164,12 +181,21 @@ public void PageViewTelemetryDeepCloneCopiesAllProperties()
pageView.Duration = TimeSpan.FromSeconds(123);
pageView.Metrics.Add("Metric1", 30);
pageView.Properties.Add("Property1", "Value1");
-
+ pageView.Extension = new MyTestExtension();
PageViewTelemetry other = (PageViewTelemetry)pageView.DeepClone();
CompareLogic deepComparator = new CompareLogic();
var result = deepComparator.Compare(pageView, other);
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+
+ [TestMethod]
+ public void PageViewTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new PageViewTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PerformanceCounterTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PerformanceCounterTelemetryTest.cs
index 61dbae64de..260cb3cc62 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PerformanceCounterTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/PerformanceCounterTelemetryTest.cs
@@ -2,6 +2,7 @@
{
using System;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using CompareLogic = KellermanSoftware.CompareNetObjects.CompareLogic;
@@ -40,6 +41,7 @@ public void PerformanceCounterTelemetryDeepCloneCopiesAllProperties()
PerformanceCounterTelemetry item = new PerformanceCounterTelemetry("someCategory", "someCounter", "an instance", 15.7);
item.Timestamp = DateTimeOffset.Now;
item.Properties.Add("p1", "p1Val");
+ item.Extension = new MyTestExtension();
PerformanceCounterTelemetry other = (PerformanceCounterTelemetry)item.DeepClone();
@@ -48,6 +50,16 @@ public void PerformanceCounterTelemetryDeepCloneCopiesAllProperties()
var result = deepComparator.Compare(item, other);
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+
+ [TestMethod]
+ public void PerformanceCounterTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new PerformanceCounterTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
+
#pragma warning restore 618
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/RequestTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/RequestTelemetryTest.cs
index f536615390..40e74dd50b 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/RequestTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/RequestTelemetryTest.cs
@@ -251,6 +251,14 @@ public void RequestTelemetryDeepCloneCopiesAllProperties()
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+ [TestMethod]
+ public void RequestTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new RequestTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
private RequestTelemetry CreateTestTelemetry()
{
var request = new RequestTelemetry();
@@ -264,6 +272,7 @@ private RequestTelemetry CreateTestTelemetry()
request.Metrics.Add("Metric1", 30);
request.Properties.Add("itempropkey", "::1");
request.Context.GlobalProperties.Add("contextpropkey", "contextpropvalue");
+ request.Extension = new MyTestExtension();
return request;
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/SessionStateTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/SessionStateTelemetryTest.cs
index 70343d45c8..f15a4910c0 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/SessionStateTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/SessionStateTelemetryTest.cs
@@ -5,6 +5,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using KellermanSoftware.CompareNetObjects;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
[TestClass]
public class SessionStateTelemetryTest
@@ -60,6 +61,7 @@ public void SessionStateTelemetryDeepCloneCopiesAllProperties()
{
var telemetry = new SessionStateTelemetry();
telemetry.State = SessionState.End;
+ telemetry.Extension = new MyTestExtension();
var other = telemetry.DeepClone();
CompareLogic deepComparator = new CompareLogic();
@@ -67,6 +69,16 @@ public void SessionStateTelemetryDeepCloneCopiesAllProperties()
var result = deepComparator.Compare(telemetry, other);
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+
+ [TestMethod]
+ public void SessionStateTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var telemetry = new SessionStateTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = telemetry.DeepClone();
+ }
+
#pragma warning restore 618
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryContextTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryContextTest.cs
index 96dd2dd272..5458a5b1bc 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryContextTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryContextTest.cs
@@ -252,7 +252,7 @@ private static string CopyAndSerialize(TelemetryContext source)
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- Telemetry.WriteTelemetryContext(new JsonWriter(stringWriter), source);
+ Telemetry.WriteTelemetryContext(new JsonSerializationWriter(stringWriter), source);
return stringWriter.ToString();
}
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryItemTestHelper.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryItemTestHelper.cs
index 07b8df65eb..d2b023e5ce 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryItemTestHelper.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TelemetryItemTestHelper.cs
@@ -1,14 +1,12 @@
namespace Microsoft.ApplicationInsights.DataContracts
{
- using System.Globalization;
using System.IO;
using System.Text;
using Microsoft.ApplicationInsights.Channel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
-
+
using JsonSerializer = Microsoft.ApplicationInsights.Extensibility.Implementation.JsonSerializer;
- using JsonWriter = Microsoft.ApplicationInsights.Extensibility.Implementation.JsonWriter;
internal static class TelemetryItemTestHelper
{
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TraceTelemetryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TraceTelemetryTest.cs
index d3239f2996..a69518e0f2 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TraceTelemetryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/DataContracts/TraceTelemetryTest.cs
@@ -155,6 +155,7 @@ public void TraceTelemetryDeepCloneCopiesAllProperties()
trace.SeverityLevel = SeverityLevel.Warning;
trace.Sequence = "123456";
trace.Timestamp = DateTimeOffset.Now;
+ trace.Extension = new MyTestExtension();
var other = trace.DeepClone();
var deepComparator = new CompareLogic();
@@ -163,6 +164,15 @@ public void TraceTelemetryDeepCloneCopiesAllProperties()
Assert.IsTrue(result.AreEqual, result.DifferencesString);
}
+ [TestMethod]
+ public void TraceTelemetryDeepCloneWithNullExtensionDoesNotThrow()
+ {
+ var trace = new TraceTelemetry();
+ // Extension is not set, means it'll be null.
+ // Validate that cloning with null Extension does not throw.
+ var other = trace.DeepClone();
+ }
+
[TestMethod]
public void TraceTelemetryPropertiesFromContextAndItemSerializesToPropertiesInJson()
{
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonSerializationWriterTests.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonSerializationWriterTests.cs
new file mode 100644
index 0000000000..d3d0bebf8f
--- /dev/null
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonSerializationWriterTests.cs
@@ -0,0 +1,165 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation
+{
+ using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+ using Newtonsoft.Json;
+ using Newtonsoft.Json.Linq;
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Globalization;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+
+
+ ///
+ /// Tests for
+ ///
+ [TestClass]
+ public class JsonSerializationWriterTests
+ {
+ [TestMethod]
+ public void SerializeComplexObject()
+ {
+ var complexExtension = new ComplexExtension();
+ var mySubSubExtension1 = new MySubSubExtension() { Field3 = "Value1 for field3", Field4 = 100.00 };
+ var mySubSubExtension2 = new MySubSubExtension() { Field3 = "Value2 for field3", Field4 = 200.00 };
+ var mySubExtension1 = new MySubExtension() { Field1 = "Value1 for field1", Field2 = 100 , MySubSubExtension = mySubSubExtension1 };
+ var mySubExtension2 = new MySubExtension() { Field1 = "Value2 for field1", Field2 = 200, MySubSubExtension = mySubSubExtension2 };
+ var listExtension = new List();
+ listExtension.Add(mySubExtension1);
+ listExtension.Add(mySubExtension2);
+
+ var listString = new List();
+ listString.Add("Item1");
+ listString.Add("Item2");
+ listString.Add("Item3");
+
+ complexExtension.MyBoolField = true;
+ complexExtension.MyDateTimeOffsetField = DateTimeOffset.Now;
+ complexExtension.MyDoubleField = 100.10;
+ complexExtension.MyIntField = 100;
+ complexExtension.MyStringField = "ValueStringField";
+ complexExtension.MyTimeSpanField = TimeSpan.FromSeconds(2);
+ complexExtension.MySubExtensionField = mySubExtension1;
+ complexExtension.MyExtensionListField = listExtension;
+ complexExtension.MyStringListField = listString;
+
+ var dicString = new Dictionary();
+ dicString.Add("Key1", "Value1");
+ dicString.Add("Key2", "Value2");
+ complexExtension.MyStringDictionaryField = dicString;
+
+ var dicDouble = new Dictionary();
+ dicDouble.Add("Key1", 1000.000);
+ dicDouble.Add("Key2", 2000.000);
+ complexExtension.MyDoubleDictionaryField = dicDouble;
+
+ var stringBuilder = new StringBuilder();
+ using (StringWriter stringWriter = new StringWriter(stringBuilder, CultureInfo.InvariantCulture))
+ {
+ var jsonSerializationWriter = new JsonSerializationWriter(stringWriter);
+ jsonSerializationWriter.WriteStartObject();
+ complexExtension.Serialize(jsonSerializationWriter);
+ jsonSerializationWriter.WriteEndObject();
+ }
+
+ string actualJson = stringBuilder.ToString();
+ Trace.WriteLine(actualJson);
+
+ JObject obj = JsonConvert.DeserializeObject(actualJson);
+
+ Assert.IsNotNull(actualJson);
+ Assert.AreEqual("ValueStringField", obj["MyStringField"].ToString());
+ Assert.AreEqual(100, int.Parse(obj["MyIntField"].ToString()));
+ Assert.AreEqual(100.10, double.Parse(obj["MyDoubleField"].ToString()));
+ Assert.AreEqual(true, bool.Parse(obj["MyBoolField"].ToString()));
+ Assert.AreEqual(TimeSpan.FromSeconds(2), TimeSpan.Parse(obj["MyTimeSpanField"].ToString()));
+ //Assert.AreEqual(DateTimeOffset., double.Parse(obj["MyDateTimeOffsetField"].ToString()));
+
+ Assert.AreEqual("Value1 for field1",obj["MySubExtensionField"]["Field1"].ToString());
+ Assert.AreEqual(100, int.Parse(obj["MySubExtensionField"]["Field2"].ToString()));
+
+ Assert.AreEqual("Value1 for field3", obj["MySubExtensionField"]["MySubSubExtension"]["Field3"].ToString());
+ Assert.AreEqual(100, int.Parse(obj["MySubExtensionField"]["MySubSubExtension"]["Field4"].ToString()));
+
+ Assert.AreEqual("Item1", obj["MyStringListField"][0].ToString());
+ Assert.AreEqual("Item2", obj["MyStringListField"][1].ToString());
+ Assert.AreEqual("Item3", obj["MyStringListField"][2].ToString());
+
+ Assert.AreEqual("Value1 for field1", obj["MyExtensionListField"][0]["Field1"].ToString());
+ Assert.AreEqual(100, int.Parse(obj["MyExtensionListField"][0]["Field2"].ToString()));
+ Assert.AreEqual("Value1 for field3", obj["MyExtensionListField"][0]["MySubSubExtension"]["Field3"].ToString());
+ Assert.AreEqual(100, int.Parse(obj["MyExtensionListField"][0]["MySubSubExtension"]["Field4"].ToString()));
+
+ Assert.AreEqual("Value2 for field1", obj["MyExtensionListField"][1]["Field1"].ToString());
+ Assert.AreEqual(200, int.Parse(obj["MyExtensionListField"][1]["Field2"].ToString()));
+ Assert.AreEqual("Value2 for field3", obj["MyExtensionListField"][1]["MySubSubExtension"]["Field3"].ToString());
+ Assert.AreEqual(200, int.Parse(obj["MyExtensionListField"][1]["MySubSubExtension"]["Field4"].ToString()));
+
+ Assert.AreEqual("Value1", obj["MyStringDictionaryField"]["Key1"].ToString());
+ Assert.AreEqual("Value2", obj["MyStringDictionaryField"]["Key2"].ToString());
+
+ Assert.AreEqual(1000, double.Parse(obj["MyDoubleDictionaryField"]["Key1"].ToString()));
+ Assert.AreEqual(2000, double.Parse(obj["MyDoubleDictionaryField"]["Key2"].ToString()));
+
+ }
+ }
+
+ public class ComplexExtension : ISerializableWithWriter
+ {
+ public string MyStringField;
+ public int MyIntField;
+ public double MyDoubleField;
+ public bool MyBoolField;
+ public TimeSpan MyTimeSpanField;
+ public DateTimeOffset MyDateTimeOffsetField;
+ public MySubExtension MySubExtensionField;
+ public IList MyStringListField;
+ public IList MyExtensionListField;
+ public IDictionary MyStringDictionaryField;
+ public IDictionary MyDoubleDictionaryField;
+
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("MyStringField", MyStringField);
+ serializationWriter.WriteProperty("MyIntField", MyIntField);
+ serializationWriter.WriteProperty("MyDoubleField", MyDoubleField);
+ serializationWriter.WriteProperty("MyBoolField", MyBoolField);
+ serializationWriter.WriteProperty("MyTimeSpanField", MyTimeSpanField);
+ serializationWriter.WriteProperty("MyDateTimeOffsetField", MyDateTimeOffsetField);
+ serializationWriter.WriteProperty("MySubExtensionField", MySubExtensionField);
+ serializationWriter.WriteProperty("MyStringListField", MyStringListField);
+ serializationWriter.WriteProperty("MyExtensionListField", MyExtensionListField.ToList());
+ serializationWriter.WriteProperty("MyStringDictionaryField", MyStringDictionaryField);
+ serializationWriter.WriteProperty("MyDoubleDictionaryField", MyDoubleDictionaryField);
+ }
+ }
+
+ public class MySubExtension : ISerializableWithWriter
+ {
+ public string Field1;
+ public int Field2;
+ public ISerializableWithWriter MySubSubExtension;
+
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("Field1", Field1);
+ serializationWriter.WriteProperty("Field2", Field2);
+ serializationWriter.WriteProperty("MySubSubExtension", MySubSubExtension);
+ }
+ }
+
+ public class MySubSubExtension : ISerializableWithWriter
+ {
+ public string Field3;
+ public double Field4;
+
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("Field3", Field3);
+ serializationWriter.WriteProperty("Field4", Field4);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonWriterTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonWriterTest.cs
index 0b5910a5b1..895d349a0b 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonWriterTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/JsonWriterTest.cs
@@ -10,12 +10,12 @@
using Microsoft.ApplicationInsights.TestFramework;
[TestClass]
- public class JsonWriterTest
+ public class JsonSerializationWriterTest
{
[TestMethod]
public void ClassIsInternalAndNotMeantToBeAccessedByCustomers()
{
- Assert.IsFalse(typeof(JsonWriter).GetTypeInfo().IsPublic);
+ Assert.IsFalse(typeof(JsonSerializationWriter).GetTypeInfo().IsPublic);
}
[TestMethod]
@@ -23,7 +23,7 @@ public void WriteStartArrayWritesOpeningSquareBracket()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteStartArray();
+ new JsonSerializationWriter(stringWriter).WriteStartArray();
Assert.AreEqual("[", stringWriter.ToString());
}
}
@@ -33,7 +33,7 @@ public void WriteStartObjectWritesOpeningCurlyBrace()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteStartObject();
+ new JsonSerializationWriter(stringWriter).WriteStartObject();
Assert.AreEqual("{", stringWriter.ToString());
}
}
@@ -43,7 +43,7 @@ public void WriteEndArrayWritesClosingSquareBracket()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteEndArray();
+ new JsonSerializationWriter(stringWriter).WriteEndArray();
Assert.AreEqual("]", stringWriter.ToString());
}
}
@@ -53,7 +53,7 @@ public void WriteEndObjectWritesClosingCurlyBrace()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteEndObject();
+ new JsonSerializationWriter(stringWriter).WriteEndObject();
Assert.AreEqual("}", stringWriter.ToString());
}
}
@@ -63,7 +63,7 @@ public void WriteRawValueWritesValueWithoutEscapingValue()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteRawValue(@"Test\Name");
+ new JsonSerializationWriter(stringWriter).WriteRawValue(@"Test\Name");
Assert.AreEqual(@"Test\Name", stringWriter.ToString());
}
}
@@ -77,7 +77,7 @@ public void WritePropertyIntWritesIntValueWithoutQuotationMark()
{
const string Name = "name";
const int Value = 42;
- new JsonWriter(stringWriter).WriteProperty(Name, Value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, Value);
Assert.AreEqual("\"" + Name + "\":" + Value, stringWriter.ToString());
}
}
@@ -87,7 +87,7 @@ public void WritePropertyIntDoesNothingIfValueIsNullBecauseItAssumesPropertyIsOp
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (int?)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (int?)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -103,7 +103,7 @@ public void WritePropertyDoubleWritesDoubleValueWithoutQuotationMark()
{
const string Name = "name";
const double Value = 42.3;
- new JsonWriter(stringWriter).WriteProperty(Name, Value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, Value);
Assert.AreEqual("\"" + Name + "\":" + Value.ToString(CultureInfo.InvariantCulture), stringWriter.ToString());
}
}
@@ -113,7 +113,7 @@ public void WritePropertyDoubleDoesNothingIfValueIsNullBecauseItAssumesPropertyI
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (double?)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (double?)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -129,7 +129,7 @@ public void WritePropertyTimeSpanWritesTimeSpanValueWithQuotationMark()
{
const string Name = "name";
TimeSpan value = TimeSpan.FromSeconds(123);
- new JsonWriter(stringWriter).WriteProperty(Name, value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, value);
Assert.AreEqual("\"" + Name + "\":\"" + value + "\"", stringWriter.ToString());
}
}
@@ -139,7 +139,7 @@ public void WritePropertyTimeSpanDoesNothingIfValueIsNullBecauseItAssumesPropert
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (TimeSpan?)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (TimeSpan?)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -155,7 +155,7 @@ public void WritePropertyStringWritesValueInDoubleQuotes()
{
const string Name = "name";
const string Value = "value";
- new JsonWriter(stringWriter).WriteProperty(Name, Value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, Value);
Assert.AreEqual("\"" + Name + "\":\"" + Value + "\"", stringWriter.ToString());
}
}
@@ -165,7 +165,7 @@ public void WritePropertyStringThrowsArgumentNullExceptionForNameInputAsNull()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var writer = new JsonWriter(stringWriter);
+ var writer = new JsonSerializationWriter(stringWriter);
AssertEx.Throws(() => writer.WriteProperty(null, "value"));
}
}
@@ -175,7 +175,7 @@ public void WritePropertyStringDoesNothingIfValueIsNullBecauseItAssumesPropertyI
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (string)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (string)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -185,7 +185,7 @@ public void WritePropertyStringDoesNothingIfValueIsEmptyBecauseItAssumesProperty
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", string.Empty);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", string.Empty);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -201,7 +201,7 @@ public void WritePropertyBooleanWritesValueWithoutQuotationMarks()
{
const string Name = "name";
const bool Value = true;
- new JsonWriter(stringWriter).WriteProperty(Name, Value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, Value);
string expectedValue = Value.ToString().ToLowerInvariant();
Assert.AreEqual("\"" + Name + "\":" + expectedValue, stringWriter.ToString());
}
@@ -212,7 +212,7 @@ public void WritePropertyBooleanDoesNothingIfValueIsNullBecauseItAssumesProperty
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (bool?)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (bool?)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -224,7 +224,7 @@ public void WritePropertyBooleanWritesFalseBecauseItIsExplicitlySet()
{
const string Name = "name";
const bool Value = false;
- new JsonWriter(stringWriter).WriteProperty(Name, Value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, Value);
string expectedValue = Value.ToString().ToLowerInvariant();
Assert.AreEqual("\"" + Name + "\":" + expectedValue, stringWriter.ToString());
}
@@ -241,7 +241,7 @@ public void WritePropertyDateTimeOffsetWritesValueInQuotationMarksAndRoundTripDa
{
const string Name = "name";
DateTimeOffset value = DateTimeOffset.UtcNow;
- new JsonWriter(stringWriter).WriteProperty(Name, value);
+ new JsonSerializationWriter(stringWriter).WriteProperty(Name, value);
string expectedValue = value.ToString("o", CultureInfo.InvariantCulture);
Assert.AreEqual("\"" + Name + "\":\"" + expectedValue + "\"", stringWriter.ToString());
}
@@ -252,7 +252,7 @@ public void WritePropertyDateTimeOffsetDoesNothingIfValueIsNullBecauseItAssumesP
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (DateTimeOffset?)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (DateTimeOffset?)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -266,7 +266,7 @@ public void WritePropertyIDictionaryDoubleWritesPropertyNameFollowedByValuesInCu
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var writer = new JsonWriter(stringWriter);
+ var writer = new JsonSerializationWriter(stringWriter);
writer.WriteProperty("name", new Dictionary { { "key1", 1 } });
AssertEx.StartsWith("\"name\":{", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
AssertEx.EndsWith("}", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
@@ -278,7 +278,7 @@ public void WritePropertyIDictionaryDoubleWritesValuesWithoutDoubleQuotes()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var writer = new JsonWriter(stringWriter);
+ var writer = new JsonSerializationWriter(stringWriter);
writer.WriteProperty("name", new Dictionary { { "key1", 1 } });
AssertEx.Contains("\"key1\":1", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
@@ -289,7 +289,7 @@ public void WritePropertyIDictionaryDoubleDoesNothingWhenDictionaryIsNullBecause
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (IDictionary)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (IDictionary)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -299,7 +299,7 @@ public void WritePropertyIDictionaryDoubleDoesNothingWhenDictionaryIsEmptyBecaus
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", new Dictionary());
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", new Dictionary());
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -313,7 +313,7 @@ public void WritePropertyIDictionaryStringStringWritesPropertyNameFollowedByValu
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var writer = new JsonWriter(stringWriter);
+ var writer = new JsonSerializationWriter(stringWriter);
writer.WriteProperty("name", new Dictionary { { "key1", "1" } });
AssertEx.StartsWith("\"name\":{", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
AssertEx.EndsWith("}", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
@@ -325,7 +325,7 @@ public void WritePropertyIDictionaryStringStringWritesValuesWithoutDoubleQuotes(
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var writer = new JsonWriter(stringWriter);
+ var writer = new JsonSerializationWriter(stringWriter);
writer.WriteProperty("name", new Dictionary { { "key1", "1" } });
AssertEx.Contains("\"key1\":\"1\"", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
@@ -336,7 +336,7 @@ public void WritePropertyIDictionaryStringStringDoesNothingWhenDictionaryIsNullB
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", (IDictionary)null);
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", (IDictionary)null);
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -346,7 +346,7 @@ public void WritePropertyIDictionaryStringStringDoesNothingWhenDictionaryIsEmpty
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new JsonWriter(stringWriter).WriteProperty("name", new Dictionary());
+ new JsonSerializationWriter(stringWriter).WriteProperty("name", new Dictionary());
Assert.AreEqual(string.Empty, stringWriter.ToString());
}
}
@@ -360,7 +360,7 @@ public void WritePropertyNameWritesPropertyNameEnclosedInDoubleQuotationMarksFol
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- new TestableJsonWriter(stringWriter).WritePropertyName("TestProperty");
+ new TestableJsonSerializationWriter(stringWriter).WritePropertyName("TestProperty");
Assert.AreEqual("\"TestProperty\":", stringWriter.ToString());
}
}
@@ -370,9 +370,9 @@ public void WritePropertyNamePrependsPropertyNameWithComaWhenCurrentObjectAlread
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WritePropertyName("Property1");
- jsonWriter.WritePropertyName("Property2");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WritePropertyName("Property1");
+ JsonSerializationWriter.WritePropertyName("Property2");
AssertEx.Contains(",\"Property2\"", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -382,10 +382,10 @@ public void WritePropertyNameDoesNotPrependPropertyNameWithComaWhenNewObjectWasS
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WritePropertyName("Property1");
- jsonWriter.WriteStartObject();
- jsonWriter.WritePropertyName("Property2");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WritePropertyName("Property1");
+ JsonSerializationWriter.WriteStartObject();
+ JsonSerializationWriter.WritePropertyName("Property2");
AssertEx.Contains("{\"Property2\"", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -395,8 +395,8 @@ public void WritePropertyNameThrowsArgumentExceptionWhenPropertyNameIsEmptyToPre
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new JsonWriter(stringWriter);
- AssertEx.Throws(() => jsonWriter.WritePropertyName(string.Empty));
+ var JsonSerializationWriter = new JsonSerializationWriter(stringWriter);
+ AssertEx.Throws(() => JsonSerializationWriter.WritePropertyName(string.Empty));
}
}
@@ -409,8 +409,8 @@ public void WriteStringEscapesQuotationMark()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteString("Test\"Value");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteString("Test\"Value");
AssertEx.Contains("Test\\\"Value", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -420,8 +420,8 @@ public void WriteStringEscapesBackslash()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteString("Test\\Value");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteString("Test\\Value");
AssertEx.Contains("Test\\\\Value", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -431,8 +431,8 @@ public void WriteStringEscapesBackspace()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteString("Test\bValue");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteString("Test\bValue");
AssertEx.Contains("Test\\bValue", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -442,8 +442,8 @@ public void WriteStringEscapesFormFeed()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteString("Test\fValue");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteString("Test\fValue");
AssertEx.Contains("Test\\fValue", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -453,8 +453,8 @@ public void WriteStringEscapesNewline()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteProperty("name", "Test\nValue");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteProperty("name", "Test\nValue");
AssertEx.Contains("Test\\nValue", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -464,8 +464,8 @@ public void WriteStringEscapesCarriageReturn()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteProperty("name", "Test\rValue");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteProperty("name", "Test\rValue");
AssertEx.Contains("Test\\rValue", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -475,17 +475,17 @@ public void WriteStringEscapesHorizontalTab()
{
using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture))
{
- var jsonWriter = new TestableJsonWriter(stringWriter);
- jsonWriter.WriteProperty("name", "Test\tValue");
+ var JsonSerializationWriter = new TestableJsonSerializationWriter(stringWriter);
+ JsonSerializationWriter.WriteProperty("name", "Test\tValue");
AssertEx.Contains("Test\\tValue", stringWriter.ToString(), StringComparison.OrdinalIgnoreCase);
}
}
#endregion
- private class TestableJsonWriter : JsonWriter
+ private class TestableJsonSerializationWriter : JsonSerializationWriter
{
- public TestableJsonWriter(TextWriter textWriter)
+ public TestableJsonSerializationWriter(TextWriter textWriter)
: base(textWriter)
{
}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/MyTestExtension.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/MyTestExtension.cs
new file mode 100644
index 0000000000..dcf4851579
--- /dev/null
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/MyTestExtension.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation
+{
+ public class MyTestExtension : IExtension
+ {
+ public int myIntField;
+ public string myStringField;
+
+ public IExtension DeepClone()
+ {
+ var other = new MyTestExtension();
+ other.myIntField = this.myIntField;
+ other.myStringField = this.myStringField;
+
+ return other;
+ }
+
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("myIntField", myIntField);
+ serializationWriter.WriteProperty("myStringField", myStringField);
+ }
+ }
+}
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/RichPayloadEventSourceTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/RichPayloadEventSourceTest.cs
index d6ce49935f..8e695667d6 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/RichPayloadEventSourceTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/Implementation/RichPayloadEventSourceTest.cs
@@ -63,7 +63,7 @@ public void RichPayloadEventSourceEventSentTest()
public void RichPayloadEventSourceExceptionSentTest()
{
var exceptionTelemetry = new ExceptionTelemetry(new SystemException("Test"));
- exceptionTelemetry.Data.exceptions[0].parsedStack = new External.StackFrame[] { new External.StackFrame() };
+ exceptionTelemetry.Data.Data.exceptions[0].parsedStack = new External.StackFrame[] { new External.StackFrame() };
this.DoTracking(
RichPayloadEventSource.Keywords.Exceptions,
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/TelemetryConfigurationFactoryTest.cs b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/TelemetryConfigurationFactoryTest.cs
index 514fd90b4b..8809b943ab 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/TelemetryConfigurationFactoryTest.cs
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Extensibility/TelemetryConfigurationFactoryTest.cs
@@ -328,6 +328,14 @@ public void LoadInstanceConvertsValueToExpectedTypeGivenXmlDefinitionWithNoChild
object instance = TestableTelemetryConfigurationFactory.LoadInstance(definition, typeof(int), null, null);
Assert.AreEqual(42, instance);
}
+
+ [TestMethod]
+ public void LoadInstanceConvertsValueToExpectedTypeGivenXmlDefinitionWithNoChildElementsParseHexValue()
+ {
+ var definition = new XElement("Definition", "0x42");
+ object instance = TestableTelemetryConfigurationFactory.LoadInstance(definition, typeof(int), null, null);
+ Assert.AreEqual(66, instance);
+ }
[TestMethod]
public void LoadInstanceTrimsValueOfGivenXmlElementToIgnoreWhitespaceUsersMayAddToConfiguration()
diff --git a/Test/Microsoft.ApplicationInsights.Test/Shared/Microsoft.ApplicationInsights.Shared.Tests.projitems b/Test/Microsoft.ApplicationInsights.Test/Shared/Microsoft.ApplicationInsights.Shared.Tests.projitems
index 28b848cd0b..a3c10ad4b4 100644
--- a/Test/Microsoft.ApplicationInsights.Test/Shared/Microsoft.ApplicationInsights.Shared.Tests.projitems
+++ b/Test/Microsoft.ApplicationInsights.Test/Shared/Microsoft.ApplicationInsights.Shared.Tests.projitems
@@ -10,6 +10,9 @@
+
+
+
@@ -113,7 +116,7 @@
-
+
diff --git a/Test/ServerTelemetryChannel.Test/Shared.Tests/Implementation/TelemetrySerializerTest.cs b/Test/ServerTelemetryChannel.Test/Shared.Tests/Implementation/TelemetrySerializerTest.cs
index 58ff199930..7080b04227 100644
--- a/Test/ServerTelemetryChannel.Test/Shared.Tests/Implementation/TelemetrySerializerTest.cs
+++ b/Test/ServerTelemetryChannel.Test/Shared.Tests/Implementation/TelemetrySerializerTest.cs
@@ -101,7 +101,7 @@ public void EnqueuesTransmissionWithExpectedProperties()
Assert.AreEqual(serializer.EndpointAddress, transmission.EndpointAddress);
Assert.AreEqual("application/x-json-stream", transmission.ContentType);
Assert.AreEqual("gzip", transmission.ContentEncoding);
- Assert.AreEqual(string.Empty, Unzip(transmission.Content));
+ Assert.AreEqual("{}", Unzip(transmission.Content));
}
[TestMethod]
diff --git a/Test/TestFramework/Shared/StubTelemetry.cs b/Test/TestFramework/Shared/StubTelemetry.cs
index a012bae7fe..c18b02a892 100644
--- a/Test/TestFramework/Shared/StubTelemetry.cs
+++ b/Test/TestFramework/Shared/StubTelemetry.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
internal sealed class StubTelemetry : ITelemetry, ISupportProperties
@@ -25,6 +26,7 @@ public StubTelemetry()
public TelemetryContext Context { get; set; }
public IDictionary Properties { get; set; }
+ public IExtension Extension { get; set; }
public void Serialize(IJsonWriter writer)
{
@@ -44,5 +46,15 @@ public void SendEvent(object writer)
{
this.OnSendEvent(writer);
}
+
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+
+ }
+
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+
+ }
}
}
diff --git a/docs/ServerTelemetryChannel error handling.md b/docs/ServerTelemetryChannel error handling.md
index c3d7763c82..50351824f6 100644
--- a/docs/ServerTelemetryChannel error handling.md
+++ b/docs/ServerTelemetryChannel error handling.md
@@ -50,8 +50,8 @@ Notes:
* This policy handles failures with status codes 408, 500, 503
* "Set timer to restore capacity using Retry-After or exponential backoff" means that
* We check that Retry-After header is present. In the header we expect to get TimeSpan. Timer is set to restore capacity after this interval. (Note that with current backend implementation Retry-After is never returned for 408, 500, 503).
- * If Retry-After header is not present we check how many consecutive errors occured so far and use exponential backoff algorythm to set a timer to restore capacity. Exponential backoff algorythm description: http://en.wikipedia.org/wiki/Exponential_backoff
-* We do not update number of consecutive errors if it was recently updated because we have mupliple sender that most likely to fail at the same time for intermittent issues.
+ * If Retry-After header is not present we check how many y consecutive errors occurred so far and use exponential backoff algorythm to set a timer to restore capacity. Exponential backoff algorythm description: http://en.wikipedia.org/wiki/Exponential_backoff
+* We do not update number of consecutive errors if it was recently updated because we have multiple sender that most likely to fail at the same time for intermittent issues.
![Img](./images/ErrorHandlingPolicy.PNG)
@@ -72,7 +72,7 @@ Notes:
### [NetworkAvailabilityTransmissionPolicy](https://github.com/Microsoft/ApplicationInsights-dotnet/blob/master/src/TelemetryChannels/ServerTelemetryChannel/Shared/Implementation/NetworkAvailabilityTransmissionPolicy.cs)
-This policy subscribes to the [network change event](https://msdn.microsoft.com/en-us/library/system.net.networkinformation.networkchange.networkaddresschanged%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396). When network becomes unavailable sender and buffer capacity are set to 0. Note that consecutive errors count that affects exponental backoff logic is not changed.
+This policy subscribes to the [network change event](https://msdn.microsoft.com/en-us/library/system.net.networkinformation.networkchange.networkaddresschanged%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396). When network becomes unavailable sender and buffer capacity are set to 0. Note that consecutive errors count that affects exponential backoff logic is not changed.
### [ApplicationLifecycleTransmissionPolicy](https://github.com/Microsoft/ApplicationInsights-dotnet/blob/master/src/TelemetryChannels/ServerTelemetryChannel/Shared/Implementation/ApplicationLifecycleTransmissionPolicy.cs)
diff --git a/src/Microsoft.ApplicationInsights/Channel/ITelemetry.cs b/src/Microsoft.ApplicationInsights/Channel/ITelemetry.cs
index d4043ad045..a33e48e4e4 100644
--- a/src/Microsoft.ApplicationInsights/Channel/ITelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/Channel/ITelemetry.cs
@@ -2,6 +2,7 @@
{
using System;
using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Extensibility;
///
/// The base telemetry type for application insights.
@@ -18,6 +19,12 @@ public interface ITelemetry
///
TelemetryContext Context { get; }
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strongly
+ /// typed object.
+ ///
+ IExtension Extension { get; set; }
+
///
/// Gets or sets the value that defines absolute order of the telemetry item.
///
@@ -43,5 +50,10 @@ public interface ITelemetry
///
/// The cloned object.
ITelemetry DeepClone();
+
+ ///
+ /// Writes serialization info about the data class of the implementing type using the given
+ ///
+ void SerializeData(ISerializationWriter serializationWriter);
}
}
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/AvailabilityTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/AvailabilityTelemetry.cs
index 8c0409cfd0..188a0caac1 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/AvailabilityTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/AvailabilityTelemetry.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Globalization;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -19,6 +20,7 @@ public sealed class AvailabilityTelemetry : ITelemetry, ISupportProperties, ISup
internal readonly string BaseType = typeof(AvailabilityData).Name;
internal readonly AvailabilityData Data;
private readonly TelemetryContext context;
+ private IExtension extension;
///
/// Initializes a new instance of the class with empty properties.
@@ -55,6 +57,7 @@ private AvailabilityTelemetry(AvailabilityTelemetry source)
this.context = source.context.DeepClone(this.Data.properties);
this.Sequence = source.Sequence;
this.Timestamp = source.Timestamp;
+ this.extension = source.extension?.DeepClone();
}
///
@@ -131,6 +134,15 @@ public TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets a dictionary of application-defined property names and values providing additional information about this availability test run.
/// Learn more
@@ -166,6 +178,12 @@ public ITelemetry DeepClone()
return new AvailabilityTelemetry(this);
}
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/DependencyTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/DependencyTelemetry.cs
index 55a7e0d86f..1f60edeab4 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/DependencyTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/DependencyTelemetry.cs
@@ -4,6 +4,7 @@ namespace Microsoft.ApplicationInsights.DataContracts
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
+ using System.Globalization;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
@@ -23,6 +24,7 @@ public sealed class DependencyTelemetry : OperationTelemetry, ITelemetry, ISuppo
internal readonly RemoteDependencyData InternalData;
private readonly TelemetryContext context;
+ private IExtension extension;
private IDictionary operationDetails;
private double? samplingPercentage;
@@ -98,6 +100,7 @@ private DependencyTelemetry(DependencyTelemetry source)
this.Timestamp = source.Timestamp;
this.samplingPercentage = source.samplingPercentage;
this.successFieldSet = source.successFieldSet;
+ this.extension = source.extension?.DeepClone();
// Only clone the details if the source has had details initialized
if (source.operationDetails != null)
@@ -124,6 +127,15 @@ public override TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strongly typed object.
+ ///
+ public override IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets Dependency ID.
///
@@ -329,6 +341,12 @@ public void SetOperationDetail(string key, object detail)
this.OperationDetails[key] = detail;
}
+ ///
+ public override void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.InternalData);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/EventTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/EventTelemetry.cs
index 172ce1fe19..2eea99a979 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/EventTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/EventTelemetry.cs
@@ -2,8 +2,10 @@
{
using System;
using System.Collections.Generic;
+ using System.Globalization;
using System.Threading;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -18,6 +20,7 @@ public sealed class EventTelemetry : ITelemetry, ISupportProperties, ISupportSam
internal readonly string BaseType = typeof(EventData).Name;
internal readonly EventData Data;
private readonly TelemetryContext context;
+ private IExtension extension;
private double? samplingPercentage;
@@ -45,6 +48,7 @@ private EventTelemetry(EventTelemetry source)
this.Sequence = source.Sequence;
this.Timestamp = source.Timestamp;
this.samplingPercentage = source.samplingPercentage;
+ this.extension = source.extension?.DeepClone();
}
///
@@ -65,6 +69,15 @@ public TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets the name of the event.
///
@@ -121,5 +134,11 @@ void ITelemetry.Sanitize()
this.Properties.SanitizeProperties();
this.Metrics.SanitizeMeasurements();
}
+
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
}
}
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/ExceptionDetailsInfo.cs b/src/Microsoft.ApplicationInsights/DataContracts/ExceptionDetailsInfo.cs
new file mode 100644
index 0000000000..059508196f
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/DataContracts/ExceptionDetailsInfo.cs
@@ -0,0 +1,64 @@
+namespace Microsoft.ApplicationInsights.DataContracts
+{
+ using System.Collections.Generic;
+ using System.Linq;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
+
+ ///
+ /// Wrapper class for that lets user gets/sets TypeName and Message.
+ ///
+ public sealed class ExceptionDetailsInfo
+ {
+ internal readonly ExceptionDetails InternalExceptionDetails = null;
+
+ ///
+ /// Constructs the instance of .
+ ///
+ /// Exception id.
+ /// Parent exception's id.
+ /// Type name for the exception.
+ /// Exception message.
+ /// Indicates that this exception has full stack information.
+ /// Exception's stack trace.
+ /// Exception's stack.
+ public ExceptionDetailsInfo(int id, int outerId, string typeName, string message, bool hasFullStack,
+ string stack, IEnumerable parsedStack)
+ {
+ this.InternalExceptionDetails = new ExceptionDetails()
+ {
+ id = id,
+ outerId = outerId,
+ typeName = typeName,
+ message = message,
+ hasFullStack = hasFullStack,
+ stack = stack,
+ parsedStack = parsedStack.Select(ps => ps.Data).ToList()
+ };
+ }
+
+ internal ExceptionDetailsInfo(ExceptionDetails exceptionDetails)
+ {
+ this.InternalExceptionDetails = exceptionDetails;
+ }
+
+ ///
+ /// Gets or sets type name of the underlying that this object represents.
+ ///
+ public string TypeName
+ {
+ get => this.InternalExceptionDetails.typeName;
+ set => this.InternalExceptionDetails.typeName = value;
+ }
+
+ ///
+ /// Gets or sets message name of the underlying that this object represents.
+ ///
+ public string Message
+ {
+ get => this.InternalExceptionDetails.message;
+ set => this.InternalExceptionDetails.message = value;
+ }
+
+ internal ExceptionDetails ExceptionDetails => this.InternalExceptionDetails;
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/ExceptionInfo.cs b/src/Microsoft.ApplicationInsights/DataContracts/ExceptionInfo.cs
new file mode 100644
index 0000000000..869a84a56d
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/DataContracts/ExceptionInfo.cs
@@ -0,0 +1,85 @@
+namespace Microsoft.ApplicationInsights.DataContracts
+{
+ using System.Collections.Concurrent;
+ using System.Collections.Generic;
+ using System.Linq;
+ using Extensibility.Implementation;
+ using Extensibility.Implementation.External;
+
+ ///
+ /// Wrapper class for that lets user provide exception data without having the actual Exception object.
+ ///
+ internal sealed class ExceptionInfo
+ {
+ private readonly ExceptionData data;
+
+ ///
+ /// Constructs the instance of
+ ///
+ public ExceptionInfo(IEnumerable exceptionDetailsInfoList, SeverityLevel? severityLevel, string problemId,
+ IDictionary properties, IDictionary measurements)
+ {
+ this.data = new ExceptionData
+ {
+ exceptions = exceptionDetailsInfoList.Select(edi => edi.ExceptionDetails).ToList(),
+ severityLevel = severityLevel.TranslateSeverityLevel(),
+ problemId = problemId,
+ properties = new ConcurrentDictionary(properties),
+ measurements = new ConcurrentDictionary(measurements)
+ };
+ }
+
+ internal ExceptionInfo(ExceptionData data)
+ {
+ this.data = data;
+ }
+
+ ///
+ /// Gets a list of to modify as needed.
+ ///
+ public IReadOnlyList ExceptionDetailsInfoList => this.data.exceptions.Select(ed => new ExceptionDetailsInfo(ed)).ToList().AsReadOnly();
+
+ ///
+ /// Gets or sets Exception severity level.
+ ///
+ public SeverityLevel? SeverityLevel
+ {
+ get => this.data.severityLevel.TranslateSeverityLevel();
+ set => this.data.severityLevel = value.TranslateSeverityLevel();
+ }
+
+ ///
+ /// Gets or sets problem id.
+ ///
+ public string ProblemId
+ {
+ get => this.data.problemId;
+ set => this.data.problemId = value;
+ }
+
+ ///
+ /// Gets or sets properties collection.
+ ///
+ public IDictionary Properties
+ {
+ get => this.data.properties;
+ set => this.data.properties = value;
+ }
+
+ ///
+ /// Gets or sets measurements collection.
+ ///
+ public IDictionary Measurements
+ {
+ get => this.data.measurements;
+ set => this.data.measurements = value;
+ }
+
+ internal ExceptionData Data => this.data;
+
+ internal ExceptionInfo DeepClone()
+ {
+ return new ExceptionInfo(this.data.DeepClone());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs
index 75fafb93ec..ae762674aa 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/ExceptionTelemetry.cs
@@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+ using System.Linq;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -15,12 +17,14 @@ public sealed class ExceptionTelemetry : ITelemetry, ISupportProperties, ISuppor
{
internal const string TelemetryName = "Exception";
internal readonly string BaseType = typeof(ExceptionData).Name;
- internal readonly ExceptionData Data;
+ internal ExceptionInfo Data = null;
- private readonly TelemetryContext context;
+ private readonly bool isCreatedFromExceptionInfo = false;
+
+ private TelemetryContext context;
+ private IExtension extension;
private Exception exception;
private string message;
-
private double? samplingPercentage;
///
@@ -28,8 +32,8 @@ public sealed class ExceptionTelemetry : ITelemetry, ISupportProperties, ISuppor
///
public ExceptionTelemetry()
{
- this.Data = new ExceptionData();
- this.context = new TelemetryContext(this.Data.properties);
+ this.Data = new ExceptionInfo(new ExceptionData());
+ this.context = new TelemetryContext(this.Data.Properties);
}
///
@@ -47,18 +51,47 @@ public ExceptionTelemetry(Exception exception)
this.Exception = exception;
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Exception info.
+ /// Severity level.
+ /// Problem id.
+ /// Properties.
+ /// Measurements.
+ public ExceptionTelemetry(IEnumerable exceptionDetailsInfoList, SeverityLevel? severityLevel, string problemId,
+ IDictionary properties, IDictionary measurements)
+ {
+ this.isCreatedFromExceptionInfo = true;
+
+ ExceptionInfo exceptionInfo = new ExceptionInfo(exceptionDetailsInfoList, severityLevel, problemId, properties, measurements);
+
+ this.Data = exceptionInfo;
+ this.context = new TelemetryContext(this.Data.Properties);
+
+ this.UpdateData(exceptionInfo);
+ }
+
///
/// Initializes a new instance of the class by cloning an existing instance.
///
/// Source instance of to clone from.
private ExceptionTelemetry(ExceptionTelemetry source)
{
+ this.isCreatedFromExceptionInfo = source.isCreatedFromExceptionInfo;
+
this.Data = source.Data.DeepClone();
- this.context = source.context.DeepClone(this.Data.properties);
+ this.context = source.context.DeepClone(this.Data.Properties);
this.Sequence = source.Sequence;
this.Timestamp = source.Timestamp;
this.samplingPercentage = source.samplingPercentage;
- this.Exception = source.Exception;
+
+ if (!this.isCreatedFromExceptionInfo)
+ {
+ this.exception = source.Exception;
+ }
+
+ this.extension = source.extension?.DeepClone();
}
///
@@ -79,6 +112,15 @@ public TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets the problemId.
///
@@ -86,12 +128,12 @@ public string ProblemId
{
get
{
- return this.Data.problemId;
+ return this.Data.ProblemId;
}
set
{
- this.Data.problemId = value;
+ this.Data.ProblemId = value;
}
}
@@ -125,13 +167,22 @@ public Exception Exception
{
get
{
- return this.exception;
+ return this.isCreatedFromExceptionInfo
+ ? throw new InvalidOperationException(
+ "The property is unavailable on an instance created from an ExceptionInfo object")
+ : this.exception;
}
set
{
+ if (this.isCreatedFromExceptionInfo)
+ {
+ throw new InvalidOperationException(
+ "The property is unavailable on an instance created from an ExceptionInfo object");
+ }
+
this.exception = value;
- this.UpdateExceptions(value);
+ this.UpdateData(value);
}
}
@@ -142,20 +193,29 @@ public string Message
{
get
{
- return this.message;
+ return this.isCreatedFromExceptionInfo
+ ? throw new InvalidOperationException(
+ "The property is unavailable on an instance created from an ExceptionInfo object")
+ : this.message;
}
set
{
+ if (this.isCreatedFromExceptionInfo)
+ {
+ throw new InvalidOperationException(
+ "The property is unavailable on an instance created from an ExceptionInfo object");
+ }
+
this.message = value;
- if (this.Data.exceptions != null && this.Data.exceptions.Count > 0)
+ if (this.Data.ExceptionDetailsInfoList != null && this.Data.ExceptionDetailsInfoList.Count > 0)
{
- this.Data.exceptions[0].message = value;
+ this.Data.ExceptionDetailsInfoList[0].Message = value;
}
else
{
- this.UpdateExceptions(this.Exception);
+ this.UpdateData(this.Exception);
}
}
}
@@ -166,16 +226,22 @@ public string Message
///
public IDictionary Metrics
{
- get { return this.Data.measurements; }
+ get { return this.Data.Measurements; }
}
+ ///
+ /// Gets the list of . User can modify the contents of individual object, but
+ /// not the list itself.
+ ///
+ public IReadOnlyList ExceptionDetailsInfoList => this.Data.ExceptionDetailsInfoList;
+
///
/// Gets a dictionary of application-defined property names and values providing additional information about this exception.
/// Learn more
///
public IDictionary Properties
{
- get { return this.Data.properties; }
+ get { return this.Data.Properties; }
}
///
@@ -183,8 +249,8 @@ public IDictionary Properties
///
public SeverityLevel? SeverityLevel
{
- get { return this.Data.severityLevel.TranslateSeverityLevel(); }
- set { this.Data.severityLevel = value.TranslateSeverityLevel(); }
+ get => this.Data.SeverityLevel;
+ set => this.Data.SeverityLevel = value;
}
///
@@ -199,7 +265,7 @@ public SeverityLevel? SeverityLevel
internal IList Exceptions
{
- get { return this.Data.exceptions; }
+ get { return this.Data.Data.exceptions; }
}
///
@@ -211,25 +277,29 @@ public ITelemetry DeepClone()
return new ExceptionTelemetry(this);
}
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data.Data);
+ }
+
///
/// Set parsedStack from an array of StackFrame objects.
///
public void SetParsedStack(System.Diagnostics.StackFrame[] frames)
{
- List orderedStackTrace = new List();
-
if (this.Exceptions != null && this.Exceptions.Count > 0)
{
if (frames != null && frames.Length > 0)
{
int stackLength = 0;
- this.Exceptions[0].parsedStack = new List();
+ this.Exceptions[0].parsedStack = new List();
this.Exceptions[0].hasFullStack = true;
for (int level = 0; level < frames.Length; level++)
{
- StackFrame sf = ExceptionConverter.GetStackFrame(frames[level], level);
+ var sf = ExceptionConverter.GetStackFrame(frames[level], level);
stackLength += ExceptionConverter.GetStackFrameLength(sf);
@@ -286,8 +356,13 @@ private void ConvertExceptionTree(Exception exception, ExceptionDetails parentEx
}
}
- private void UpdateExceptions(Exception exception)
+ private void UpdateData(Exception exception)
{
+ if (this.isCreatedFromExceptionInfo)
+ {
+ throw new InvalidOperationException("Operation is not supported given the state of the object.");
+ }
+
// collect the set of exceptions detail info from the passed in exception
List exceptions = new List();
this.ConvertExceptionTree(exception, null, exceptions);
@@ -297,21 +372,36 @@ private void UpdateExceptions(Exception exception)
{
// TODO: when we localize these messages, we should consider not using InvariantCulture
// create our "message" exception.
- InnerExceptionCountExceededException countExceededException = new InnerExceptionCountExceededException(
- string.Format(
- CultureInfo.InvariantCulture,
- "The number of inner exceptions was {0} which is larger than {1}, the maximum number allowed during transmission. All but the first {1} have been dropped.",
- exceptions.Count,
- Constants.MaxExceptionCountToSave));
+ InnerExceptionCountExceededException countExceededException =
+ new InnerExceptionCountExceededException(
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "The number of inner exceptions was {0} which is larger than {1}, the maximum number allowed during transmission. All but the first {1} have been dropped.",
+ exceptions.Count,
+ Constants.MaxExceptionCountToSave));
// remove all but the first N exceptions
- exceptions.RemoveRange(Constants.MaxExceptionCountToSave, exceptions.Count - Constants.MaxExceptionCountToSave);
+ exceptions.RemoveRange(Constants.MaxExceptionCountToSave,
+ exceptions.Count - Constants.MaxExceptionCountToSave);
// we'll add our new exception and parent it to the root exception (first one in the list)
exceptions.Add(ExceptionConverter.ConvertToExceptionDetails(countExceededException, exceptions[0]));
}
- this.Data.exceptions = exceptions;
+ this.Data = new ExceptionInfo(exceptions.Select(ex => new ExceptionDetailsInfo(ex)), this.SeverityLevel,
+ this.ProblemId, this.Properties, this.Metrics);
+ this.context = new TelemetryContext(this.Data.Properties);
+ }
+
+ private void UpdateData(ExceptionInfo exceptionInfo)
+ {
+ if (!this.isCreatedFromExceptionInfo)
+ {
+ throw new InvalidOperationException("Operation is not supported given the state of the object.");
+ }
+
+ this.Data = exceptionInfo ?? throw new ArgumentNullException(nameof(exceptionInfo));
+ this.context = new TelemetryContext(this.Data.Properties);
}
}
}
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/MetricTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/MetricTelemetry.cs
index a936256af0..d62d5331a9 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/MetricTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/MetricTelemetry.cs
@@ -3,7 +3,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+ using System.Globalization;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -15,10 +17,10 @@ public sealed class MetricTelemetry : ITelemetry, ISupportProperties
{
internal const string TelemetryName = "Metric";
- internal readonly string BaseType = typeof(MetricData).Name;
-
+ internal readonly string BaseType = typeof(MetricData).Name;
internal readonly MetricData Data;
internal readonly DataPoint Metric;
+ private IExtension extension;
///
/// Initializes a new instance of the class with empty
@@ -131,6 +133,7 @@ private MetricTelemetry(MetricTelemetry source)
this.Context = source.Context.DeepClone(this.Data.properties);
this.Sequence = source.Sequence;
this.Timestamp = source.Timestamp;
+ this.extension = source.extension?.DeepClone();
}
///
@@ -148,6 +151,15 @@ private MetricTelemetry(MetricTelemetry source)
///
public TelemetryContext Context { get; }
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets the name of the metric.
///
@@ -239,6 +251,12 @@ public ITelemetry DeepClone()
return new MetricTelemetry(this);
}
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/PageViewPerformanceTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/PageViewPerformanceTelemetry.cs
new file mode 100644
index 0000000000..ee0f9995b7
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/DataContracts/PageViewPerformanceTelemetry.cs
@@ -0,0 +1,234 @@
+namespace Microsoft.ApplicationInsights.DataContracts
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation;
+ using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
+
+ ///
+ /// Telemetry type used to track page load performance.
+ ///
+ public sealed class PageViewPerformanceTelemetry : ITelemetry, ISupportProperties, ISupportSampling
+ {
+ internal const string TelemetryName = "PageViewPerformance";
+
+ internal const string BaseType = "PageViewPerformanceData";
+
+ internal readonly PageViewPerfData Data;
+ private IExtension extension;
+ private double? samplingPercentage;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public PageViewPerformanceTelemetry()
+ {
+ this.Data = new PageViewPerfData();
+ this.Context = new TelemetryContext(this.Data.properties);
+ }
+
+ ///
+ /// Initializes a new instance of the class with the
+ /// specified .
+ ///
+ /// The is null or empty string.
+ public PageViewPerformanceTelemetry(string pageName) : this()
+ {
+ this.Name = pageName;
+ }
+
+ ///
+ /// Initializes a new instance of the class by cloning an existing instance.
+ ///
+ /// Source instance of to clone from.
+ private PageViewPerformanceTelemetry(PageViewPerformanceTelemetry source)
+ {
+ this.Data = source.Data.DeepClone();
+ this.Context = source.Context.DeepClone(this.Data.properties);
+ this.extension = source.extension?.DeepClone();
+ }
+
+ ///
+ /// Gets or sets date and time when event was recorded.
+ ///
+ public DateTimeOffset Timestamp { get; set; }
+
+ ///
+ /// Gets or sets the value that defines absolute order of the telemetry item.
+ ///
+ public string Sequence { get; set; }
+
+ ///
+ /// Gets the context associated with the current telemetry item.
+ ///
+ public TelemetryContext Context { get; private set; }
+
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
+ ///
+ /// Gets or sets page view ID.
+ ///
+ public string Id
+ {
+ get { return this.Data.id; }
+ set { this.Data.id = value; }
+ }
+
+ ///
+ /// Gets or sets the name of the page.
+ ///
+ public string Name
+ {
+ get { return this.Data.name; }
+ set { this.Data.name = value; }
+ }
+
+ ///
+ /// Gets or sets the page view Uri.
+ ///
+ public Uri Url
+ {
+ get
+ {
+ if (this.Data.url.IsNullOrWhiteSpace())
+ {
+ return null;
+ }
+
+ return new Uri(this.Data.url, UriKind.RelativeOrAbsolute);
+ }
+
+ set
+ {
+ if (value == null)
+ {
+ this.Data.url = null;
+ }
+ else
+ {
+ this.Data.url = value.ToString();
+ }
+ }
+ }
+
+ ///
+ /// Gets or sets the page view duration.
+ ///
+ public TimeSpan Duration
+ {
+ get { return Utils.ValidateDuration(this.Data.duration); }
+ set { this.Data.duration = value.ToString(); }
+ }
+
+ ///
+ /// Gets or sets the page DOM processing time.
+ ///
+ public TimeSpan DomProcessing
+ {
+ get { return Utils.ValidateDuration(this.Data.domProcessing); }
+ set { this.Data.domProcessing = value.ToString(); }
+ }
+
+ ///
+ /// Gets or sets the page loading total time.
+ ///
+ public TimeSpan PerfTotal
+ {
+ get { return Utils.ValidateDuration(this.Data.perfTotal); }
+ set { this.Data.perfTotal = value.ToString(); }
+ }
+
+ ///
+ /// Gets or sets the page load network time.
+ ///
+ public TimeSpan NetworkConnect
+ {
+ get { return Utils.ValidateDuration(this.Data.networkConnect); }
+ set { this.Data.networkConnect = value.ToString(); }
+ }
+
+ ///
+ /// Gets or sets the page load send request time.
+ ///
+ public TimeSpan SentRequest
+ {
+ get { return Utils.ValidateDuration(this.Data.sentRequest); }
+ set { this.Data.sentRequest = value.ToString(); }
+ }
+
+ ///
+ /// Gets or sets the page load recieve response duration.
+ ///
+ public TimeSpan ReceivedResponse
+ {
+ get { return Utils.ValidateDuration(this.Data.receivedResponse); }
+ set { this.Data.receivedResponse = value.ToString(); }
+ }
+
+ ///
+ /// Gets a dictionary of custom defined metrics.
+ /// Learn more
+ ///
+ public IDictionary Metrics
+ {
+ get { return this.Data.measurements; }
+ }
+
+ ///
+ /// Gets a dictionary of application-defined property names and values providing additional information about this page view.
+ /// Learn more
+ ///
+ public IDictionary Properties
+ {
+ get { return this.Data.properties; }
+ }
+
+ ///
+ /// Gets or sets data sampling percentage (between 0 and 100).
+ /// Should be 100/n where n is an integer. Learn more
+ ///
+ double? ISupportSampling.SamplingPercentage
+ {
+ get { return this.samplingPercentage; }
+ set { this.samplingPercentage = value; }
+ }
+
+ ///
+ /// Deeply clones a object.
+ ///
+ /// A cloned instance.
+ public ITelemetry DeepClone()
+ {
+ return new PageViewPerformanceTelemetry(this);
+ }
+
+ ///
+ /// Sanitizes the properties based on constraints.
+ ///
+ void ITelemetry.Sanitize()
+ {
+ this.Name = this.Name.SanitizeName();
+ this.Name = Utils.PopulateRequiredStringValue(this.Name, "name", typeof(PageViewTelemetry).FullName);
+ this.Properties.SanitizeProperties();
+ this.Metrics.SanitizeMeasurements();
+ this.Url = this.Url.SanitizeUri();
+ this.Id.SanitizeName();
+ }
+
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/PageViewTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/PageViewTelemetry.cs
index a5442dd0a1..fd7fc7c654 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/PageViewTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/PageViewTelemetry.cs
@@ -5,6 +5,7 @@
using System.Globalization;
using System.Threading;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -21,10 +22,10 @@ public sealed class PageViewTelemetry : ITelemetry, ISupportProperties, ISupport
{
internal const string TelemetryName = "PageView";
- internal readonly string BaseType = typeof(PageViewData).Name;
-
+ internal readonly string BaseType = typeof(PageViewData).Name;
internal readonly PageViewData Data;
private readonly TelemetryContext context;
+ private IExtension extension;
private double? samplingPercentage;
@@ -55,6 +56,7 @@ private PageViewTelemetry(PageViewTelemetry source)
{
this.Data = source.Data.DeepClone();
this.context = source.context.DeepClone(this.Data.properties);
+ this.extension = source.extension?.DeepClone();
}
///
@@ -75,6 +77,15 @@ public TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets page view ID.
///
@@ -167,6 +178,12 @@ public ITelemetry DeepClone()
return new PageViewTelemetry(this);
}
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/PerformanceCounterTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/PerformanceCounterTelemetry.cs
index 7c89011484..62854cf869 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/PerformanceCounterTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/PerformanceCounterTelemetry.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
///
/// The class that represents information about performance counters.
@@ -11,8 +12,7 @@
[Obsolete("Use MetricTelemetry instead.")]
public sealed class PerformanceCounterTelemetry : ITelemetry, ISupportProperties
{
- internal readonly MetricTelemetry Data;
-
+ internal readonly MetricTelemetry Data;
private string categoryName = string.Empty;
private string counterName = string.Empty;
@@ -94,6 +94,15 @@ public TelemetryContext Context
}
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.Data.Extension; }
+ set { this.Data.Extension = value; }
+ }
+
///
/// Gets or sets the counter value.
///
@@ -183,6 +192,12 @@ public ITelemetry DeepClone()
return new PerformanceCounterTelemetry(this);
}
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ this.Data.SerializeData(serializationWriter);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/RequestTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/RequestTelemetry.cs
index 12f65d7267..76192ac44d 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/RequestTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/RequestTelemetry.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Globalization;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -24,7 +25,7 @@ public sealed class RequestTelemetry : OperationTelemetry, ITelemetry, ISupportP
internal readonly RequestData Data;
private readonly TelemetryContext context;
private bool successFieldSet;
-
+ private IExtension extension;
private double? samplingPercentage;
///
@@ -62,6 +63,7 @@ private RequestTelemetry(RequestTelemetry source)
this.Sequence = source.Sequence;
this.Timestamp = source.Timestamp;
this.successFieldSet = source.successFieldSet;
+ this.extension = source.extension?.DeepClone();
}
///
@@ -82,6 +84,15 @@ public override TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public override IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets Request ID.
///
@@ -224,6 +235,12 @@ public override ITelemetry DeepClone()
return new RequestTelemetry(this);
}
+ ///
+ public override void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/SessionStateTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/SessionStateTelemetry.cs
index 6079268db8..ff23946a4d 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/SessionStateTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/SessionStateTelemetry.cs
@@ -2,6 +2,7 @@
{
using System;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
///
/// Telemetry type used to track user sessions.
@@ -67,6 +68,15 @@ public TelemetryContext Context
get { return this.Data.Context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.Data.Extension; }
+ set { this.Data.Extension = value; }
+ }
+
///
/// Gets or sets the value that defines absolute order of the telemetry item.
///
@@ -129,5 +139,11 @@ void ITelemetry.Sanitize()
{
((ITelemetry)this.Data).Sanitize();
}
+
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ this.Data.SerializeData(serializationWriter);
+ }
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/StackFrame.cs b/src/Microsoft.ApplicationInsights/DataContracts/StackFrame.cs
new file mode 100644
index 0000000000..b2755741dc
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/DataContracts/StackFrame.cs
@@ -0,0 +1,27 @@
+namespace Microsoft.ApplicationInsights.DataContracts
+{
+ using System;
+
+ ///
+ /// Wrapper class for for API exposure.
+ ///
+ public sealed class StackFrame
+ {
+ ///
+ /// Constructs an instance.
+ ///
+ public StackFrame(string assembly, string fileName, int level, int line, string method)
+ {
+ this.Data = new Extensibility.Implementation.External.StackFrame()
+ {
+ assembly = assembly,
+ fileName = fileName,
+ level = level,
+ line = line,
+ method = method
+ };
+ }
+
+ internal Extensibility.Implementation.External.StackFrame Data { get; private set; } = null;
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/TelemetryContext.cs b/src/Microsoft.ApplicationInsights/DataContracts/TelemetryContext.cs
index bfc40703a4..2d342eb7f7 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/TelemetryContext.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/TelemetryContext.cs
@@ -139,6 +139,7 @@ public LocationContext Location
/// Gets a dictionary of application-defined property values.
/// Learn more
///
+ [Obsolete("Use GlobalProperties to set global level properties. For properties at item level, use ISupportProperties.Properties.")]
public IDictionary Properties
{
get { return this.properties; }
@@ -149,7 +150,7 @@ public IDictionary Properties
/// Future SDK versions could serialize this separately from the item level properties.
/// Learn more
///
- internal IDictionary GlobalProperties
+ public IDictionary GlobalProperties
{
get { return this.globalProperties; }
}
diff --git a/src/Microsoft.ApplicationInsights/DataContracts/TraceTelemetry.cs b/src/Microsoft.ApplicationInsights/DataContracts/TraceTelemetry.cs
index 054c833699..4282760fa1 100644
--- a/src/Microsoft.ApplicationInsights/DataContracts/TraceTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/DataContracts/TraceTelemetry.cs
@@ -2,7 +2,9 @@
{
using System;
using System.Collections.Generic;
+ using System.Globalization;
using Microsoft.ApplicationInsights.Channel;
+ using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.ApplicationInsights.Extensibility.Implementation;
using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
@@ -18,6 +20,7 @@ public sealed class TraceTelemetry : ITelemetry, ISupportProperties, ISupportSam
internal readonly string BaseType = typeof(MessageData).Name;
internal readonly MessageData Data;
private readonly TelemetryContext context;
+ private IExtension extension;
private double? samplingPercentage;
@@ -57,6 +60,7 @@ private TraceTelemetry(TraceTelemetry source)
this.Sequence = source.Sequence;
this.Timestamp = source.Timestamp;
this.samplingPercentage = source.samplingPercentage;
+ this.extension = source.extension?.DeepClone();
}
///
@@ -77,6 +81,15 @@ public TelemetryContext Context
get { return this.context; }
}
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public IExtension Extension
+ {
+ get { return this.extension; }
+ set { this.extension = value; }
+ }
+
///
/// Gets or sets the message text. For example, the text that would normally be written to a log file line.
///
@@ -123,6 +136,12 @@ public ITelemetry DeepClone()
return new TraceTelemetry(this);
}
+ ///
+ public void SerializeData(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty(this.Data);
+ }
+
///
/// Sanitizes the properties based on constraints.
///
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/IExtension.cs b/src/Microsoft.ApplicationInsights/Extensibility/IExtension.cs
new file mode 100644
index 0000000000..8681097cfe
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/IExtension.cs
@@ -0,0 +1,13 @@
+namespace Microsoft.ApplicationInsights.Extensibility
+{
+ ///
+ /// Interface for defining strongly typed extensions to telemetry types.
+ ///
+ public interface IExtension : ISerializableWithWriter
+ {
+ ///
+ /// Deep clones the members of the class.
+ ///
+ IExtension DeepClone();
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/ISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/ISerializableWithWriter.cs
new file mode 100644
index 0000000000..a1e4ab5064
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/ISerializableWithWriter.cs
@@ -0,0 +1,13 @@
+namespace Microsoft.ApplicationInsights.Extensibility
+{
+ ///
+ /// Interface for defining objects which can be serialized with a given
+ ///
+ public interface ISerializableWithWriter
+ {
+ ///
+ /// Writes serialization info about the class using the given
+ ///
+ void Serialize(ISerializationWriter serializationWriter);
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/ISerializationWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/ISerializationWriter.cs
new file mode 100644
index 0000000000..83f5591e05
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/ISerializationWriter.cs
@@ -0,0 +1,86 @@
+namespace Microsoft.ApplicationInsights.Extensibility
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// The interface for defining writers capable of serializing data into various formats.
+ ///
+ public interface ISerializationWriter
+ {
+ ///
+ /// Writes name and value for a string field
+ ///
+ void WriteProperty(string name, string value);
+
+ ///
+ /// Writes name and value for a double field
+ ///
+ void WriteProperty(string name, double? value);
+
+ ///
+ /// Writes name and value for a int field
+ ///
+ void WriteProperty(string name, int? value);
+
+ ///
+ /// Writes name and value for a boolean field
+ ///
+ void WriteProperty(string name, bool? value);
+
+ ///
+ /// Writes name and value for a TimeSpan field
+ ///
+ void WriteProperty(string name, TimeSpan? value);
+
+ ///
+ /// Writes name and value for a DateTimeOffset field
+ ///
+ void WriteProperty(string name, DateTimeOffset? value);
+
+ ///
+ /// Writes name and value for a ISerializableWithWriter field
+ ///
+ void WriteProperty(string name, ISerializableWithWriter value);
+
+ ///
+ /// Writes value ISerializableWithWriter field
+ ///
+ void WriteProperty(ISerializableWithWriter value);
+
+ ///
+ /// Writes name and values for a IList field of strings
+ ///
+ void WriteProperty(string name, IList items);
+
+ ///
+ /// Writes name and values for a IList field of objects implementing ISerializableWithWriter
+ ///
+ void WriteProperty(string name, IList items);
+
+ ///
+ /// Writes name and value for a IDictionary field with string,string as key,value
+ ///
+ void WriteProperty(string name, IDictionary items);
+
+ ///
+ /// Writes name and value for a IDictionary field with string,string as key,value
+ ///
+ void WriteProperty(string name, IDictionary items);
+
+ ///
+ /// Marks beginning of a complex object.
+ ///
+ void WriteStartObject(string name);
+
+ ///
+ /// Marks beginning of a complex object.
+ ///
+ void WriteStartObject();
+
+ ///
+ /// Marks ending of a complex object.
+ ///
+ void WriteEndObject();
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/AvailabilityDataISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/AvailabilityDataISerializableWithWriter.cs
new file mode 100644
index 0000000000..5bde401a42
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/AvailabilityDataISerializableWithWriter.cs
@@ -0,0 +1,25 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System.Diagnostics;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class AvailabilityData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("id", this.id);
+ serializationWriter.WriteProperty("name", this.name);
+ serializationWriter.WriteProperty("duration", Utils.ValidateDuration(this.duration));
+ serializationWriter.WriteProperty("success", this.success);
+ serializationWriter.WriteProperty("runLocation", this.runLocation);
+ serializationWriter.WriteProperty("message", this.message);
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/DataPointIExtension.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/DataPointIExtension.cs
new file mode 100644
index 0000000000..bd654095a7
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/DataPointIExtension.cs
@@ -0,0 +1,22 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class DataPoint : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ns", this.ns);
+ serializationWriter.WriteProperty("name", this.name);
+ serializationWriter.WriteProperty("kind", this.kind.ToString());
+ serializationWriter.WriteProperty("value", this.value);
+ serializationWriter.WriteProperty("count", this.count.HasValue ? this.count : 1);
+ serializationWriter.WriteProperty("min", this.min);
+ serializationWriter.WriteProperty("max", this.max);
+ serializationWriter.WriteProperty("stdDev", this.stdDev);
+ }
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/EventDataISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/EventDataISerializableWithWriter.cs
new file mode 100644
index 0000000000..1820667ae9
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/EventDataISerializableWithWriter.cs
@@ -0,0 +1,21 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System.Diagnostics;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class EventData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("name", this.name);
+
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/ExceptionDataISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/ExceptionDataISerializableWithWriter.cs
new file mode 100644
index 0000000000..c385f58564
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/ExceptionDataISerializableWithWriter.cs
@@ -0,0 +1,25 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System;
+ using System.Diagnostics;
+ using System.Linq;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class ExceptionData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("problemId", this.problemId);
+ serializationWriter.WriteProperty("exceptions", this.exceptions.ToList());
+ serializationWriter.WriteProperty("severityLevel", this.severityLevel.TranslateSeverityLevel().HasValue ? this.severityLevel.TranslateSeverityLevel().Value.ToString() : null);
+
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/ExceptionDetailsISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/ExceptionDetailsISerializableWithWriter.cs
new file mode 100644
index 0000000000..5e2e918d33
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/ExceptionDetailsISerializableWithWriter.cs
@@ -0,0 +1,22 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System;
+ using System.Linq;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter.
+ ///
+ internal partial class ExceptionDetails : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("id", this.id);
+ serializationWriter.WriteProperty("outerId", this.outerId);
+ serializationWriter.WriteProperty("typeName", this.typeName);
+ serializationWriter.WriteProperty("message", this.message);
+ serializationWriter.WriteProperty("hasFullStack", this.hasFullStack);
+ serializationWriter.WriteProperty("stack", this.stack);
+ serializationWriter.WriteProperty("parsedStack", this.parsedStack.ToList());
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/MessageDataIExtension.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/MessageDataIExtension.cs
new file mode 100644
index 0000000000..592fe1e6af
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/MessageDataIExtension.cs
@@ -0,0 +1,22 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System;
+ using System.Diagnostics;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class MessageData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("message", this.message);
+ serializationWriter.WriteProperty("severityLevel", this.severityLevel.HasValue ? this.severityLevel.Value.ToString() : null);
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/MetricDataISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/MetricDataISerializableWithWriter.cs
new file mode 100644
index 0000000000..89eb5e72a7
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/MetricDataISerializableWithWriter.cs
@@ -0,0 +1,20 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System.Diagnostics;
+ using System.Linq;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class MetricData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("metrics", this.metrics.ToList());
+ serializationWriter.WriteProperty("properties", this.properties);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewDataIExtension.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewDataIExtension.cs
new file mode 100644
index 0000000000..f1eadb1a53
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewDataIExtension.cs
@@ -0,0 +1,20 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class PageViewData : ISerializableWithWriter
+ {
+ public new void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("name", this.name);
+ serializationWriter.WriteProperty("url", this.url);
+ serializationWriter.WriteProperty("duration", Utils.ValidateDuration(this.duration));
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfData.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfData.cs
index b9a2259138..14fbec9eb0 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfData.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfData.cs
@@ -1,14 +1,34 @@
namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
{
-#if NET45
- // .Net 4.5 has a custom implementation of RichPayloadEventSource
-#else
///
/// Partial class to add the EventData attribute and any additional customizations to the generated type.
///
+#if NET45
+ // .Net 4.5 has a custom implementation of RichPayloadEventSource
+#else
[System.Diagnostics.Tracing.EventData(Name = "PartB_PageViewPerfData")]
+#endif
internal partial class PageViewPerfData
{
+ public new PageViewPerfData DeepClone()
+ {
+ var other = new PageViewPerfData();
+ this.ApplyProperties(other);
+ return other;
+ }
+
+ protected override void ApplyProperties(EventData other)
+ {
+ base.ApplyProperties(other);
+ PageViewPerfData otherPageViewPerf = other as PageViewPerfData;
+ if (otherPageViewPerf != null)
+ {
+ otherPageViewPerf.domProcessing = this.domProcessing;
+ otherPageViewPerf.perfTotal = this.perfTotal;
+ otherPageViewPerf.networkConnect = this.networkConnect;
+ otherPageViewPerf.sentRequest = this.sentRequest;
+ otherPageViewPerf.receivedResponse = this.receivedResponse;
+ }
+ }
}
-#endif
}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfDataIExtension.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfDataIExtension.cs
new file mode 100644
index 0000000000..7417ff207c
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/PageViewPerfDataIExtension.cs
@@ -0,0 +1,23 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class PageViewPerfData : ISerializableWithWriter
+ {
+ public new void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("name", this.name);
+ serializationWriter.WriteProperty("url", this.url);
+ serializationWriter.WriteProperty("duration", Utils.ValidateDuration(this.duration));
+ serializationWriter.WriteProperty("domProcessing", Utils.ValidateDuration(this.domProcessing));
+ serializationWriter.WriteProperty("perfTotal", Utils.ValidateDuration(this.perfTotal));
+ serializationWriter.WriteProperty("networkConnect", Utils.ValidateDuration(this.networkConnect));
+ serializationWriter.WriteProperty("sentRequest", Utils.ValidateDuration(this.sentRequest));
+ serializationWriter.WriteProperty("receivedResponse", Utils.ValidateDuration(this.receivedResponse));
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/RemoteDependencyDataISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/RemoteDependencyDataISerializableWithWriter.cs
new file mode 100644
index 0000000000..87b4c96f3b
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/RemoteDependencyDataISerializableWithWriter.cs
@@ -0,0 +1,27 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System.Diagnostics;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class RemoteDependencyData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("name", this.name);
+ serializationWriter.WriteProperty("id", this.id);
+ serializationWriter.WriteProperty("data", this.data);
+ serializationWriter.WriteProperty("duration", Utils.ValidateDuration(this.duration));
+ serializationWriter.WriteProperty("resultCode", this.resultCode);
+ serializationWriter.WriteProperty("success", this.success);
+ serializationWriter.WriteProperty("type", this.type);
+ serializationWriter.WriteProperty("target", this.target);
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/RequestDataISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/RequestDataISerializableWithWriter.cs
new file mode 100644
index 0000000000..1da9c3a024
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/RequestDataISerializableWithWriter.cs
@@ -0,0 +1,26 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System.Diagnostics;
+ using Microsoft.ApplicationInsights;
+ using Microsoft.ApplicationInsights.DataContracts;
+
+ ///
+ /// Partial class to implement ISerializableWithWriter
+ ///
+ internal partial class RequestData : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("ver", this.ver);
+ serializationWriter.WriteProperty("id", this.id);
+ serializationWriter.WriteProperty("source", this.source);
+ serializationWriter.WriteProperty("name", this.name);
+ serializationWriter.WriteProperty("duration", Utils.ValidateDuration(this.duration));
+ serializationWriter.WriteProperty("success", this.success);
+ serializationWriter.WriteProperty("responseCode", this.responseCode);
+ serializationWriter.WriteProperty("url", this.url);
+ serializationWriter.WriteProperty("properties", this.properties);
+ serializationWriter.WriteProperty("measurements", this.measurements);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/StackFrameISerializableWithWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/StackFrameISerializableWithWriter.cs
new file mode 100644
index 0000000000..4e00b4e532
--- /dev/null
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/External/StackFrameISerializableWithWriter.cs
@@ -0,0 +1,19 @@
+namespace Microsoft.ApplicationInsights.Extensibility.Implementation.External
+{
+ using System;
+
+ ///
+ /// Partial class to impelement ISerializableWithWriter
+ ///
+ internal partial class StackFrame : ISerializableWithWriter
+ {
+ public void Serialize(ISerializationWriter serializationWriter)
+ {
+ serializationWriter.WriteProperty("level", this.level);
+ serializationWriter.WriteProperty("method", this.method);
+ serializationWriter.WriteProperty("assembly", this.assembly);
+ serializationWriter.WriteProperty("fileName", this.fileName);
+ serializationWriter.WriteProperty("line", this.line);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonWriter.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializationWriter.cs
similarity index 62%
rename from src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonWriter.cs
rename to src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializationWriter.cs
index ef9f353dd0..59e6326685 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonWriter.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializationWriter.cs
@@ -1,81 +1,67 @@
namespace Microsoft.ApplicationInsights.Extensibility.Implementation
-{
+{
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
- using Microsoft.ApplicationInsights.DataContracts;
+ using Microsoft.ApplicationInsights.Extensibility;
- internal class JsonWriter : IJsonWriter
+ internal class JsonSerializationWriter : ISerializationWriter
{
- private readonly EmptyObjectDetector emptyObjectDetector;
private readonly TextWriter textWriter;
private bool currentObjectHasProperties;
- internal JsonWriter(TextWriter textWriter)
+ public JsonSerializationWriter(TextWriter textWriter)
{
- this.emptyObjectDetector = new EmptyObjectDetector();
- this.textWriter = textWriter;
- }
-
- public void WriteStartArray()
- {
- this.textWriter.Write('[');
+ this.textWriter = textWriter;
}
+ ///
public void WriteStartObject()
- {
+ {
this.textWriter.Write('{');
this.currentObjectHasProperties = false;
}
- public void WriteEndArray()
- {
- this.textWriter.Write(']');
- }
-
- public void WriteEndObject()
+ ///
+ public void WriteStartObject(string name)
{
- this.textWriter.Write('}');
- }
-
- public void WriteComma()
- {
- this.textWriter.Write(',');
- }
-
- public void WriteRawValue(object value)
- {
- this.textWriter.Write(string.Format(CultureInfo.InvariantCulture, "{0}", value));
- }
+ this.WritePropertyName(name);
+ this.textWriter.Write('{');
+ this.currentObjectHasProperties = false;
+ }
+ ///
public void WriteProperty(string name, string value)
{
if (!string.IsNullOrEmpty(value))
- {
+ {
this.WritePropertyName(name);
this.WriteString(value);
}
}
- public void WriteProperty(string name, bool? value)
+ ///
+ public void WriteProperty(string name, int? value)
{
if (value.HasValue)
{
this.WritePropertyName(name);
- this.textWriter.Write(value.Value ? "true" : "false");
+ this.textWriter.Write(value.Value.ToString(CultureInfo.InvariantCulture));
}
}
- public void WriteProperty(string name, int? value)
+ ///
+ public void WriteProperty(string name, bool? value)
{
if (value.HasValue)
{
this.WritePropertyName(name);
- this.textWriter.Write(value.Value.ToString(CultureInfo.InvariantCulture));
+ this.textWriter.Write(value.Value ? "true" : "false");
}
}
+ ///
public void WriteProperty(string name, double? value)
{
if (value.HasValue)
@@ -85,6 +71,7 @@ public void WriteProperty(string name, double? value)
}
}
+ ///
public void WriteProperty(string name, TimeSpan? value)
{
if (value.HasValue)
@@ -93,6 +80,7 @@ public void WriteProperty(string name, TimeSpan? value)
}
}
+ ///
public void WriteProperty(string name, DateTimeOffset? value)
{
if (value.HasValue)
@@ -101,6 +89,77 @@ public void WriteProperty(string name, DateTimeOffset? value)
}
}
+ ///
+ public void WriteProperty(string name, IList items)
+ {
+ bool commaNeeded = false;
+ if (items != null && items.Count > 0)
+ {
+ this.WritePropertyName(name);
+
+ this.WriteStartArray();
+
+ foreach (var item in items)
+ {
+ if (commaNeeded)
+ {
+ this.WriteComma();
+ }
+
+ this.WriteString(item);
+ commaNeeded = true;
+ }
+
+ this.WriteEndArray();
+ }
+ }
+
+ ///
+ public void WriteProperty(string name, IList items)
+ {
+ bool commaNeeded = false;
+ if (items != null && items.Count > 0)
+ {
+ this.WritePropertyName(name);
+ this.WriteStartArray();
+ foreach (var item in items)
+ {
+ if (commaNeeded)
+ {
+ this.WriteComma();
+ }
+
+ this.WriteStartObject();
+ item.Serialize(this);
+ commaNeeded = true;
+ this.WriteEndObject();
+ }
+
+ this.WriteEndArray();
+ }
+ }
+
+ ///
+ public void WriteProperty(string name, ISerializableWithWriter value)
+ {
+ if (value != null)
+ {
+ this.WriteStartObject(name);
+ value.Serialize(this);
+ this.WriteEndObject();
+ }
+ }
+
+ ///
+ public void WriteProperty(ISerializableWithWriter value)
+ {
+ if (value != null)
+ {
+ value.Serialize(this);
+ }
+ }
+
+ ///
public void WriteProperty(string name, IDictionary values)
{
if (values != null && values.Count > 0)
@@ -116,6 +175,7 @@ public void WriteProperty(string name, IDictionary values)
}
}
+ ///
public void WriteProperty(string name, IDictionary values)
{
if (values != null && values.Count > 0)
@@ -131,14 +191,13 @@ public void WriteProperty(string name, IDictionary values)
}
}
- ///
- /// Writes the specified property name enclosed in double quotation marks followed by a colon.
- ///
- ///
- /// When this method is called multiple times, the second call after
- /// and all subsequent calls will write a coma before the name.
- ///
- public void WritePropertyName(string name)
+ ///
+ public void WriteEndObject()
+ {
+ this.textWriter.Write('}');
+ }
+
+ internal void WritePropertyName(string name)
{
if (name == null)
{
@@ -162,8 +221,28 @@ public void WritePropertyName(string name)
this.WriteString(name);
this.textWriter.Write(':');
}
-
- protected void WriteString(string value)
+
+ internal void WriteStartArray()
+ {
+ this.textWriter.Write('[');
+ }
+
+ internal void WriteEndArray()
+ {
+ this.textWriter.Write(']');
+ }
+
+ internal void WriteComma()
+ {
+ this.textWriter.Write(',');
+ }
+
+ internal void WriteRawValue(object value)
+ {
+ this.textWriter.Write(string.Format(CultureInfo.InvariantCulture, "{0}", value));
+ }
+
+ internal void WriteString(string value)
{
this.textWriter.Write('"');
@@ -209,106 +288,5 @@ protected void WriteString(string value)
this.textWriter.Write('"');
}
-
- private sealed class EmptyObjectDetector : IJsonWriter
- {
- public bool IsEmpty { get; set; }
-
- public void WriteStartArray()
- {
- }
-
- public void WriteStartObject()
- {
- }
-
- public void WriteEndArray()
- {
- }
-
- public void WriteEndObject()
- {
- }
-
- public void WriteComma()
- {
- }
-
- public void WriteProperty(string name, string value)
- {
- if (!string.IsNullOrEmpty(value))
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, bool? value)
- {
- if (value.HasValue)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, int? value)
- {
- if (value.HasValue)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, double? value)
- {
- if (value.HasValue)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, TimeSpan? value)
- {
- if (value.HasValue)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, DateTimeOffset? value)
- {
- if (value.HasValue)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, IDictionary value)
- {
- if (value != null && value.Count > 0)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WriteProperty(string name, IDictionary value)
- {
- if (value != null && value.Count > 0)
- {
- this.IsEmpty = false;
- }
- }
-
- public void WritePropertyName(string name)
- {
- }
-
- public void WriteRawValue(object value)
- {
- if (value != null)
- {
- this.IsEmpty = false;
- }
- }
- }
}
-}
+}
\ No newline at end of file
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializer.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializer.cs
index 71ed3f126e..ae3c00c991 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializer.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/JsonSerializer.cs
@@ -10,8 +10,6 @@
using System.Text;
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.DataContracts;
- using Microsoft.ApplicationInsights.Extensibility.Implementation.External;
- using Microsoft.ApplicationInsights.Extensibility.Implementation.Platform;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
///
@@ -148,85 +146,6 @@ internal static string SerializeAsString(ITelemetry telemetry)
return SerializeAsString(new ITelemetry[] { telemetry });
}
- #region Exception Serializer helper
-
- private static void SerializeExceptions(IEnumerable exceptions, IJsonWriter writer)
- {
- int exceptionArrayIndex = 0;
-
- foreach (ExceptionDetails exceptionDetails in exceptions)
- {
- if (exceptionArrayIndex++ != 0)
- {
- writer.WriteComma();
- }
-
- writer.WriteStartObject();
- writer.WriteProperty("id", exceptionDetails.id);
- if (exceptionDetails.outerId != 0)
- {
- writer.WriteProperty("outerId", exceptionDetails.outerId);
- }
-
- writer.WriteProperty(
- "typeName",
- Utils.PopulateRequiredStringValue(exceptionDetails.typeName, "typeName", typeof(ExceptionTelemetry).FullName));
- writer.WriteProperty(
- "message",
- Utils.PopulateRequiredStringValue(exceptionDetails.message, "message", typeof(ExceptionTelemetry).FullName));
-
- if (exceptionDetails.hasFullStack)
- {
- writer.WriteProperty("hasFullStack", exceptionDetails.hasFullStack);
- }
-
- writer.WriteProperty("stack", exceptionDetails.stack);
-
- if (exceptionDetails.parsedStack.Count > 0)
- {
- writer.WritePropertyName("parsedStack");
-
- writer.WriteStartArray();
-
- int stackFrameArrayIndex = 0;
-
- foreach (StackFrame frame in exceptionDetails.parsedStack)
- {
- if (stackFrameArrayIndex++ != 0)
- {
- writer.WriteComma();
- }
-
- writer.WriteStartObject();
- SerializeStackFrame(frame, writer);
- writer.WriteEndObject();
- }
-
- writer.WriteEndArray();
- }
-
- writer.WriteEndObject();
- }
- }
-
- private static void SerializeStackFrame(StackFrame frame, IJsonWriter writer)
- {
- writer.WriteProperty("level", frame.level);
- writer.WriteProperty(
- "method",
- Utils.PopulateRequiredStringValue(frame.method, "StackFrameMethod", typeof(ExceptionTelemetry).FullName));
- writer.WriteProperty("assembly", frame.assembly);
- writer.WriteProperty("fileName", frame.fileName);
-
- // 0 means it is unavailable
- if (frame.line != 0)
- {
- writer.WriteProperty("line", frame.line);
- }
- }
-
- #endregion Exception Serializer helper
-
///
/// Creates a GZIP compression stream that wraps . For windows phone 8.0 it returns .
///
@@ -235,66 +154,107 @@ private static Stream CreateCompressedStream(Stream stream)
return new GZipStream(stream, CompressionMode.Compress);
}
- private static void SerializeTelemetryItem(ITelemetry telemetryItem, JsonWriter jsonWriter)
+ private static void SerializeTelemetryItem(ITelemetry telemetryItem, JsonSerializationWriter jsonSerializationWriter)
{
+ jsonSerializationWriter.WriteStartObject();
+
if (telemetryItem is EventTelemetry)
{
EventTelemetry eventTelemetry = telemetryItem as EventTelemetry;
- SerializeEventTelemetry(eventTelemetry, jsonWriter);
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, eventTelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, eventTelemetry.BaseType, EventTelemetry.TelemetryName);
}
else if (telemetryItem is ExceptionTelemetry)
{
- ExceptionTelemetry exceptionTelemetry = telemetryItem as ExceptionTelemetry;
- SerializeExceptionTelemetry(exceptionTelemetry, jsonWriter);
+ ExceptionTelemetry exTelemetry = telemetryItem as ExceptionTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, exTelemetry.Data.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, exTelemetry.BaseType, ExceptionTelemetry.TelemetryName);
}
else if (telemetryItem is MetricTelemetry)
{
- MetricTelemetry metricTelemetry = telemetryItem as MetricTelemetry;
- SerializeMetricTelemetry(metricTelemetry, jsonWriter);
+ MetricTelemetry mTelemetry = telemetryItem as MetricTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, mTelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, mTelemetry.BaseType, MetricTelemetry.TelemetryName);
}
else if (telemetryItem is PageViewTelemetry)
{
- PageViewTelemetry pageViewTelemetry = telemetryItem as PageViewTelemetry;
- SerializePageViewTelemetry(pageViewTelemetry, jsonWriter);
+ PageViewTelemetry pvTelemetry = telemetryItem as PageViewTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, pvTelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, pvTelemetry.BaseType, PageViewTelemetry.TelemetryName);
+ }
+ else if (telemetryItem is PageViewPerformanceTelemetry)
+ {
+ PageViewPerformanceTelemetry pvptelemetry = telemetryItem as PageViewPerformanceTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, pvptelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, PageViewPerformanceTelemetry.BaseType, PageViewPerformanceTelemetry.TelemetryName);
}
else if (telemetryItem is DependencyTelemetry)
{
- DependencyTelemetry remoteDependencyTelemetry = telemetryItem as DependencyTelemetry;
- SerializeDependencyTelemetry(remoteDependencyTelemetry, jsonWriter);
+ DependencyTelemetry depTelemetry = telemetryItem as DependencyTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, depTelemetry.InternalData.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, depTelemetry.BaseType, DependencyTelemetry.TelemetryName);
}
else if (telemetryItem is RequestTelemetry)
{
- RequestTelemetry requestTelemetry = telemetryItem as RequestTelemetry;
- SerializeRequestTelemetry(requestTelemetry, jsonWriter);
+ RequestTelemetry reqTelemetry = telemetryItem as RequestTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, reqTelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, reqTelemetry.BaseType, RequestTelemetry.TelemetryName);
}
#pragma warning disable 618
+ else if (telemetryItem is PerformanceCounterTelemetry)
+ {
+ PerformanceCounterTelemetry pcTelemetry = telemetryItem as PerformanceCounterTelemetry;
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, pcTelemetry.Properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, pcTelemetry.Data.BaseType, MetricTelemetry.TelemetryName);
+ }
else if (telemetryItem is SessionStateTelemetry)
{
- EventTelemetry telemetry = (telemetryItem as SessionStateTelemetry).Data;
- SerializeEventTelemetry(telemetry, jsonWriter);
+ SessionStateTelemetry ssTelemetry = telemetryItem as SessionStateTelemetry;
+ SerializeHelper(telemetryItem, jsonSerializationWriter, ssTelemetry.Data.BaseType, EventTelemetry.TelemetryName);
}
#pragma warning restore 618
- else if (telemetryItem is TraceTelemetry)
+ else if (telemetryItem is TraceTelemetry)
{
TraceTelemetry traceTelemetry = telemetryItem as TraceTelemetry;
- SerializeTraceTelemetry(traceTelemetry, jsonWriter);
- }
-#pragma warning disable 618
- else if (telemetryItem is PerformanceCounterTelemetry)
- {
- MetricTelemetry telemetry = (telemetryItem as PerformanceCounterTelemetry).Data;
- SerializeMetricTelemetry(telemetry, jsonWriter);
- }
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, traceTelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, traceTelemetry.BaseType, TraceTelemetry.TelemetryName);
+ }
else if (telemetryItem is AvailabilityTelemetry)
{
AvailabilityTelemetry availabilityTelemetry = telemetryItem as AvailabilityTelemetry;
- SerializeAvailability(availabilityTelemetry, jsonWriter);
+ Utils.CopyDictionary(telemetryItem.Context.GlobalProperties, availabilityTelemetry.Data.properties);
+
+ SerializeHelper(telemetryItem, jsonSerializationWriter, availabilityTelemetry.BaseType, AvailabilityTelemetry.TelemetryName);
}
else
{
- string msg = string.Format(CultureInfo.InvariantCulture, "Unknown telemetry type: {0}", telemetryItem.GetType());
+ string msg = string.Format(CultureInfo.InvariantCulture, "Unknown telemetry type: {0}", telemetryItem.GetType());
CoreEventSource.Log.LogVerbose(msg);
}
+
+ jsonSerializationWriter.WriteEndObject();
+ }
+
+ private static void SerializeHelper(ITelemetry telemetryItem, JsonSerializationWriter jsonSerializationWriter, string baseType, string telemetryName)
+ {
+ jsonSerializationWriter.WriteProperty("name", telemetryItem.WriteTelemetryName(telemetryName));
+ telemetryItem.WriteEnvelopeProperties(jsonSerializationWriter);
+ jsonSerializationWriter.WriteStartObject("data");
+ jsonSerializationWriter.WriteProperty("baseType", baseType);
+ jsonSerializationWriter.WriteStartObject("baseData");
+ telemetryItem.SerializeData(jsonSerializationWriter);
+ jsonSerializationWriter.WriteEndObject(); // baseData
+ jsonSerializationWriter.WriteProperty("extension", telemetryItem.Extension);
+ jsonSerializationWriter.WriteEndObject(); // data
}
///
@@ -302,7 +262,8 @@ private static void SerializeTelemetryItem(ITelemetry telemetryItem, JsonWriter
///
private static void SeializeToStream(IEnumerable telemetryItems, TextWriter streamWriter)
{
- JsonWriter jsonWriter = new JsonWriter(streamWriter);
+ // JsonWriter jsonWriter = new JsonWriter(streamWriter);
+ JsonSerializationWriter jsonSerializationWriter = new JsonSerializationWriter(streamWriter);
int telemetryCount = 0;
foreach (ITelemetry telemetryItem in telemetryItems)
@@ -314,314 +275,8 @@ private static void SeializeToStream(IEnumerable telemetryItems, Tex
telemetryItem.Context.SanitizeGlobalProperties();
telemetryItem.Sanitize();
- SerializeTelemetryItem(telemetryItem, jsonWriter);
- }
- }
-
- #region Serialize methods for each ITelemetry implementation
-
- private static void SerializeEventTelemetry(EventTelemetry eventTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- eventTelemetry.WriteTelemetryName(writer, EventTelemetry.TelemetryName);
- eventTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("baseType", eventTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", eventTelemetry.Data.ver);
- writer.WriteProperty("name", eventTelemetry.Data.name);
- writer.WriteProperty("measurements", eventTelemetry.Data.measurements);
- Utils.CopyDictionary(eventTelemetry.Context.GlobalProperties, eventTelemetry.Data.properties);
- writer.WriteProperty("properties", eventTelemetry.Data.properties);
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- private static void SerializeExceptionTelemetry(ExceptionTelemetry exceptionTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- exceptionTelemetry.WriteTelemetryName(writer, ExceptionTelemetry.TelemetryName);
- exceptionTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("baseType", exceptionTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", exceptionTelemetry.Data.ver);
- writer.WriteProperty("problemId", exceptionTelemetry.Data.problemId);
- Utils.CopyDictionary(exceptionTelemetry.Context.GlobalProperties, exceptionTelemetry.Data.properties);
- writer.WriteProperty("properties", exceptionTelemetry.Data.properties);
- writer.WriteProperty("measurements", exceptionTelemetry.Data.measurements);
- writer.WritePropertyName("exceptions");
- {
- writer.WriteStartArray();
-
- SerializeExceptions(exceptionTelemetry.Exceptions, writer);
-
- writer.WriteEndArray();
- }
-
- if (exceptionTelemetry.Data.severityLevel.HasValue)
- {
- writer.WriteProperty("severityLevel", exceptionTelemetry.Data.severityLevel.Value.ToString());
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
+ SerializeTelemetryItem(telemetryItem, jsonSerializationWriter);
}
-
- writer.WriteEndObject();
- }
-
- private static void SerializeMetricTelemetry(MetricTelemetry metricTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- metricTelemetry.WriteTelemetryName(writer, MetricTelemetry.TelemetryName);
- metricTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- // TODO: MetricTelemetry should write type as this.data.baseType once Common Schema 2.0 compliant.
- writer.WriteProperty("baseType", metricTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", metricTelemetry.Data.ver);
- writer.WritePropertyName("metrics");
- {
- writer.WriteStartArray();
- writer.WriteStartObject();
-
- string metricNamespace = metricTelemetry.Metric.ns;
- if (false == String.IsNullOrEmpty(metricNamespace))
- {
- writer.WriteProperty("ns", metricNamespace);
- }
-
- writer.WriteProperty("name", metricTelemetry.Metric.name);
- writer.WriteProperty("kind", metricTelemetry.Metric.kind.ToString());
- writer.WriteProperty("value", metricTelemetry.Metric.value);
- writer.WriteProperty("count", metricTelemetry.Metric.count);
- writer.WriteProperty("min", metricTelemetry.Metric.min);
- writer.WriteProperty("max", metricTelemetry.Metric.max);
- writer.WriteProperty("stdDev", metricTelemetry.Metric.stdDev);
- writer.WriteEndObject();
- writer.WriteEndArray();
- }
-
- Utils.CopyDictionary(metricTelemetry.Context.GlobalProperties, metricTelemetry.Data.properties);
- writer.WriteProperty("properties", metricTelemetry.Data.properties);
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- private static void SerializePageViewTelemetry(PageViewTelemetry pageViewTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- pageViewTelemetry.WriteTelemetryName(writer, PageViewTelemetry.TelemetryName);
- pageViewTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- // TODO: MetricTelemetry should write type as this.data.baseType once Common Schema 2.0 compliant.
- writer.WriteProperty("baseType", pageViewTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", pageViewTelemetry.Data.ver);
- writer.WriteProperty("name", pageViewTelemetry.Data.name);
- writer.WriteProperty("url", pageViewTelemetry.Data.url);
- writer.WriteProperty("duration", pageViewTelemetry.Data.duration);
- writer.WriteProperty("measurements", pageViewTelemetry.Data.measurements);
- Utils.CopyDictionary(pageViewTelemetry.Context.GlobalProperties, pageViewTelemetry.Data.properties);
- writer.WriteProperty("properties", pageViewTelemetry.Data.properties);
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- private static void SerializeDependencyTelemetry(DependencyTelemetry dependencyTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- dependencyTelemetry.WriteTelemetryName(writer, DependencyTelemetry.TelemetryName);
- dependencyTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("baseType", dependencyTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", dependencyTelemetry.InternalData.ver);
- writer.WriteProperty("name", dependencyTelemetry.InternalData.name);
- writer.WriteProperty("id", dependencyTelemetry.InternalData.id);
- writer.WriteProperty("data", dependencyTelemetry.InternalData.data);
- writer.WriteProperty("duration", dependencyTelemetry.InternalData.duration);
- writer.WriteProperty("resultCode", dependencyTelemetry.InternalData.resultCode);
- writer.WriteProperty("success", dependencyTelemetry.InternalData.success);
- writer.WriteProperty("type", dependencyTelemetry.InternalData.type);
- writer.WriteProperty("target", dependencyTelemetry.InternalData.target);
- Utils.CopyDictionary(dependencyTelemetry.Context.GlobalProperties, dependencyTelemetry.InternalData.properties);
- writer.WriteProperty("properties", dependencyTelemetry.InternalData.properties);
- writer.WriteProperty("measurements", dependencyTelemetry.InternalData.measurements);
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- private static void SerializeRequestTelemetry(RequestTelemetry requestTelemetry, JsonWriter jsonWriter)
- {
- jsonWriter.WriteStartObject();
-
- requestTelemetry.WriteTelemetryName(jsonWriter, RequestTelemetry.TelemetryName);
- requestTelemetry.WriteEnvelopeProperties(jsonWriter);
- jsonWriter.WritePropertyName("data");
- {
- jsonWriter.WriteStartObject();
-
- jsonWriter.WriteProperty("baseType", requestTelemetry.BaseType);
- jsonWriter.WritePropertyName("baseData");
- {
- jsonWriter.WriteStartObject();
-
- jsonWriter.WriteProperty("ver", requestTelemetry.Data.ver);
- jsonWriter.WriteProperty("id", requestTelemetry.Data.id);
- jsonWriter.WriteProperty("source", requestTelemetry.Data.source);
- jsonWriter.WriteProperty("name", requestTelemetry.Data.name);
- jsonWriter.WriteProperty("duration", requestTelemetry.Duration);
- jsonWriter.WriteProperty("success", requestTelemetry.Data.success);
- jsonWriter.WriteProperty("responseCode", requestTelemetry.Data.responseCode);
- jsonWriter.WriteProperty("url", requestTelemetry.Data.url);
- jsonWriter.WriteProperty("measurements", requestTelemetry.Data.measurements);
- Utils.CopyDictionary(requestTelemetry.Context.GlobalProperties, requestTelemetry.Data.properties);
- jsonWriter.WriteProperty("properties", requestTelemetry.Data.properties);
-
- jsonWriter.WriteEndObject();
- }
-
- jsonWriter.WriteEndObject();
- }
-
- jsonWriter.WriteEndObject();
}
-
- private static void SerializeTraceTelemetry(TraceTelemetry traceTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- traceTelemetry.WriteTelemetryName(writer, TraceTelemetry.TelemetryName);
- traceTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- // TODO: MetricTelemetry should write type as this.data.baseType once Common Schema 2.0 compliant.
- writer.WriteProperty("baseType", traceTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", traceTelemetry.Data.ver);
- writer.WriteProperty("message", traceTelemetry.Message);
-
- if (traceTelemetry.SeverityLevel.HasValue)
- {
- writer.WriteProperty("severityLevel", traceTelemetry.SeverityLevel.Value.ToString());
- }
-
- Utils.CopyDictionary(traceTelemetry.Context.GlobalProperties, traceTelemetry.Data.properties);
- writer.WriteProperty("properties", traceTelemetry.Properties); // TODO: handle case where the property dictionary doesn't need to be instantiated.
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- ///
- /// Serializes this object in JSON format.
- ///
- private static void SerializeAvailability(AvailabilityTelemetry availabilityTelemetry, JsonWriter writer)
- {
- writer.WriteStartObject();
-
- availabilityTelemetry.WriteTelemetryName(writer, AvailabilityTelemetry.TelemetryName);
- availabilityTelemetry.WriteEnvelopeProperties(writer);
- writer.WritePropertyName("data");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("baseType", availabilityTelemetry.BaseType);
- writer.WritePropertyName("baseData");
- {
- writer.WriteStartObject();
-
- writer.WriteProperty("ver", availabilityTelemetry.Data.ver);
- writer.WriteProperty("id", availabilityTelemetry.Data.id);
- writer.WriteProperty("name", availabilityTelemetry.Data.name);
- writer.WriteProperty("duration", availabilityTelemetry.Duration);
- writer.WriteProperty("success", availabilityTelemetry.Data.success);
- writer.WriteProperty("runLocation", availabilityTelemetry.Data.runLocation);
- writer.WriteProperty("message", availabilityTelemetry.Data.message);
- Utils.CopyDictionary(availabilityTelemetry.Context.GlobalProperties, availabilityTelemetry.Data.properties);
- writer.WriteProperty("properties", availabilityTelemetry.Data.properties);
- writer.WriteProperty("measurements", availabilityTelemetry.Data.measurements);
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- writer.WriteEndObject();
- }
-
- #endregion Serialize methods for each ITelemetry implementation
}
}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/OperationTelemetry.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/OperationTelemetry.cs
index f4db060d5d..c5c5e5189c 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/OperationTelemetry.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/OperationTelemetry.cs
@@ -74,6 +74,11 @@ public DateTimeOffset StartTime
///
public abstract string Sequence { get; set; }
+ ///
+ /// Gets or sets gets the extension used to extend this telemetry instance using new strong typed object.
+ ///
+ public abstract IExtension Extension { get; set; }
+
///
/// Gets or sets Time in StopWatch ticks representing begin time of the operation. Used internally
/// for calculating duration between begin and end.
@@ -94,6 +99,9 @@ void ITelemetry.Sanitize()
/// A cloned instance.
public abstract ITelemetry DeepClone();
+ ///
+ public abstract void SerializeData(ISerializationWriter serializationWriter);
+
///
/// Sets operation Id.
///
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.Keywords.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.Keywords.cs
index 8f3d2c1a5e..c92cde86d4 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.Keywords.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.Keywords.cs
@@ -66,6 +66,11 @@ public sealed class Keywords
/// Keyword for operations (Start/Stop).
///
public const EventKeywords Operations = (EventKeywords)0x400;
+
+ ///
+ /// Keyword for page view performance.
+ ///
+ public const EventKeywords PageViewPerformance = (EventKeywords)0x800;
}
}
}
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.TelemetryHandler.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.TelemetryHandler.cs
index ce26da562a..923a85c210 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.TelemetryHandler.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.TelemetryHandler.cs
@@ -73,6 +73,9 @@ private Dictionary> CreateTelemetryHandlers(EventSource
// PageView
telemetryHandlers.Add(typeof(PageViewTelemetry), this.CreateHandlerForPageViewTelemetry(eventSource, writeGenericMethod, eventSourceOptionsType, eventSourceOptionsKeywordsProperty));
+ // PageView
+ telemetryHandlers.Add(typeof(PageViewPerformanceTelemetry), this.CreateHandlerForPageViewPerformanceTelemetry(eventSource, writeGenericMethod, eventSourceOptionsType, eventSourceOptionsKeywordsProperty));
+
#pragma warning disable 618
// SessionState
telemetryHandlers.Add(typeof(SessionStateTelemetry), this.CreateHandlerForSessionStateTelemetry(eventSource, writeGenericMethod, eventSourceOptionsType, eventSourceOptionsKeywordsProperty));
@@ -502,7 +505,7 @@ private Action CreateHandlerForExceptionTelemetry(EventSource eventS
eventSourceOptionsKeywordsProperty.SetValue(eventSourceOptions, keywords);
var dummyExceptionData = new ExceptionData();
var dummyExceptionDetails = new ExceptionDetails();
- var dummyStackFrame = new StackFrame();
+ var dummyStackFrame = new External.StackFrame();
var writeMethod = writeGenericMethod.MakeGenericMethod(new
{
PartA_iKey = this.dummyPartAiKeyValue,
@@ -550,7 +553,7 @@ private Action CreateHandlerForExceptionTelemetry(EventSource eventS
{
item.Sanitize();
var telemetryItem = item as ExceptionTelemetry;
- var data = telemetryItem.Data;
+ var data = telemetryItem.Data.Data;
var extendedData = new
{
// The properties and layout should be the same as the anonymous type in the above MakeGenericMethod
@@ -722,6 +725,64 @@ private Action CreateHandlerForPageViewTelemetry(EventSource eventSo
};
}
+ ///
+ /// Create handler for page view performance telemetry.
+ ///
+ private Action CreateHandlerForPageViewPerformanceTelemetry(EventSource eventSource, MethodInfo writeGenericMethod, Type eventSourceOptionsType, PropertyInfo eventSourceOptionsKeywordsProperty)
+ {
+ var eventSourceOptions = Activator.CreateInstance(eventSourceOptionsType);
+ var keywords = Keywords.PageViews;
+ eventSourceOptionsKeywordsProperty.SetValue(eventSourceOptions, keywords);
+ var dummyPageViewPerfData = new PageViewPerfData();
+ var writeMethod = writeGenericMethod.MakeGenericMethod(new
+ {
+ PartA_iKey = this.dummyPartAiKeyValue,
+ PartA_Tags = this.dummyPartATagsValue,
+ PartB_PageViewPerfData = new
+ {
+ // The properties and layout should be the same as PageViewPerfData_types.cs (EventData_types.cs)
+ dummyPageViewPerfData.perfTotal,
+ dummyPageViewPerfData.networkConnect,
+ dummyPageViewPerfData.sentRequest,
+ dummyPageViewPerfData.receivedResponse,
+ dummyPageViewPerfData.domProcessing,
+ dummyPageViewPerfData.url,
+ dummyPageViewPerfData.duration,
+ dummyPageViewPerfData.ver,
+ dummyPageViewPerfData.name,
+ dummyPageViewPerfData.properties,
+ dummyPageViewPerfData.measurements,
+ }
+ }.GetType());
+
+ return (item) =>
+ {
+ if (this.EventSourceInternal.IsEnabled(EventLevel.Verbose, keywords))
+ {
+ item.Sanitize();
+ var telemetryItem = item as PageViewTelemetry;
+ var data = telemetryItem.Data;
+ var extendedData = new
+ {
+ // The properties and layout should be the same as the anonymous type in the above MakeGenericMethod
+ PartA_iKey = telemetryItem.Context.InstrumentationKey,
+ PartA_Tags = telemetryItem.Context.SanitizedTags,
+ PartB_PageViewPerfData = new
+ {
+ data.url,
+ data.duration,
+ data.ver,
+ data.name,
+ data.properties,
+ data.measurements,
+ }
+ };
+
+ writeMethod.Invoke(eventSource, new object[] { PageViewTelemetry.TelemetryName, eventSourceOptions, extendedData });
+ }
+ };
+ }
+
///
/// Create handler for session state telemetry.
///
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.cs
index 529c7843ec..1240eee405 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/RichPayloadEventSource.cs
@@ -144,7 +144,7 @@ public void Process(ITelemetry item)
ExceptionTelemetry.TelemetryName,
telemetryItem.Context.InstrumentationKey,
telemetryItem.Context.SanitizedTags,
- telemetryItem.Data,
+ telemetryItem.Data.Data,
telemetryItem.Context.Flags,
Keywords.Exceptions);
}
@@ -184,6 +184,23 @@ public void Process(ITelemetry item)
telemetryItem.Context.Flags,
Keywords.PageViews);
}
+ else if (item is PageViewPerformanceTelemetry)
+ {
+ if (!this.EventSourceInternal.IsEnabled(EventLevel.Verbose, Keywords.PageViewPerformance))
+ {
+ return;
+ }
+
+ item.Sanitize();
+ var telemetryItem = item as PageViewPerformanceTelemetry;
+ this.WriteEvent(
+ PageViewPerformanceTelemetry.TelemetryName,
+ telemetryItem.Context.InstrumentationKey,
+ telemetryItem.Context.SanitizedTags,
+ telemetryItem.Data,
+ telemetryItem.Context.Flags,
+ Keywords.PageViewPerformance);
+ }
#pragma warning disable 618
else if (item is SessionStateTelemetry)
{
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Telemetry.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Telemetry.cs
index 632b5c305d..0fb91713be 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Telemetry.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/Telemetry.cs
@@ -7,7 +7,7 @@
internal static class Telemetry
{
- public static void WriteEnvelopeProperties(this ITelemetry telemetry, IJsonWriter json)
+ public static void WriteEnvelopeProperties(this ITelemetry telemetry, ISerializationWriter json)
{
json.WriteProperty("time", telemetry.Timestamp.UtcDateTime.ToString("o", CultureInfo.InvariantCulture));
@@ -25,7 +25,7 @@ public static void WriteEnvelopeProperties(this ITelemetry telemetry, IJsonWrite
WriteTelemetryContext(json, telemetry.Context);
}
- public static void WriteTelemetryName(this ITelemetry telemetry, IJsonWriter json, string telemetryName)
+ public static string WriteTelemetryName(this ITelemetry telemetry, string telemetryName)
{
// A different event name prefix is sent for normal mode and developer mode.
bool isDevMode = false;
@@ -44,10 +44,11 @@ public static void WriteTelemetryName(this ITelemetry telemetry, IJsonWriter jso
isDevMode ? Constants.DevModeTelemetryNamePrefix : Constants.TelemetryNamePrefix,
NormalizeInstrumentationKey(telemetry.Context.InstrumentationKey),
telemetryName);
- json.WriteProperty("name", eventName);
+
+ return eventName;
}
- public static void WriteTelemetryContext(IJsonWriter json, TelemetryContext context)
+ public static void WriteTelemetryContext(ISerializationWriter json, TelemetryContext context)
{
if (context != null)
{
diff --git a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/TelemetryConfigurationFactory.cs b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/TelemetryConfigurationFactory.cs
index 107eaab0f7..0847ccee4b 100644
--- a/src/Microsoft.ApplicationInsights/Extensibility/Implementation/TelemetryConfigurationFactory.cs
+++ b/src/Microsoft.ApplicationInsights/Extensibility/Implementation/TelemetryConfigurationFactory.cs
@@ -411,7 +411,16 @@ private static void LoadInstanceFromValue(XElement definition, Type expectedType
}
else
{
- instance = Convert.ChangeType(valueString, expectedType, CultureInfo.InvariantCulture);
+ if (valueString.IndexOf("0x", StringComparison.OrdinalIgnoreCase) == 0)
+ {
+ CultureInfo provider = CultureInfo.InvariantCulture;
+
+ instance = Int32.Parse(valueString.Remove(0, 2), NumberStyles.AllowHexSpecifier, provider);
+ }
+ else
+ {
+ instance = Convert.ChangeType(valueString, expectedType, CultureInfo.InvariantCulture);
+ }
}
}
catch (InvalidCastException e)
@@ -458,4 +467,4 @@ private static IEnumerable GetPropertyDefinitions(XElement instanceDef
return attributeDefinitions.Concat(elementDefinitions);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj b/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj
index 2f8e05d4ab..8e62f5ffb8 100644
--- a/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj
+++ b/src/Microsoft.ApplicationInsights/Microsoft.ApplicationInsights.csproj
@@ -52,10 +52,12 @@
All
+
All
-
+
+
All
@@ -69,11 +71,11 @@
- PublicAPI.Shipped.txt
+ PublicAPI.Shipped.txt
- PublicAPI.Unshipped.txt
-
+ PublicAPI.Unshipped.txt
+