我有一个在多个会话上从多个用户在Windows服务器上运行的进程(可能多达50个并发用户),我想:
所以我想我会试试nLog:
<?xml version="1.0" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogFile="file.txt">
<targets async="false">
<target name="regFile" xsi:type="File"
layout="${longdate} [${windows-identity}][${processid}]${threadname} ${uppercase:${level}} ${callsite} - ${message}${onexception:${newline}${exception:format=tostring}}"
fileName="${basedir}/logs/test.log"
archiveFileName="${basedir}/logs/test.{#####}.log"
archiveAboveSize="102400"
archiveNumbering="Rolling"
maxArchiveFiles="14"
concurrentWrites="true"
keepFileOpen="true"
autoFlush="true"
/>
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="regFile" />
</rules>
</nlog>
我还写了一个小测试员:
class Program
{
private static Logger m_log = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
// Load logger configuration
var assemblyLocation = Assembly.GetExecutingAssembly().Location;
var assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (assemblyDirectory != null)
{
var logConfig = new FileInfo(Path.Combine(assemblyDirectory, "nlogConfig.xml"));
NLog.LogManager.Configuration = new NLog.Config.XmlLoggingConfiguration(logConfig.FullName, true);
}
if (args.Length == 1)
{
var sw = Stopwatch.StartNew();
var size = Int32.Parse(args[0]);
m_log.Info("Will launch {0} process and wait for them to come back...",size);
var handles = new WaitHandle[size];
for (int i = 0; i < size; i++)
{
var p = Process.Start(Assembly.GetExecutingAssembly().Location);
var processHandle = OpenProcess(
ProcessAccessFlags.Synchronize, false, p.Id);
if (processHandle != IntPtr.Zero)
handles[i] = new ManualResetEvent(false)
{
SafeWaitHandle = new SafeWaitHandle(processHandle, false)
};
m_log.Fatal("Started pid={0}.",p.Id);
}
m_log.Info("Created the processes, now wait.");
WaitHandle.WaitAll(handles);
sw.Stop();
Thread.Sleep(100);
m_log.Info("Done, took {0}.",sw.ElapsedMilliseconds);
}
else
{
m_log.Info("Running for {0} * {1}",1000,m_log.ToString());
for (int i = 0; i < 1000; i++)
{
m_log.Error("Hello nlog {0}", i);
}
}
}
#region Native API
[Flags]
enum ProcessAccessFlags
{
All = 0x001F0FFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VMOperation = 0x00000008,
VMRead = 0x00000010,
VMWrite = 0x00000020,
DupHandle = 0x00000040,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
Synchronize = 0x00100000
}
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, bool bInheritHandle, int dwProcessId);
#endregion
}
运行得很好,只要我不需要存档...... 像这样运行我的测试器:“LoggerTester.exe 10”我得到了
也许我要求的很多,我必须使用某种内存记录器模式(使用1个记录器来实际管理文件),但我真的希望能够这样做。
在任何地方找不到任何参考,所以我想我在这里试试运气......谢谢。
答案 0 :(得分:0)
我认为您将无法从多个进程登录到单个文件。我建议尝试其他一些目标:
我过去使用DatabaseTarget取得了成功。
我没有其他目标的经验,但我确实实现了一次LoggingService。它与LogReceiverWebServiceTarget非常相似。这是一个实现日志记录界面的WCF服务。我们有一个相应的Target,可以配置为与日志服务端点进行通信。我们还实现了一些缓存和刷新,以便我们发送消息块而不是为每条消息进行服务调用。
祝你好运!答案 1 :(得分:0)
NLog现在对并发存档逻辑进行了一些改进:
这样做可以在执行归档操作时更好地协调并发进程。当然,协调/同步仍然会降低性能。
与其在多个并发进程中尝试重命名/移动相同的静态文件名,不如在NLog 4.5(及更高版本)中建议在文件名中包含${shortdate}
。这样可以减少参加日间战斗的机会:
<target name="regFile" xsi:type="File"
fileName="${basedir}/logs/test.${shortdate}.log"
archiveAboveSize="102400"
maxArchiveFiles="14"
concurrentWrites="true"
keepFileOpen="true" />