How to use Serilog in WCF with Autofac? - wcf

I am completely new to wcf and serilog and autofac, and I am trying to integrate all three of them. I am trying to log all events into a txt file and I somehow got it to work using this code in global asax:
var logFilePath = Path.Combine(ApplicationData.Current.LocalFolder.Path, "Log/Log.txt");
ILogger logger = new LoggerConfiguration()
.WriteTo.File(logFilePath)
.CreateLogger();
Log.Logger = logger;
logger.Information("Application Startup...");
and not this code:
var builder = new ContainerBuilder();
builder.RegisterType<Service1>();
builder.Register<ILogger>((c, p) =>
{
return new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.File(logFilePath)
.CreateLogger();
}).SingleInstance();
AutofacHostFactory.Container = builder.Build();
What is the difference between this two codes?
With the first code I can already log information in other classes, but I have come to find out that it is not good practice to manually log. I have tried using dependency injection like below in other classes:
ILogger _logger;
public AddCard(ILogger logger)
{
_logger = logger;
}
But for some reason it does not work. I am trying to make serilog log events at a global scale yet I do not understand how serilog and autofac tie in together in wcf. I have more than 40 tabs open trying to piece together what info I can, but Im still finding it hard to understand.

Related

How to use .net6 to operate redis?

I upgraded to the latest .net6 version, but how to configure the connection service, I can't find the entry. Can I still use the previous Startup.cs configuration in .net6? Any help is greatly appreciated!I have read the documentation, but it didn't help me:https://learn.microsoft.com/en-us/dotnet/core/compatibility/6.0
1. You can register redis service like below.
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "jason******FebB5A=,ssl=True,abortConnect=False";
});
And you can use redis in your controller, like below:
public HomeController(ILogger<WeatherForecastController> logger, CosmosClient client,IDistributedCache distributedCache)
{
_logger = logger;
_client = client;
_distributedCache = distributedCache;
}
And the test result like below:

how to send logging data to app insights from a library project

I have an aspnet core 2 web app which relies on a "Business" project to handle some logic. I am trying to set up the web app so that its ILogger logs are sent to App Insights. I can send the logs fine if I call the logger.Log method from within its Controller Actions. However, when making calls to classes in another project, which is part of the same solution, where I have an instance of ILogger and logging from there, it doesn't send any log data to App Insights. Am I missing something here? I would imagine if I have configured the logging and app insights in the web app correctly, I can call any other library from there and the logging data would be sent fine.
Approach 1 -
You will have to register your business logic class in Core API project in Startup; something similar to below
builder.Services.AddScoped<IMyClass, MyClass>();
And you will have to define a constructor which takes an ILogger instance in your business class; something like below
private readonly ILogger<MyClass> _logger;
public MyClass(ILogger<MyClass> logger)
{
_logger = logger;
}
// _logger.LogInformation("Hi from MyClass"); e.g. logging
This approach means ILogger will be injected with all required settings into your business lib.
Approach 2 -
You will have to install the AppInsights worker package in your business lib project
Microsoft.ApplicationInsights.WorkerService
from here
Then, you will have to write code for logging into AppInsights, something like below
var serviceCollection = new ServiceCollection();
serviceCollection.AddApplicationInsightsTelemetryWorkerService(options => options.ConnectionString = "my-key");
serviceCollection.AddLogging(builder => builder
.AddFilter<Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider>("", LogLevel.Information)
.AddFilter("Default", LogLevel.Information)
.AddFilter("Microsoft", LogLevel.Warning)
.AddFilter("System", LogLevel.Warning)
);
var serviceProvider = serviceCollection.BuildServiceProvider();
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
var telemetryClient = serviceProvider.GetService<TelemetryClient>();
var logger = loggerFactory.CreateLogger("my-logger");
logger.LogInformation("Hi from MyClass");
// flush and sleep at the end, before returning to the caller so that no messages are lost
telemetryClient.Flush();
System.Threading.Thread.Sleep(5000);
You would need the Microsoft.Extensions.DependencyInjection and Microsoft.Extensions.Logging packages in your business lib project for this approach. This approach means you will write appinsights logging independently to your lib project.

Log hangfire events using existing serilog

