Skip to content

Commit 97849df

Browse files
committed
Send telemetry when it fails to generate token, open conversation, or refresh token
1 parent adfe00d commit 97849df

File tree

3 files changed

+72
-51
lines changed

3 files changed

+72
-51
lines changed

shell/agents/Microsoft.Azure.Agent/ChatSession.cs

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,8 @@ internal async Task<string> RefreshAsync(IStatusContext context, bool force, Can
8787
}
8888
}
8989

90-
try
91-
{
92-
_token = await GenerateTokenAsync(context, cancellationToken);
93-
return await StartConversationAsync(context, cancellationToken);
94-
}
95-
catch (Exception)
96-
{
97-
Reset();
98-
throw;
99-
}
90+
_token = await GenerateTokenAsync(context, cancellationToken);
91+
return await OpenConversationAsync(context, cancellationToken);
10092
}
10193

10294
private void Reset()
@@ -113,57 +105,83 @@ private void Reset()
113105

114106
private async Task<string> GenerateTokenAsync(IStatusContext context, CancellationToken cancellationToken)
115107
{
116-
context.Status("Get Azure CLI login token ...");
117-
// Get an access token from the AzCLI login, using the specific audience guid.
118-
AccessToken accessToken = await new AzureCliCredential()
119-
.GetTokenAsync(
120-
new TokenRequestContext(["7000789f-b583-4714-ab18-aef39213018a/.default"]),
121-
cancellationToken);
122-
123-
context.Status("Request for DirectLine token ...");
124-
StringContent content = new("{\"conversationType\": \"Chat\"}", Encoding.UTF8, Utils.JsonContentType);
125-
HttpRequestMessage request = new(HttpMethod.Post, DL_TOKEN_URL) { Content = content };
126-
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
108+
try
109+
{
110+
context.Status("Get Azure CLI login token ...");
111+
// Get an access token from the AzCLI login, using the specific audience guid.
112+
AccessToken accessToken = await new AzureCliCredential()
113+
.GetTokenAsync(
114+
new TokenRequestContext(["7000789f-b583-4714-ab18-aef39213018a/.default"]),
115+
cancellationToken);
116+
117+
context.Status("Request for DirectLine token ...");
118+
StringContent content = new("{\"conversationType\": \"Chat\"}", Encoding.UTF8, Utils.JsonContentType);
119+
HttpRequestMessage request = new(HttpMethod.Post, DL_TOKEN_URL) { Content = content };
120+
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Token);
121+
122+
HttpResponseMessage response = await _httpClient.SendAsync(request, cancellationToken);
123+
response.EnsureSuccessStatusCode();
127124

128-
HttpResponseMessage response = await _httpClient.SendAsync(request, cancellationToken);
129-
response.EnsureSuccessStatusCode();
125+
using Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken);
126+
var dlToken = JsonSerializer.Deserialize<DirectLineToken>(stream, Utils.JsonOptions);
127+
return dlToken.DirectLine.Token;
128+
}
129+
catch (Exception e)
130+
{
131+
if (e is not OperationCanceledException)
132+
{
133+
Telemetry.Trace(AzTrace.Exception("Failed to generate the initial DL token."), e);
134+
}
130135

131-
using Stream stream = await response.Content.ReadAsStreamAsync(cancellationToken);
132-
var dlToken = JsonSerializer.Deserialize<DirectLineToken>(stream, Utils.JsonOptions);
133-
return dlToken.DirectLine.Token;
136+
Reset();
137+
throw;
138+
}
134139
}
135140

