Unity开发HoloLens 2应用:自定义ETW日志无法正常输出至设备门户
我正在使用Unity开发一款HoloLens 2应用,该应用包含UDP连接等功能,大部分测试场景下必须部署到HoloLens设备才能进行——Holographic Remoting和Unity Play Mode无法满足测试需求。
为了实现便捷的实时调试日志,我尝试实现自定义ETW(Event Tracing for Windows)提供者,以便让日志条目显示在Windows Device Portal(UWP设备的Web管理界面)中。但找到的都是2016年的教程,且无法正常实现功能。
我在Unity项目中添加了如下类/脚本:
using System.Diagnostics.Tracing; namespace Assets.Scripts { [EventSource(Name = "HololensSource", Guid = "69aa67d2-5948-46c5-9b93-0f7fdb0f21cb")] internal sealed class HololensSource : EventSource { public void Message(string message) { Write(message); } public static readonly HololensSource Log = new HololensSource(); } }
并在应用中确定会被调用的多个位置进行调用:
HololensSource.Log.Message("My log message.");
应用可正常构建并运行,无报错。但在Device Portal的“Custom Providers”下添加指定Guid并启用后,启动应用仅能获取少量(2-6条)无有效信息的事件日志,且日志无法按时触发,之后完全停止输出。尝试显式指定ActivityId也无任何变化。
请问当前使用自定义ETW提供者是否有重大变更?如今应如何正确实现?同时也欢迎提供可行的替代方案!
一、正确实现自定义ETW提供者
ETW在UWP和Unity结合的场景下确实有规范更新,旧教程的写法缺少关键元数据和调用规范,以下是正确实现步骤:
规范EventSource的日志方法
必须使用[Event]属性标记日志方法,指定唯一事件ID,并调用WriteEvent而非基类的Write方法,确保参数正确序列化:using System.Diagnostics.Tracing; namespace Assets.Scripts { [EventSource(Name = "HololensSource", Guid = "69aa67d2-5948-46c5-9b93-0f7fdb0f21cb")] internal sealed class HololensSource : EventSource { // 每个事件需分配唯一ID(从1开始),Level定义日志级别,Message指定格式占位符 [Event(1, Level = EventLevel.Informational, Message = "{0}")] public void Message(string message) { WriteEvent(1, message); } public static readonly HololensSource Log = new HololensSource(); } }配置Unity UWP构建选项
- 在
Player Settings->UWP->Publishing Settings中,启用Compile .NET code to C++(IL2CPP),ETW在IL2CPP编译模式下兼容性更稳定。 - 若使用.NET Native编译,需添加
link.xml文件确保EventSource类不被裁剪:<linker> <assembly fullname="Assembly-CSharp"> <type fullname="Assets.Scripts.HololensSource" preserve="all" /> </assembly> </linker>
- 在
Device Portal的正确操作流程
- 打开HoloLens 2的Device Portal,进入
System->Event Tracing。 - 在
Custom Providers中添加目标Guid,设置日志级别为Informational或更高。 - 先点击Start Tracing,再启动应用,确保跟踪会话在应用初始化前已启动。
- 打开HoloLens 2的Device Portal,进入
二、替代方案
如果ETW仍存在兼容性问题,以下是更可靠的实时日志方案:
UDP实时日志转发
利用UDP将日志直接发送到PC端的接收工具,适合UDP功能测试场景:using System.Net; using System.Net.Sockets; using System.Text; public class UdpLogger { private UdpClient _udpClient; private IPEndPoint _remoteEndpoint; public UdpLogger(string pcIp, int port) { _udpClient = new UdpClient(); _remoteEndpoint = new IPEndPoint(IPAddress.Parse(pcIp), port); } public void Log(string message) { byte[] data = Encoding.UTF8.GetBytes($"{System.DateTime.Now:HH:mm:ss}: {message}"); _udpClient.Send(data, data.Length, _remoteEndpoint); } }PC端可使用Python或C#编写简易UDP接收程序,实时打印日志内容。
Unity Debug.Log + Device Portal应用日志
- 在Unity中启用
Development Build并勾选Script Debugging,使用Debug.Log输出日志。 - 在Device Portal的
Apps->Installed Apps中找到目标应用,点击View Logs即可查看实时输出。
- 在Unity中启用
Visual Studio远程调试日志
将HoloLens 2与Visual Studio连接,打开Debug->Windows->Output窗口,设置输出源为目标应用,即可实时查看Debug.Log的输出,同时支持断点调试结合日志分析。
内容的提问来源于stack exchange,提问作者Finrod_Amandil

