【问题标题】:Sitecore Custom Log, how to write only one file per day?Sitecore自定义日志,如何每天只写一个文件?
【发布时间】:2017-04-27 06:26:58
【问题描述】:

我们实现了自定义日志并写入自定义日志文件。 问题是,日志每天创建几次,文件名如下:

MyCustom.log.20161208.165109
MyCustom.log.20161208.165845
MyCustom.log.20161208.175134
MyCustom.log.20161208.184432

定义是这样的:

    <appender name="MyCustomLogAppender" type="log4net.Appender.SitecoreLogFileAppender, Sitecore.Logging">
  <file value="$(dataFolder)/logs/MyCustom.log.{date}.txt" />
  <appendToFile value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%4t %d{ABSOLUTE} %-5p %m%n" />
  </layout>
  <encoding value="utf-8" />
</appender>

谁能告诉我我需要配置什么才能每天只接收一个文件?或者换句话说,什么时候创建一个新文件?

【问题讨论】:

  • 它发生在您的本地环境或产品上吗?您的应用程序池是否被回收?只要您的应用程序没有重新启动,如果您不使用滚动文件附加程序,则应该只有 1 个日志文件。
  • 感谢 Marek 的提示,我不知道每次回收应用程序池时都会创建一个新日志。

标签: sitecore log4net sitecore7.2


【解决方案1】:

如果您重写 SitecoreLogFileAppender 的标准行为并创建一个继承自 FileAppender 的新 CustomLogFileAppender 类,您可以轻松克服这个问题。不幸的是,SitecoreLogFileAppender 不为您提供仅覆盖您需要修改以满足您的要求的特定方法的可能性。因此,您需要将 SitecoreLogFileAppender 中的所有代码复制到新创建的文件附加程序中。

namespace MyProject.Core
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Runtime.InteropServices;
    using System.Web;
    using log4net.Appender;
    using log4net.spi;

    /// <summary>
    /// Custom log file appender
    /// </summary>	
    public class CustomLogFileAppender : FileAppender
    {
        /// <summary>
        /// The m_current date
        /// </summary>
        private DateTime m_currentDate;

        /// <summary>
        /// The m_original file name
        /// </summary>
        private string m_originalFileName;

        /// <summary>
        /// Initializes a new instance of the <see cref="CustomLogFileAppender"/> class.
        /// </summary>
        public CustomLogFileAppender()
        {
            this.m_currentDate = DateTime.Now;
        }

        /// <summary>
        /// Gets or sets the file.
        /// </summary>
        /// <value>
        /// The file.
        /// </value>
        public override string File
        {
            get
            {
                return base.File;
            }

            set
            {
                if (this.m_originalFileName == null)
                {
                    string str = value;
                    Dictionary<string, string> variables = ConfigReader.GetVariables();
                    foreach (string index in variables.Keys)
                    {
                        string oldValue = "$(" + index + ")";
                        str = str.Replace(oldValue, variables[index]);
                    }

                    this.m_originalFileName = this.MapPath(str.Trim());
                }

                base.File = this.m_originalFileName;
            }
        }

        /// <summary>
        /// Makes the path.
        /// </summary>
        /// <param name="part1">The part1.</param>
        /// <param name="part2">The part2.</param>
        /// <param name="separator">The separator.</param>
        /// <returns>
        /// Complete path.
        /// </returns>
        public static string MakePath(string part1, string part2, char separator)
        {
            if (string.IsNullOrEmpty(part1))
            {
                return part2 ?? string.Empty;
            }

            if (string.IsNullOrEmpty(part2))
            {
                return part1 ?? string.Empty;
            }

            if ((int)part1[part1.Length - 1] == (int)separator)
            {
                part1 = part1.Substring(0, part1.Length - 1);
            }

            if ((int)part2[0] == (int)separator)
            {
                part2 = part2.Substring(1);
            }

            return part1 + (object)separator + part2;
        }

        /// <summary>
        /// Appends the specified logging event.
        /// </summary>
        /// <param name="loggingEvent">The logging event.</param>
        protected override void Append(LoggingEvent loggingEvent)
        {
            DateTime now = DateTime.Now;
            if (this.m_currentDate.Day != now.Day || this.m_currentDate.Month != now.Month || this.m_currentDate.Year != now.Year)
            {
                lock (this)
                {
                    this.CloseFile();
                    this.m_currentDate = DateTime.Now;
                    this.OpenFile(string.Empty, false);
                }
            }

            base.Append(loggingEvent);
        }

        /// <summary>
        /// Opens the file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="append">if set to <c>true</c> [append].</param>
        protected override void OpenFile(string fileName, bool append)
        {
            fileName = this.m_originalFileName;
            fileName = fileName.Replace("{date}", this.m_currentDate.ToString("yyyyMMdd"));
            fileName = fileName.Replace("{time}", this.m_currentDate.ToString("HHmmss"));
            fileName = fileName.Replace("{processid}", CustomLogFileAppender.GetCurrentProcessId().ToString());

            base.OpenFile(fileName, append);
        }

        /// <summary>
        /// Gets the current process identifier.
        /// </summary>
        /// <returns>
        /// The process Id.
        /// </returns>
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern int GetCurrentProcessId();

        /// <summary>
        /// Gets the name of the timed file.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns>
        /// Filename with timestamp.
        /// </returns>
        private string GetTimedFileName(string fileName)
        {
            int num = fileName.LastIndexOf('.');
            if (num < 0)
            {
                return fileName;
            }

            return
                string.Concat(
                    new object[4]
                        {
                            (object)fileName.Substring(0, num), (object)'.', (object)this.m_currentDate.ToString("HHmmss"),
                            (object)fileName.Substring(num)
                        });
        }

        /// <summary>
        /// Determines whether the specified file name is locked.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns>
        /// Locked or not.
        /// </returns>
        private bool IsLocked(string fileName)
        {
            if (!System.IO.File.Exists(fileName))
            {
                return false;
            }

            try
            {
                FileStream fileStream = System.IO.File.OpenWrite(fileName);
                if (fileStream == null)
                {
                    return true;
                }

                fileStream.Close();
                return false;
            }
            catch (Exception ex)
            {
                string message = ex.Message;
                return true;
            }
        }

        /// <summary>
        /// Maps the path.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns>
        /// Mapped path.
        /// </returns>
        private string MapPath(string fileName)
        {
            if (fileName == string.Empty || fileName.IndexOf(":/", System.StringComparison.Ordinal) >= 0 || fileName.IndexOf("://", System.StringComparison.Ordinal) >= 0)
            {
                return fileName;
            }

            var index = fileName.IndexOfAny(new char[2] { '\\', '/' });
            if (index >= 0 && (int)fileName[index] == 92)
            {
                return fileName.Replace('/', '\\');
            }

            fileName = fileName.Replace('\\', '/');
            if (HttpContext.Current != null)
            {
                return HttpContext.Current.Server.MapPath(fileName);
            }

            return (int)fileName[0] == 47 ? SitecoreLogFileAppender.MakePath(HttpRuntime.AppDomainAppPath, fileName.Replace('/', '\\'), '\\') : fileName;
        }
    }
}

