@@ -23,62 +23,140 @@ internal sealed class HttpClientLatencyLogEnricher : IHttpClientLogEnricher
2323{
2424 private static readonly ObjectPool < StringBuilder > _builderPool = PoolFactory . SharedStringBuilderPool ;
2525 private readonly HttpClientLatencyContext _latencyContext ;
26-
26+ private readonly HttpLatencyMediator _httpLatencyMediator ;
2727 private readonly CheckpointToken _enricherInvoked ;
2828
29- public HttpClientLatencyLogEnricher ( HttpClientLatencyContext latencyContext , ILatencyContextTokenIssuer tokenIssuer )
29+ public HttpClientLatencyLogEnricher (
30+ HttpClientLatencyContext latencyContext ,
31+ ILatencyContextTokenIssuer tokenIssuer ,
32+ HttpLatencyMediator httpLatencyMediator )
3033 {
3134 _latencyContext = latencyContext ;
35+ _httpLatencyMediator = httpLatencyMediator ;
3236 _enricherInvoked = tokenIssuer . GetCheckpointToken ( HttpCheckpoints . EnricherInvoked ) ;
3337 }
3438
35- public void Enrich ( IEnrichmentTagCollector collector , HttpRequestMessage request , HttpResponseMessage ? response , Exception ? exception )
39+ public void Enrich ( IEnrichmentTagCollector collector , HttpRequestMessage ? request , HttpResponseMessage ? response , Exception ? exception )
3640 {
3741 if ( response != null )
3842 {
3943 var lc = _latencyContext . Get ( ) ;
40- lc ? . AddCheckpoint ( _enricherInvoked ) ;
41-
42- StringBuilder stringBuilder = _builderPool . Get ( ) ;
43-
44- // Add serverName, checkpoints to outgoing http logs.
45- AppendServerName ( response . Headers , stringBuilder ) ;
46- _ = stringBuilder . Append ( ',' ) ;
4744
4845 if ( lc != null )
4946 {
50- AppendCheckpoints ( lc , stringBuilder ) ;
47+ // Add the checkpoint
48+ lc . AddCheckpoint ( _enricherInvoked ) ;
49+
50+ // Use the mediator to record all metrics
51+ _httpLatencyMediator . RecordEnd ( lc , response ) ;
5152 }
5253
53- collector . Add ( "LatencyInfo" , stringBuilder . ToString ( ) ) ;
54+ StringBuilder stringBuilder = _builderPool . Get ( ) ;
55+
56+ try
57+ {
58+ /* Add version, serverName, checkpoints, and measures to outgoing http logs.
59+ * Schemas: 1) ServerName,CheckpointName,CheckpointValue
60+ * 2) v1.0,ServerName,TagName,TagValue,CheckpointName,CheckpointValue,MetricName,MetricValue
61+ */
62+
63+ // Add version
64+ _ = stringBuilder . Append ( "v1.0" ) ;
65+ _ = stringBuilder . Append ( ',' ) ;
66+
67+ // Add server name
68+ AppendServerName ( response . Headers , stringBuilder ) ;
69+ _ = stringBuilder . Append ( ',' ) ;
70+
71+ // Add tags, checkpoints, and measures
72+ if ( lc != null )
73+ {
74+ AppendTags ( lc , stringBuilder ) ;
75+ _ = stringBuilder . Append ( ',' ) ;
76+
77+ AppendCheckpoints ( lc , stringBuilder ) ;
78+ _ = stringBuilder . Append ( ',' ) ;
5479
55- _builderPool . Return ( stringBuilder ) ;
80+ AppendMeasures ( lc , stringBuilder ) ;
81+ }
82+
83+ collector . Add ( "LatencyInfo" , stringBuilder . ToString ( ) ) ;
84+ }
85+ finally
86+ {
87+ _builderPool . Return ( stringBuilder ) ;
88+ }
5689 }
5790 }
5891
5992 private static void AppendServerName ( HttpHeaders headers , StringBuilder stringBuilder )
6093 {
6194 if ( headers . TryGetValues ( TelemetryConstants . ServerApplicationNameHeader , out var values ) )
6295 {
63- _ = stringBuilder . Append ( values ! . First ( ) ) ;
96+ _ = stringBuilder . Append ( values . First ( ) ) ;
6497 }
6598 }
6699
67100 private static void AppendCheckpoints ( ILatencyContext latencyContext , StringBuilder stringBuilder )
68101 {
102+ const int MillisecondsPerSecond = 1000 ;
103+
69104 var latencyData = latencyContext . LatencyData ;
70- for ( int i = 0 ; i < latencyData . Checkpoints . Length ; i ++ )
105+ var checkpointCount = latencyData . Checkpoints . Length ;
106+
107+ for ( int i = 0 ; i < checkpointCount ; i ++ )
71108 {
72109 _ = stringBuilder . Append ( latencyData . Checkpoints [ i ] . Name ) ;
73110 _ = stringBuilder . Append ( '/' ) ;
74111 }
75112
76113 _ = stringBuilder . Append ( ',' ) ;
77- for ( int i = 0 ; i < latencyData . Checkpoints . Length ; i ++ )
114+
115+ for ( int i = 0 ; i < checkpointCount ; i ++ )
116+ {
117+ var cp = latencyData . Checkpoints [ i ] ;
118+ _ = stringBuilder . Append ( ( long ) Math . Round ( ( ( double ) cp . Elapsed / cp . Frequency ) * MillisecondsPerSecond ) ) ;
119+ _ = stringBuilder . Append ( '/' ) ;
120+ }
121+ }
122+
123+ private static void AppendMeasures ( ILatencyContext latencyContext , StringBuilder stringBuilder )
124+ {
125+ var latencyData = latencyContext . LatencyData ;
126+ var measureCount = latencyData . Measures . Length ;
127+
128+ for ( int i = 0 ; i < measureCount ; i ++ )
129+ {
130+ _ = stringBuilder . Append ( latencyData . Measures [ i ] . Name ) ;
131+ _ = stringBuilder . Append ( '/' ) ;
132+ }
133+
134+ _ = stringBuilder . Append ( ',' ) ;
135+
136+ for ( int i = 0 ; i < measureCount ; i ++ )
137+ {
138+ _ = stringBuilder . Append ( latencyData . Measures [ i ] . Value ) ;
139+ _ = stringBuilder . Append ( '/' ) ;
140+ }
141+ }
142+
143+ private static void AppendTags ( ILatencyContext latencyContext , StringBuilder stringBuilder )
144+ {
145+ var latencyData = latencyContext . LatencyData ;
146+ var tagCount = latencyData . Tags . Length ;
147+
148+ for ( int i = 0 ; i < tagCount ; i ++ )
149+ {
150+ _ = stringBuilder . Append ( latencyData . Tags [ i ] . Name ) ;
151+ _ = stringBuilder . Append ( '/' ) ;
152+ }
153+
154+ _ = stringBuilder . Append ( ',' ) ;
155+
156+ for ( int i = 0 ; i < tagCount ; i ++ )
78157 {
79- var ms = ( ( double ) latencyData . Checkpoints [ i ] . Elapsed / latencyData . Checkpoints [ i ] . Frequency ) * 1000 ;
80- _ = stringBuilder . Append ( ms ) ;
158+ _ = stringBuilder . Append ( latencyData . Tags [ i ] . Value ) ;
81159 _ = stringBuilder . Append ( '/' ) ;
82160 }
83161 }
84- }
162+ }
0 commit comments