1+ // -----------------------------------------------------------------------
2+ // <copyright file="TraceTestSteps.cs" company="Microsoft Corp.">
3+ // Copyright (c) Microsoft Corp. All rights reserved.
4+ // </copyright>
5+ // -----------------------------------------------------------------------
6+
7+ namespace Common . Monitoring . Tests . Steps
8+ {
9+ using System ;
10+ using System . IO ;
11+ using System . Linq ;
12+ using System . Text . Json ;
13+ using Common . Monitoring . Utils ;
14+ using FluentAssertions ;
15+ using Reqnroll ;
16+
17+ [ Binding ]
18+ public class ConvertTraceSteps
19+ {
20+ private readonly ScenarioContext context ;
21+ private readonly IReqnrollOutputHelper outputHelper ;
22+
23+ public ConvertTraceSteps ( ScenarioContext context , IReqnrollOutputHelper outputHelper )
24+ {
25+ this . context = context ;
26+ this . outputHelper = outputHelper ;
27+ }
28+
29+ [ Given ( "otlp trace file at \" ([^\" ]+)\" " ) ]
30+ public void GivenOtlpTraceFileAt ( string otlpTraceFile )
31+ {
32+ this . context . Set ( otlpTraceFile , "otlpTraceFile" ) ;
33+ }
34+
35+ [ When ( "I export the trace to a temp folder \" ([^\" ]+)\" " ) ]
36+ public void WhenIExportTheTraceToATempFile ( string tempTraceFolder )
37+ {
38+ var otlpTraceFile = this . context . Get < string > ( "otlpTraceFile" ) ;
39+ this . outputHelper . WriteLine ( $ "reading otlp trace file { otlpTraceFile } ...") ;
40+ var parser = new OtlpTraceParser ( ) ;
41+ var parsedTempTraces = parser . TempoTraceFromOtlpJsonFile ( otlpTraceFile ) ;
42+ this . outputHelper . WriteLine ( $ "parsed { parsedTempTraces . Count } traces from otlp trace file { otlpTraceFile } ...") ;
43+
44+ this . context . Set ( tempTraceFolder , "tempTraceFolder" ) ;
45+ if ( ! Directory . Exists ( tempTraceFolder ) )
46+ {
47+ Directory . CreateDirectory ( tempTraceFolder ) ;
48+ }
49+
50+ foreach ( var trace in parsedTempTraces )
51+ {
52+ var traceId = trace . traceId ;
53+ var root = trace . root ;
54+ var firstSpan = root . Batches
55+ . SelectMany ( b => b . InstrumentationLibrarySpans )
56+ . SelectMany ( s => s . Spans )
57+ . OrderBy ( s => s . StartTimeUnixNano )
58+ . FirstOrDefault ( ) ;
59+ if ( firstSpan == null )
60+ {
61+ continue ;
62+ }
63+
64+ var unixMilliseconds = firstSpan . StartTimeUnixNano / 1_000_000 ;
65+ var spanStartTime = DateTimeOffset . FromUnixTimeMilliseconds ( ( long ) unixMilliseconds ) . UtcDateTime ;
66+ var traceFileName = $ "{ spanStartTime . ToLocalTime ( ) : yyyyMMdd-HHmm} -{ firstSpan . Name } -{ traceId . Substring ( 0 , 6 ) } .json";
67+ var invalidChars = Path . GetInvalidFileNameChars ( ) ;
68+ var sanitizedFileName = new string ( traceFileName . Select ( c => invalidChars . Contains ( c ) ? '_' : c ) . ToArray ( ) ) ;
69+ var tempTraceFile = Path . Combine ( tempTraceFolder , sanitizedFileName ) ;
70+ File . WriteAllText ( tempTraceFile , JsonSerializer . Serialize ( root , parser . Options ) ) ;
71+ }
72+ }
73+
74+ [ Then ( "the temp files should exist" ) ]
75+ public void ThenTheTempFileShouldExist ( )
76+ {
77+ var tempTraceFolder = this . context . Get < string > ( "tempTraceFolder" ) ;
78+ var tempTraceFiles = Directory . GetFiles ( tempTraceFolder ) ;
79+ tempTraceFiles . Should ( ) . NotBeEmpty ( ) ;
80+ }
81+ }
82+ }
0 commit comments