Trace in Azure Bot Service - debugging

I'm following this step to enable tracing in Azure Bot App Service https://microsoft.github.io/AzureTipsAndTricks/blog/tip30.html
However, my trace does not appear in the log stream.
I can see a bunch of other logs here.
I also tried "#define TRACE" at the class with the code
System.Diagnostics.Trace.WriteLine("Entering the About View");
Am I missing anything?
My Azure Web App setting: https://pictr.com/images/2019/06/25/5BHthA.png
My Log stream: https://pictr.com/images/2019/06/25/5BHszI.png
Thanks.

Thanks. Can use below to log to App Service's Logstream as well if using Starter Bot at https://github.com/martinkearn/Bot-Starter-Template/:
ILogger<BotFrameworkHttpAdapter> logger,
logger.LogError($"Exception caught on attempting to Delete ConversationState : {e.Message}");

Apart from the changes in the portal to enable it; you'll want to use the Microsoft.Exensions.Logging namespace. Add the Microsoft.Extensions.Logging.AzureAppServices package (version appropriate for your project).
Then add logging for azure (AddAzureWebAppDiagnostics) where you setup your host:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging((logging) =>
{
logging.AddAzureWebAppDiagnostics();
});
Then make sure your class implements ILogger. You can see an example of that in the Core bot sample here.
Then just do your logging in the method you wish:
Logger.LogInformation("This is my test.");
Here's some more info:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2

Related