Im new to hangfire, and im trying to setup a way to log the events using my existing serilog logger in an asp.net web api. Here is my logger class:
public static class LoggerInitializer
{
private static ILogger CreateLog()
{
var settings = Settings.Instance;
Log.Logger = new LoggerConfiguration().
MinimumLevel.Debug().
WriteTo.RollingFile(settings.LoggerDebugDirectory +"Debug-{Date}.txt", restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Debug,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}").
WriteTo.RollingFile(settings.LoggerVerboseDirectory + "Debug-{Date}.txt").
CreateLogger();
return Log.Logger;
}
static ILogger _logger;
public static ILogger GetLogger()
{
if (_logger != null)
return _logger;
return _logger = CreateLog();
}
}
and in my startup file I add the code from the hangfire documentation:
GlobalConfiguration.Configuration
.UseSqlServerStorage(Settings.Instance.NLSContextConnectionString);
app.UseHangfireDashboard();
app.UseHangfireServer();
My hangfire works perfectly, but how do i enable make hangfire use my serilog?
It's possible that Hangfire is initializing and caching its own internal logger before CreateLog() is being called by the application.
To test this theory, try moving the code that initializes Log.Logger to the very beginning of the app's startup code, e.g. in Global.Application_Start() or similar.
In Hangfire 1.6.19 (and maybe before that, I did not check) adding the NuGet Package to your project gives you an extension method on IGlobalConfiguration :
configuration.UseSerilogLogProvider();

How to configure NServiceBus with two RavenDB IDocumentStores?

In NSB 5, how do I correctly configure NSB with autofac container with one IDocumentStore for NSB data and a separate IDocumentStore for application data? I've pasted the relevant part of EndpointConfig below:
// Raven DataStore for Freight system
var appDataStore = new DocumentStore {
ConnectionStringName = "RavenDB",
DefaultDatabase = "ApplicationData"
};
appDataStore .Initialize();
// Raven DataStore for NServiceBus
var nsbDataStore = new DocumentStore
{
ConnectionStringName = "NServiceBus.Persistence",
DefaultDatabase = "BookingProcessing"
};
nsbDataStore.Initialize();
// Set up and build AutoFac container
var builder = new ContainerBuilder();
builder.RegisterInstance<DocumentStore>(appDataStore ).As<IDocumentStore>().SingleInstance();
var container = builder.Build();
// Set up NServiceBus
configuration.UseContainer<AutofacBuilder>(customizations => customizations.ExistingLifetimeScope(container));
configuration.UsePersistence<RavenDBPersistence>().SetDefaultDocumentStore(nsbDataStore);
I know this isn't working since I had problems storing sagas in another question. The SagaPersister tried to persist saga in appDataStore, but the Timeout Messages was persisted in nsbDataStore.
This issue is now fixed in NServiceBus.RavenDB v2.0.1
This is a sample for 4.x using unit of work,
If you use
Look here to see how you can implement IManageUnitsOfWork
The Init is here
Look here for the usage
will this help?

Ninject with Log4Net extensions via TaskScheduller no logging output and no error

I have a console application project that is using Ninject and Log4Net.
When i run the app on my machine, the logging is working fine. When i run the app on the production server, the logging is working fine. When i run the program via TaskScheduller task which is being set so that is is being run by some other user, i get no logging output by any of the appenders. I'm using RollingFileAppender, SmtpAppender and AdoNetAppender.
The strange thing is, that the program is running fine, it just doesnt log anything.
I presume that because the app is working if i run it locally, the log4net configuration is fine.
I resolve logger in the main method of the program and then inject it via constructor parameter when needed. This is how i get the logger in the main method of the app:
XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config"));
var kernel = new StandardKernel();
var loggerFactory = kernel.Get<Log4NetLoggerFactory>();
ILogger logger = loggerFactory.GetCurrentClassLogger();
logger.Info(" Test ");
Any hints, pointers or anything....as i don't know what else to try.
The extension is normally used like this:
public class MyClass
{
private readonly ILogger log;
public MyClass(ILogger log)
{
this.log = log;
log.Info("Created MyClass");
}
}
XmlConfigurator.ConfigureAndWatch(new FileInfo("log4net.config"));
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<MyClass>().ToSelf();
kernel.Get<MyClass>(); // will cause the log message to print
}
Just let Ninject worry about injecting the ILogger into your class. You can't request an ILogger from the IKernel in the same place you declare the kernel because you've got no context.
You can do this though:
ILogger log = new Log4NetLoggerFactory().GetCurrentClassLogger();
log.Info("Test");