Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure WebJobs (3.x) Continuous job not showing Functions in Dashboard

We have an Azure WebJob (3.x) running under an API App in Azure, all Core 2.1. It publishes fine, and runs, but doesn't show any Functions or list the Function Invocations on the dashboard. Which is odd, because the console output for the job does show it detecting a function:

[10/17/2018 09:26:19 > fa7c81: SYS INFO] Run script 'run.cmd' with script host - 'WindowsScriptHost'
[10/17/2018 09:26:19 > fa7c81: SYS INFO] Status changed to Running
[10/17/2018 09:26:19 > fa7c81: INFO] 
[10/17/2018 09:26:19 > fa7c81: INFO] D:\local\Temp\jobs\continuous\SubmissionJob\43ucb4rv.ipc>dotnet SubmissionJob.dll  
[10/17/2018 09:26:21 > fa7c81: INFO] dbug: Microsoft.Extensions.Hosting.Internal.Host[1]
[10/17/2018 09:26:21 > fa7c81: INFO]       Hosting starting
[10/17/2018 09:26:21 > fa7c81: INFO] info: Microsoft.Azure.WebJobs.Hosting.JobHostService[0]
[10/17/2018 09:26:21 > fa7c81: INFO]       Starting JobHost
[10/17/2018 09:26:21 > fa7c81: INFO] info: Host.Startup[0]
[10/17/2018 09:26:21 > fa7c81: INFO]       Found the following functions:
[10/17/2018 09:26:21 > fa7c81: INFO]       SubmissionJob.Functions.ProcessQueueMessageAsync
[10/17/2018 09:26:21 > fa7c81: INFO]       
[10/17/2018 09:26:21 > fa7c81: INFO] Application started. Press Ctrl+C to shut down.
[10/17/2018 09:26:21 > fa7c81: INFO] Hosting environment: QA

The Program.cs Program class looks like this:

