@@ -104,3 +104,29 @@ extension String {
104
104
bytes. append ( UInt8 ( ascii: " \" " ) )
105
105
}
106
106
}
107
+
108
+ extension AmazonHeaders {
109
+ /// Generates (X-Ray) trace ID.
110
+ /// # Trace ID Format
111
+ /// A `trace_id` consists of three numbers separated by hyphens.
112
+ /// For example, `1-58406520-a006649127e371903a2de979`. This includes:
113
+ /// - The version number, that is, 1.
114
+ /// - The time of the original request, in Unix epoch time, in **8 hexadecimal digits**.
115
+ /// For example, 10:00AM December 1st, 2016 PST in epoch time is `1480615200` seconds, or `58406520` in hexadecimal digits.
116
+ /// - A 96-bit identifier for the trace, globally unique, in **24 hexadecimal digits**.
117
+ /// # References
118
+ /// - [Generating trace IDs](https://docs.aws.amazon.com/xray/latest/devguide/xray-api-sendingdata.html#xray-api-traceids)
119
+ /// - [Tracing header](https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader)
120
+ internal static func generateXRayTraceID( ) -> String {
121
+ // The version number, that is, 1.
122
+ let version : UInt = 1
123
+ // The time of the original request, in Unix epoch time, in 8 hexadecimal digits.
124
+ let now = UInt32 ( DispatchWallTime . now ( ) . millisSinceEpoch / 1000 )
125
+ let dateValue = String ( now, radix: 16 , uppercase: false )
126
+ let datePadding = String ( repeating: " 0 " , count: max ( 0 , 8 - dateValue. count) )
127
+ // A 96-bit identifier for the trace, globally unique, in 24 hexadecimal digits.
128
+ let identifier = String ( UInt64 . random ( in: UInt64 . min ... UInt64 . max) | 1 << 63 , radix: 16 , uppercase: false )
129
+ + String( UInt32 . random ( in: UInt32 . min ... UInt32 . max) | 1 << 31 , radix: 16 , uppercase: false )
130
+ return " \( version) - \( datePadding) \( dateValue) - \( identifier) "
131
+ }
132
+ }
0 commit comments