How to implement logging to azure eventhub from azure webjob

209 Views Asked by At

Im trying to implement a custom logger that sends logs to azure eventhub from a azure webjob but having trouble making it work. Is there a simpler way than using a custom logger? I have tried writing my own solution which is almost identical to this solution I found on github. https://github.com/UKHO/EventHub-Logging-Provider/tree/main/UKHO.Logging.EventHubLogProvider

The solution works well if I implement it on a simple webapi in .net but when implementing it on a azure webjob if fails with a stackoverflow-exception during startup when the customlogger "Log"-function is called. I guess that the azure sdk does something different than a webapi...Is there perhaps a way to only initilize the custom logger on classes maybe from a specific namespace or something?

public class CustomLogger : ILogger
    {
        private readonly string componentName;
        private readonly string environment;
        private readonly string machineName;
        private readonly EventHubBufferedProducerClient eventHubBufferedProducerClient;

        public CustomLogger(string componentName, string environment, string machineName, EventHubBufferedProducerClient eventHubBufferedProducerClient)
        {
            this.componentName = componentName;
            this.environment = environment;
            this.machineName = machineName;
            this.eventHubBufferedProducerClient = eventHubBufferedProducerClient;
          
        }

        public IDisposable? BeginScope<TState>(TState state) where TState : notnull
        {
            return default!;
        }

        public bool IsEnabled(LogLevel logLevel)
        {
            return !string.IsNullOrEmpty(componentName);
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }

            var logEvent = new LogEvent
            {
                Component = this.componentName,
                Level = logLevel.ToString(),
                Host = this.machineName,
                Environment = this.environment,
                Message = formatter(state, exception),
                Exception = exception?.ToString()
            };

            this.eventHubBufferedProducerClient.EnqueueEventAsync(new EventData(System.Text.Json.JsonSerializer.Serialize(logEvent))).Wait();
        }
    }
1

There are 1 best solutions below

0
On

Here is the way i acheived Creating a custom logger for sending logs to Azure Event Hubs from an Azure WebJob. Ensure proper initialization and disposal of resources.

  1. Create a Custom Logger Class This class will send log messages to Azure Event Hubs.
    using System;
    using Microsoft.Extensions.Logging;
    
    public class EventHubLogger : ILogger
    {
        private readonly string _eventHubConnectionString;
        private readonly string _eventHubName;
    
        public EventHubLogger(string eventHubConnectionString, string eventHubName)
        {
            _eventHubConnectionString = eventHubConnectionString;
            _eventHubName = eventHubName;
        }
    
        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }
    
        public bool IsEnabled(LogLevel logLevel)
        {
            return true; // Implement your log level filtering logic here
        }
    
        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {
            if (!IsEnabled(logLevel))
            {
                return;
            }
    
            string logMessage = formatter(state, exception);
    
        }
    }
  1. Create a Custom Logger Provider
    using Microsoft.Extensions.Logging;
    
    public class EventHubLoggerProvider : ILoggerProvider
    {
        private readonly string _eventHubConnectionString;
        private readonly string _eventHubName;
    
        public EventHubLoggerProvider(string eventHubConnectionString, string eventHubName)
        {
            _eventHubConnectionString = eventHubConnectionString;
            _eventHubName = eventHubName;
        }
    
        public ILogger CreateLogger(string categoryName)
        {
            return new EventHubLogger(_eventHubConnectionString, _eventHubName);
        }
    
        public void Dispose()
        {
            // Dispose of any resources if needed
        }
    }
  1. Configure the Custom Logger in Your WebJob
    using Microsoft.Extensions.Logging;
    using System;
    
    class Program
    {
        static void Main()
        {
            string eventHubConnectionString = "your_eventhub_connection_string";
            string eventHubName = "your_eventhub_name";
    
            var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder.AddProvider(new EventHubLoggerProvider(eventHubConnectionString, eventHubName));
            });
    
            ILogger logger = loggerFactory.CreateLogger("MyCustomLoggerCategory");
    
    
            logger.LogInformation("This is a log message.");
    
            // Run your WebJob logic here
            // ...
    
            Console.WriteLine("Azure WebJob has completed.");
    
            // You might want to wait for user input to keep the console window open, depending on your deployment method
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }

Result

Console enter image description here

Requests in EventHub

enter image description here