diff --git a/src/EasyTrace.Tests/Export/ActivityExportTests.cs b/src/EasyTrace.Tests/Export/ActivityExportTests.cs index 6690757..449fabb 100644 --- a/src/EasyTrace.Tests/Export/ActivityExportTests.cs +++ b/src/EasyTrace.Tests/Export/ActivityExportTests.cs @@ -88,7 +88,7 @@ public Task SingleBatchActivity() var inMemoryExporter = new InMemoryExport(); var source = new TraceActivitySourceBuilder() .SetTimeProvider(new MoqTimeProvider()) - .SetIdentifierGenerator(MoqIdentGenerator.Sequence(1)) + .SetIdentifierGenerator(MoqIdentGenerator.Sequence(2)) .SetBatchExportOptions(new BatchExportOptions { MaxExportBatchSize = 2, @@ -116,7 +116,7 @@ public Task MultiBatchActivity() var inMemoryExporter = new InMemoryExport(); var source = new TraceActivitySourceBuilder() .SetTimeProvider(new MoqTimeProvider()) - .SetIdentifierGenerator(MoqIdentGenerator.Sequence(10)) + .SetIdentifierGenerator(MoqIdentGenerator.Sequence(20)) .SetBatchExportOptions(new BatchExportOptions { MaxExportBatchSize = 2, diff --git a/src/EasyTrace.Tests/Export/OtlpExportTests.cs b/src/EasyTrace.Tests/Export/OtlpExportTests.cs index f035c3b..ba71f97 100644 --- a/src/EasyTrace.Tests/Export/OtlpExportTests.cs +++ b/src/EasyTrace.Tests/Export/OtlpExportTests.cs @@ -38,11 +38,7 @@ public Task HttpExport() // Make activity source. var source = new TraceActivitySourceBuilder() .SetTimeProvider(new MoqTimeProvider()) - .SetIdentifierGenerator(MoqIdentGenerator.Set( - ActivityTraceId.CreateFromString("0af7651916cd43dd8448eb211c80319c"), - ActivitySpanId.CreateFromString("b7ad6b7169203331"), - ActivitySpanId.CreateFromString("b9ad6b7169203331") - )) + .SetIdentifierGenerator(MoqIdentGenerator.Sequence(9)) .SetResources(new Dictionary { ["telemetry.sdk.name"] = "easytrace", @@ -52,7 +48,7 @@ public Task HttpExport() }) .SetBatchExportOptions(new BatchExportOptions { - MaxExportBatchSize = 2, + MaxExportBatchSize = 3, ScheduledDelayMilliseconds = uint.MaxValue, }) .AddOtlpExporter(new HttpExportParameters @@ -62,11 +58,27 @@ public Task HttpExport() }) .Build(nameof(ActivityExportTests)); - // TODO: Add more actions (x3 MaxExportBatchSize) to test splitting into multiple messages. // Make activity for batch export. { - using var _ = source.Start(); - using var __ = source.Start(); + { + using (var _ = source.Start()) {} + using (var _ = source.Start()) {} + using (var _ = source.Start()) {} + } + Task.Delay(100).Wait(); + + { + using var _ = source.Start(); + using (var __ = source.Start()) {} + using (var __ = source.Start()) {} + } + Task.Delay(100).Wait(); + + { + using var _ = source.Start(); + using var __ = source.Start(); + using var ___ = source.Start(); + } Task.Delay(100).Wait(); } @@ -138,7 +150,13 @@ public static TestRequestCache GetInstance() public void Set(string key, byte[] value) { - _cache[key] = value; + if (_cache.TryGetValue(key, out var list)) + { + list.Add(Convert.ToHexStringLower(value)); + return; + } + + _cache[key] = [Convert.ToHexStringLower(value)]; } public string GetAllCache() @@ -149,7 +167,7 @@ public string GetAllCache() { result.Append(" {\n"); result.AppendFormat($" \"key\": \"{item.Key}\",\n"); - result.AppendFormat($" \"value\": \"{string.Join(", ", item.Value)}\",\n"); + result.AppendFormat($" \"value\": \"{string.Join(", \n", item.Value)}\",\n"); result.Append(" },\n"); } @@ -157,6 +175,6 @@ public string GetAllCache() return result.ToString(); } - private readonly ConcurrentDictionary _cache = new(); + private readonly ConcurrentDictionary> _cache = new(); private static TestRequestCache? _instance; } \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.GroupActivity.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.GroupActivity.verified.txt index 92d1629..f7556bd 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.GroupActivity.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.GroupActivity.verified.txt @@ -1,5 +1,5 @@ [ - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b9ad6b7169203331|Source: ActivityExportTests |OperationName: Child2|Kind: Internal|StartTime: 00:00:00.0000300|EndTime: 00:00:00.0000400, - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b8ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000500, - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000600 + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b9ad6b7169203331|ParentId: b8ad6b7169203331|Source: ActivityExportTests |OperationName: Child2|Kind: Internal|StartTime: 00:00:00.0000300|EndTime: 00:00:00.0000400, + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b8ad6b7169203331|ParentId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000500, + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000600 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.MultiBatchActivity.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.MultiBatchActivity.verified.txt index 4aff729..021c21e 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.MultiBatchActivity.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.MultiBatchActivity.verified.txt @@ -1,22 +1,22 @@ [ - TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b76d6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000300, - TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b5ad6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000400, - TraceId: 0a27651916cd43dd8448eb211c80319c|SpanId: b7ad8b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000600|EndTime: 00:00:00.0000700, - TraceId: 0a27651916cd43dd8448eb211c80319c|SpanId: b7a76b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000500|EndTime: 00:00:00.0000800, - TraceId: 0af3651916cd43dd8448eb211c80319c|SpanId: baad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0001000|EndTime: 00:00:00.0001100, - TraceId: 0af3651916cd43dd8448eb211c80319c|SpanId: b7ad697169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000900|EndTime: 00:00:00.0001200, - TraceId: 0af7451916cd43dd8448eb211c80319c|SpanId: b7ac6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0001400|EndTime: 00:00:00.0001500, - TraceId: 0af7451916cd43dd8448eb211c80319c|SpanId: b7bd6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0001300|EndTime: 00:00:00.0001600, - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6e7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0001800|EndTime: 00:00:00.0001900, - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7addb7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0001700|EndTime: 00:00:00.0002000, - TraceId: 06f7651916cd43dd8448eb211c80319c|SpanId: b70d6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0002200|EndTime: 00:00:00.0002300, - TraceId: 06f7651916cd43dd8448eb211c80319c|SpanId: bfad6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0002100|EndTime: 00:00:00.0002400, - TraceId: 0a77651916cd43dd8448eb211c80319c|SpanId: b7ad2b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0002600|EndTime: 00:00:00.0002700, - TraceId: 0a77651916cd43dd8448eb211c80319c|SpanId: b7a16b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0002500|EndTime: 00:00:00.0002800, - TraceId: 0af8651916cd43dd8448eb211c80319c|SpanId: b4ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0003000|EndTime: 00:00:00.0003100, - TraceId: 0af8651916cd43dd8448eb211c80319c|SpanId: b7ad637169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0002900|EndTime: 00:00:00.0003200, - TraceId: 0af7951916cd43dd8448eb211c80319c|SpanId: b7a66b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0003400|EndTime: 00:00:00.0003500, - TraceId: 0af7951916cd43dd8448eb211c80319c|SpanId: b75d6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0003300|EndTime: 00:00:00.0003600, - TraceId: 0af76a1916cd43dd8448eb211c80319c|SpanId: b7ad687169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0003800|EndTime: 00:00:00.0003900, - TraceId: 0af76a1916cd43dd8448eb211c80319c|SpanId: b7ad7b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0003700|EndTime: 00:00:00.0004000 + TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b2ad6b7169203331|ParentId: b1ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000300, + TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b1ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000400, + TraceId: 02f7651916cd43dd8448eb211c80319c|SpanId: b7a46b7169203331|ParentId: b73d6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000600|EndTime: 00:00:00.0000700, + TraceId: 02f7651916cd43dd8448eb211c80319c|SpanId: b73d6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000500|EndTime: 00:00:00.0000800, + TraceId: 0a37651916cd43dd8448eb211c80319c|SpanId: b7ad667169203331|ParentId: b7ad5b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0001000|EndTime: 00:00:00.0001100, + TraceId: 0a37651916cd43dd8448eb211c80319c|SpanId: b7ad5b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000900|EndTime: 00:00:00.0001200, + TraceId: 0af4651916cd43dd8448eb211c80319c|SpanId: b7ad6b7869203331|ParentId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0001400|EndTime: 00:00:00.0001500, + TraceId: 0af4651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0001300|EndTime: 00:00:00.0001600, + TraceId: 0af7551916cd43dd8448eb211c80319c|SpanId: b7ad6b716a203331|ParentId: b7ad6b7199203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0001800|EndTime: 00:00:00.0001900, + TraceId: 0af7551916cd43dd8448eb211c80319c|SpanId: b7ad6b7199203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0001700|EndTime: 00:00:00.0002000, + TraceId: 0af7661916cd43dd8448eb211c80319c|SpanId: b7ad6b71692c3331|ParentId: b7ad6b7169b03331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0002200|EndTime: 00:00:00.0002300, + TraceId: 0af7661916cd43dd8448eb211c80319c|SpanId: b7ad6b7169b03331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0002100|EndTime: 00:00:00.0002400, + TraceId: 0af7657916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203e31|ParentId: b7ad6b716920d331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0002600|EndTime: 00:00:00.0002700, + TraceId: 0af7657916cd43dd8448eb211c80319c|SpanId: b7ad6b716920d331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0002500|EndTime: 00:00:00.0002800, + TraceId: 0af7651816cd43dd8448eb211c80319c|SpanId: b7ad6b716920333f|ParentId: b7ad6b71692033f1|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0003000|EndTime: 00:00:00.0003100, + TraceId: 0af7651816cd43dd8448eb211c80319c|SpanId: b7ad6b71692033f1|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0002900|EndTime: 00:00:00.0003200, + TraceId: 0af7651996cd43dd8448eb211c80319c|SpanId: bdad6b7169203331|ParentId: bead6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0003400|EndTime: 00:00:00.0003500, + TraceId: 0af7651996cd43dd8448eb211c80319c|SpanId: bead6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0003300|EndTime: 00:00:00.0003600, + TraceId: 0af765191acd43dd8448eb211c80319c|SpanId: b7ab6b7169203331|ParentId: b7cd6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0003800|EndTime: 00:00:00.0003900, + TraceId: 0af765191acd43dd8448eb211c80319c|SpanId: b7cd6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0003700|EndTime: 00:00:00.0004000 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.ScheduledBatchEnable.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.ScheduledBatchEnable.verified.txt index 142bbd5..08397f6 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.ScheduledBatchEnable.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.ScheduledBatchEnable.verified.txt @@ -1,4 +1,4 @@ [ - TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b76d6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000300, - TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b5ad6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000400 + TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b2ad6b7169203331|ParentId: b1ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000300, + TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b1ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000400 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Client.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Client.verified.txt index fb4ce15..5e16ec6 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Client.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Client.verified.txt @@ -1,3 +1,3 @@ [ - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: TestName|Kind: Client|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: TestName|Kind: Client|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Consumer.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Consumer.verified.txt index 3932493..d261d56 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Consumer.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Consumer.verified.txt @@ -1,3 +1,3 @@ [ - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: TestName|Kind: Consumer|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: TestName|Kind: Consumer|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Internal.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Internal.verified.txt index 7f84458..77707f0 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Internal.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Internal.verified.txt @@ -1,3 +1,3 @@ [ - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: TestName|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: TestName|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Producer.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Producer.verified.txt index 5c59694..f5f467c 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Producer.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Producer.verified.txt @@ -1,3 +1,3 @@ [ - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: TestName|Kind: Producer|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: TestName|Kind: Producer|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Server.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Server.verified.txt index 74f1f32..6bbc690 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Server.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleActivity_kind=Server.verified.txt @@ -1,3 +1,3 @@ [ - TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|Source: ActivityExportTests |OperationName: TestName|Kind: Server|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 + TraceId: 0af7651916cd43dd8448eb211c80319c|SpanId: b7ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: TestName|Kind: Server|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000200 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleBatchActivity.verified.txt b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleBatchActivity.verified.txt index 8e64d43..08397f6 100644 --- a/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleBatchActivity.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/ActivityExportTests.SingleBatchActivity.verified.txt @@ -1,4 +1,4 @@ [ - TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b74d6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000300, - TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b3ad6b7169203331|Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000400 + TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b2ad6b7169203331|ParentId: b1ad6b7169203331|Source: ActivityExportTests |OperationName: Child1|Kind: Internal|StartTime: 00:00:00.0000200|EndTime: 00:00:00.0000300, + TraceId: 01f7651916cd43dd8448eb211c80319c|SpanId: b1ad6b7169203331|ParentId: |Source: ActivityExportTests |OperationName: Parent|Kind: Internal|StartTime: 00:00:00.0000100|EndTime: 00:00:00.0000400 ] \ No newline at end of file diff --git a/src/EasyTrace.Tests/Export/snapshots/OtlpExportTests.HttpExport.verified.txt b/src/EasyTrace.Tests/Export/snapshots/OtlpExportTests.HttpExport.verified.txt index 6aa4edb..3c3e942 100644 --- a/src/EasyTrace.Tests/Export/snapshots/OtlpExportTests.HttpExport.verified.txt +++ b/src/EasyTrace.Tests/Export/snapshots/OtlpExportTests.HttpExport.verified.txt @@ -1,6 +1,8 @@ [ { "key": "/v1/traces", - "value": "10, 194, 130, 128, 0, 10, 144, 129, 128, 0, 10, 161, 128, 128, 0, 10, 18, 116, 101, 108, 101, 109, 101, 116, 114, 121, 46, 115, 100, 107, 46, 110, 97, 109, 101, 18, 11, 10, 9, 101, 97, 115, 121, 116, 114, 97, 99, 101, 10, 162, 128, 128, 0, 10, 22, 116, 101, 108, 101, 109, 101, 116, 114, 121, 46, 115, 100, 107, 46, 108, 97, 110, 103, 117, 97, 103, 101, 18, 8, 10, 6, 100, 111, 116, 110, 101, 116, 10, 160, 128, 128, 0, 10, 21, 116, 101, 108, 101, 109, 101, 116, 114, 121, 46, 115, 100, 107, 46, 118, 101, 114, 115, 105, 111, 110, 18, 7, 10, 5, 49, 46, 48, 46, 48, 10, 153, 128, 128, 0, 10, 12, 115, 101, 114, 118, 105, 99, 101, 46, 110, 97, 109, 101, 18, 9, 10, 7, 117, 110, 107, 110, 111, 119, 110, 18, 168, 129, 128, 0, 10, 149, 128, 128, 0, 10, 19, 65, 99, 116, 105, 118, 105, 116, 121, 69, 120, 112, 111, 114, 116, 84, 101, 115, 116, 115, 18, 194, 128, 128, 0, 10, 16, 10, 247, 101, 25, 22, 205, 67, 221, 132, 72, 235, 33, 28, 128, 49, 156, 18, 8, 185, 173, 107, 113, 105, 32, 51, 49, 133, 1, 1, 1, 0, 0, 42, 10, 72, 116, 116, 112, 69, 120, 112, 111, 114, 116, 48, 1, 57, 32, 78, 67, 82, 207, 76, 35, 13, 65, 48, 117, 67, 82, 207, 76, 35, 13, 18, 194, 128, 128, 0, 10, 16, 10, 247, 101, 25, 22, 205, 67, 221, 132, 72, 235, 33, 28, 128, 49, 156, 18, 8, 183, 173, 107, 113, 105, 32, 51, 49, 133, 1, 1, 1, 0, 0, 42, 10, 72, 116, 116, 112, 69, 120, 112, 111, 114, 116, 48, 1, 57, 16, 39, 67, 82, 207, 76, 35, 13, 65, 64, 156, 67, 82, 207, 76, 35, 13", + "value": "0a898380000a908180000aa18080000a1274656c656d657472792e73646b2e6e616d65120b0a096561737974726163650aa28080000a1674656c656d657472792e73646b2e6c616e677561676512080a06646f746e65740aa08080000a1574656c656d657472792e73646b2e76657273696f6e12070a05312e302e300a998080000a0c736572766963652e6e616d6512090a07756e6b6e6f776e12ef8180000a958080000a1341637469766974794578706f7274546573747312c28080000a1001f7651916cd43dd8448eb211c80319c1208b1ad6b71692033318501010100002a0a487474704578706f727430013910274352cf4c230d41204e4352cf4c230d12c28080000a1002f7651916cd43dd8448eb211c80319c1208b2ad6b71692033318501010100002a0a487474704578706f727430013930754352cf4c230d41409c4352cf4c230d12c28080000a100a37651916cd43dd8448eb211c80319c1208b73d6b71692033318501010100002a0a487474704578706f727430013950c34352cf4c230d4160ea4352cf4c230d, +0a9d8380000a908180000aa18080000a1274656c656d657472792e73646b2e6e616d65120b0a096561737974726163650aa28080000a1674656c656d657472792e73646b2e6c616e677561676512080a06646f746e65740aa08080000a1574656c656d657472792e73646b2e76657273696f6e12070a05312e302e300a998080000a0c736572766963652e6e616d6512090a07756e6b6e6f776e12838280000a958080000a1341637469766974794578706f7274546573747312cc8080000a100af4651916cd43dd8448eb211c80319c1208b7ad5b71692033312208b7a46b71692033318501010100002a0a487474704578706f727430013980384452cf4c230d41905f4452cf4c230d12cc8080000a100af4651916cd43dd8448eb211c80319c1208b7ad6671692033312208b7a46b71692033318501010100002a0a487474704578706f7274300139a0864452cf4c230d41b0ad4452cf4c230d12c28080000a100af4651916cd43dd8448eb211c80319c1208b7a46b71692033318501010100002a0a487474704578706f727430013970114452cf4c230d41c0d44452cf4c230d, +0a9d8380000a908180000aa18080000a1274656c656d657472792e73646b2e6e616d65120b0a096561737974726163650aa28080000a1674656c656d657472792e73646b2e6c616e677561676512080a06646f746e65740aa08080000a1574656c656d657472792e73646b2e76657273696f6e12070a05312e302e300a998080000a0c736572766963652e6e616d6512090a07756e6b6e6f776e12838280000a958080000a1341637469766974794578706f7274546573747312cc8080000a100af7551916cd43dd8448eb211c80319c1208b7ad6b71992033312208b7ad6b78692033318501010100002a0a487474704578706f7274300139f0494552cf4c230d4100714552cf4c230d12cc8080000a100af7551916cd43dd8448eb211c80319c1208b7ad6b78692033312208b7ad6b71692033318501010100002a0a487474704578706f7274300139e0224552cf4c230d4110984552cf4c230d12c28080000a100af7551916cd43dd8448eb211c80319c1208b7ad6b71692033318501010100002a0a487474704578706f7274300139d0fb4452cf4c230d4120bf4552cf4c230d", }, ] diff --git a/src/EasyTrace.Tests/TestData/MoqExportInMemory.cs b/src/EasyTrace.Tests/TestData/MoqExportInMemory.cs index cdd2a97..b1c0326 100644 --- a/src/EasyTrace.Tests/TestData/MoqExportInMemory.cs +++ b/src/EasyTrace.Tests/TestData/MoqExportInMemory.cs @@ -12,6 +12,7 @@ public void Export(scoped in TraceActivityRef activityRef) Items.Add( $"{nameof(ITraceActivity.TraceId)}: {Convert.ToHexStringLower(activityRef.TraceId.AsReadOnlySpan())}|" + $"{nameof(ITraceActivity.SpanId)}: {Convert.ToHexStringLower(activityRef.SpanId.AsReadOnlySpan())}|" + + $"{nameof(ITraceActivity.ParentId)}: {Convert.ToHexStringLower(activityRef.ParentId.AsReadOnlySpan())}|" + $"{nameof(ITraceActivity.Source)}: {activityRef.Source.Name} {activityRef.Source.Version}|" + $"{nameof(ITraceActivity.OperationName)}: {activityRef.OperationName}|" + $"{nameof(ITraceActivity.Kind)}: {activityRef.Kind}|" + diff --git a/src/EasyTrace.Tests/TestData/MoqIdentGenerator.cs b/src/EasyTrace.Tests/TestData/MoqIdentGenerator.cs index 5a98fe6..bfc5c4b 100644 --- a/src/EasyTrace.Tests/TestData/MoqIdentGenerator.cs +++ b/src/EasyTrace.Tests/TestData/MoqIdentGenerator.cs @@ -15,26 +15,29 @@ public static MoqIdentGenerator Sequence(int activityCount) { const string traceIdStr = "0af7651916cd43dd8448eb211c80319c"; const string spanIdStr = "b7ad6b7169203331"; - const string hexCharStr = "0123456789abcdef"; + // A maximum of 48 non-duplicate changes are allowed, after which duplicates begin. + // This should be sufficient for testing + const string saltCharStr = "0123456789abcdeffedcba987654321098765fedcba43210"; var charIndex = 0; - // count of activities, each activity will require its own traceId and spanId. - activityCount *= 2; var traceIds = Enumerable.Range(0, activityCount) .Select(i => { var traceIdChars = traceIdStr.ToCharArray(); - traceIdChars[i % 5 + 1] = hexCharStr[++charIndex % hexCharStr.Length]; - return ActivityTraceId.CreateFromString(new string(traceIdChars)); + var charSelected = i % traceIdStr.Length; + traceIdChars[charSelected == 0 ? 1 : charSelected] = saltCharStr[++charIndex % saltCharStr.Length]; + return ActivityTraceId.CreateFromString(traceIdChars); }) .ToArray(); + charIndex = 0; var spanIds = Enumerable.Range(0, activityCount) .Select(i => { var spanIdChars = spanIdStr.ToCharArray(); - spanIdChars[i % 5 + 1] = hexCharStr[++charIndex % hexCharStr.Length]; + var charSelected = i % spanIdStr.Length; + spanIdChars[charSelected == 0 ? 1 : charSelected] = saltCharStr[++charIndex % saltCharStr.Length]; return ActivitySpanId.CreateFromString(spanIdChars); }) .ToArray(); diff --git a/src/EasyTrace/Activity/ITraceActivity.cs b/src/EasyTrace/Activity/ITraceActivity.cs index 6446ce8..c72acc7 100644 --- a/src/EasyTrace/Activity/ITraceActivity.cs +++ b/src/EasyTrace/Activity/ITraceActivity.cs @@ -7,6 +7,7 @@ public interface ITraceActivity { TraceIdentifier TraceId { get; } TraceIdentifier SpanId { get; } + TraceIdentifier ParentId { get; } TraceActivitySource Source { get; } string OperationName { get; } ActivityKind Kind { get; } diff --git a/src/EasyTrace/Activity/TraceActivity.cs b/src/EasyTrace/Activity/TraceActivity.cs index a3ffa6b..ee5a731 100644 --- a/src/EasyTrace/Activity/TraceActivity.cs +++ b/src/EasyTrace/Activity/TraceActivity.cs @@ -10,6 +10,7 @@ public class TraceActivity : ITraceActivity, ICopiable public TraceIdentifier TraceId { get; } = TraceIdentifier.CreateTraceId(); public TraceIdentifier SpanId { get; } = TraceIdentifier.CreateSpanId(); + public TraceIdentifier ParentId { get; } = TraceIdentifier.CreateSpanId(); public TraceActivitySource Source { get; internal set; } = TraceActivitySource.Empty; public string OperationName { get; set; } = string.Empty; public ActivityKind Kind { get; set; } @@ -18,12 +19,15 @@ public class TraceActivity : ITraceActivity, ICopiable public TimeSpan Duration => EndTime - StartTime; public bool Recorded { get; set; } public bool RemoteParent { get; set; } - + public TraceActivity? Parent { get; set; } + public void Clear() { OperationName = string.Empty; StartTime = DateTime.MinValue; EndTime = DateTime.MinValue; + ParentId.Clear(); + Parent = null; } public void CopyFrom(TraceActivity source) @@ -37,6 +41,7 @@ public void CopyTo(TraceActivity destination) destination.OperationName = OperationName; destination.TraceId.CopyFrom(TraceId); destination.SpanId.CopyFrom(SpanId); + destination.ParentId.CopyFrom(ParentId); destination.StartTime = StartTime; destination.EndTime = EndTime; destination.Recorded = Recorded; diff --git a/src/EasyTrace/Activity/TraceActivityRef.cs b/src/EasyTrace/Activity/TraceActivityRef.cs index 0e2d48d..7c05101 100644 --- a/src/EasyTrace/Activity/TraceActivityRef.cs +++ b/src/EasyTrace/Activity/TraceActivityRef.cs @@ -9,6 +9,7 @@ public readonly ref struct TraceActivityRef(TraceActivity activity) { public TraceIdentifier TraceId => activity.TraceId; public TraceIdentifier SpanId => activity.SpanId; + public TraceIdentifier ParentId => activity.ParentId; public TraceActivitySource Source => activity.Source; public string OperationName => activity.OperationName; diff --git a/src/EasyTrace/Export/Otlp/Protobuf/ProtobufSerializer.cs b/src/EasyTrace/Export/Otlp/Protobuf/ProtobufSerializer.cs index 92a70ed..96d1740 100644 --- a/src/EasyTrace/Export/Otlp/Protobuf/ProtobufSerializer.cs +++ b/src/EasyTrace/Export/Otlp/Protobuf/ProtobufSerializer.cs @@ -99,6 +99,11 @@ private static void WriteActivity(ProtobufStream stream, scoped in TraceActivity stream.WriteByteArrayWithTag(ProtobufFieldNumber.TraceId, activity.TraceId.AsReadOnlySpan()); stream.WriteByteArrayWithTag(ProtobufFieldNumber.SpanId, activity.SpanId.AsReadOnlySpan()); + if (activity.ParentId.IsNotEmpty) + { + stream.WriteByteArrayWithTag(ProtobufFieldNumber.ParentId, activity.ParentId.AsReadOnlySpan()); + } + var activityTraceFlags = activity.Recorded ? ActivityTraceFlags.Recorded : ActivityTraceFlags.None; var spanFlags = (uint)activityTraceFlags & 0x000000FF; diff --git a/src/EasyTrace/Identifier/TraceIdentifier.cs b/src/EasyTrace/Identifier/TraceIdentifier.cs index 5a8ae76..9d36bd8 100644 --- a/src/EasyTrace/Identifier/TraceIdentifier.cs +++ b/src/EasyTrace/Identifier/TraceIdentifier.cs @@ -4,6 +4,9 @@ public class TraceIdentifier(int byteLength) { private readonly byte[] _bytes = new byte[byteLength]; + public bool IsEmpty { get; private set; } = true; + public bool IsNotEmpty => !IsEmpty; + public static TraceIdentifier CreateTraceId() => new(16); public static TraceIdentifier CreateSpanId() => new(8); @@ -11,16 +14,23 @@ public class TraceIdentifier(int byteLength) public void Generate(ITraceIdentifierGenerator generator) { generator.Generate(_bytes.AsSpan(0, byteLength)); + IsEmpty = false; + } + + public void Clear() + { + IsEmpty = true; } public void CopyFrom(TraceIdentifier source) { + IsEmpty = source.IsEmpty; source.AsReadOnlySpan().CopyTo(_bytes); } public ReadOnlySpan AsReadOnlySpan() { - return new ReadOnlySpan(_bytes, 0, byteLength); + return IsEmpty ? ReadOnlySpan.Empty : new ReadOnlySpan(_bytes, 0, byteLength); } public bool SequenceEqual(TraceIdentifier other) diff --git a/src/EasyTrace/TraceActivitySource.cs b/src/EasyTrace/TraceActivitySource.cs index 7543369..25efe26 100644 --- a/src/EasyTrace/TraceActivitySource.cs +++ b/src/EasyTrace/TraceActivitySource.cs @@ -12,7 +12,7 @@ namespace EasyTrace; public class TraceActivitySource(string name, Version? version = null) : IDisposable { - private static readonly ThreadLocal ParentActivityByThreadLocal = new(); + private readonly ThreadLocal _parentActivityByThreadLocal = new(); internal static readonly TraceActivitySource Empty = new(nameof(Empty)); @@ -24,10 +24,10 @@ public class TraceActivitySource(string name, Version? version = null) : IDispos private bool _disposed; - private static TraceActivity? Parent + private TraceActivity? Parent { - get => ParentActivityByThreadLocal.Value; - set => ParentActivityByThreadLocal.Value = value; + get => _parentActivityByThreadLocal.Value; + set => _parentActivityByThreadLocal.Value = value; } public string Name { get; } = name; @@ -47,10 +47,14 @@ private static TraceActivity? Parent if (Parent == null) { + activity.Parent = null; + activity.ParentId.Clear(); activity.TraceId.Generate(IdentifierGenerator); } else { + activity.Parent = Parent; + activity.ParentId.CopyFrom(Parent.SpanId); activity.TraceId.CopyFrom(Parent.TraceId); } @@ -63,7 +67,7 @@ private static TraceActivity? Parent // TODO: Support mark if parent is remote. activity.RemoteParent = false; - Parent ??= activity; + Parent = activity; scoped var activityRef = new TraceActivityRef(activity); GroupInterceptor?.Start(activityRef); @@ -80,20 +84,15 @@ public void Stop(TraceActivity activity) activity.EndTime = TimeProvider.GetDateTime(); } + Parent = activity.Parent; scoped var activityRef = new TraceActivityRef(activity); GroupInterceptor?.Stop(in activityRef); BatchExporter?.Handle(in activityRef); - - if (Parent == activity) - { - Parent = null; - } - - activity.Clear(); } finally { + activity.Clear(); TraceActivityPool.Shared.Return(activity); } }