unitycontainer / microsoft-logging Goto Github PK
View Code? Open in Web Editor NEWAdapter for Microsoft.Extensions.Logging
License: Apache License 2.0
Adapter for Microsoft.Extensions.Logging
License: Apache License 2.0
Hi,
This is not working if you rely on automatic constructor registration, https://unitycontainer.github.io/tutorials/registration/Type/Constructor/automatic.html
I've forked this repo, and updated all the dependencies to Unity 5.11.1 and Logging Abstractions 3.0.0
If you add an empty constructor to the LoggedType
in the unit test, and run them, it will fail. Unity is probably not picking up ILogger
and ILogger<>
as resolvable types.
Is this expected behaviour? Or could something be done about it? Because if you use dependencies that do resolve, it will pick the correct constructor (the one with the most arguments)
Thanks,
P.
Hi,
will you update your library to support ILoggingBuilder as LoggerFactory is getting deprecated in version 2.2 of Microsoft.Extensions.Logging ?
see this: dotnet/extensions#615
Thank you!
After the update to 1.0.2, application crashes on "AddNewExtension". Version 1.0.1 works.
Log:
Exception thrown: 'Unity.Exceptions.ResolutionFailedException' in Unity.Container.dll
An unhandled exception of type 'Unity.Exceptions.ResolutionFailedException' occurred in Unity.Container.dll
Resolution of the dependency failed, type = 'Unity.Microsoft.Logging.LoggingExtension', name = '(none)'.
Exception occurred while: Calling constructor Unity.Microsoft.Logging.LoggingExtension().
Exception is: MethodAccessException - Attempt by security transparent method 'Unity.Microsoft.Logging.LoggingExtension..ctor()' to access security critical method 'Microsoft.Extensions.Logging.LoggerFactory..ctor()' failed.
-----------------------------------------------
At the time of the exception, the container was:
Resolving Unity.Microsoft.Logging.LoggingExtension,(none)
Calling constructor Unity.Microsoft.Logging.LoggingExtension()
Regards,
TheAifam5
My usecase is that the ILoggerFactory is build as part of startup and I want to lazy create it until the first ILogger is needed.
I modified the extension
public class LoggingExtension : UnityContainerExtension,
IBuildPlanCreatorPolicy,
IBuildPlanPolicy
{
#region Fields
private readonly MethodInfo _createLoggerMethod = typeof(LoggingExtension).GetTypeInfo()
.GetDeclaredMethod(nameof(CreateLogger));
#endregion
#region Constructors
//[InjectionConstructor]
//public LoggingExtension()
//{
// LoggerFactory = new LoggerFactory();
//}
//public LoggingExtension(ILoggerFactory factory)
//{
// LoggerFactory = factory ?? new LoggerFactory();
//}
#endregion
#region Public Members
//public ILoggerFactory LoggerFactory { get; }
#endregion
#region IBuildPlanPolicy
public void BuildUp(IBuilderContext context)
{
context.Existing = null == context.ParentContext
? context.ParentContext.Container.Resolve<ILoggerFactory>().CreateLogger(context.OriginalBuildKey.Name ?? string.Empty)
: context.Container.Resolve<ILoggerFactory>().CreateLogger(context.ParentContext.BuildKey.Type);
context.BuildComplete = true;
}
#endregion
#region IBuildPlanCreatorPolicy
IBuildPlanPolicy IBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, INamedType buildKey)
{
var info = (context ?? throw new ArgumentNullException(nameof(context))).BuildKey
.Type
.GetTypeInfo();
if (!info.IsGenericType) return this;
var buildMethod = _createLoggerMethod.MakeGenericMethod(info.GenericTypeArguments.First())
.CreateDelegate(typeof(DynamicBuildPlanMethod));
return new DynamicMethodBuildPlan((DynamicBuildPlanMethod)buildMethod, context.Container.Resolve<ILoggerFactory>());
}
#endregion
#region Implementation
private static void CreateLogger<T>(IBuilderContext context, ILoggerFactory loggerFactory)
{
context.Existing = loggerFactory.CreateLogger<T>();
context.BuildComplete = true;
}
protected override void Initialize()
{
Context.Policies.Set(typeof(ILogger), string.Empty, typeof(IBuildPlanPolicy), this);
Context.Policies.Set<IBuildPlanCreatorPolicy>(this, typeof(ILogger));
Context.Policies.Set<IBuildPlanCreatorPolicy>(this, typeof(ILogger<>));
}
private delegate void DynamicBuildPlanMethod(IBuilderContext context, ILoggerFactory loggerFactory);
private class DynamicMethodBuildPlan : IBuildPlanPolicy
{
private readonly DynamicBuildPlanMethod _buildMethod;
private readonly ILoggerFactory _loggerFactory;
/// <summary>
///
/// </summary>
/// <param name="buildMethod"></param>
/// <param name="loggerFactory"></param>
public DynamicMethodBuildPlan(DynamicBuildPlanMethod buildMethod,
ILoggerFactory loggerFactory)
{
_buildMethod = buildMethod;
_loggerFactory = loggerFactory;
}
/// <summary>
///
/// </summary>
/// <param name="context"></param>
public void BuildUp(IBuilderContext context)
{
_buildMethod(context, _loggerFactory);
}
}
#endregion
}
What do you think, should we consider resolving it instead of giving it when constructing the extension?
Hi,
We are using Microsoft Unity application block for DI and logging. We're planning to upgrade to Unity package (5.11.1). We're investigation as to what it takes to get this working. So we removed Microsoft.Practices.Unity.dll, Microsoft.Practices.Unity.Configuration.dll, Microsoft.Practices.Unity.Interception.dll and added Unity.Abstractions.dll, Unity.Configuration.dll, Unity.Container.dll, Unity.Interception.dll. We updated config file in unity section to point to Unit.Container. Somehow, we got the unity working. However, we encountered issues while logging using unity container.
`public class LogMethodRegistration : UnityContainerExtension
{
///
/// <summary>
/// Called when [register].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="RegisterEventArgs"/> instance containing the event data.</param>
private void OnRegister(object sender, RegisterEventArgs e)
{
System.Diagnostics.Debug.Assert(false, "OnRegister");
if (e != null && e.TypeFrom != null && e.TypeFrom.IsInterface)
{
/*var interfaceInterceptor = new Interceptor<InterfaceInterceptor>();
interfaceInterceptor.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies);
var interceptionBehavior = new InterceptionBehavior<LogMethodInterceptionBehavior>();
interceptionBehavior.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies);*/
}
}
}
[SecurityCritical]
public class LogMethodInterceptionBehavior : IInterceptionBehavior
{
///
/// <summary>
/// Invokes the specified input.
/// </summary>
/// <param name="input">The input.</param>
/// <param name="getNext">The get next.</param>
/// <returns>Object of type IMethodReturn</returns>
[SecurityCritical]
public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
ArgumentValidator.ValidateForNotNull("getNext", getNext);
// Log method invoked, by default we don't log method inputs
bool logMethodInputs = false;
this.LogMethodInvoked(input, logMethodInputs);
// Invoke the next behavior in the chain.
IMethodReturn methodReturn = getNext()(input, getNext);
// Log method completed, by default we don't log method outputs
bool logMethodOutputs = false;
this.LogMethodCompleted(input, methodReturn, logMethodOutputs);
return methodReturn;
}
/// <summary>
/// Gets the required interfaces.
/// </summary>
/// <returns>Object of type IEnumerable of Type</returns>
[SecurityCritical]
public IEnumerable<Type> GetRequiredInterfaces()
{
return Type.EmptyTypes;
}
/// <summary>
/// Logs the method invoked.
/// </summary>
/// <param name="methodInvocation">The method invocation.</param>
/// <param name="logMethodInputs">if set to <c>true</c> [log method inputs].</param>
protected void LogMethodInvoked(IMethodInvocation methodInvocation, bool logMethodInputs)
{
ArgumentValidator.ValidateForNotNull("methodInvocation", methodInvocation);
// Before invoking the method on the original target.
Logger.Log(
LogMessage.InvokedMethod,
LogCategory.Information,
methodInvocation.MethodBase.DeclaringType,
methodInvocation.MethodBase.Name,
methodInvocation.MethodBase);
if (logMethodInputs)
{
if (methodInvocation.Arguments.Count > 0)
{
bool logAdditionalInformation = false;
Logger.Log(LogMessage.MethodInputParameters, LogCategory.Information, logAdditionalInformation);
for (int i = 0; i < methodInvocation.Arguments.Count; i++)
{
Logger.Log(
LogMessage.ParameterNameAndValue,
LogCategory.Information,
logAdditionalInformation,
methodInvocation.Arguments.ParameterName(i),
methodInvocation.Arguments[i]);
}
}
}
}
/// <summary>
/// Logs the method completed.
/// </summary>
/// <param name="methodInvocation">The method invocation.</param>
/// <param name="methodReturn">The method return.</param>
/// <param name="logMethodOutputs">if set to <c>true</c> [log method outputs].</param>
protected void LogMethodCompleted(
IMethodInvocation methodInvocation,
IMethodReturn methodReturn,
bool logMethodOutputs)
{
ArgumentValidator.ValidateForNotNull("methodInvocation", methodInvocation);
ArgumentValidator.ValidateForNotNull("methodReturn", methodReturn);
// After invoking the method on the original target, log the method completion
if (methodReturn.Exception != null)
{
// Log method exception
Logger.Log(
LogMessage.CompletedMethodWithException,
LogCategory.Information,
methodInvocation.MethodBase.DeclaringType,
methodInvocation.MethodBase.Name,
methodInvocation.MethodBase,
methodReturn.Exception);
// Log any inner exception
if (methodReturn.Exception.InnerException != null)
{
bool logAdditionalInformation = false;
Logger.Log(
LogMessage.InnerException,
LogCategory.Information,
logAdditionalInformation,
methodReturn.Exception.InnerException);
}
}
else
{
// Log method method completed
Logger.Log(
LogMessage.CompletedMethod,
LogCategory.Information,
methodInvocation.MethodBase.DeclaringType,
methodInvocation.MethodBase.Name,
methodInvocation.MethodBase);
// Log method outputs if required
if (logMethodOutputs)
{
if (methodReturn.Outputs.Count > 0)
{
bool logAdditionalInformation = false;
Logger.Log(LogMessage.MethodOutputParameters, LogCategory.Information, logAdditionalInformation);
for (int i = 0; i < methodReturn.Outputs.Count; i++)
{
Logger.Log(
LogMessage.ParameterNameAndValue,
LogCategory.Information,
logAdditionalInformation,
methodReturn.Outputs.ParameterName(i),
methodReturn.Outputs[i]);
}
}
if (methodReturn.ReturnValue != null)
{
bool logAdditionalInformation = false;
Logger.Log(
LogMessage.MethodOutput,
LogCategory.Information,
logAdditionalInformation,
methodReturn.ReturnValue);
}
}
}
}
}
`
When launching app, it threw at this.Container.AddNewExtension() The error is Attempt by method 'LogMethodRegistration.Initialize()' to access method 'Unity.ExtensionExtensions.AddNewExtension<Unity.Interception.Interception>(Unity.IUnityContainer)' failed
We don't know what the error means and don't know its usage either. There is no documentation about Unity as a whole.
Could you assist us in resolving this issue? Also, could point any documentation for all Unity packages for reference?
Thanks,
Amit
Hi,
When I use the sample code in Readme.md to create a logger factory I get a warning that it is obselete: "This method is obselete and will be removed in future versions. The recommended alternative is using LoggerFactory to configure filtering and ConsoleLoggerOptions to configure logging options."
I'm not quite sure how to implement that, could the sample code be updated?
The sample code in question is:
ILoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new ConsoleLoggerProvider((text, logLevel) => logLevel >= LogLevel.Debug, false));
Thanks
Jim
Instead of referencing Microsoft.Extensions.Logging package Microsoft.Extensions.Logging.Abstractions package could be used.
This changelog should explain how to migrate
Originally posted by @ENikS in https://github.com/unitycontainer/unity/issues/313#issuecomment-617993501
Hi,
In reference to https://github.com/unitycontainer/unity/issues/313
That changelog did not help us. We've resolved one issue. However, we've not idea out addPolicies usage.
`
///
/// Called when [register].
///
/// The sender.
/// The instance containing the event data.
private void OnRegister(object sender, RegisterEventArgs e)
{
System.Diagnostics.Debug.Assert(false, "OnRegister");
if (e != null && e.TypeFrom != null && e.TypeFrom.IsInterface)
{
/*var interfaceInterceptor = new Interceptor();
interfaceInterceptor.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies);
var interceptionBehavior = new InterceptionBehavior<LogMethodInterceptionBehavior>();
interceptionBehavior.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies);*/
}
}
`
At the minute, AddPolicies is throwing compile time error stating Context.Policies is read-only.
Can you assist us in resolving the issue?
Thanks,
Amit
I noticed that the extension doesn't register ILoggerFactory
despite that Microsoft's documentation says that it's a valid use case to inject the factory to be able to explicitly specify the log category. Maybe the instance of the factory could be registered as well?
Hi,
I was wandering why this library is using [assembly:SecurityTransparent] because it gives me the following error when starting an ASP.NET MVC 5 application:
Attempt by security transparent method 'Unity.Microsoft.Logging.LoggingExtension..ctor(Microsoft.Extensions.Logging.ILoggerFactory)' to access security critical type 'Microsoft.Extensions.Logging.ILoggerFactory' failed
Regards,
Emanuel
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.