in appservice/src/startStreamingLogs.ts [49:105]
void callWithTelemetryAndErrorHandling('appService.streamingLogs', async (streamContext: IActionContext) => {
streamContext.errorHandling.suppressDisplay = true;
let timerId: NodeJS.Timer | undefined;
if (site.isFunctionApp) {
// For Function Apps, we have to ping "/admin/host/status" every minute for logging to work
// https://github.com/Microsoft/vscode-azurefunctions/issues/227
await pingFunctionApp(streamContext, site);
// eslint-disable-next-line @typescript-eslint/no-misused-promises
timerId = setInterval(async () => await pingFunctionApp(streamContext, site), 60 * 1000);
}
const genericClient: ServiceClient = await createGenericClient(streamContext, new BasicAuthenticationCredentials(creds.publishingUserName, nonNullProp(creds, 'publishingPassword')));
const abortController: AbortController = new AbortController();
const logsResponse: HttpOperationResponse = await genericClient.sendRequest({
method: 'GET',
url: `${site.kuduUrl}/api/logstream/${logsPath}`,
streamResponseBody: true,
abortSignal: abortController.signal
});
await new Promise<void>((onLogStreamEnded: () => void, reject: (err: Error) => void): void => {
const newLogStream: ILogStream = {
dispose: (): void => {
logsResponse.readableStreamBody?.removeAllListeners();
abortController.abort();
outputChannel.show();
if (timerId) {
clearInterval(timerId);
}
outputChannel.appendLine(localize('logStreamDisconnected', 'Disconnected from log-streaming service.'));
newLogStream.isConnected = false;
void onLogStreamEnded();
},
isConnected: true,
outputChannel: outputChannel
};
logsResponse.readableStreamBody?.on('data', (chunk: Buffer | string) => {
outputChannel.append(chunk.toString());
}).on('error', (err: Error) => {
if (timerId) {
clearInterval(timerId);
}
newLogStream.isConnected = false;
outputChannel.show();
outputChannel.appendLine(localize('logStreamError', 'Error connecting to log-streaming service:'));
outputChannel.appendLine(parseError(err).message);
reject(err);
}).on('complete', () => {
newLogStream.dispose();
});
logStreams.set(logStreamId, newLogStream);
onLogStreamCreated(newLogStream);
});
});