我们已经实现了自定义日志并写入自定义日志文件。 问题是,日志每天创建几次,文件名如下:
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>
任何人都可以告诉我需要配置什么,以便每天只接收一个文件?或者换句话说,什么时候创建一个新文件?
答案 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中的所有代码复制到新创建的文件追加器中。
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;
请在此处找到更多信息:https://sitecore.unic.com/2015/01/27/create-a-single-sitecore-log-file-per-day