136-
private async Task<string> StartConversationAsync(IStatusContext context, CancellationToken cancellationToken)
141+
private async Task<string> OpenConversationAsync(IStatusContext context, CancellationToken cancellationToken)
137142
{
138-
context.Status("Start a new chat session ...");
139-
HttpRequestMessage request = new(HttpMethod.Post, CONVERSATION_URL);
140-
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
143+
try
144+
{
145+
context.Status("Start a new chat session ...");
146+
HttpRequestMessage request = new(HttpMethod.Post, CONVERSATION_URL);
147+
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
141148

142-
HttpResponseMessage response = await _httpClient.SendAsync(request, cancellationToken);
143-
response.EnsureSuccessStatusCode();
149+
HttpResponseMessage response = await _httpClient.SendAsync(request, cancellationToken);
150+
response.EnsureSuccessStatusCode();
144151

145-
using Stream content = await response.Content.ReadAsStreamAsync(cancellationToken);
146-
SessionPayload spl = JsonSerializer.Deserialize<SessionPayload>(content, Utils.JsonOptions);
152+
using Stream content = await response.Content.ReadAsStreamAsync(cancellationToken);
153+
SessionPayload spl = JsonSerializer.Deserialize<SessionPayload>(content, Utils.JsonOptions);
147154

148-
_token = spl.Token;
149-
_conversationId = spl.ConversationId;
150-
_conversationUrl = $"{CONVERSATION_URL}/{_conversationId}/activities";
151-
_streamUrl = spl.StreamUrl;
152-
_expireOn = DateTime.UtcNow.AddSeconds(spl.ExpiresIn);
153-
_copilotReceiver = await AzureCopilotReceiver.CreateAsync(_streamUrl);
155+
_token = spl.Token;
156+
_conversationId = spl.ConversationId;
157+
_conversationUrl = $"{CONVERSATION_URL}/{_conversationId}/activities";
158+
_streamUrl = spl.StreamUrl;
159+
_expireOn = DateTime.UtcNow.AddSeconds(spl.ExpiresIn);
160+
_copilotReceiver = await AzureCopilotReceiver.CreateAsync(_streamUrl);
154161

155-
Log.Debug("[ChatSession] Conversation started. Id: {0}", _conversationId);
162+
Log.Debug("[ChatSession] Conversation started. Id: {0}", _conversationId);
156163

157-
while (true)
164+
while (true)
165+
{
166+
CopilotActivity activity = _copilotReceiver.Take(cancellationToken);
167+
if (activity.IsMessage && activity.IsFromCopilot && _copilotReceiver.Watermark is 0)
168+
{
169+
activity.ExtractMetadata(out _, out ConversationState conversationState);
170+
int chatNumber = conversationState.DailyConversationNumber;
171+
int requestNumber = conversationState.TurnNumber;
172+
return $"{activity.Text}\nThis is chat #{chatNumber}, request #{requestNumber}.\n";
173+
}
174+
}
175+
}
176+
catch (Exception e)
158177
{
159-
CopilotActivity activity = _copilotReceiver.Take(cancellationToken);
160-
if (activity.IsMessage && activity.IsFromCopilot && _copilotReceiver.Watermark is 0)
178+
if (e is not OperationCanceledException)
161179
{
162-
activity.ExtractMetadata(out _, out ConversationState conversationState);
163-
int chatNumber = conversationState.DailyConversationNumber;
164-
int requestNumber = conversationState.TurnNumber;
165-
return $"{activity.Text}\nThis is chat #{chatNumber}, request #{requestNumber}.\n";
180+
Telemetry.Trace(AzTrace.Exception("Failed to open conversation with the initial DL token."), e);
166181
}
182+
183+
Reset();
184+
throw;
167185
}
168186
}
169187

@@ -216,6 +234,7 @@ private async Task RenewTokenAsync(CancellationToken cancellationToken)
216234
catch (Exception e) when (e is not OperationCanceledException)
217235
{
218236
Reset();
237+
Telemetry.Trace(AzTrace.Exception("Failed to refresh the DL token."), e);
219238
throw new TokenRequestException($"Failed to refresh the 'DirectLine' token: {e.Message}.", e);
220239
}
221240
}

shell/agents/Microsoft.Azure.Agent/DataRetriever.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ private AzCLICommand QueryForMetadata(string azCommand)
586586
["Command"] = azCommand,
587587
["Message"] = "AzCLI metadata service returns unsuccessful status code for query."
588588
};
589-
Telemetry.Trace(AzTrace.Exception(response: null, details));
589+
Telemetry.Trace(AzTrace.Exception(details));
590590
}
591591
}
592592
}
@@ -600,7 +600,7 @@ private AzCLICommand QueryForMetadata(string azCommand)
600600
["Command"] = azCommand,
601601
["Message"] = "AzCLI metadata query and process raised an exception."
602602
};
603-
Telemetry.Trace(AzTrace.Exception(response: null, details), e);
603+
Telemetry.Trace(AzTrace.Exception(details), e);
604604
}
605605
}
606606

shell/agents/Microsoft.Azure.Agent/Telemetry.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ internal static AzTrace Exception(CopilotResponse response, object details)
132132
// Don't create an object when telemetry is disabled.
133133
return null;
134134
}
135+
136+
internal static AzTrace Exception(object details) => Exception(response: null, details);
135137
}
136138

137139
internal class Telemetry
@@ -231,7 +233,7 @@ internal static void Initialize()
231233
internal static void Trace(AzTrace trace) => s_singleton?.LogTelemetry(trace, exception: null);
232234

233235
/// <summary>
234-
/// Trace a telemetry metric and an Exception with it.
236+
/// Trace a telemetry metric and an exception with it.
235237
/// The method does nothing when telemetry is disabled.
236238
/// </summary>
237239
internal static void Trace(AzTrace trace, Exception exception) => s_singleton?.LogTelemetry(trace, exception);

0 commit comments

Comments
 (0)