System.Diagnostics.TraceSource 未将数据发送到 Application Insights

Posted

技术标签:

【中文标题】System.Diagnostics.TraceSource 未将数据发送到 Application Insights【英文标题】:System.Diagnostics.TraceSource not sending data to Application Insights 【发布时间】:2021-11-02 03:45:07 【问题描述】:

我在我的项目中设置了应用程序洞察,它运行良好,它将数据发送到 Azure 没有任何问题,现在我正在尝试使用 System.Diagnostics.SourceTrace 将一些跟踪日志发送到发送到 azure 的遥测数据中在 Webhost 应用程序中引用的内部 nuget 包中(这个 nuget 包不包含对应用程序洞察力的引用),事情是......由于某种原因,它只是没有到达该代码,嗯,它确实做到了不是同时,当我在输出窗口中调试时,我可以看到当它遇到 Sytem.Diagnostics.TraceEvent() 方法时创建了一个事件,但它显示如下

Application Insights Telemetry (unconfigured): "name":"Microsoft.ApplicationInsights.Message","time":"2021-09-01T22:43:18.7652108Z","tags":"ai.cloud.roleInstance":

这让我认为,由于某种原因,遥测客户端正在丢失对检测密钥或类似内容的引用,我不知道如何解决这个问题,因为它只发生在那里。

编辑: 以下是我们设置跟踪源的方式,此代码位于 webhost 应用程序的 web.config 文件中,该文件引用另一个项目,该项目正在引用发生日志记录的 nuget 包。

        <source name="MySource" switchValue="Error, Information, Warning">
          <listeners>
            <add name="AppInsights"  type="Microsoft.ApplicationInsights.TraceListener.ApplicationInsightsTraceListener, Microsoft.ApplicationInsights.TraceListener" />
          </listeners>
        </source>

我调试了发生日志记录的类,当我评估遥测配置对象时,它缺少检测密钥(这很奇怪,因为大多数遥测工作正常)

这是我们设置 telemetryClient 的代码:

public void Initialize()
        
            if (_initialized) return;
            lock (_initializationLock)
            
                if (_initialized) return;
                var iKey = ApplicationInsightsConfiguration.InstrumentationKey;

                //Call this even if ikey is null or empty
                MonitoringSettings = new Settings(iKey);

                //If we don't have a key we can't do anything
                if (string.IsNullOrEmpty(iKey))
                
                    Logger.Info($"No Application Insights telemetry key is available (Production flag: SystemSettings.IsProductionServer)");
                    TelemetryConfiguration.Active.DisableTelemetry = true;
                    return;
                

                //Set telemetry key
                TelemetryConfiguration.Active.InstrumentationKey = iKey;

                //Set up custom telemetry initializers
                //We need to initialize it before we send the non-prod custom event, so that the event will contain all required info
                SetUpTelemetryInitializers();

                //Disable telemetry reporting if it is not production instance
                //If overridden in web.ApplicationInsightsConfiguration explicitly, allow telemetry reporting
                if (ApplicationInsightsConfiguration.ForceSendTelemetry)
                
                    Client.TrackEvent("ForceSendTelemetry enabled.");
                

                //Set up custom telemetry filtration
                SetUpTelemetryProcessors();

                //send the license information if it has not already been sent for this Middleware instance startup
                SendLicenseConfiguration();

                //Track the event
                Client.TrackEvent("Telemetry Opt In", MonitoringSettings.GetAsDictionary());

                _initialized = true;
            
        

值得一提的是,如果我将遥测密钥添加到应用程序配置中,则跟踪侦听器可以工作...由于某种原因,当我们以编程方式添加它时,它会丢失对具有正确检测的原始遥测配置对象的引用键,我认为这正在发生,因为我正在使用 appinsights 的侦听器创建一个新的 TraceSource 对象,其中包括一个新的配置实例。

【问题讨论】:

您能否发布代码,说明您如何为SourceTrace 集合配置和使用TelemetryClient 您可能想先查看 TraceSource 和官方 TraceEvent 文档:TraceSource Class。 @PeterBons,我刚刚更新了我的问题,我添加了一些代码来解释我们如何设置东西。谢谢! 【参考方案1】:

谢谢Jiayao。发布您的建议作为帮助其他社区成员的答案。

使应用程序能够跟踪代码执行并将跟踪消息与其源相关联的属性。

public class TraceSource

以下代码可帮助您理解Tracesource 类并演示开关和过滤器的用法。

// The following configuration file can be used with this sample.
// When using a configuration file #define ConfigFile.
//            <source name="TraceTest" switchName="SourceSwitch" switchType="System.Diagnostics.SourceSwitch" >
//                    <add name="console" type="System.Diagnostics.ConsoleTraceListener" initializeData="false" />
//                    <remove name ="Default" />
//            <!-- You can set the level at which tracing is to occur -->
//            <add name="SourceSwitch" value="Warning" />
//            <!-- You can turn tracing off -->
//            <!--add name="SourceSwitch" value="Off" -->
//        <trace autoflush="true" indentsize="4"></trace>
#define TRACE
//#define ConfigFile