public static async Task Main(string[] args)
    {
        var builder = new HostBuilder()
            .UseEnvironment(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"))
            .ConfigureWebJobs(b =>
            {
                b.AddAzureStorageCoreServices()
                    .AddAzureStorage()
                    .AddServiceBus()
                    .AddEventHubs();
            })
            .ConfigureAppConfiguration(b =>
            {
                // Adding command line as a configuration source
                b.AddCommandLine(args);
            })
            .ConfigureLogging((context, b) =>
            {
                b.SetMinimumLevel(LogLevel.Debug);
                b.AddConsole();

                // If this key exists in any config, use it to enable App Insights
                var appInsightsKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
                if (!string.IsNullOrEmpty(appInsightsKey))
                {
                    b.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
                }
            })
            .ConfigureServices((context, services) =>
            {
                services.AddAutoMapper();

                services.AddMemoryCache();

                services.AddDbContext<SubmissionsDbContext>(opts =>
                    opts.UseSqlServer(context.Configuration.GetConnectionString("DefaultConnection")));

                // cloud services
                services.AddTransient(s =>
                    CloudStorageAccount.Parse(
                        context.Configuration.GetConnectionString("AzureQueueConnectionString")));
                services.AddTransient<IBlobReadService, AzureBlobReadService>();
                services.AddSingleton<IBlobWriteService, AzureBlobWriteService>();
                services.AddSingleton<IQueueWriteService, AzureQueueWriteService>();

                // submission services
                services.AddScoped<ISubmissionStatusService, SubmissionStatusService>();

                services.AddSingleton<Functions, Functions>();

                // job activator, required in webjobs sdk 3+
                services.AddSingleton<IJobActivator>(new WebJobsActivator(services.BuildServiceProvider()));
            })
            .UseConsoleLifetime();;

        var host = builder.Build();
        using (host)
        {
            await host.RunAsync();
        }
    }

The Functions.cs has a method with the following signature:

public async Task ProcessQueueMessageAsync([QueueTrigger("operations")] CloudQueueMessage incomingMessage, TextWriter log)

...scm.azurewebsites.net/azurejobs/#/jobs/continuous/SubmissionJob shows

Continuous WebJob Details SubmissionJob
Running
Run command: run.cmd

But there's no list of function invocations below it, and the job remains permanently in a Running state. If I go to the 'Functions' link in Kudu, it says there are no functions/function invocations to display.

Any thoughts?

The bulk of this worked fine in Framework 4.7, though the app builder was clearly different.

like image 880
Matt Styles Avatar asked Oct 17 '18 14:10

Matt Styles


2 Answers

The answer to this is twofold.

You can write to the Kudu Dashboard with

var builder = new HostBuilder()
    .ConfigureWebJobs(b =>
    {
        b.AddDashboardLogging();
    });

This will work and show function invocations for WebJobs 1.x, 2.x. However, from WebJobs SDK 3.x onwards, this is obsolete. The console output will continue to show in Kudu Dashboard, but functions will not be detected and won't be displayed, nor their invocations. Application Insights is recommended instead.

var builder = new HostBuilder()
    .ConfigureLogging((context, b) =>
    {
        b.SetMinimumLevel(LogLevel.Debug);
        b.AddConsole();

        // If this key exists in any config, use it to enable App Insights.
        // This may already be configured in Azure Portal if running WebJob udner existing app with App Insights.
        var appInsightsKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
        if (!string.IsNullOrEmpty(appInsightsKey))
        {
            b.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
        }
    });

Make sure that you have configured a connection string named AzureWebJobsStorage with a storage connection string.

See also: https://github.com/Azure/azure-webjobs-sdk/wiki/Application-Insights-Integration

And: https://docs.microsoft.com/en-us/azure/app-service/webjobs-sdk-get-started#add-application-insights-logging

like image 65
Matt Styles Avatar answered Sep 17 '22 08:09

Matt Styles


So I just 'Upgraded' to Microsoft.Azure.WebJobs v3.0.14 in an effort to keep our NuGet packages 'current' and I hit this same issue.

I had be using an earlier version that had a much simpler process of creating a triggering a web job using the 'Call' method of the JobHOst object which basically setup all your Dashboard logging for you.

The process I was using was literally 2 lines of code to initialize and trigged the web job which magically also setup Dashboard logging for you.

After 'Upgrading' and determine the new process for triggering the web jobs with the 'CallAsync' method I found that all by the 'Top Level' dashboard logs were gone. The 'Function' data was no longer reporting and I could not longer verify exactly what my web job had done for debugging. All I could see was 'Success' or 'Failure' message.

I spent several hours trying to figure out how to use the AddDashboardLogging methods in both the HostBuilder ConfigwebJobs and ConfigureLogging sections, but these setting appear to have no affect.

After much trial and error I finally discovered how to get my debugging data back.

Basically they changed how Dashboard logging works. You don't use the AddDashboardLogging method at all. Instead you just use the AddConsole method. This does not bring back the 'Function' links that you may be used to, but it does ensure all your general 'Logging' output is published to the 'Top Level' Dashboard Log. So instead of navigating to the 'Function' then selecting 'Toggle Output' you just select the 'Toggle Output' from the top level dashboard view that used to contain minimal data.

Here is what worked for me:

First ensure you have all 3 of these using statements, if you can't add them all you are probably missing NuGet.

using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

Next Create your Host Builder and use the 'ConfigureLogging(Logger)' method (NOT THE ONE WITH 2 INPUTS) and call the AddConsole method for the Logger object.

Here is my minimal example code:

    var builder = new HostBuilder();
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
    })
    .ConfigureLogging((logger) =>
    {
        logger.AddConsole();
    });

Again this does not bring back the 'Function' links but it did get my debugging log message to be printed to the 'Top Level' web job log. (Also note that it does not require you to call the obsolete AddDashboardLogging method)

like image 37
woeful Avatar answered Sep 17 '22 08:09

woeful