Agent Handoff intermediator-bot-sample (c#) by tompaana on github doesn't work on upgrading Microsoft.Bot.Builder and related packages to Ver 4.10.3

Problem Statement
This is regarding the Live Agent Handoff intermediator-bot-sample (c#) created by tompaana at https://github.com/tompaana/intermediator-bot-sample on guithub.
The intermediator-bot-sample works perfectly with Microsoft.Bot.Builder (4.2.2) and Microsoft.Bot.Builder.Integration.AspNet.Core(4.2.2) and dependent Version 4.2.2 packages but, It does not use Dialogs.
The HandoffMiddleware Code stopped getting invoked , when I added the package Microsoft.Bot.Builder.Dialogs (4.10.3) (as my existing code requires Dialogs) . This also caused upgrading to Microsoft.Bot.Builder to version 4.10.3 along with it's dependent packages i.e. Microsoft.Bot.Builder.Integration.AspNet.Core etc..
Community Support
The Original Author Handoff intermediator-bot-sample Tomi Paananen A.K.A tompaana has moved on to other projects and would no longer be able to devote time to this project and has requested to reach out MS Botframework community members for support (Refer: Author Response to Github issue raised).
Requesting BotFramework community to please help out to add Agent Hand Off functionality to my existing Chatbot
Observation :
Even After Package upgrade, the HandoffMiddleware class is getting successfully instantiated during Startup.
My retrofitted code contains BotController class via which all the API get invoked. This BotController class which isn't present in the original Handoff intermediator-bot-sample code.
On typing any utterance on the chat bot (Upgraded/new code), the control goes into the BotController class rather than invoking/triggering HandoffMiddleware.OnTurnAsync(...)
As the original intermediator-bot-sample code does not have any BotController/ API Controller, could this be the reason that utterances aren't getting routed via, HandoffMiddleware Middleware if so, how could I fix the issue?
// Licensed under the MIT License.
//
// Generated with Bot Builder V4 SDK Template for Visual Studio EchoBot v4.6.2
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
namespace Neo.Controllers
{
// This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
// implementation at runtime. Multiple different IBot implementations running at different endpoints can be
// achieved by specifying a more specific type for the bot constructor argument.
[Route("api/messages")]
[ApiController]
public class BotController : ControllerBase
{
private readonly IBotFrameworkHttpAdapter Adapter;
private readonly IBot Bot;
public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
{
Adapter = adapter;
Bot = bot;
}
[HttpPost, HttpGet]
public async Task PostAsync()
{
// Delegate the processing of the HTTP POST to the adapter.
// The adapter will invoke the bot.
await Adapter.ProcessAsync(Request, Response, Bot);
}
}
}
Referenced Packages
Original intermediator-bot-sample referenced Packages
Upgraded intermediator-bot-sample referenced Packages
Original intermediator-bot-sample Solution Files
Upgraded intermediator-bot-sample Solution Files
Query
Could you please suggest How I can fix this issue?
As the HandoffMiddleware.OnTurnAsync(..) works fine when I execute the coriginal code_ but, doesn't get triggered from My Code after retrofitting IntermediateBot code with upgraded Microsoft.Bot.Builder and related packages to Version 4.10.3 .
Pointing to an existing working Agent HandOff sample(c#) would also help
The following solution makes the upgraded Tompanna Agent Handoff solution work smoothly:
The solution lies in the way BotFrameworkHttpAdapter needs to invoke HandoffMiddleware.
The inspection Middleware example in Github provides the methodology to invoke any middleware i.e. in those scenarios where we have the upgraded Microsoft.Bot.Builder and related packages which introduce the concept of BotController class / API Controller .
Code reference of AdapterWithInspection.cs from BotBuilder-Samples/samples
Replace InspectionMiddleware in the following code with HandoffMiddleware
namespace Microsoft.BotBuilderSamples
{
public class AdapterWithInspection : BotFrameworkHttpAdapter
{
public AdapterWithInspection(IConfiguration configuration, InspectionState inspectionState, UserState userState, ConversationState conversationState, ILogger<BotFrameworkHttpAdapter> logger)
: base(configuration, logger)
{
// Inspection needs credentiaols because it will be sending the Activities and User and Conversation State to the emulator
var credentials = new MicrosoftAppCredentials(configuration["MicrosoftAppId"], configuration["MicrosoftAppPassword"]);
//***********************************************************************************//
//* InspectionMiddleware needs to be replace HandOffMddieWare in the execution pipeline *//
//***********************************************************************************//
Use(new InspectionMiddleware(inspectionState, userState, conversationState, credentials));
OnTurnError = async (turnContext, exception) =>
{
// Log any leaked exception from the application.
logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");
// Send a message to the user
await turnContext.SendActivityAsync("The bot encountered an error or bug.");
await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");
// Send a trace activity, which will be displayed in the Bot Framework Emulator
await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError");
};
}
}
}
New code should look like the following
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
namespace Microsoft.BotBuilderSamples
{
public class AdapterWithInspection : BotFrameworkHttpAdapter
{
public AdapterWithInspection(IConfiguration configuration, InspectionState inspectionState, UserState userState, ConversationState conversationState, ILogger<BotFrameworkHttpAdapter> logger)
: base(configuration, logger)
{
// Inspection needs credentials because it will be sending the Activities and User and Conversation State to the emulator
var credentials = new MicrosoftAppCredentials(configuration["MicrosoftAppId"], configuration["MicrosoftAppPassword"]);
//***********************************************************************************//
//*************** Adding HandOffMddieWare in the execution pipeline *****************//
//***********************************************************************************//
Use(new HandoffMiddleware(configuration));
OnTurnError = async (turnContext, exception) =>
{
// Log any leaked exception from the application.
logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");
// Send a message to the user
await turnContext.SendActivityAsync("The bot encountered an error or bug.");
await turnContext.SendActivityAsync("To continue to run this bot, please fix the bot source code.");
// Send a trace activity, which will be displayed in the Bot Framework Emulator
await turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError");
};
}
}
}
NOTE
You would need to inject dependencies in the Startup.cs accordingly
Inject Dependencies in Startup.cs
Add following code to facilitate dependency injection of AdapterWithInspection
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithInspection>();

Xamarin - .NET Standard - Use Azure DevOps Services with VssAadCredential -

I want to create a Xamarin.Forms app where I have to login to a specific Azure DevOps environment/project.
To try out the Azure DevOps Service library I first created a Console App (.NET Framework 4.7.2) to login to the Azure DevOps environment/project. The following code was used for login process (+ extra code to validate the connection actualy works).
public void Login(string _userName, string _pwd)
{
ProjectHttpClient projectClient;
this.Credentials = new VssAadCredential(_userName, _pwd);
this.Connection = new VssConnection(new Uri(this.DevOpsPath), this.Credentials);
this.InitReferences(this.ProjectName);
projectClient = this.Connection.GetClient<ProjectHttpClient>();
this.ProjectReference = projectClient.GetProjects(null, top: 1).Result.Where(item => item.Name == this.ProjectName).FirstOrDefault();
}
When I use the same piece of code in the Xamarin.Forms App (.NET Standard 2.1) it no longer works and I get the following error when executing the last line:
One or more errors occurred. (Could not resolve type with token
0100008d from typeref (expected class
'Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContextIntegratedAuthExtensions'
in assembly 'Microsoft.IdentityModel.Clients.ActiveDirectory,
Version=3.19.4.11002, Culture=neutral,
PublicKeyToken=31bf3856ad364e35'))
When using the VssBasicCredential with a personal acces token, the code runs as expected. However I would prefer using the VssAadCredential and not the VssBasicCredential.
I'm not aware that the VssAadCredential is not supported in .NET Standard and can find no documentation relating to the issue.
Has anyone had a similar experience that might solve this problem or can anyone provide me with some documentation declaring that this cannot work as of yet?

Web API works locally but doesn’t work on azure

I have created a web API connected to azure sql server in .net core using visual studio for Mac đź’». Then I created a web app in azure and then published by project directly in visual studio for Mac to azure.
After I published I try to access the api using postman and chrome (URL/api/menu) but I got 500 server error which is generic and doesn’t tell me anything.
In visual studio for Mac I got the green light it said published and directly took me to the new url.
So, what do you guys thing is the problem.
This is my first time using azure so I didn’t change any setting or anything
Since many different problems can cause this error page, I can strongly recommend the following in order to determine the root cause quickly and easily, without struggling with Azure (or any server/platform for that matter) to get logs.
You can enable extremely helpful error messages at startup by setting the .UseSetting("detailedErrors", "true") and .CaptureStartupErrors(true) actions in your Program.cs file.
For ASP.NET CORE 2.1
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.CaptureStartupErrors(true)
.UseSetting("detailedErrors", "true")
.UseStartup<Startup>()
.Build();
}
Add these commands in your startup.cs class:
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
also enable stdoutLog in your web.config file
stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout"
Error code 500 in web api,usually, means problems with a configuration in Startup.cs - the most common problems include an issue with DB itself, an issue with migrations (if you are using Code First approach), problems with appsettings.js.
Please refer to the log file in .\logs\stdout.
Hope it helps.

Deploy ASP.net core 2.1 WEB API to IIS using Visual Studio Code

Working on an ASP.net core 2.1 web API project. I need to enable the API so that it can be accesed by client applications that we also have under developement.
So far, the only way I've found to publish to IIS is by doing a manual process:
Run dotnet publish -c Release
Copy the files in bin\Release\netcoreapp2.1\publish\ to my IIS Web App folder
I wonder if there is a more straight forward way of doing this.
Also It takes quite sometime to build this release, so for a development environment it's quite a slow process. The problem is that we cannot allow external access to the WEB api when running with F5 on the Integrated test server. How can we enable an more agile testing environment?
Another issue is that when calling for example fetch('MyAPIServer/api/MyItems') from a javascript application, I get a CORS error:
Failed to load http://localhost:86/api/shit: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8082' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled
Is enabling CORS absolutely necesary when developing this type of apps?
If I fetch like this:
fetch(
`http://localhost:86/api/shit`,{mode: 'no-cors'}
)
I get:
Uncaught (in promise) SyntaxError: Unexpected end of input
at eval (Pos.vue?7f37:68)
As far as the CORs issue goes you can add the following to your startup:
public void ConfigureServices(IServiceCollection services)
{
// Rest of config stuff ...
services.AddCors();
}
Then in you will also need to add the following.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors(builder =>
{
builder.WithOrigins("http://localhost:8080",
"http://localhost:8081",
"http://localhost:8082")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
app.UseMvc();
}

Anyone using Serilog.Extras.MSOwin

I was wondering if anyone has seen a demo/example of using the Serilog.Extras.MSOwin package with a web api project or a example/tutorial of using Serilog with a web api project.
Any help greatly appreciated,
Jim
I will take this as question as "How do I used Serilog.Extras.MSOwin?" and given it is currently a rather small library answer here.
This reflects the current library (1.4.102) and is subject to change in the future.
Serilog.Extras.MSOwin provides two things: a Microsoft.Owin.Logging.ILoggerFactory implementation to have OWIN's logging infrastructure write to Serilog (more details about logging in OWIN in this blog post) and Guid identifier (RequestId) for each web request to aid in associating logged events.
The Logging integration is done with the following:
IAppBuilder app = ...;
Serilog.ILogger logger = ...'
app.SetLoggerFactory( new Serilog.Extras.MSOwin.LoggerFactory( logger ) );
The request id functionality needs to be registered in the OWIN pipeline:
IAppBuilder app = ...;
app.UseSerilogRequestContext("RequestId");
You will want to register that very early in the pipeline because any logging occurring before that pipeline step will not have the request id available.
You also need will need to retrieve it from the LogContext using Enrich.FromLogContext() and add that property to what you write to your sinks. For example,
const string DefaultOutputTemplate =
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} ({RequestId}) {Message}{NewLine}{Exception}";
ILogger logger =
new LoggerConfiguration().Enrich.FromLogContext()
.WriteTo
.RollingFile(
"log.txt",
outputTemplate: DefaultOutputTemplate)
.CreateLogger();
Serilog.Extras.MSOwin was superseded by SerilogWeb.Owin (which has since also been discontinued.)

Resources