using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.IO;
using System.Security.Permissions;

namespace Testing

    class TraceTest
    
        // Initialize the trace source.
        static TraceSource ts = new TraceSource("TraceTest");
        [SwitchAttribute("SourceSwitch", typeof(SourceSwitch))]
        static void Main()
        
            try
            
                // Initialize trace switches.
#if(!ConfigFile)
                SourceSwitch sourceSwitch = new SourceSwitch("SourceSwitch", "Verbose");
                ts.Switch = sourceSwitch;
                int idxConsole = ts.Listeners.Add(new System.Diagnostics.ConsoleTraceListener());
                ts.Listeners[idxConsole].Name = "console";
#endif
                DisplayProperties(ts);
                ts.Listeners["console"].TraceOutputOptions |= TraceOptions.Callstack;
                ts.TraceEvent(TraceEventType.Warning, 1);
                ts.Listeners["console"].TraceOutputOptions = TraceOptions.DateTime;
                // Issue file not found message as a warning.
                ts.TraceEvent(TraceEventType.Warning, 2, "File Test not found");
                // Issue file not found message as a verbose event using a formatted string.
                ts.TraceEvent(TraceEventType.Verbose, 3, "File 0 not found.", "test");
                // Issue file not found message as information.
                ts.TraceInformation("File 0 not found.", "test");
                ts.Listeners["console"].TraceOutputOptions |= TraceOptions.LogicalOperationStack;
                // Issue file not found message as an error event.
                ts.TraceEvent(TraceEventType.Error, 4, "File 0 not found.", "test");
                // Test the filter on the ConsoleTraceListener.
                ts.Listeners["console"].Filter = new SourceFilter("No match");
                ts.TraceData(TraceEventType.Error, 5,
                    "SourceFilter should reject this message for the console trace listener.");
                ts.Listeners["console"].Filter = new SourceFilter("TraceTest");
                ts.TraceData(TraceEventType.Error, 6,
                    "SourceFilter should let this message through on the console trace listener.");
                ts.Listeners["console"].Filter = null;
                // Use the TraceData method.
                ts.TraceData(TraceEventType.Warning, 7, new object());
                ts.TraceData(TraceEventType.Warning, 8, new object[]  "Message 1", "Message 2" );
                // Activity tests.
                ts.TraceEvent(TraceEventType.Start, 9, "Will not appear until the switch is changed.");
                ts.Switch.Level = SourceLevels.ActivityTracing | SourceLevels.Critical;
                ts.TraceEvent(TraceEventType.Suspend, 10, "Switch includes ActivityTracing, this should appear");
                ts.TraceEvent(TraceEventType.Critical, 11, "Switch includes Critical, this should appear");
                ts.Flush();
                ts.Close();
                Console.WriteLine("Press any key to exit.");
                Console.Read();
            
            catch (Exception e)
            
                // Catch any unexpected exception.
                Console.WriteLine("Unexpected exception: " + e.ToString());
                Console.Read();
            
        
        public static void DisplayProperties(TraceSource ts)
        
            Console.WriteLine("TraceSource name = " + ts.Name);
            Console.WriteLine("TraceSource switch level = " + ts.Switch.Level);
            Console.WriteLine("TraceSource switch = " + ts.Switch.DisplayName);
            SwitchAttribute[] switches = SwitchAttribute.GetAll(typeof(TraceTest).Assembly);
            for (int i = 0; i < switches.Length; i++)
            
                Console.WriteLine("Switch name = " + switches[i].SwitchName);
                Console.WriteLine("Switch type = " + switches[i].SwitchType);
            
#if(ConfigFile)
            // Get the custom attributes for the TraceSource.
            Console.WriteLine("Number of custom trace source attributes = "
                + ts.Attributes.Count);
            foreach (DictionaryEntry de in ts.Attributes)
                Console.WriteLine("Custom trace source attribute = "
                    + de.Key + "  " + de.Value);
            // Get the custom attributes for the trace source switch.
            foreach (DictionaryEntry de in ts.Switch.Attributes)
                Console.WriteLine("Custom switch attribute = "
                    + de.Key + "  " + de.Value);
#endif
            Console.WriteLine("Number of listeners = " + ts.Listeners.Count);
            foreach (TraceListener traceListener in ts.Listeners)
            
                Console.Write("TraceListener: " + traceListener.Name + "\t");
                // The following output can be used to update the configuration file.
                Console.WriteLine("AssemblyQualifiedName = " +
                    (traceListener.GetType().AssemblyQualifiedName));
            
        
    

如需更多信息,请验证TraceSource Class。

【讨论】:

感谢您的详细解答。希望这可以帮助他们。

以上是关于System.Diagnostics.TraceSource 未将数据发送到 Application Insights的主要内容,如果未能解决你的问题,请参考以下文章