From 8ed07c1caed2f24526f8d3e413f0e0ed3f03110c Mon Sep 17 00:00:00 2001 From: Brandon Chong Date: Mon, 22 Feb 2021 12:00:53 -0800 Subject: [PATCH 1/2] fixes NRE --- .../Tracing/TraceWriter.TraceJsonWriter.cs | 17 +- .../Tracing/TraceWriter.TraceTextWriter.cs | 23 +- .../TraceWriterBaselineTests.TraceData.xml | 314 ++++++++++++++---- .../Tracing/TraceWriterBaselineTests.cs | 219 ++++++++---- 4 files changed, 427 insertions(+), 146 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs index bb963e7f8f..6646f7c714 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs @@ -158,7 +158,7 @@ public void Visit(PointOperationStatisticsTraceDatum pointOperationStatisticsTra this.jsonWriter.WriteStringValue("PointOperationStatistics"); this.jsonWriter.WriteFieldName("ActivityId"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ActivityId); + this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ActivityId ?? ""); this.jsonWriter.WriteFieldName("ResponseTimeUtc"); this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ResponseTimeUtc.ToString("o", CultureInfo.InvariantCulture)); @@ -173,7 +173,7 @@ public void Visit(PointOperationStatisticsTraceDatum pointOperationStatisticsTra this.jsonWriter.WriteNumber64Value(pointOperationStatisticsTraceDatum.RequestCharge); this.jsonWriter.WriteFieldName("RequestUri"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.RequestUri); + this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.RequestUri ?? ""); if (!string.IsNullOrEmpty(pointOperationStatisticsTraceDatum.ErrorMessage)) { @@ -250,7 +250,7 @@ private static void VisitAddressResolutionStatistics( } jsonWriter.WriteFieldName("TargetEndpoint"); - jsonWriter.WriteStringValue(addressResolutionStatistics.TargetEndpoint); + jsonWriter.WriteStringValue(addressResolutionStatistics.TargetEndpoint ?? ""); jsonWriter.WriteObjectEnd(); } @@ -271,7 +271,7 @@ private static void VisitStoreResponseStatistics( jsonWriter.WriteStringValue(storeResponseStatistics.RequestOperationType.ToString()); jsonWriter.WriteFieldName("LocationEndpoint"); - jsonWriter.WriteStringValue(storeResponseStatistics.LocationEndpoint.ToString()); + jsonWriter.WriteStringValue(storeResponseStatistics.LocationEndpoint?.ToString() ?? ""); if (storeResponseStatistics.StoreResult != null) { @@ -301,7 +301,7 @@ private void WriteJsonUriArray(string propertyName, IEnumerable uris) { foreach (Uri contactedReplica in uris) { - this.jsonWriter.WriteStringValue(contactedReplica.ToString()); + this.jsonWriter.WriteStringValue(contactedReplica?.ToString() ?? ""); } } @@ -326,6 +326,11 @@ private void WriteJsonUriArrayWithDuplicatesCounted(string propertyName, IReadOn for (int i = 0; i < totalCount; i++) { Uri contactedReplica = uris[i]; + if (contactedReplica == null) + { + continue; + } + if (contactedReplica.Equals(previous)) { duplicateCount++; @@ -345,7 +350,7 @@ private void WriteJsonUriArrayWithDuplicatesCounted(string propertyName, IReadOn this.jsonWriter.WriteFieldName("Count"); this.jsonWriter.WriteNumber64Value(duplicateCount); this.jsonWriter.WriteFieldName("Uri"); - this.jsonWriter.WriteStringValue(contactedReplica.ToString()); + this.jsonWriter.WriteStringValue(contactedReplica?.ToString() ?? ""); this.jsonWriter.WriteObjectEnd(); } diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceTextWriter.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceTextWriter.cs index 5a66be1587..443c6fc040 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceTextWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceTextWriter.cs @@ -322,12 +322,12 @@ public void Visit(QueryMetricsTraceDatum queryMetricsTraceDatum) public void Visit(PointOperationStatisticsTraceDatum pointOperationStatisticsTraceDatum) { StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.AppendLine($"Activity ID: {pointOperationStatisticsTraceDatum.ActivityId}"); + stringBuilder.AppendLine($"Activity ID: {pointOperationStatisticsTraceDatum.ActivityId ?? ""}"); stringBuilder.AppendLine($"Status Code: {pointOperationStatisticsTraceDatum.StatusCode}/{pointOperationStatisticsTraceDatum.SubStatusCode}"); stringBuilder.AppendLine($"Response Time: {pointOperationStatisticsTraceDatum.ResponseTimeUtc.ToString("hh:mm:ss:fff", CultureInfo.InvariantCulture)}"); stringBuilder.AppendLine($"Request Charge: {pointOperationStatisticsTraceDatum.RequestCharge}"); - stringBuilder.AppendLine($"Request URI: {pointOperationStatisticsTraceDatum.RequestUri}"); - stringBuilder.AppendLine($"Session Tokens: {pointOperationStatisticsTraceDatum.RequestSessionToken} / {pointOperationStatisticsTraceDatum.ResponseSessionToken}"); + stringBuilder.AppendLine($"Request URI: {pointOperationStatisticsTraceDatum.RequestUri ?? ""}"); + stringBuilder.AppendLine($"Session Tokens: {pointOperationStatisticsTraceDatum.RequestSessionToken ?? ""} / {pointOperationStatisticsTraceDatum.ResponseSessionToken ?? ""}"); if (pointOperationStatisticsTraceDatum.ErrorMessage != null) { stringBuilder.AppendLine($"Error Message: {pointOperationStatisticsTraceDatum.ErrorMessage}"); @@ -349,6 +349,11 @@ public void Visit(ClientSideRequestStatisticsTraceDatum clientSideRequestStatist Dictionary uriAndCounts = new Dictionary(); foreach (Uri uri in clientSideRequestStatisticsTraceDatum.ContactedReplicas) { + if (uri == null) + { + continue; + } + if (!uriAndCounts.TryGetValue(uri, out int count)) { count = 0; @@ -359,19 +364,19 @@ public void Visit(ClientSideRequestStatisticsTraceDatum clientSideRequestStatist foreach (KeyValuePair uriAndCount in uriAndCounts) { - stringBuilder.AppendLine($"{space}{uriAndCount.Key}: {uriAndCount.Value}"); + stringBuilder.AppendLine($"{space}{uriAndCount.Key?.ToString() ?? ""}: {uriAndCount.Value}"); } stringBuilder.AppendLine("Failed to Contact Replicas"); foreach (Uri failedToContactReplica in clientSideRequestStatisticsTraceDatum.FailedReplicas) { - stringBuilder.AppendLine($"{space}{failedToContactReplica}"); + stringBuilder.AppendLine($"{space}{failedToContactReplica?.ToString() ?? ""}"); } stringBuilder.AppendLine("Regions Contacted"); foreach (Uri regionContacted in clientSideRequestStatisticsTraceDatum.ContactedReplicas) { - stringBuilder.AppendLine($"{space}{regionContacted}"); + stringBuilder.AppendLine($"{space}{regionContacted?.ToString() ?? ""}"); } stringBuilder.AppendLine("Address Resolution Statistics"); @@ -409,8 +414,8 @@ public void Visit(ClientSideRequestStatisticsTraceDatum clientSideRequestStatist if (stat.StoreResult != null) { stringBuilder.AppendLine($"{space}Store Result"); - stringBuilder.AppendLine($"{space}{space}Activity Id: {stat.StoreResult.ActivityId}"); - stringBuilder.AppendLine($"{space}{space}Store Physical Address: {stat.StoreResult.StorePhysicalAddress}"); + stringBuilder.AppendLine($"{space}{space}Activity Id: {stat.StoreResult.ActivityId ?? ""}"); + stringBuilder.AppendLine($"{space}{space}Store Physical Address: {stat.StoreResult.StorePhysicalAddress?.ToString() ?? ""}"); stringBuilder.AppendLine($"{space}{space}Status Code: {stat.StoreResult.StatusCode}/{stat.StoreResult.SubStatusCode}"); stringBuilder.AppendLine($"{space}{space}Is Valid: {stat.StoreResult.IsValid}"); stringBuilder.AppendLine($"{space}{space}LSN Info"); @@ -419,7 +424,7 @@ public void Visit(ClientSideRequestStatisticsTraceDatum clientSideRequestStatist stringBuilder.AppendLine($"{space}{space}{space}Global LSN: {stat.StoreResult.GlobalCommittedLSN}"); stringBuilder.AppendLine($"{space}{space}{space}Quorum Acked LSN: {stat.StoreResult.QuorumAckedLSN}"); stringBuilder.AppendLine($"{space}{space}{space}Using LSN: {stat.StoreResult.UsingLocalLSN}"); - stringBuilder.AppendLine($"{space}{space}Session Token: {stat.StoreResult.SessionToken.ConvertToString()}"); + stringBuilder.AppendLine($"{space}{space}Session Token: {stat.StoreResult.SessionToken?.ConvertToString() ?? ""}"); stringBuilder.AppendLine($"{space}{space}Quorum Info"); stringBuilder.AppendLine($"{space}{space}{space}Current Replica Set Size: {stat.StoreResult.CurrentReplicaSetSize}"); stringBuilder.AppendLine($"{space}{space}{space}Current Write Quorum: {stat.StoreResult.CurrentWriteQuorum}"); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml index 681ca867af..d1703d0de2 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml @@ -3,22 +3,22 @@ Point Operation Statistics @@ -54,6 +54,62 @@ } }, "children": [] +}]]> + + + + + Point Operation Statistics Default + + + + + Status Code: 0/Unknown + Response Time: 12:00:00:000 + Request Charge: 0 + Request URI: + Session Tokens: / + ) +]]> + ", + "ResponseTimeUtc": "0001-01-01T00:00:00", + "StatusCode": 0, + "SubStatusCode": 0, + "RequestCharge": 0, + "RequestUri": "" + } + }, + "children": [] }]]> @@ -126,58 +182,58 @@ Client Side Request Stats @@ -274,6 +330,142 @@ } }, "children": [] +}]]> + + + + + Client Side Request Stats Default + + + + + Regions Contacted + + Address Resolution Statistics + ┌────────────────┬──────────────┬──────────────────────────────────────────────────┐ + │Start Time (utc)│End Time (utc)│Endpoint │ + ├────────────────┼──────────────┼──────────────────────────────────────────────────┤ + │ 12:00:00:000│ NO END TIME│ │ + │ 12:00:00:000│ NO END TIME│ │ + └────────────────┴──────────────┴──────────────────────────────────────────────────┘ + Store Response Statistics + {space}Start Time Not Found + End Time: 12:00:00:000 + Resource Type: Database + Operation Type: Create + Store Result + Activity Id: + Store Physical Address: + Status Code: 0/Unknown + Is Valid: False + LSN Info + LSN: 0 + Item LSN: 0 + Global LSN: 0 + Quorum Acked LSN: 0 + Using LSN: False + Session Token: + Quorum Info + Current Replica Set Size: 0 + Current Write Quorum: 0 + Is Client CPU Overloaded: False + Exception + ) +]]> + " + ], + "FailedReplicas": [ + "" + ], + "AddressResolutionStatistics": [ + { + "StartTimeUTC": "0001-01-01T00:00:00", + "EndTimeUTC": "EndTime Never Set.", + "TargetEndpoint": "" + }, + { + "StartTimeUTC": "0001-01-01T00:00:00", + "EndTimeUTC": "EndTime Never Set.", + "TargetEndpoint": "" + } + ], + "StoreResponseStatistics": [ + { + "ResponseTimeUTC": "0001-01-01T00:00:00", + "ResourceType": "Database", + "OperationType": "Create", + "LocationEndpoint": "", + "StoreResult": "StorePhysicalAddress: , LSN: 0, GlobalCommittedLsn: 0, PartitionKeyRangeId: , IsValid: False, StatusCode: 0, SubStatusCode: 0, RequestCharge: 0, ItemLSN: 0, SessionToken: , UsingLocalLSN: False, TransportException: null" + } + ] + } + }, + "children": [] }]]> diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs index 63b3471463..dfda2d8ef7 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Tracing/TraceWriterBaselineTests.cs @@ -277,26 +277,51 @@ public void TraceData() // Point Operation Statistics //---------------------------------------------------------------- { - startLineNumber = GetLineNumber(); - TraceForBaselineTesting rootTrace; - using (rootTrace = TraceForBaselineTesting.GetRootTrace()) { - PointOperationStatisticsTraceDatum datum = new PointOperationStatisticsTraceDatum( - activityId: Guid.Empty.ToString(), - responseTimeUtc: new DateTime(2020, 1, 2, 3, 4, 5, 6), - statusCode: System.Net.HttpStatusCode.OK, - subStatusCode: Documents.SubStatusCodes.WriteForbidden, - requestCharge: 4, - errorMessage: null, - method: HttpMethod.Post, - requestUri: "http://localhost.com", - requestSessionToken: nameof(PointOperationStatisticsTraceDatum.RequestSessionToken), - responseSessionToken: nameof(PointOperationStatisticsTraceDatum.ResponseSessionToken)); - rootTrace.AddDatum("Point Operation Statistics", datum); + startLineNumber = GetLineNumber(); + TraceForBaselineTesting rootTrace; + using (rootTrace = TraceForBaselineTesting.GetRootTrace()) + { + PointOperationStatisticsTraceDatum datum = new PointOperationStatisticsTraceDatum( + activityId: Guid.Empty.ToString(), + responseTimeUtc: new DateTime(2020, 1, 2, 3, 4, 5, 6), + statusCode: System.Net.HttpStatusCode.OK, + subStatusCode: Documents.SubStatusCodes.WriteForbidden, + requestCharge: 4, + errorMessage: null, + method: HttpMethod.Post, + requestUri: "http://localhost.com", + requestSessionToken: nameof(PointOperationStatisticsTraceDatum.RequestSessionToken), + responseSessionToken: nameof(PointOperationStatisticsTraceDatum.ResponseSessionToken)); + rootTrace.AddDatum("Point Operation Statistics", datum); + } + endLineNumber = GetLineNumber(); + + inputs.Add(new Input("Point Operation Statistics", rootTrace, startLineNumber, endLineNumber)); } - endLineNumber = GetLineNumber(); - inputs.Add(new Input("Point Operation Statistics", rootTrace, startLineNumber, endLineNumber)); + { + startLineNumber = GetLineNumber(); + TraceForBaselineTesting rootTrace; + using (rootTrace = TraceForBaselineTesting.GetRootTrace()) + { + PointOperationStatisticsTraceDatum datum = new PointOperationStatisticsTraceDatum( + activityId: default, + responseTimeUtc: default, + statusCode: default, + subStatusCode: default, + requestCharge: default, + errorMessage: default, + method: default, + requestUri: default, + requestSessionToken: default, + responseSessionToken: default); + rootTrace.AddDatum("Point Operation Statistics Default", datum); + } + endLineNumber = GetLineNumber(); + + inputs.Add(new Input("Point Operation Statistics Default", rootTrace, startLineNumber, endLineNumber)); + } } //---------------------------------------------------------------- @@ -325,62 +350,116 @@ public void TraceData() // Client Side Request Stats //---------------------------------------------------------------- { - startLineNumber = GetLineNumber(); - TraceForBaselineTesting rootTrace; - using (rootTrace = TraceForBaselineTesting.GetRootTrace()) { - ClientSideRequestStatisticsTraceDatum datum = new ClientSideRequestStatisticsTraceDatum(DateTime.MinValue); - - Uri uri1 = new Uri("http://someUri1.com"); - Uri uri2 = new Uri("http://someUri2.com"); - - datum.ContactedReplicas.Add(uri1); - datum.ContactedReplicas.Add(uri2); - - ClientSideRequestStatisticsTraceDatum.AddressResolutionStatistics mockStatistics = new ClientSideRequestStatisticsTraceDatum.AddressResolutionStatistics( - DateTime.MinValue, - DateTime.MaxValue, - "http://localhost.com"); - datum.EndpointToAddressResolutionStatistics["asdf"] = mockStatistics; - datum.EndpointToAddressResolutionStatistics["asdf2"] = mockStatistics; - - datum.FailedReplicas.Add(uri1); - datum.FailedReplicas.Add(uri2); - - datum.RegionsContacted.Add(uri1); - datum.RegionsContacted.Add(uri2); - - datum.RequestEndTimeUtc = DateTime.MaxValue; - - StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( - DateTime.MinValue, - DateTime.MaxValue, - new Documents.StoreResult( - storeResponse: new StoreResponse(), - exception: null, - partitionKeyRangeId: 42.ToString(), - lsn: 1337, - quorumAckedLsn: 23, - requestCharge: 3.14, - currentReplicaSetSize: 4, - currentWriteQuorum: 3, - isValid: true, - storePhysicalAddress: new Uri("http://storephysicaladdress.com"), - globalCommittedLSN: 1234, - numberOfReadRegions: 13, - itemLSN: 15, - sessionToken: new SimpleSessionToken(42), - usingLocalLSN: true, - activityId: Guid.Empty.ToString()), - ResourceType.Document, - OperationType.Query, - uri1); - datum.StoreResponseStatisticsList.Add(storeResponseStatistics); - rootTrace.AddDatum("Client Side Request Stats", datum); + startLineNumber = GetLineNumber(); + TraceForBaselineTesting rootTrace; + using (rootTrace = TraceForBaselineTesting.GetRootTrace()) + { + ClientSideRequestStatisticsTraceDatum datum = new ClientSideRequestStatisticsTraceDatum(DateTime.MinValue); + + Uri uri1 = new Uri("http://someUri1.com"); + Uri uri2 = new Uri("http://someUri2.com"); + + datum.ContactedReplicas.Add(uri1); + datum.ContactedReplicas.Add(uri2); + + ClientSideRequestStatisticsTraceDatum.AddressResolutionStatistics mockStatistics = new ClientSideRequestStatisticsTraceDatum.AddressResolutionStatistics( + DateTime.MinValue, + DateTime.MaxValue, + "http://localhost.com"); + datum.EndpointToAddressResolutionStatistics["asdf"] = mockStatistics; + datum.EndpointToAddressResolutionStatistics["asdf2"] = mockStatistics; + + datum.FailedReplicas.Add(uri1); + datum.FailedReplicas.Add(uri2); + + datum.RegionsContacted.Add(uri1); + datum.RegionsContacted.Add(uri2); + + datum.RequestEndTimeUtc = DateTime.MaxValue; + + StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( + DateTime.MinValue, + DateTime.MaxValue, + new Documents.StoreResult( + storeResponse: new StoreResponse(), + exception: null, + partitionKeyRangeId: 42.ToString(), + lsn: 1337, + quorumAckedLsn: 23, + requestCharge: 3.14, + currentReplicaSetSize: 4, + currentWriteQuorum: 3, + isValid: true, + storePhysicalAddress: new Uri("http://storephysicaladdress.com"), + globalCommittedLSN: 1234, + numberOfReadRegions: 13, + itemLSN: 15, + sessionToken: new SimpleSessionToken(42), + usingLocalLSN: true, + activityId: Guid.Empty.ToString()), + ResourceType.Document, + OperationType.Query, + uri1); + datum.StoreResponseStatisticsList.Add(storeResponseStatistics); + rootTrace.AddDatum("Client Side Request Stats", datum); + } + endLineNumber = GetLineNumber(); + + inputs.Add(new Input("Client Side Request Stats", rootTrace, startLineNumber, endLineNumber)); } - endLineNumber = GetLineNumber(); - inputs.Add(new Input("Client Side Request Stats", rootTrace, startLineNumber, endLineNumber)); + { + startLineNumber = GetLineNumber(); + TraceForBaselineTesting rootTrace; + using (rootTrace = TraceForBaselineTesting.GetRootTrace()) + { + ClientSideRequestStatisticsTraceDatum datum = new ClientSideRequestStatisticsTraceDatum(DateTime.MinValue); + datum.ContactedReplicas.Add(default); + + ClientSideRequestStatisticsTraceDatum.AddressResolutionStatistics mockStatistics = new ClientSideRequestStatisticsTraceDatum.AddressResolutionStatistics( + default, + default, + targetEndpoint: "asdf"); + datum.EndpointToAddressResolutionStatistics["asdf"] = default; + datum.EndpointToAddressResolutionStatistics["asdf2"] = default; + + datum.FailedReplicas.Add(default); + + datum.RegionsContacted.Add(default); + + datum.RequestEndTimeUtc = default; + + StoreResponseStatistics storeResponseStatistics = new StoreResponseStatistics( + requestStartTime: default, + requestResponseTime: default, + new Documents.StoreResult( + storeResponse: new StoreResponse(), + exception: default, + partitionKeyRangeId: default, + lsn: default, + quorumAckedLsn: default, + requestCharge: default, + currentReplicaSetSize: default, + currentWriteQuorum: default, + isValid: default, + storePhysicalAddress: default, + globalCommittedLSN: default, + numberOfReadRegions: default, + itemLSN: default, + sessionToken: default, + usingLocalLSN: default, + activityId: default), + resourceType: default, + operationType: default, + locationEndpoint: default); ; + datum.StoreResponseStatisticsList.Add(storeResponseStatistics); + rootTrace.AddDatum("Client Side Request Stats Default", datum); + } + endLineNumber = GetLineNumber(); + + inputs.Add(new Input("Client Side Request Stats Default", rootTrace, startLineNumber, endLineNumber)); + } } //---------------------------------------------------------------- From 96a9984cf7561112b9c1b5864e76821abbbbb72b Mon Sep 17 00:00:00 2001 From: Brandon Chong Date: Mon, 22 Feb 2021 12:22:55 -0800 Subject: [PATCH 2/2] opted for json null --- .../Tracing/TraceWriter.TraceJsonWriter.cs | 59 ++++++++++++------- .../TraceWriterBaselineTests.TraceData.xml | 18 +++--- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs index 6646f7c714..a24b156dea 100644 --- a/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs +++ b/Microsoft.Azure.Cosmos/src/Tracing/TraceWriter.TraceJsonWriter.cs @@ -158,7 +158,7 @@ public void Visit(PointOperationStatisticsTraceDatum pointOperationStatisticsTra this.jsonWriter.WriteStringValue("PointOperationStatistics"); this.jsonWriter.WriteFieldName("ActivityId"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ActivityId ?? ""); + this.WriteStringValueOrNull(pointOperationStatisticsTraceDatum.ActivityId); this.jsonWriter.WriteFieldName("ResponseTimeUtc"); this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ResponseTimeUtc.ToString("o", CultureInfo.InvariantCulture)); @@ -173,25 +173,16 @@ public void Visit(PointOperationStatisticsTraceDatum pointOperationStatisticsTra this.jsonWriter.WriteNumber64Value(pointOperationStatisticsTraceDatum.RequestCharge); this.jsonWriter.WriteFieldName("RequestUri"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.RequestUri ?? ""); + this.WriteStringValueOrNull(pointOperationStatisticsTraceDatum.RequestUri); - if (!string.IsNullOrEmpty(pointOperationStatisticsTraceDatum.ErrorMessage)) - { - this.jsonWriter.WriteFieldName("ErrorMessage"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ErrorMessage); - } + this.jsonWriter.WriteFieldName("ErrorMessage"); + this.WriteStringValueOrNull(pointOperationStatisticsTraceDatum.ErrorMessage); - if (pointOperationStatisticsTraceDatum.RequestSessionToken != null) - { - this.jsonWriter.WriteFieldName("RequestSessionToken"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.RequestSessionToken); - } + this.jsonWriter.WriteFieldName("RequestSessionToken"); + this.WriteStringValueOrNull(pointOperationStatisticsTraceDatum.RequestSessionToken); - if (pointOperationStatisticsTraceDatum.ResponseSessionToken != null) - { - this.jsonWriter.WriteFieldName("ResponseSessionToken"); - this.jsonWriter.WriteStringValue(pointOperationStatisticsTraceDatum.ResponseSessionToken); - } + this.jsonWriter.WriteFieldName("ResponseSessionToken"); + this.WriteStringValueOrNull(pointOperationStatisticsTraceDatum.ResponseSessionToken); this.jsonWriter.WriteObjectEnd(); } @@ -250,7 +241,14 @@ private static void VisitAddressResolutionStatistics( } jsonWriter.WriteFieldName("TargetEndpoint"); - jsonWriter.WriteStringValue(addressResolutionStatistics.TargetEndpoint ?? ""); + if (addressResolutionStatistics.TargetEndpoint == null) + { + jsonWriter.WriteNullValue(); + } + else + { + jsonWriter.WriteStringValue(addressResolutionStatistics.TargetEndpoint); + } jsonWriter.WriteObjectEnd(); } @@ -271,7 +269,14 @@ private static void VisitStoreResponseStatistics( jsonWriter.WriteStringValue(storeResponseStatistics.RequestOperationType.ToString()); jsonWriter.WriteFieldName("LocationEndpoint"); - jsonWriter.WriteStringValue(storeResponseStatistics.LocationEndpoint?.ToString() ?? ""); + if (storeResponseStatistics.LocationEndpoint == null) + { + jsonWriter.WriteNullValue(); + } + else + { + jsonWriter.WriteStringValue(storeResponseStatistics.LocationEndpoint.ToString()); + } if (storeResponseStatistics.StoreResult != null) { @@ -301,7 +306,7 @@ private void WriteJsonUriArray(string propertyName, IEnumerable uris) { foreach (Uri contactedReplica in uris) { - this.jsonWriter.WriteStringValue(contactedReplica?.ToString() ?? ""); + this.WriteStringValueOrNull(contactedReplica?.ToString()); } } @@ -350,7 +355,7 @@ private void WriteJsonUriArrayWithDuplicatesCounted(string propertyName, IReadOn this.jsonWriter.WriteFieldName("Count"); this.jsonWriter.WriteNumber64Value(duplicateCount); this.jsonWriter.WriteFieldName("Uri"); - this.jsonWriter.WriteStringValue(contactedReplica?.ToString() ?? ""); + this.WriteStringValueOrNull(contactedReplica?.ToString()); this.jsonWriter.WriteObjectEnd(); } @@ -361,6 +366,18 @@ private void WriteJsonUriArrayWithDuplicatesCounted(string propertyName, IReadOn this.jsonWriter.WriteArrayEnd(); } + + private void WriteStringValueOrNull(string value) + { + if (value == null) + { + this.jsonWriter.WriteNullValue(); + } + else + { + this.jsonWriter.WriteStringValue(value); + } + } } } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml index d1703d0de2..d8ce160869 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/BaselineTest/TestBaseline/TraceWriterBaselineTests.TraceData.xml @@ -49,6 +49,7 @@ "SubStatusCode": 3, "RequestCharge": 4, "RequestUri": "http://localhost.com", + "ErrorMessage": null, "RequestSessionToken": "RequestSessionToken", "ResponseSessionToken": "ResponseSessionToken" } @@ -101,12 +102,15 @@ "data": { "Point Operation Statistics Default": { "Id": "PointOperationStatistics", - "ActivityId": "", + "ActivityId": null, "ResponseTimeUtc": "0001-01-01T00:00:00", "StatusCode": 0, "SubStatusCode": 0, "RequestCharge": 0, - "RequestUri": "" + "RequestUri": null, + "ErrorMessage": null, + "RequestSessionToken": null, + "ResponseSessionToken": null } }, "children": [] @@ -437,21 +441,21 @@ "Id": "AggregatedClientSideRequestStatistics", "ContactedReplicas": [], "RegionsContacted": [ - "" + null ], "FailedReplicas": [ - "" + null ], "AddressResolutionStatistics": [ { "StartTimeUTC": "0001-01-01T00:00:00", "EndTimeUTC": "EndTime Never Set.", - "TargetEndpoint": "" + "TargetEndpoint": null }, { "StartTimeUTC": "0001-01-01T00:00:00", "EndTimeUTC": "EndTime Never Set.", - "TargetEndpoint": "" + "TargetEndpoint": null } ], "StoreResponseStatistics": [ @@ -459,7 +463,7 @@ "ResponseTimeUTC": "0001-01-01T00:00:00", "ResourceType": "Database", "OperationType": "Create", - "LocationEndpoint": "", + "LocationEndpoint": null, "StoreResult": "StorePhysicalAddress: , LSN: 0, GlobalCommittedLsn: 0, PartitionKeyRangeId: , IsValid: False, StatusCode: 0, SubStatusCode: 0, RequestCharge: 0, ItemLSN: 0, SessionToken: , UsingLocalLSN: False, TransportException: null" } ]