【问题标题】:Elmah logPath outside wwwrootwwwroot 外的 Elmah logPath
【发布时间】:2011-10-15 23:03:59
【问题描述】:

我们正在尝试部署我们的项目,但我们无法让 elmah 在 wwwroot 之外创建 xml 日志。它目前正在登录到 inetpub{site}\wwwroot\App_Data 因为这是唯一可行的路径。我们想让它记录到我们的 inetpub{site}\logs 文件夹。关于让它发挥作用的任何想法?我们已经尝试了文件夹的 ..\ 和 ../ 路径,但它们似乎不起作用。

【问题讨论】:

    标签: asp.net-mvc-3 elmah


    【解决方案1】:

    ELMAH logPath 只能在 Web.config 中配置,可以是虚拟路径(如果以“~/”开头)或绝对文件系统路径。 Web.config中ELMAH logPath的默认配置为:

    <elmah>
        <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/Elmah.Errors" />
    

    但是有一种解决方法是如何以编程方式设置 ELMAH logPath:

    public class MvcApplication : HttpApplication
    {
        private static string _elmahDirectory;
        private static readonly FieldInfo ElmahLogPathField = typeof(XmlFileErrorLog).GetField("_logPath", BindingFlags.NonPublic | BindingFlags.Instance);
    
        protected void Application_Start()
        {
            // Assign your path here
            _elmahDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            ...
        }
    
        protected void Application_BeginRequest()
        {
            var xmlFileErrorLog = (XmlFileErrorLog)Elmah.ErrorLog.GetDefault(HttpContext.Current);
            ElmahLogPathField.SetValue(xmlFileErrorLog, _elmahDirectory);
        }
    }
    

    【讨论】:

      【解决方案2】:

      关于让它发挥作用的任何想法?

      您可以提供日志文件的绝对路径,但您应该确保配置为在 IIS 下运行您的 Web 应用程序的帐户对该文件夹具有写入权限,以便它可以在其中创建和修改文件。

      【讨论】:

        【解决方案3】:

        正如 Darin 所提到的,您是否确保运行 Web 应用程序的用户帐户可以访问您的日志文件夹。我认为相对路径应该没问题吗?还要确保文件夹存在?

        【讨论】:

          【解决方案4】:

          如果您需要从代码中设置 logPath,而不是在配置文件中进行配置,请执行以下操作:

          默认情况下,ELMAH 会读取您的 web.config 文件以找出要创建的 ErrorLog 实现。但是,您可以覆盖此机制以实现您自己的 IServiceProvider 实现并注册一个使用 ServiceCenter.Current 属性返回实例的委托。

          这样的IServiceProvider 实现如下所示:

          internal sealed class ElmahServiceProvider : IServiceProvider
          {
              private readonly ErrorLog defaultErrorLog;
          
              private ElmahServiceProvider(ErrorLog defaultErrorLog)
              {
                  Requires.IsNotNull(defaultErrorLog, "defaultErrorLog");
                  this.defaultErrorLog = defaultErrorLog;
              }
          
              public object GetService(Type serviceType)
              {
                  return serviceType == typeof(ErrorLog) ? this.defaultErrorLog : null;
              }
          }
          

          在应用程序启动期间,您可以执行以下操作:

          // Option 1: using a virtual path
          var logger = new XmlFileErrorLog(new Dictionary<string, string>
          {
              { "logPath", "~/myCustomPath" }
          });
          
          // Option 2: using a fixed path
          var logger = new XmlFileErrorLog("c:\\logFiles");
          
          // Creating the provider and registering it in the ServiceCenter.
          var provider = new ElmahServiceProvider(logger);
          ServiceCenter.Current = c => provider;
          

          这可以让您避免必须恢复到反射。

          【讨论】:

          • 好主意,但您的示例代码存在问题。似乎“需要”是您在此处进行空检查的自定义类。 Dictionary 对象也有语法问题。
          猜你喜欢
          • 2017-11-20
          • 1970-01-01
          • 2012-08-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-24
          • 2013-07-21
          相关资源
          最近更新 更多