Im trying to filter my input to application insight by configuration. Im sending data from SeriLog with the ApplicationInsightsTraces-sink as can be seen below in my configuration:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.WriteTo
.ApplicationInsightsTraces(Configuration.GetSection("ApplicationInsights")
.GetSection("InstrumentationKey").Value)
.CreateLogger();
This code sends the correct data to the "Trace" in Application Insights but AI gets the traces from somewhere else also. I guess the framework in some way? I would like to turn off the standard logging of traces from the framework so that I can use only one filter for what to log (loglevel and specific overrides for example "Microsoft.AspNetCore": "Warning". I would prefer to not filter in a processor for each Trace. Any ideas?
It seems to be working the way I want it to when I reset the options object by row provided below. Im not exactly sure which property in ApplicationInsightsServiceOptions that did the change.
services.Configure<ApplicationInsightsServiceOptions>(
options => Configuration.GetSection("applicationInsights").Bind(options));
Related
I have recently implemented Serilog logging into my ASP.NET Core/.NET5 web app that uses SignalR. I'm using the Elasticsearch sink and everything is largely working as expected. I decided to add some additional HttpContext properties to be logged on each request, so I went down the road of extending the call to UseSerilogRequestLogging() in StartUp.cs as to enrich the diagnostic context with a couple of extra properties (mainly because this seemed like the simplest way to do it):
app.UseSerilogRequestLogging(options =>
{
options.EnrichDiagnosticContext = (diagnosticContext, httpContext) =>
{
diagnosticContext.Set("HttpRequestClientIP", httpContext.Connection.RemoteIpAddress);
diagnosticContext.Set("UserName", httpContext.User?.Identity?.Name == null ? "(anonymous)" : httpContext.User.Identity.Name);
};
});
At first, this seemed to work as expected until I noticed it wasn't always working. I really want the extra properties logged on all log records written, and it seems to work fine on log records that are written automatically by Serilog when typical HTTP GETs, HTTP POSTs, etc. occur... But in my Signalr Hub class, I have a couple of places where I'm manually writing my own log records like Logger.Log(LogLevel.Information, "whatever.."), but these extra properties are simply not there on these records.
What am I missing here? Is it something about this being in a Signalr Hub that makes them unavailable? Or perhaps there's something I'm doing wrong with my Logger.Log() calls?
Any ideas would be appreciated.
Thanks-
It's not gonna to work with signalR.
Behind the screen, app.UseSerilogRequestLogging make use of a middleware in the request pipeline, that call RequestLoggingMiddleware as what you can see in detail here.
SignalR use the first Http request to setting to connection up to websocket, which won't goes through the pipeline at all. Therefore, doesn't have anything to do with RequestLoggingMiddleware, which you are using to logging out the request.
I finally ended up going with a couple of custom Enrichers. I did experiment briefly with middleware vs enrichers and they both seem to work as expected. Both always added the additional properties to all log entries. I'm still not quite sure I understand why the DiagnosticContext option behaves the way it does, unless it is simply due to the logging in question being in a SignalR hub as #Gordon Khanh Ng. posted. If that were the root of the problem though, you wouldn't think the enrichers or middleware would work either.
With Serilog in asp.net core you can change the log level in runtine by using
MinimumLevel.ControlledBy(SeriLogLevelSwitch).
Is there a similar way to do this with LoggerConfiguration().WriteTo.File(...)
For instance i need to change the configuration for log fileSizeLimitBytes, or rollingInterval withour restaring the service. Can this be achieved with Serilog?
By pulling in the latest Serilog.AspNetCore you'll find a class called ReloadableLogger, constructed through the CreateBootstrapLogger() extension method:
// using Serilog;
var logger = new LoggerConfiguration()
.WriteTo.File(...)
.CreateBootstrapLogger();
// Optional but suggested:
Log.Logger = logger;
// Use the logger...
// Change parameters later on:
logger.Reload(lc => lc
.WriteTo.File(...));
You might find that some interactions between CreateBootstrapLogger() and UseSerilog(callback) in ASP.NET Core trip things up a bit; if you use this technique, try the parameterless version of UseSerilog().
ReloadableLogger has only just appeared and is focusing on a slightly different scenario, so you may still need to work through some awkwardness setting this up - YMMV.
I've hooked up Miniprofiler to my local ASP.NET Core project and it works as expected. Now I need it to work in a hosted environment where there are multiple instances of the same website and there are no sticky sessions. It is my understanding that this should be supported if you just set the storage option when configuring the profiler. However, setting the storage does not seem to do anything. I initialize the storage like this:
var redisConnection = "...";
MiniProfiler.DefaultOptions.Storage = new RedisStorage(redisConnection);
app.UseMiniProfiler();
After doing this, I expected that I could open a profiled page and a result would be added to my redis cache. I would then also expect that a new instance of my website would list the original profiling result. However, nothing is written to the cache when generating new profile results.
To test the connection, I tried manually saving a profiler instance (storage.Save()) and it gets saved to the storage. But again, the saved result is not loaded when showing profiler results (and regardless, none of the examples I've seen requires you to do this). I have a feeling that I've missed some point about how the storage is supposed to work.
It turns out that my assumption that MiniProfiler.DefaultOptions.Storage would be used was wrong. After changing my setup code to the following, it works.
// Startup.cs ConfigureServices
var redisConnection = "...";
services.AddMiniProfiler(o =>
{
o.RouteBasePath = "/profiler";
o.Storage = new RedisStorage(redisConnection); // This is new
});
// Startup.cs Configure
app.UseMiniProfiler();
I'm using Serilog from within my website & web API all good.
Now I want to use Serilog from within WCF.
But when I new up a LoggerConfiguration and create a logger from within WCF, the logging doesn't seem to work? Eg nothing is being output to the text file.
var seriLog = new LoggerConfiguration()
.WriteTo.File(#"C:\Serilogs\myapp.txt")
.CreateLogger();
seriLog.Debug("log message");
Ultimately I want to write to Seq from within the WCF service.
What am I missing or doing wrong?
Has anyone got some working code samples of how this would be done?
Are there tricks to using the Serilog/Seq stack from within WCF?
There are a couple of things to that come to mind-
First, is the setup code here being executed only once, i.e. at application startup, so there is exactly one logger pointing to the text file? Only one instance of the logger can use the file at a time.
Next, is the process running with permission to access the file?
Last, is the file open e.g. in Notepad or another app that might have it locked?
If none of these spark any ideas, you can set up Serilog's self-log before configuring the logger:
SelfLog.Out = Console.Error;
This should get shown in the VS debugger, so if Serilog's catching and suppressing any exceptions you should see them.
If you can't run it in a debugger, try:
SelfLog.Out = File.OpenText(#"C:\loglog.txt");
Sometimes I find running the app under the debugger with "Break on all exceptions" enabled can be a quick way to get to the bottom of it, too (Ctrl-D,E -> CLR Exceptions [x] Thrown, [x] Unhandled).
Folks,
I got NServiceBus logging working correctly following the directions found here:
http://docs.particular.net/nservicebus/logging/
However, I am using Common.Logging. If I use the LogManager for Common.Logging, it doesn't log.
If I use the LogManager for log4net, everything works just fine.
Anyone have any insight here?
I figured this out. I needed to programatically set up Common.Logging instead of declaratively (in the config file).
Basically, I added this line before I did my fluent bus configuration:
LogManager.Adapter = new Log4NetLoggerFactoryAdapter(new NameValueCollection { { "configType", "INLINE" } });
SetLoggingLibrary.Log4Net(log4net.Config.XmlConfigurator.Configure);
And my bus logging section looks like this:
.Log4Net<ColoredConsoleAppender>(cca =>
{
cca.Layout = patternLayout;
})
.Log4Net<RollingFileAppender>(fa =>
{
fa.File = "log/handler.log";
fa.AppendToFile = true;
fa.RollingStyle = RollingFileAppender.RollingMode.Size;
fa.MaxSizeRollBackups = 5;
fa.MaximumFileSize = "1000KB";
fa.StaticLogFileName = true;
fa.Layout = patternLayout;
})
This allows me to load the logging levels in the config file, but leave the appender configuration in code as suggested by Udi (and I think it's a great idea)
I know I could of used the built in logging level of nServiceBus, but I couldn't figure out how to get fine grained control of that so that I could ignore nHibernate logging, but get all of the nServiceBus logging.
If anyone needs more guidance as to what I did, just comment here, or if you know how to get fine grained control using the nServiceBus logging level, let me know that too.
Common.Logging serves as an abstraction from log4net for the internal purposes of NServiceBus.
As of NServiceBus 5 CommonLogging is supported OOTB http://docs.particular.net/nservicebus/logging/common-logging