Sitecore Custom Log,如何每天只写一个文件?

时间:2016-12-12 11:38:04

标签: sitecore log4net sitecore7.2

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

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>

任何人都可以告诉我需要配置什么,以便每天只接收一个文件?或者换句话说,什么时候创建一个新文件?

2 个答案:

答案 0 :(得分:3)

Sitecore使用log4net作为其底层日志框架,这意味着您可以使用任何标准的appender。虽然Sitecore添加了自定义SitecoreLogFileAppender appender,但您只需使用RollingFileAppender并根据日期滚动日志文件。

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

特别是使用Sitecore,将appender更改为以下内容:

<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以上,您可以根据需要删除此节点。此值可确保log4net自动删除超过30天的任何日志。
  • datePattern:设置滚动文件的日期格式。请注意,文件后缀包含在单引号中。有关详细信息,请参阅此previous answer
  • staticLogFileName:如果设置为true,则最新的日志文件将始终具有相同的名称,但请注意,由于您的file值没有文件后缀。

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

答案 1 :(得分:1)

如果覆盖SitecoreLogFileAppender的标准行为并创建一个继承自FileAppender的新CustomLogFileAppender类,则可以轻松解决此问题。遗憾的是,SitecoreLogFileAppender不提供覆盖您需要根据您的要求修改的特定方法的可能性。因此,您需要将SitecoreLogFileAppender中的所有代码复制到新创建的文件追加器中。

&#13;
&#13;
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;
        }
    }
}
&#13;
&#13;
&#13;

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