0

I had a C# console application which was getting data from a database querying it and then awaits 1 hour to query new data. The program.cs was used as a startup class to do the dependency injections. The results shown on the console when running the console application are the following:

Console Application Results

I had to transform this console application to an azure timer trigger function so that it runs every 1hour, do the same job as explained above and log the same information as shown in the image. So what I did is that I copied the code from the program.cs file and pasted it in the timer trigger run method. Here is the code:

namespace ExportServiceFunctionApp
{
    public class ExportServiceFunctionApp
    {
        [FunctionName("ExportServiceFunctionApp")]
        public static void Run([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer, ILogger log)
        {
            log?.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

            try
            {
                IServiceCollection services = new ServiceCollection();


                services.AddSingleton<IDataReceiver, DataReceiver.DataReceiver>()
                        .AddSingleton<IDataProcessor, DataProcessor.DataProcessor>()
                        .AddSingleton<IDataClient, KustoDataClient>()
                        .AddSingleton<IAzureBlobClient, AzureBlobClient>()
                        .AddSingleton<IAzureKustoClient, AzureKustoClient>()
                        .AddSingleton<IQueriesSettings, QueriesSettings>()
                        .AddSingleton<IExportServiceSettings, ExportServiceSettings>()
                        .AddTransient<IRawData, RawData>()
                        .AddLogging();

                IServiceProvider serviceProvider = services.BuildServiceProvider();

                log?.LogInformation("Start initialization.");
                var dataProcessor = serviceProvider.GetRequiredService<IDataProcessor>();

                log?.LogInformation("Start data processing.");
                dataProcessor.Start();
            }
            catch (Exception ex)
            {
            }
        }
    }
}

You can also find the structure of the FunctionApp here:

Function App Structure

The ExportServiceFunctionApp.cs is executing successfully but what I am missing here is the logs coming from other classes. An example is the DataReceiver.cs (Note: There are other classes too). What I need is to have the same results and logs shown above in the console application.

The results of the function app are shown here:

FunctionApp Results

As you can see here, the logs that are only showing on the console are the ones who are used in the Run method of the ExportServiceFunctionApp.cs but all other logs that are used in the other classes are not

As an example: The ILogger is injected in the DataReceiver constructor but the logs are not appearing on the console when the FunctionApp is running locally. Here is the code of DataReceiver.cs

public class DataReceiver : IDataReceiver
    {
        private readonly IExportServiceSettings _exportServiceSettings;
        private readonly ILogger _logger;
        private CancellationToken _cancellationToken;
        private TimeSpan _interval;
        private DateTime _lastTo;

        public DataReceiver(IExportServiceSettings exportServiceSettings, ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory?.CreateLogger<DataReceiver>();
            _exportServiceSettings = exportServiceSettings;
        }

The host.json has the following structure:

{
  "version": "2.0",
  "logging": {
    "fileLoggingMode": "always",
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      }
    },
    "logLevel": {
      "default": "Information"
    }
  }
}

Can someone please tell me how to log the messages coming from the other classes in the same way how they are shown in the results of the console application. I still don't know why only the logs in RUN method are being shown. I previously asked a similar question but I guess it wasn't explained in a good way.

Noobie2021
  • 281
  • 4
  • 23
  • You should pass on the same `ILogger` instance that received by the trigger function to your worker function, then you will be able to see the logs. – Anand Sowmithiran Dec 13 '21 at 13:11
  • @AnandSowmithiran Thank you for your answer. Can you please tell me how to do that ? In my case, what should I add in the DataReceiver.cs and what should I modify in the host.json file ? – Noobie2021 Dec 14 '21 at 07:53
  • The DataProcessor should be modified to either have a logger property or take an argument of type ILogger for its Start method. Then you can pass the same `log` argument of your trigger function. Apart from the log level you don't need to change anything in the host.json file. – Anand Sowmithiran Dec 14 '21 at 14:35
  • @AnandSowmithiran Thanks for your answer. The DataProcessor already has a logger property the same way it is being show above in the DataReceiver. I still don't know what else is missing. Can you please tell me what should I do exactly in the Run method. What should be added there because something is definitely missing. I have been trying to solve the problem for the past couple of days but still it is not working. – Noobie2021 Dec 14 '21 at 17:04

0 Answers0