I need to know how to write log for each logged in users separately.
For example USER A, then the file should be created as logs/USER A/06.02.2024.log.
I am using Log4Net to write logs to file. Please support.
I need to write custom logging for each user's separately. I tried the below code, but file not created.
public class Log4NetLogger : ILogger
{
private readonly ILog _logger;
public Log4NetLogger(ILog logger)
{
_logger = logger;
}
public IDisposable BeginScope<TState>(TState state)
{
return null; // No scope support in log4net
}
public bool IsEnabled(LogLevel logLevel)
{
switch (logLevel)
{
case LogLevel.Trace:
case LogLevel.Debug:
return _logger.IsDebugEnabled;
case LogLevel.Information:
return _logger.IsInfoEnabled;
case LogLevel.Warning:
return _logger.IsWarnEnabled;
case LogLevel.Error:
return _logger.IsErrorEnabled;
case LogLevel.Critical:
return _logger.IsFatalEnabled;
default:
throw new ArgumentOutOfRangeException(nameof(logLevel), logLevel, null);
}
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception,
Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
var message = formatter(state, exception);
if (string.IsNullOrWhiteSpace(message))
{
return;
}
switch (logLevel)
{
case LogLevel.Trace:
case LogLevel.Debug:
_logger.Debug(message);
break;
case LogLevel.Information:
_logger.Info(message);
break;
case LogLevel.Warning:
_logger.Warn(message);
break;
case LogLevel.Error:
_logger.Error(message, exception);
break;
case LogLevel.Critical:
_logger.Fatal(message, exception);
break;
default:
_logger.Warn($"Encountered unknown log level {logLevel}, writing out as Info.");
_logger.Info(message, exception);
break;
}
}
}
}
And the custom class
public class CustomLoggerFactory : ILoggerFactory
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomLoggerFactory(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void AddProvider(ILoggerProvider provider)
{
// Do nothing or implement as needed
}
public ILogger CreateLogger(string categoryName)
{
var logger = LogManager.GetLogger(categoryName);
var user = _httpContextAccessor.HttpContext?.User;
if (user != null && user.Identity.IsAuthenticated)
{
var userId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (!string.IsNullOrEmpty(userId))
{
var logFilePath = $"logs/{userId}/log.txt";
var logFolder = Path.GetDirectoryName(logFilePath);
if (!Directory.Exists(logFolder))
{
Directory.CreateDirectory(logFolder);
}
// Configure log4net to use the dynamic file path
GlobalContext.Properties["LogFileName"] = logFilePath;
}
}
return new Log4NetLogger(logger);
}
public void Dispose()
{
// Dispose resources if needed
}
}
And in startup
public static void ConfigureLogging(ILoggingBuilder loggingBuilder)
{
loggingBuilder.ClearProviders();
loggingBuilder.AddLog4Net();
loggingBuilder.Services.AddSingleton<ILoggerFactory, CustomLoggerFactory>();
}