我正在尝试解决 log4net 不是多进程安全的问题。因为有时日志文件被锁定并且同一应用程序的另一个线程无法写入它。我想要做的是创建日志文件,该文件具有唯一的 id 到其上的线程。目前我正在使用 Thread.CurrentThread.GetHashCode()、Process.GetCurrentProcess() 和 System.Environment.MachineName 作为文件名的一部分。这是否足够或多余,或者是否有更好的方法来获得一个唯一的 ID,它是多线程/进程/网络农场/网络花园安全的日志文件名?或者,有没有更好的方法来编写日志文件?提前致谢。
2 回答
作为一般理论:您的机器 ID(主机名,或者更好的是,第一个网络接口的 MAC 地址)加上进程 ID/线程 ID 应该是普遍唯一的,所以是的,我认为您有一个有效的解决方案。
MAC 地址非常好,如果你能获得它们,因为它们“保证”是普遍唯一的(尽管虚拟化可能会破坏它);主机名“应该”是唯一的,但对此的保证少了一点(例如:有人建立了一系列克隆的机器并意外地将其主机名设置为全部匹配)。但是,我假设(因为您被标记为 asp.net)您在某种 Windows 域中运行,该域保证了唯一的主机名。
如果我理解正确,您希望为每台机器的每个进程的每个线程创建一个日志文件。因此,根据您正在执行的操作的描述,您的日志文件名可能如下所示:
machine1_processid1_thread1.log
machine1_processid1_thread2.log
machine1_processid2_thread1.log
machine2_processid1_thread1.log
etc...
您是否关心日志文件名的任何组成部分的实际值是多少?换句话说,日志文件名由可识别的组件(机器名称、线程 ID、进程 ID 等)组成真的很重要吗?或者日志文件名只是唯一的就足够了吗?
一种方法是简单地使用 Guid。因此,在您创建日志文件名的地方,您可以执行以下操作:
string logFileName = Guid.NewGuid().ToString() + ".log"
这可能会实现您拥有唯一命名的日志文件的目标。我想可能最终会发生 Guid 的冲突,但我对此知之甚少,无法确定。但是,这种方法并不是非常用户友好。谁真的想查看一个充满基于 guid 的文件名的文件夹并尝试确定他们真正想要查看的文件名?
也许了解生成日志的机器和过程很有用?这样,如果您知道或怀疑某些问题来自特定机器或特定进程,您可以只找到从该机器/进程生成的那些文件。在这种情况下,您仍然可以使用 Guid 来命名文件,但您可以增加机器名称和/或进程:
string logFileName = string.Format("{0}_{1}_{2}.log",
Environment.MachineName,
Process.GetCurrentProcess().ProcessName,
Guid.NewGuid());
这应该提供一个对用户更友好的日志文件名,并且在所有标准中仍然是唯一的。
总之,我建议尝试使用 Guid,因为它的既定目的是提供全局唯一标识符,而不是尝试提出自己的算法。正如我上面提到的,主要的缺点是挖掘一个充满基于 guid 的日志文件的文件夹,试图找到“正确的”日志文件可能会很烦人。使用更多用户友好的数据(例如机器名称、进程名称等)来增加文件名可能会有所帮助。
最后,我会提到,如果您确实使用 Guid,则有几个选项可用于格式化 guid。