• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

microsoft / botbuilder-js / 12302726031

12 Dec 2024 06:40PM UTC coverage: 84.055% (-0.6%) from 84.691%
12302726031

Pull #4806

github

web-flow
Merge 87fc178f5 into 3b8fcab21
Pull Request #4806: feat: Support Sso for SharePoint bot ACEs

8149 of 10862 branches covered (75.02%)

Branch coverage included in aggregate %.

7 of 57 new or added lines in 5 files covered. (12.28%)

153 existing lines in 14 files now uncovered.

20438 of 23148 relevant lines covered (88.29%)

3457.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.46
/libraries/botbuilder-applicationinsights/src/applicationInsightsTelemetryClient.ts
1
/**
2
 * @module botbuilder-applicationinsights
3
 */
4
/**
5
 * Copyright (c) Microsoft Corporation. All rights reserved.
6
 * Licensed under the MIT License.
7
 */
8
import * as appInsights from 'applicationinsights';
1✔
9
import * as cls from 'cls-hooked';
1✔
10
import * as crypto from 'crypto';
1✔
11

12
import {
13
    Activity,
14
    BotTelemetryClient,
15
    BotPageViewTelemetryClient,
16
    TelemetryDependency,
17
    TelemetryEvent,
18
    TelemetryException,
19
    TelemetryTrace,
20
    TelemetryPageView,
21
} from 'botbuilder-core';
22

23
// This is the currently recommended work-around for using Application Insights with async/await
24
// https://github.com/Microsoft/ApplicationInsights-node.js/issues/296
25
// This allows AppInsights to automatically apply the appropriate context objects deep inside the async/await chain.
26
import {
1✔
27
    CorrelationContext,
28
    CorrelationContextManager,
29
} from 'applicationinsights/out/AutoCollection/CorrelationContextManager';
30

31
const origGetCurrentContext = CorrelationContextManager.getCurrentContext;
1✔
32
const ns = cls.createNamespace('my.request');
1✔
33

34
function getCurrentContext(): CorrelationContext {
35
    return ns.get('ctx') || origGetCurrentContext();
96✔
36
}
37

38
// Overwrite the built-in getCurrentContext() method with a new one.
39
CorrelationContextManager.getCurrentContext = getCurrentContext;
1✔
40

41
export const ApplicationInsightsWebserverMiddleware: any = (req: any, res: any, next: any): void => {
1✔
42
    // Check to see if the request contains an incoming request.
43
    // If so, set it into the Application Insights context.
44
    const activity: Partial<Activity> = req.body;
2✔
45
    if (activity && activity.id) {
2✔
46
        const context: CorrelationContext = appInsights.getCorrelationContext();
1✔
47
        context['activity'] = req.body;
1✔
48
    }
49

50
    ns.bindEmitter(req);
2✔
51
    ns.bindEmitter(res);
2✔
52
    ns.run((): void => {
2✔
53
        ns.set('ctx', origGetCurrentContext());
2✔
54
        next();
2✔
55
    });
56
};
57

58
/**
59
 * This is a wrapper class around the Application Insights node client.
60
 * This is primarily designed to be used alongside the WaterfallDialog telemetry collection.
61
 * It provides a pre-configured App Insights client, and wrappers around
62
 * the major tracking functions, allowing it to conform to Botbuilder's generic BotTelemetryClient interface.
63
 * To use it, create pass in an instrumentation key:
64
 *
65
 * ```
66
 * const myDialog = new WaterfallDialog('my_dialog', steps);
67
 * const appInsightsClient = new ApplicationInsightsTelemetryClient(my_instrumentation_key);
68
 * myDialog.telemetryClient = appInsightsClient;
69
 * ```
70
 */
