9

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
KyleMit
  • 30,350
  • 66
  • 462
  • 664
mslugx
  • 724
  • 7
  • 15
  • 1
    It looks like run.csx can't find the code in your Code.cs file? Is that code in one of the .dll files you import in the top of your run.csx files? Also, your error messages are out of date with your code, as there is no reference to log.Error() at line 12, and ex.Rethrow() is on line 12, not line 13. – Connor McMahon Sep 24 '18 at 22:02
  • @ConnorMcMahon the thing is if i don't use Ilogger, then it will work, but if i replace traceWriter with Ilogger, then this error happens. :( – mslugx Sep 26 '18 at 21:02
  • Without more than the signature of your Run method in the Code.cs file, it is very difficult to diagnose this. – Connor McMahon Sep 26 '18 at 22:17
  • also, what version are you upgrading from? Was this a v1 function application before? – Connor McMahon Sep 26 '18 at 22:18
  • I am upgrading from V2 to V2. But for different nuget version to fit in the new V2 standards. I updated the run method as well. please take a look. – mslugx Sep 27 '18 at 23:41

1 Answers1

12

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");
        }
    }
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
Troy Witthoeft
  • 2,498
  • 2
  • 28
  • 37
  • 4
    Having just done this, a word of caution is to reverse the parameters as TraceWriter.Error(message,exp) becomes ILogger.LogError(exp,message). If you don't reverse like I did, you end up calling ILogger.LogError(message,args) and you will get Invalid Format String. – Iain Jan 23 '19 at 00:51
  • Solid advice for people making this upgrade. – Troy Witthoeft Jul 22 '22 at 04:17