/
TelemetryQnAMaker.cs
129 lines (111 loc) · 6.04 KB
/
TelemetryQnAMaker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace SupportBot.Middleware.Telemetry
{
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.AI.QnA;
/// <summary>
/// MyAppInsightsQnARecognizer invokes the QnA Maker and logs some results into Application Insights.
/// Logs the score, and (optionally) question along with Conversation and ActivityID.
///
/// Customize for specific reporting needs.
///
/// The Custom Event name this logs is "QnAMessage"
/// See <seealso cref="QnAMaker"/> for additional information.
/// </summary>
public class TelemetryQnaMaker : QnAMaker
{
public static readonly string QnAMsgEvent = "QnAMessage";
/// <summary>
/// Initializes a new instance of the <see cref="TelemetryQnaMaker"/> class.
/// </summary>
/// <param name="endpoint">The endpoint of the knowledge base to query.</param>
/// <param name="options">The options for the QnA Maker knowledge base.</param>
/// <param name="logUserName">Option to log user name to Application Insights (PII consideration).</param>
/// <param name="logOriginalMessage">Option to log the original message to Application Insights (PII consideration).</param>
/// <param name="httpClient">An alternate client with which to talk to QnAMaker.
/// If null, a default client is used for this instance.</param>
public TelemetryQnaMaker(QnAMakerEndpoint endpoint, QnAMakerOptions options = null, bool logUserName = true, bool logOriginalMessage = true, HttpClient httpClient = null)
: base(endpoint, options, httpClient)
{
LogUserName = logUserName;
LogOriginalMessage = logOriginalMessage;
Endpoint = endpoint;
}
public bool LogUserName { get; }
public bool LogOriginalMessage { get; }
public QnAMakerEndpoint Endpoint { get; }
public new async Task<QueryResult[]> GetAnswersAsync(ITurnContext context, QnAMakerOptions options = null)
{
// Call QnA Maker
var queryResults = await base.GetAnswersAsync(context, options);
// Find the Bot Telemetry Client
if (queryResults != null && context.TurnState.TryGetValue(TelemetryLoggerMiddleware.AppInsightsServiceKey, out var telemetryClient))
{
var telemetryProperties = new Dictionary<string, string>();
var telemetryMetrics = new Dictionary<string, double>();
// For some customers, logging original text name within Application Insights might be an issue.
var text = context.Activity.Text;
if (LogOriginalMessage && !string.IsNullOrWhiteSpace(text))
{
telemetryProperties.Add(QnATelemetryConstants.OriginalQuestionProperty, text);
}
if (LogOriginalMessage && options.StrictFilters.Length > 0)
{
var metadata = this.GetMetadata(options.StrictFilters);
telemetryProperties.Add(QnATelemetryConstants.OriginalMetadataProperty, metadata);
}
// For some customers, logging user name within Application Insights might be an issue.
var userName = context.Activity.From.Name;
if (LogUserName && !string.IsNullOrWhiteSpace(userName))
{
telemetryProperties.Add(QnATelemetryConstants.UsernameProperty, userName);
}
// Fill in Qna Results (found or not)
if (queryResults.Length > 0)
{
for (var i = 0; i < queryResults.Length; i++)
{
var queryResult = queryResults[i];
telemetryProperties.Add(QnATelemetryConstants.QuestionProperty + i.ToString(), string.Join(",", queryResult.Questions));
telemetryProperties.Add(QnATelemetryConstants.AnswerProperty + i.ToString(), queryResult.Answer);
telemetryProperties.Add(QnATelemetryConstants.ScoreProperty + i.ToString(), queryResult.Score.ToString());
if (queryResult.Metadata.Length > 0)
{
var metadata = this.GetMetadata(queryResult.Metadata);
telemetryProperties.Add(QnATelemetryConstants.MetadataProperty + i.ToString(), metadata);
}
}
}
else
{
telemetryProperties.Add(QnATelemetryConstants.QuestionProperty, "No Qna Question matched");
telemetryProperties.Add(QnATelemetryConstants.AnswerProperty, "No Qna Question matched");
}
telemetryProperties.Add(TelemetryConstants.FromIdProperty, context.Activity.From.Id);
telemetryProperties.Add(TelemetryConstants.FromNameProperty, context.Activity.From.Name);
telemetryProperties.Add(SupportBot.Service.TelemetryConstants.ChannelId, context.Activity.ChannelId);
telemetryProperties.Add(SupportBot.Service.TelemetryConstants.ActivityId, context.Activity.Id);
if (context.Activity.ReplyToId != null)
{
telemetryProperties.Add(SupportBot.Service.TelemetryConstants.ReplyToId, context.Activity.ReplyToId);
}
// Track the event
((IBotTelemetryClient)telemetryClient).TrackEvent(QnAMsgEvent, telemetryProperties, telemetryMetrics);
}
return queryResults;
}
private string GetMetadata(Metadata[] metadatas)
{
var result = string.Empty;
foreach (var metadata in metadatas)
{
result = result + metadata.Name + ":" + metadata.Value + ";";
}
return result;
}
}
}