EventSource/Enterprise 库日志记录缓存已删除的方法,(可能在 instrumentationManifest 中!)
EventSource/Enterprise Library Logging caches deleted methods, (possibly in a instrumentationManifest!)
短版
如果我改变这个...
EventSource(Name="BasicLogger")
public class BasicLogger : EventSource { ... }
到这个...
EventSource(Name="HardymanDatabaseLog")
public class BasicLogger : EventSource { ... }
...我仍然收到日志消息,但它们已损坏。
要么消息没有到达,要么它们被我当前项目中甚至不存在的 missing/deleted/removed 方法格式化!
由于某些未知原因,特定字符串有问题 'HardymanDatabaseLog'
我认为这可能归因于在某处出现的损坏的检测清单。
继续阅读以了解更多...! (谢谢 :o))
长版(带图片)
我有一个简单的控制台应用程序,它通过 nuget 包引用 EnterpriseLibrary.SemanticLogging
。
使用 here 中的示例代码,我添加了 BasicLogger
class.
当我 运行 我的简单应用程序时...
using System.ComponentModel;
using System.Diagnostics.Tracing;
namespace Etw
{
class Program
{
static void Main(string[] args)
{
BasicLogger.Log.Error("Hello1");
BasicLogger.Log.Critical("Hello2");
}
}
[EventSource(Name = "BasicLogger")]
public class BasicLogger : EventSource
{
public static readonly BasicLogger Log = new BasicLogger();
[Event(1, Message = "{0}", Level = EventLevel.Critical)]
public void Critical(string message)
{ if (IsEnabled()) WriteEvent(1, message); }
[Event(2, Message = "{0}", Level = EventLevel.Error)]
public void Error(string message)
{ if (IsEnabled()) WriteEvent(2, message); }
[Event(3, Message = "{0}", Level = EventLevel.Warning)]
public void Warning(string message)
{ if (IsEnabled()) WriteEvent(3, message); }
[Event(4, Message = "{0}", Level = EventLevel.Informational)]
public void Informational(string message)
{ if (IsEnabled()) WriteEvent(4, message); }
}
}
...我在日志查看器控制台中收到以下响应 (SemanticLogging-svc.exe
)
...正确!
BUT,如果我现在将 EventSource
属性更新为 [EventSource(Name = "HardymanDatabaseLog")]
,并将我的 SemanticLogging-svc.xml
调整为也引用 HardymanDatabaseLog
...
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns="http://schemas.microsoft.com/practices/2013/entlib/semanticlogging/etw" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/practices/2013/entlib/semanticlogging/etw SemanticLogging-svc.xsd">
<sinks>
<consoleSink name="ConsoleEventSink">
<sources>
<eventSource name="HardymanDatabaseLog" level="LogAlways" />
</sources>
<eventTextFormatter header="+=========================================+"/>
</consoleSink>
</sinks>
</configuration>
...然后我在日志查看器控制台中收到以下响应...
...不仅丢失了第一条消息,还破坏了第二条消息!
如果您仔细查看开始于 EventId : 1
的那一行,您会看到它说 Message : Application Started
... 该消息是如何、为什么以及从哪里来的?! ...甚至 Level : Informational
位也是错误的...我的代码有 Level = Critical
!
在这个问题开始之前,我在 BasicLogger
class 中创建了一个(已删除很久的)方法,它具有属性 [Event(1, Message = "Application Started.", Level = EventLevel.Informational)]
,现在,每当我设置 EventSource(Name="HardymanDatabaseLog")
, 正在调用这个幻象方法。
要明确... 文本 'Application Started' 不再存在于我的应用程序中的任何地方(我正在使用一个全新的项目)...此错误的唯一原因是重用 'HardymanDatabaseLog' EventSource 名称。
以下是我到目前为止所做的尝试清除任何导致事情出错的损坏信息:
- 重新启动我的电脑(标准!)
- 删除并重新添加对 Enterprise Library 的所有引用(问题在不同的解决方案之间仍然存在,因此它不能是 application/solution 级别设置)
- 停止并删除 perfmon > 数据收集器集 > 事件跟踪会话 > Microsoft-SemanticLogging-Etw-ConsoleEventSink
- 查看
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog
以查看我的应用程序是否已注册(当然在注册表中的任何地方都找不到“HardymanDatabaseLog”)
- 睡吧
- System.Diagnostics.EventLog.DeleteEventSource("HardymanDatabaseLog")
- Clean/Rebuild/Clean/Build/Clean/etc/etc解决方案
- 运行 我的应用程序没有 visual studio 主机应用程序
这是我尝试过但没有成功的...
- 确定企业库是否保留配置数据
- 确定 .NET EventSource 是否保留配置数据
- 重新安装企业库(只有
install-packages.ps1
包含在 download 中)
- 用头敲键盘
所有 help/suggestions 感激不尽。
更新
使用 JustDecompile,我在 EventSource
代码中找到了一个使用名为 ManifestBuilder
的对象的方法。该方法似乎构建了一个 <instrumentationManifest />
文档,其中肯定包含似乎潜伏在幻影方法中的所有信息。
也许有人可以阐明这些神奇文档在 .NET 和 Enterprise Library 上下文中的存储位置?
更新 2
正如@Randy Levy 通过调查 SLAB 源发现的那样,可以通过删除 C:\Users\<UserName>\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF
中的文件来解决问题。他的回答也和这个问题有关... SLAB, out-of-process: changing the signature of an event source method causes incorrect event logging.
谢谢@Randy Levy!
这听起来确实像是某种清单缓存 and/or 损坏问题。
对于控制台应用程序,SLAB ETW 服务将清单缓存在 C:\Users\\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF。如果存在清单缓存问题,则删除该目录中的清单 .xml 文件(在本例中为 BasicLogger.manifest.xml 和 HardymanDatabaseLog.manifest.xml)应该(希望)解决问题。
步骤是停止服务,删除 .xml 文件,然后重新启动服务。
确保您检查的是运行您的服务的用户配置文件。
因此,如果您的 Enterprise Library 语义日志记录服务在 LocalService 或 NetworkService 上运行,路径将不会是 c:\users...
这种情况下的路径将是
C:\Windows\ServiceProfiles\LocalService\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF
或
C:\Windows\ServiceProfiles\NetworkService\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF
短版
如果我改变这个...
EventSource(Name="BasicLogger")
public class BasicLogger : EventSource { ... }
到这个...
EventSource(Name="HardymanDatabaseLog")
public class BasicLogger : EventSource { ... }
...我仍然收到日志消息,但它们已损坏。
要么消息没有到达,要么它们被我当前项目中甚至不存在的 missing/deleted/removed 方法格式化!
由于某些未知原因,特定字符串有问题 'HardymanDatabaseLog'
我认为这可能归因于在某处出现的损坏的检测清单。
继续阅读以了解更多...! (谢谢 :o))
长版(带图片)
我有一个简单的控制台应用程序,它通过 nuget 包引用 EnterpriseLibrary.SemanticLogging
。
使用 here 中的示例代码,我添加了 BasicLogger
class.
当我 运行 我的简单应用程序时...
using System.ComponentModel;
using System.Diagnostics.Tracing;
namespace Etw
{
class Program
{
static void Main(string[] args)
{
BasicLogger.Log.Error("Hello1");
BasicLogger.Log.Critical("Hello2");
}
}
[EventSource(Name = "BasicLogger")]
public class BasicLogger : EventSource
{
public static readonly BasicLogger Log = new BasicLogger();
[Event(1, Message = "{0}", Level = EventLevel.Critical)]
public void Critical(string message)
{ if (IsEnabled()) WriteEvent(1, message); }
[Event(2, Message = "{0}", Level = EventLevel.Error)]
public void Error(string message)
{ if (IsEnabled()) WriteEvent(2, message); }
[Event(3, Message = "{0}", Level = EventLevel.Warning)]
public void Warning(string message)
{ if (IsEnabled()) WriteEvent(3, message); }
[Event(4, Message = "{0}", Level = EventLevel.Informational)]
public void Informational(string message)
{ if (IsEnabled()) WriteEvent(4, message); }
}
}
...我在日志查看器控制台中收到以下响应 (SemanticLogging-svc.exe
)
...正确!
BUT,如果我现在将 EventSource
属性更新为 [EventSource(Name = "HardymanDatabaseLog")]
,并将我的 SemanticLogging-svc.xml
调整为也引用 HardymanDatabaseLog
...
<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns="http://schemas.microsoft.com/practices/2013/entlib/semanticlogging/etw" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.microsoft.com/practices/2013/entlib/semanticlogging/etw SemanticLogging-svc.xsd">
<sinks>
<consoleSink name="ConsoleEventSink">
<sources>
<eventSource name="HardymanDatabaseLog" level="LogAlways" />
</sources>
<eventTextFormatter header="+=========================================+"/>
</consoleSink>
</sinks>
</configuration>
...然后我在日志查看器控制台中收到以下响应...
...不仅丢失了第一条消息,还破坏了第二条消息!
如果您仔细查看开始于 EventId : 1
的那一行,您会看到它说 Message : Application Started
... 该消息是如何、为什么以及从哪里来的?! ...甚至 Level : Informational
位也是错误的...我的代码有 Level = Critical
!
在这个问题开始之前,我在 BasicLogger
class 中创建了一个(已删除很久的)方法,它具有属性 [Event(1, Message = "Application Started.", Level = EventLevel.Informational)]
,现在,每当我设置 EventSource(Name="HardymanDatabaseLog")
, 正在调用这个幻象方法。
要明确... 文本 'Application Started' 不再存在于我的应用程序中的任何地方(我正在使用一个全新的项目)...此错误的唯一原因是重用 'HardymanDatabaseLog' EventSource 名称。
以下是我到目前为止所做的尝试清除任何导致事情出错的损坏信息:
- 重新启动我的电脑(标准!)
- 删除并重新添加对 Enterprise Library 的所有引用(问题在不同的解决方案之间仍然存在,因此它不能是 application/solution 级别设置)
- 停止并删除 perfmon > 数据收集器集 > 事件跟踪会话 > Microsoft-SemanticLogging-Etw-ConsoleEventSink
- 查看
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog
以查看我的应用程序是否已注册(当然在注册表中的任何地方都找不到“HardymanDatabaseLog”) - 睡吧
- System.Diagnostics.EventLog.DeleteEventSource("HardymanDatabaseLog")
- Clean/Rebuild/Clean/Build/Clean/etc/etc解决方案
- 运行 我的应用程序没有 visual studio 主机应用程序
这是我尝试过但没有成功的...
- 确定企业库是否保留配置数据
- 确定 .NET EventSource 是否保留配置数据
- 重新安装企业库(只有
install-packages.ps1
包含在 download 中) - 用头敲键盘
所有 help/suggestions 感激不尽。
更新
使用 JustDecompile,我在 EventSource
代码中找到了一个使用名为 ManifestBuilder
的对象的方法。该方法似乎构建了一个 <instrumentationManifest />
文档,其中肯定包含似乎潜伏在幻影方法中的所有信息。
也许有人可以阐明这些神奇文档在 .NET 和 Enterprise Library 上下文中的存储位置?
更新 2
正如@Randy Levy 通过调查 SLAB 源发现的那样,可以通过删除 C:\Users\<UserName>\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF
中的文件来解决问题。他的回答也和这个问题有关... SLAB, out-of-process: changing the signature of an event source method causes incorrect event logging.
谢谢@Randy Levy!
这听起来确实像是某种清单缓存 and/or 损坏问题。
对于控制台应用程序,SLAB ETW 服务将清单缓存在 C:\Users\\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF。如果存在清单缓存问题,则删除该目录中的清单 .xml 文件(在本例中为 BasicLogger.manifest.xml 和 HardymanDatabaseLog.manifest.xml)应该(希望)解决问题。
步骤是停止服务,删除 .xml 文件,然后重新启动服务。
确保您检查的是运行您的服务的用户配置文件。 因此,如果您的 Enterprise Library 语义日志记录服务在 LocalService 或 NetworkService 上运行,路径将不会是 c:\users...
这种情况下的路径将是
C:\Windows\ServiceProfiles\LocalService\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF
或
C:\Windows\ServiceProfiles\NetworkService\AppData\Local\TempD2611AE-6432-4639-8B91-3E46EB56CADF