71
export class ApplicationInsightsTelemetryClient implements BotTelemetryClient, BotPageViewTelemetryClient {
1✔
72
    private client: appInsights.TelemetryClient;
73
    private config: appInsights.Configuration;
74

75
    /**
76
     * Creates a new instance of the
77
     * [ApplicationInsightsTelemetryClient](xref:botbuilder-applicationinsights.ApplicationInsightsTelemetryClient)
78
     * class.
79
     *
80
     * @param connectionString The ApplicationInsights connection string.
81
     *
82
     * @remarks The settings parameter is passed directly into appInsights.setup().
83
     * https://www.npmjs.com/package/applicationinsights#basic-usage
84
     */
85
    constructor(connectionString: string);
86
    /**
87
     * Creates a new instance of the
88
     * [ApplicationInsightsTelemetryClient](xref:botbuilder-applicationinsights.ApplicationInsightsTelemetryClient)
89
     * class.
90
     *
91
     * @param instrumentationKey The ApplicationInsights instrumentation key.
92
     *
93
     * @remarks The settings parameter is passed directly into appInsights.setup().
94
     * https://www.npmjs.com/package/applicationinsights#basic-usage
95
     */
96
    constructor(instrumentationKey: string);
97

98
    /**
99
     * @internal
100
     */
101
    constructor(setupString: string) {
102
        this.config = appInsights
13✔
103
            .setup(setupString)
104
            .setAutoDependencyCorrelation(true)
105
            .setAutoCollectRequests(true)
106
            .setAutoCollectPerformance(true)
107
            .setAutoCollectExceptions(true)
108
            .setAutoCollectDependencies(true)
109
            .start();
110

111
        this.client = appInsights.defaultClient;
12✔
112

113
        this.client.addTelemetryProcessor(addBotIdentifiers);
12✔
114
    }
115

116
    // Protects against JSON.stringify cycles
117
    private toJSON(): unknown {
UNCOV
118
        return { name: 'ApplicationInsightsTelemetryClient' };
×
119
    }
120

121
    /**
122
     * Provides access to the Application Insights configuration that is running here.
123
     * Allows developers to adjust the options, for example:
124
     * `appInsightsClient.configuration.setAutoCollectDependencies(false)`
125
     *
126
     * @returns app insights configuration
127
     */
128
    get configuration(): appInsights.Configuration {
129
        return this.config;
1✔
130
    }
131

132
    /**
133
     * Provides direct access to the telemetry client object, which might be necessary for some operations.
134
     *
135
     * @returns app insights telemetry client
136
     */
137
    get defaultClient(): appInsights.TelemetryClient {
138
        return this.client;
9✔
139
    }
140

141
    /**
142
     * Sends information about an external dependency (outgoing call) in the application.
143
     *
144
     * @param telemetry The [TelemetryDependency](xref:botbuilder-core.TelemetryDependency) to track.
145
     */
146
    trackDependency(telemetry: TelemetryDependency): void {
147
        this.defaultClient.trackDependency(telemetry);
1✔
148
    }
149

150
    /**
151
     * Logs custom events with extensible named fields.
152
     *
153
     * @param telemetry The [TelemetryEvent](xref:botbuilder-core.TelemetryEvent) to track.
154
     */
155
    trackEvent(telemetry: TelemetryEvent): void {
156
        const { name, properties, metrics: measurements } = telemetry;
3✔
157
        this.defaultClient.trackEvent({ name, properties, measurements });
3✔
158
    }
159

160
    /**
161
     * Logs a system exception.
162
     *
163
     * @param telemetry The [TelemetryException](xref:botbuilder-core.TelemetryException) to track.
164
     */
165
    trackException(telemetry: TelemetryException): void {
166
        this.defaultClient.trackException(telemetry);
1✔
167
    }
168

169
    /**
170
     * Sends a trace message.
171
     *
172
     * @param telemetry The [TelemetryTrace](xref:botbuilder-core.TelemetryTrace) to track.
173
     */
174
    trackTrace(telemetry: TelemetryTrace): void {
175
        this.defaultClient.trackTrace(telemetry);
1✔
176
    }
177

178
    /**
179
     * Logs a dialog entry as an Application Insights page view.
180
     *
181
     * @param telemetry The [TelemetryPageView](xref:botbuilder-core.TelemetryPageView) to track.
182
     */
183
    trackPageView(telemetry: TelemetryPageView): void {
184
        this.defaultClient.trackPageView(telemetry);
1✔
185
    }
186

187
    /**
188
     * Flushes the in-memory buffer and any metrics being pre-aggregated.
189
     */
190
    flush(): void {
191
        this.defaultClient.flush();
1✔
192
    }
193
}
194

195
/* Define the telemetry initializer function which is responsible for setting the userId. sessionId and some other values
196
 * so that application insights can correlate related events.
197
 */
198
function addBotIdentifiers(envelope: appInsights.Contracts.Envelope, context: { [name: string]: any }): boolean {
199
    if (context.correlationContext && context.correlationContext.activity) {
7✔
200
        const activity: Partial<Activity> = context.correlationContext.activity;
2✔
201
        const telemetryItem: any = envelope.data['baseData']; // TODO: update when envelope ts definition includes baseData
2✔
202
        const userId: string = activity.from ? activity.from.id : '';
2✔
203
        const channelId: string = activity.channelId || '';
2✔
204
        const conversationId: string = activity.conversation ? activity.conversation.id : '';
2✔
205
        // Hashed ID is used due to max session ID length for App Insights session Id
206
        const sessionId: string = conversationId
2✔
207
            ? crypto.createHash('sha256').update(conversationId).digest('base64')
2✔
208
            : '';
209

210
        // set user id and session id
211
        envelope.tags[appInsights.defaultClient.context.keys.userId] = channelId + userId;
2✔
212
        envelope.tags[appInsights.defaultClient.context.keys.sessionId] = sessionId;
2✔
213

214
        // Add additional properties
215
        telemetryItem.properties = telemetryItem.properties || {};
2✔
216
        telemetryItem.properties.activityId = activity.id;
2✔
217
        telemetryItem.properties.channelId = channelId;
2✔
218
        telemetryItem.properties.activityType = activity.type;
2✔
219
        telemetryItem.properties.conversationId = conversationId;
2✔
220
    }
221

222
    return true;
7✔
223
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc