Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace TraceWriter With ILogger in azure function V2

We are trying to migrate azure function to sdk.functions 1.0.21 and we upgraded everything to 3.0.0-rc1 . The console prompted us that the TraceWriter is obsolete and to use ILogger instead. However, we keep running into issues.

Here's the code that I'm using:

code.cs:

public static async Task Run(Message queueItem, ILogger log, ExecutionContext context){
  using (var scope = Resolver.CreateScope())
  {
    var timer = new Stopwatch();

    try
    {
      var resolver = scope.ServiceProvider;

      logger = resolver.GetService<IBestLogger>().WithInvocationId(context);
      client = resolver.GetService<IServiceBusFactory>().GetClient(logger, _queue, _failedQueue);
      auditRepository = resolver.GetService<ITplTransactionAuditRepository>();

      asnService = resolver.GetService<IAsnService>();
      var sfWmsService = resolver.GetService<ISnapfulfilWmsService>();

      logger.CreateContext($"{_queue} process is started for message id.").WithServiceBusMessage(queueItem).LogInformation();
    }
  }

  catch (Exception ex2)
  {
    errorMessage = $"Unable to set record to Error status for message id {queueItem.MessageId} in {_queue}.";
    if (logger == null)
      log.Error(errorMessage);
    else
      logger.CreateContext(errorMessage, ex2).LogError();
  }
}

function.json:

{
  "bindings": [
    {
      "queueName": "%InvoiceDetailCalculate_Queue%",
      "connection": "ServiceBus_Connection",
      "name": "queueItem",
      "type": "serviceBusTrigger",
      "direction": "in",
      "accessRights": "manage"
    }
  ],
  "disabled": false
}

Run.csx:

#r "../bin/Best.Billing.Functions.dll"
#r "../bin/Best.Libraries.Utility.dll"

public static async void Run(Message queueItem, ILogger log, ExecutionContext context)
{
    try
    {
        Code.Run(queueItem, log, context).Wait();
    }
    catch (Exception ex)
    {        
        ex.Rethrow();
    }
}

The error messages are:

Run.csx(4,26): warning AF008: This method has the async keyword but it returns void
Run.csx(4,30): error CS0246: The type or namespace name 'Message' could not be found (are you missing a using directive or an assembly reference?)
Run.csx(8,9): error CS0103: The name 'Code' does not exist in the current context
Run.csx(12,13): error CS1061: 'ILogger' does not contain a definition for 'Error' and no extension method 'Error' accepting a first argument of type 'ILogger' could be found (are you missing a using directive or an assembly reference?)
Run.csx(13,12): error CS1061: 'Exception' does not contain a definition for 'Rethrow' and no extension method 'Rethrow' accepting a first argument of type 'Exception' could be found (are you missing a using directive or an assembly reference?)
Run.csx(4,26): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
Function compilation error
like image 968
mslugx Avatar asked Sep 21 '18 18:09

mslugx


1 Answers

You need to do two things:

  1. First, add a reference to the Ilogger.

    At the top of the function, add a using Microsoft.Extensions.Logging; statement.

  2. Second, you'll need to use the Ilogger method names. Change log.Error(errorMessage) to log.LogError(errorMessage). You'll need to do this everywhere you were calling the TraceWriter methods.

Here's a full list of the newer ILogger methods.

As an example, below is a fully implemented Azure Function v2 .NET Standard using Ilogger instead of Tracewriter:

using System.IO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using Microsoft.Extensions.Logging;

namespace FunctionApp1
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static IActionResult Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");


            string name = req.Query["name"];

            string requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}
like image 137
Troy Witthoeft Avatar answered Oct 10 '22 23:10

Troy Witthoeft