I have an ASP NET MVC project which uses Ninject for IoC. Have added a Serilog logger
public class LoggingModule : BaseModule
{
public override void Load()
{
var fileName = "c:\path\file.log";
var loggerConfiguration = new LoggerConfiguration()
.WriteTo.RollingFile(fileName, LogEventLevel.Debug)
.MinimumLevel.Verbose();
var logger = loggerConfiguration.CreateLogger();
Log.Logger = logger;
Bind<ILogger>().ToConstant(logger);
}
}
And am injecting this into a Controller.
When I exercise the code that uses it to log it will log once and then never again until I restart the web app.
I'm using the same configuration code (without ninject) in a windows service which works fine.
Versions installed are
<package id="Serilog" version="2.3.0" targetFramework="net45" />
<package id="Serilog.Sinks.File" version="3.1.0" targetFramework="net45" />
<package id="Serilog.Sinks.RollingFile" version="3.2.0" targetFramework="net45" />
<package id="Ninject" version="3.2.2.0" targetFramework="net45" />
<package id="Ninject.MVC3" version="3.2.1.0" targetFramework="net45" />
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net45" />
<package id="Ninject.Web.Common.WebHost" version="3.2.3.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />
Update:
Following on from Caio's answer. I added in the SelfLog and see...
2016-11-22T14:29:25.6317957Z Caught exception while emitting to sink Serilog.Core.Sinks.RestrictedSink: System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'The rolling log file has been disposed.'.
at Serilog.Sinks.RollingFile.RollingFileSink.Emit(LogEvent logEvent)
at Serilog.Core.Sinks.SafeAggregateSink.Emit(LogEvent logEvent)
Update 2:
This turned out to be a bug in the way that IDependencyResolver had been implemented in our project. IDependencyResolver implements IDisposable and our implementation called dispose on the kernel. (Un?)luckily this had just never caused an issue before.
I've marked Caio's answer as the answer because him pointing me to the SelfLog gave me the tool to unwind what was happening. Thanks to all the helped though!
Have you tried checking the output from Serilog's self log, to see if there's any error occurring internally?
e.g.
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));
https://github.com/serilog/serilog/wiki/Debugging-and-Diagnostics
First question: Are you using one of the Ninject.MVC packages? If not, I'd try this first as they plug the Ninject container into the MVC pipeline correctly.
https://www.nuget.org/packages/Ninject.MVC5/
Also:
You can sometimes have an order-of-operations problem with DI containers. For this reason I find that it's unsafe to do much setup logic directly in the NinjectModule. I'd try something like this instead:
Bind<ILogger>().ToMethod(context => {
var fileName = "c:\path\file.log";
var loggerConfiguration = new LoggerConfiguration()
.WriteTo.RollingFile(fileName, LogEventLevel.Debug)
.MinimumLevel.Verbose();
var logger = loggerConfiguration.CreateLogger();
Log.Logger = logger;
}).In <whatever> Scope()
Related
I am trying to implement Identity using the Mediatr library and pattern...
The code i am using did work in dotnetcore 2.x and identity 2.2 but is broken in dotnetcore 3.x and identity 3.1.1...
My Application class library is netstandard2.1 and hase the following dependencies set.
<PackageReference Include="FluentValidation.AspNetCore" Version="8.6.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.1" />
I have my request handler like so;
public class Handler : IRequestHandler<Query, AppUser>
{
private readonly UserManager<AppUser> _userManager;
private readonly SignInManager<AppUser> _signInManager;
public Handler(UserManager<AppUser> userManager, SignInManager<AppUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
public async Task<AppUser> Handle(Query request, CancellationToken cancellationToken)
{
var user = await _userManager.FindByEmailAsync(request.Email);
if (user == null)
{
throw new Exception("Unauthorized");
}
// var result = await _signInManager.CheckPasswordSignInAsync(user, request.Password, false);
var result = await _userManager.CheckPasswordAsync(user, request.Password);
if (result)
{
return user;
}
throw new Exception("Unauthorized");
}
}
The issue I am having here is that I cannot resolve SignInManager anymore and I am not sure why. I cannot find much info about any of the breaking changes around this between identity versions either.
Where has the SignInManager gone? I thought UserManager were in the same namespace and UserManager resolves just fine. Super confused right now, as you can see, i am about ready to cheat my way out but it doesn't sit right with me.
With the same dependencies in my API project I can reference SignInManager with the same namespace and i can use it to sign in directly in the controller. How can i decouple this in to a Mediatr Handler?
Starting with version 3.0, ASP.NET Core is no longer fully distributed through NuGet. Instead, it is shipped as part of the .NET Core runtime as a shared framework. Only optional packages, like the Microsoft.AspNetCore.Identity.EntityFrameworkCore are still distributed through NuGet. However, those packages do not have transient dependencies defined which will automatically work, so you will still need to properly reference this shared framework in order to use these types.
In order to do this, you will need to switch your project to target netcoreapp3.1 since ASP.NET Core only runs on .NET Core and won’t work with .NET Standard.
Once you have done that, you can reference the shared framework using a framework reference. So your project file should look like this:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FluentValidation.AspNetCore" Version="8.6.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.1" />
</ItemGroup>
</Project>
I am able to cause a reproducible out of memory exception to occur when enqueuing and processing background jobs with Hangfire.
The jobs are simple Console.WriteLine invocations so I wouldn't expect heap memory to increase the way that it does.
Have I configured incorrectly or should I think about filing an issue?
Results (VMMap)
Using Redis as backing storage for Jobs:
At start, total heap = 29,088K;
after 5,000 jobs, 938,672K;
6,000 jobs, 1,056,004K;
7,000 jobs, 1,219,296K;
8,000 jobs, heap value is not present;
within 100 more jobs, the iisexpress.exe instance crashes.
With SQL storage the limit is much higher ~= 15,000 jobs.
Setup
empty ASP.NET project;
install Owin packages for IIS hosting and Hangfire;
startup class and controller.
Packages
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Hangfire.Core" version="1.6.6" targetFramework="net452" />
<package id="Hangfire.Pro" version="1.4.7" targetFramework="net452" />
<package id="Hangfire.Pro.PerformanceCounters" version="1.4.7" targetFramework="net452" />
<package id="Hangfire.Pro.Redis" version="2.0.2" targetFramework="net452" />
<package id="Hangfire.SqlServer" version="1.6.6" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Net.Compilers" version="1.0.0" targetFramework="net452" developmentDependency="true" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="Owin" version="1.0" targetFramework="net452" />
<package id="StackExchange.Redis" version="1.1.606" targetFramework="net452" />
</packages>
Controller
public class DefaultController : ApiController
{
static int _;
[HttpPost]
public void Post(int count = 1000)
{
for (var i = 0; i < count; ++i)
{
BackgroundJob.Enqueue(() => Console.WriteLine(_));
++_;
}
}
}
Startup
static class AppSettings
{
internal static bool HangfireUseRedis => true;
internal static int RedisDatabase => 0;
internal static string RedisConnection => "localhost:6379";
internal static string SqlConnection => "Data Source=(localdb)\\v11.0;Initial Catalog=Hangfire";
}
public class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
if (AppSettings.HangfireUseRedis)
{
var redisOptions = new RedisStorageOptions
{
Database = AppSettings.RedisDatabase,
Prefix = "Foobar:"
};
GlobalConfiguration.Configuration.UseRedisStorage(AppSettings.RedisConnection, redisOptions);
}
else
{
GlobalConfiguration.Configuration.UseSqlServerStorage(AppSettings.SqlConnection);
}
JobHelper.SetSerializerSettings(new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All });
app.UseHangfireServer();
app.UseHangfireDashboard();
app.UseWebApi(config);
}
}
After receiving your mini dump file (1.2 GB), I was able to get information about heaps of your process. Most of them don't contain anything interesting, and their size is relatively small, here is the excerpt for the most important onces:
GC Heap Size: Size: 0x9f7eb8 (10452664) bytes.
Jit code heap: Size: 0x1000 (4096) bytes total, 0x905a4d00 (2421837056) bytes wasted.
As we can see, GC Heap Size is about 10 MB, so there are no leaks in .NET code itself, since its size is relatively small. But Jit code heap looks very strange, so I decided to see what modules are used by the process, and found Stackify Profiler's one:
6b0d0000 6b23a000 StackifyProfiler_x86 (deferred)
PEB shows the environment variable StackifyIsPrefix=1 that tells us Stackify Prefix is used. Profilers may modify the JIT code for instrumentation puproses, so I've decided to install Stackify Prefix to try to reproduce the issue.
I've created a simple MVC application, modified the Home/Index action to enqueue 10000 of background jobs, and enabled the profiler. After doing this step, I've found that it takes too long to get that page – 1.5 minutes, and profiler didn't show any data. It was too long. So I decided to compare the timing with profiler turned off – it took only 5 seconds. That's a huge difference, but I was unable to reproduce memory problems.
I've decreased the number of jobs to 100, turned on the profiler and realized that every call to Redis is counted, there are hundreds of records for calls to Redis. Storing all of them may introduce memory issues, but I don't know exactly how they are stored in Stackify Prefix.
I was unable to reproduce the original memory issue. However, Stackify Prefix does significantly affect the execution by increasing its duration. Have you tried to disable the Stackify Prefix profiler and re-run your tests? Updated version may also fix the memory issue.
I can concur with the above comment from odinserj, because I wrote the Prefix profiler.
We've made some design changes to help account for background threads that run in libraries like Hangfire. The issue is that we keep shadow stacks in memory per thread - in a normal web app, we flush this stack when the request ends. But the threads that Hangfire spins up will exist for the lifetime of the app domain.
You'll find that in the lastest version, the impact should be much smaller, as we have accounted for some specific hangfire methods, and we then release some of that shadow stack.
I want to access files (images, text files etc.) from an USB stick on my Raspberry Pi 2 using Windows 10 IoT Core.
So I've added the to the appxmanifest file.
When using this code in my IBackgroundTask I get an access denied error in the second line:
public sealed class StartupTask : IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
//...
Windows.Storage.StorageFolder sf = Windows.Storage.KnownFolders.RemovableDevices;
//get list of drives
IReadOnlyList<Windows.Storage.StorageFolder> list = await sf.GetFoldersAsync();
...
}
}
I found that I should add the fileTypeAssociation with the file types I'd like to access in Package.appxmanifest so I did that:
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10" IgnorableNamespaces="uap mp iot">
<Identity Name="test-uwp" Publisher="CN=user" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="8f31dff8-3a2b-4df1-90bb-2c5267f32980" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>test</DisplayName>
<PublisherDisplayName>user</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App">
<uap:VisualElements DisplayName="test" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="test" BackgroundColor="transparent" AppListEntry="none">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="test.StartupTask">
<BackgroundTasks>
<iot:Task Type="startup" />
</BackgroundTasks>
</Extension>
<uap:Extension Category="windows.fileTypeAssociation">
<uap:FileTypeAssociation Name="myimages">
<uap:SupportedFileTypes>
<uap:FileType ContentType="image/jpeg">.jpg</uap:FileType>
</uap:SupportedFileTypes>
</uap:FileTypeAssociation>
</uap:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<uap:Capability Name="removableStorage" />
</Capabilities>
</Package>
If I want to deploy that, I get the following error:
Severity Code Description Project File Line Suppression State
Error Error : DEP0700 : Registration of the app failed.
AppxManifest.xml(37,10): error 0x80070490: Cannot register the
test-uwp_1.0.0.0_arm__yzekw4x8qxe1g package because the following
error was encountered while parsing the windows.fileTypeAssociation
Extension element: Element not found. . Try again and contact the
package publisher if the problem persists. (0x80073cf6)
As soon as I remove the uap:Extension element, the error goes away (but the access denied is still there).
Did I miss anything? Is it not possible to access files from an USB stick using a background service (I want to run that headless with no user interaction)?
At the moment you can't register a headless app that uses filetypeAssociation.
There is a workaround - see here: https://github.com/ms-iot/ntvsiot/issues/62
Simply add a headed app (project) to your solution (no need for any special code there).
Add a reference to this project in your headless app.
Now change the manifest of the headless (file asso..) and add Executable: YourHeadedApp.exe and EntryPoint: YourHeadedApp.App now with the next deploy the EXE will be included in deployment - so it can be found when the manifest is checked.
How to include Spring configuration files optionally? I think about something simular to this:
<spring>
<context>
<resource uri="file:///Objects/RequiredObjects.xml" />
<resource uri="file:///Objects/OptionalObjects.xml" required="false" />
</context>
This way I could provide developers the possibility to override some configuration parts (e.g. for a local speed improvement or automatism during app startup) without affecting the app.config and the problem that a developer could checkin his modified file when it is not really his intent to change the config for all.
Not as simple as in AutoFac (because there is already a builtin way) but possible to achieve something similar with a little coding:
using System.IO;
using System.Xml;
using Spring.Core.IO;
public class OptionalFileSystemResource : FileSystemResource
{
public OptionalFileSystemResource(string uri)
: base(uri)
{
}
public override Stream InputStream
{
get
{
if (System.IO.File.Exists(this.Uri.LocalPath))
{
return base.InputStream;
}
return CreateEmptyStream();
}
}
private static Stream CreateEmptyStream()
{
var xml = new XmlDocument();
xml.LoadXml("<objects />");
var stream = new MemoryStream();
xml.Save(stream);
stream.Position = 0;
return stream;
}
}
Register a section handler:
<sectionGroup name="spring">
...
<section name="resourceHandlers" type="Spring.Context.Support.ResourceHandlersSectionHandler, Spring.Core"/>
...
</sectionGroup>
...
<spring>
<resourceHandlers>
<handler protocol="optionalfile" type="MyCoolStuff.OptionalFileSystemResource, MyCoolStuff" />
</resourceHandlers>
...
<context>
<resource uri="file://Config/MyMandatoryFile.xml" />
<resource uri="optionalfile://Config/MyOptionalFile.xml" />
...
You'll find more information about resources and resource handlers in the Spring.Net documentation.
I have a small set of ServiceStack REST services that is using NLog 2.1 (from NuGet) for logging.
My test server is running:
Windows 7
IIS 7.5
.NET 4.5
NLog config:
<nlog throwExceptions="true" internalLogToConsole="true" internalLogLevel="Debug" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="c" xsi:type="Console" />
<target name="f1" xsi:type="File" fileName="C:\logs\test.log" />
</targets>
<rules>
<logger name="*" writeTo="c,f1" />
</rules>
</nlog>
My NLog config is exceedingly simple... just trying to get it working...
and in this configuration, everything works fine. NLog creates the log files correctly.
On my DEVELOPMENT machine, I am using:
Windows 7
Xamarin Studio / XSP4
Mono 3.2.3
Here is my Application_Start...
protected void Application_Start() {
LogManager.LogFactory = new NLogFactory();
ILog log = LogManager.GetLogger(typeof(Global));
log.Info("Application_Start called");
try {
new AppHost().Init();
} catch (Exception e) {
log.Error("Exception caught initializing AppHost");
}
}
In this configuration, my service's AppHost().Init() throws an exception as ServiceStack is registering my services in ServiceController.cs. I believe that part is irrelevant except that it is the first time something is logged outside of Application_Start (because both of the calls in Application_Start work... the log.info before the exception and the log.error after the exception).
Here is the exception that is shown:
The most relevant bit is that there was a System.NotImplementedException thrown at NLog.Internal.FileAppenders.BaseFileAppender.WindowsCreateFile (System.String fileName, Boolean allowConcurrentWrite).
I have found a workaround (in the accepted answer below). Hopefully anyone else who runs into this will quickly come upon this solution.
Some digging around on Google led me to this NLog pull request:
Avoid Win32-specific file functions in Mono where parts not implemented.
It appears that this change tries to use the preprocessor to NOT call WindowsCreateFile at all. However, for some reason, this still executes.
So I then went to check the newest version of BaseFileAppender.cs in the NLog GitHub repository to make sure someone didn't at some later point break this again.
#if !NET_CF && !SILVERLIGHT && !MONO
try
{
if (!this.CreateFileParameters.ForceManaged && PlatformDetector.IsDesktopWin32)
{
return this.WindowsCreateFile(this.FileName, allowConcurrentWrite);
}
}
catch (SecurityException)
{
InternalLogger.Debug("Could not use native Windows create file, falling back to managed filestream");
}
#endif
Hmmm... it's still there. What gives? Why doesn't MONO seem to be defined by the preprocessor, thus allowing this block to execute? I'm not sure. Before I started down that path of investigation, I noticed another change...
if (!this.CreateFileParameters.ForceManaged && ...
So after following that tracing that ForceManaged boolean back to it's origin, it appeared that I could set forceManaged="true" on my FileTarget declaration in my NLog config. Could it really be that simple?!
<nlog throwExceptions="true" internalLogToConsole="true" internalLogLevel="Debug" xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="c" xsi:type="Console" />
<target name="f1" xsi:type="File" forceManaged="true" fileName="C:\logs\test.log" />
</targets>
<rules>
<logger name="*" writeTo="c,f1" />
</rules>
</nlog>
Once that change was made, everything worked... the call to WindowsCreateFile that was throwing the exception was skipped & a managed filestream was used instead, which works great. Hallelujah!
Lastly, I could not find that forceManaged flag in the NLog documentation anywhere. Would likely have found this solution sooner if it was.