请在此处找到更多信息:https://sitecore.unic.com/2015/01/27/create-a-single-sitecore-log-file-per-day

【讨论】:

    【解决方案2】:

    Sitecore 使用 log4net 作为其底层日志框架,这意味着您可以使用任何标准附加程序。尽管 Sitecore 添加了一个自定义的 SitecoreLogFileAppender 附加程序,但您可以简单地使用 RollingFileAppender 并根据日期滚动日志文件。

    您可以在文档的log4net config examples section 中找到示例。

    特别是使用 Sitecore,将附加程序更改为以下内容:

    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender, Sitecore.Logging">
      <file value="$(dataFolder)/logs/log" />
      <appendToFile value="true" />
      <rollingStyle value="Date" />
      <maxSizeRollBackups value="30" />
      <datePattern value=".yyyyMMdd'.txt'" />
      <staticLogFileName value="false" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%4t %d{ABSOLUTE} %-5p %m%n" />
      </layout>
      <encoding value="utf-8" />
    </appender>
    

    关于上述配置更改的一些细节:

    • file :要登录的文件的名称。请注意,我们使用以下设置对此进行了补充。
    • rollingStyle :滚动每个文件的格式。
    • maxSizeRollBackups : 上面已经设置为 30,如果你愿意,可以移除这个节点。此值可确保任何超过 30 天的日志都会被 log4net 自动删除。
    • datePattern :设置滚动文件的日期格式。请注意,文件后缀包含在单引号中。有关详细信息,请参阅此previous answer
    • staticLogFileName :如果设置为 true,那么最新的日志文件将始终具有相同的名称,但请注意,由于您的 file 值,没有文件后缀。

    这些文件现在将以log.yyyMMdd.txt 格式在与以前相同的日志文件夹中生成,并且不会因每次应用程序重启/应用程序池回收而生成不同的文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      • 2011-02-23
      • 2012-10-17
      • 2012-05-08
      • 1970-01-01
      相关资源
      最近更新 更多