如何在多线程,多进程,网络花园和网络农场的情况下获得一个唯一的id



我正试图绕过log4net不是多进程安全的问题。因为有时日志文件被锁定,同一应用程序的另一个线程无法写入它。我要做的是创建具有唯一id的日志文件上的线程。目前我正在使用Thread.CurrentThread.GetHashCode(), Process.GetCurrentProcess()和System.Environment.MachineName作为文件名的一部分。这是否足够或冗余,或者是否有更好的方法来获得一个唯一的id,是多线程/进程/web农场/web花园安全作为日志文件名?或者,是否有更好的方式来编写日志文件?

如果我理解正确的话,您希望为每个线程、每个进程、每台机器创建一个日志文件。因此,给定您正在执行的操作的描述,您的日志文件名可能看起来像这样:

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"

这可能会实现您拥有唯一命名的日志文件的目标。我想有可能最终会有Guids的碰撞,但我对这一点了解不够,不能肯定。但是,这种方法对用户并不友好。谁真的想查看一个文件夹,里面全是基于向导的文件名,并试图确定他们真正想要查看的是哪个?

也许了解生成日志的机器和过程是有用的?这样,如果您知道或怀疑某个问题来自特定的机器或特定的进程,您就可以找到从该机器/进程生成的那些文件。在这种情况下,您仍然可以使用Guid来命名文件,但是您可以添加机器名和进程名:

string logFileName = string.Format("{0}_{1}_{2}.log", 
                                   Environment.MachineName,
                                   Process.GetCurrentProcess().ProcessName,
                                   Guid.NewGuid());

这应该给出一个更用户友好的日志文件名,并且在所有标准中仍然是唯一的。

总之,我建议尝试使用Guid,因为它的声明目的是提供一个全局唯一标识符,而不是试图提出自己的算法。正如我上面提到的,主要缺点是,在一个充满基于指南的日志文件的文件夹中查找"正确"的日志文件可能会很烦人。在文件名中添加更多用户友好的数据,如机器名、进程名等,可能会有所帮助。

最后,我要提一下,如果您确实使用Guid,有几个选项可用于格式化Guid。

http://msdn.microsoft.com/en-us/library/97af8hh4.aspx

作为一般理论:您的机器ID(主机名,或者更好的是,第一个网络接口的MAC地址)加上进程ID/线程ID应该是普遍唯一的,所以是的,我认为您已经得到了一个有效的解决方案。

MAC地址是很棒的,如果你能获得它们,因为它们是"保证"普遍唯一的(尽管虚拟化可能会破坏这一点);主机名"应该"是唯一的,但这一点就没有那么保证了(例如:有人建立了一系列克隆机器,并意外地将它们的主机名设置为全部匹配)。我假设(因为你被标记为asp.net),你运行在某种类型的Windows域,有保证唯一的主机名,然而。

最新更新