109 lines
3.2 KiB
C#
109 lines
3.2 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using JetBrains.Annotations;
|
|
using Microsoft.AspNet.Diagnostics.Entity.Utilities;
|
|
using Microsoft.Data.Entity.Storage;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
#if DNXCORE50
|
|
using System.Threading;
|
|
#else
|
|
using System.Runtime.Remoting.Messaging;
|
|
#endif
|
|
|
|
namespace Microsoft.AspNet.Diagnostics.Entity
|
|
{
|
|
public class DataStoreErrorLogger : ILogger
|
|
{
|
|
#if DNXCORE50
|
|
private readonly AsyncLocal<DataStoreErrorLog> _log = new AsyncLocal<DataStoreErrorLog>();
|
|
#else
|
|
private const string ContextName = "__DataStoreErrorLog";
|
|
#endif
|
|
|
|
public virtual DataStoreErrorLog LastError
|
|
{
|
|
get
|
|
{
|
|
#if DNXCORE50
|
|
return _log.Value;
|
|
#else
|
|
return (DataStoreErrorLog)CallContext.LogicalGetData(ContextName);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
public virtual void StartLoggingForCurrentCallContext()
|
|
{
|
|
// Because CallContext is cloned at each async operation we cannot
|
|
// lazily create the error object when an error is encountered, otherwise
|
|
// it will not be available to code outside of the current async context.
|
|
// We create it ahead of time so that any cloning just clones the reference
|
|
// to the object that will hold any errors.
|
|
#if DNXCORE50
|
|
_log.Value = new DataStoreErrorLog();
|
|
#else
|
|
CallContext.LogicalSetData(ContextName, new DataStoreErrorLog());
|
|
#endif
|
|
}
|
|
|
|
public virtual void Log(LogLevel logLevel, int eventId, [CanBeNull] object state, [CanBeNull] Exception exception, [CanBeNull] Func<object, Exception, string> formatter)
|
|
{
|
|
var errorState = state as DatabaseErrorLogState;
|
|
if (errorState != null && exception != null && LastError != null)
|
|
{
|
|
LastError.SetError(errorState.ContextType, exception);
|
|
}
|
|
}
|
|
|
|
public virtual bool IsEnabled(LogLevel logLevel)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
public virtual IDisposable BeginScopeImpl(object state)
|
|
{
|
|
return NullScope.Instance;
|
|
}
|
|
|
|
private class NullScope : IDisposable
|
|
{
|
|
public static NullScope Instance = new NullScope();
|
|
|
|
public void Dispose()
|
|
{ }
|
|
}
|
|
|
|
public class DataStoreErrorLog
|
|
{
|
|
private Type _contextType;
|
|
private Exception _exception;
|
|
|
|
public virtual void SetError([NotNull] Type contextType, [NotNull] Exception exception)
|
|
{
|
|
Check.NotNull(contextType, nameof(contextType));
|
|
Check.NotNull(exception, nameof(exception));
|
|
|
|
_contextType = contextType;
|
|
_exception = exception;
|
|
}
|
|
|
|
public virtual bool IsErrorLogged
|
|
{
|
|
get { return _exception != null; }
|
|
}
|
|
|
|
public virtual Type ContextType
|
|
{
|
|
get { return _contextType; }
|
|
}
|
|
|
|
public virtual Exception Exception
|
|
{
|
|
get { return _exception; }
|
|
}
|
|
}
|
|
}
|
|
}
|