Мониторинг производительности для автономного настольного приложения.NET с New Relic

Я хотел бы знать, есть ли способ контролировать производительность автономного настольного приложения.NET? (Например, foobar.exe)

Это клиентское приложение, которое в конечном итоге может взаимодействовать с веб-службой или базой данных, поэтому в случае подключения к базе данных, в идеале, я бы хотел;

  1. контролировать производительность приложения (например, затраченное время или количество вызванных методов и т. д.)
  2. отслеживать запросы / процедуры SQL, которые выполняются

Любая помощь с благодарностью.

Спасибо,

1 ответ

Решение

Я работаю на New Relic.

Можно отслеживать производительность приложений, не относящихся к IIS, при условии, что они удовлетворяют следующим требованиям:

  • Функция Instrument All .NET Applications должна быть включена

  • App.config и / или newrelic.config должны быть настроены для.exe

Вы можете прочитать больше об этих требованиях на нашем сайте документации здесь: https://docs.newrelic.com/docs/dotnet/instrumenting-custom-applications

Вам может потребоваться собрать пользовательские метрики с помощью нашего.NET агента API. Методы RecordMetric, RecordResponseTimeMetric и IncrementCounter специально работают с не веб-приложениями. Наша документация по API агента.NET находится здесь: https://docs.newrelic.com/docs/dotnet/net-agent-api

Вы также можете настроить пользовательские транзакции для отслеживания не веб-транзакций. Обычно мы можем отследить функции, которые используют HttpObjects, но следующее - это новая функция, реализованная в версии агента 2.24.218.0. В случаях не веб-приложений и асинхронных вызовов, где нет контекста транзакции, следующая функция может использоваться для создания транзакций, когда агент обычно не делает этого. Это ручной процесс с помощью пользовательского файла инструментария.

Создайте пользовательский файл инструментария с именем, скажем, CustomInstrumentation.xml, в C:\ProgramData\New Relic.NET Agent\Extensions вместе с CoreInstrumentation.xml. Добавьте следующее содержимое в файл пользовательских инструментов:

<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
  <instrumentation>
    <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Category/Name">
      <match assemblyName="AssemblyName" className="NameSpace.ClassName">
        <exactMethodMatcher methodName="MethodName" />
      </match>
    </tracerFactory>
  </instrumentation>
</extension>

Вы должны изменить значения атрибута Category/Name, AssemblyName, NameSpace.ClassName и MethodName выше:

Транзакция начинается, когда объект типа NameSpace.ClassName из AssemblyName сборки вызывает метод MethodName. Транзакция заканчивается, когда метод возвращает или выдает исключение. Транзакция будет иметь имя Name и будет сгруппирована по типу транзакции, указанному в Category. В интерфейсе New Relic вы можете выбрать тип транзакции в раскрывающемся меню Тип при просмотре страницы Мониторинг> Транзакции.

Обратите внимание, что и Категория, и Имя должны присутствовать и должны быть разделены косой чертой.

Как и следовало ожидать, инструментальная активность (методы, база данных, внешние компоненты), возникающая во время вызова метода, будет показана в таблице разбивки транзакций и в трассировках транзакций.

Вот более конкретный пример. Сначала файл инструментария:

<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
  <instrumentation>
    <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Background/Bars">
      <match assemblyName="Foo" className="Foo.Bar">
        <exactMethodMatcher methodName="Bar1" />
        <exactMethodMatcher methodName="Bar2" />
      </match>
    </tracerFactory>
    <tracerFactory metricName="Custom/some custom metric name">
      <match assemblyName="Foo" className="Foo.Bar">
        <exactMethodMatcher methodName="Bar3" />
      </match>
    </tracerFactory>
  </instrumentation>
</extension>

Теперь немного кода:

var foo = new Foo();
foo.Bar1(); // Creates a transaction named Bars in category Background
foo.Bar2(); // Same here.
foo.Bar3(); // Won't create a new transaction.  See notes below.

public class Foo
{
    // this will result in a transaction with an External Service request segment in the transaction trace
    public void Bar1()
    {
        new WebClient().DownloadString("http://www.google.com/);
    }

    // this will result in a transaction that has one segment with a category of "Custom" and a name of "some custom metric name"
    public void Bar2()
    {
        // the segment for Bar3 will contain your SQL query inside of it and possibly an execution plan
        Bar3();
    }

    // if Bar3 is called directly, it won't get a transaction made for it.
    // However, if it is called inside of Bar1 or Bar2 then it will show up as a segment containing the SQL query
    private void Bar3()
    {
        using (var connection = new SqlConnection(ConnectionStrings["MsSqlConnection"].ConnectionString))
        {
            connection.Open();
            using (var command = new SqlCommand("SELECT * FROM table", connection))
            using (var reader = command.ExecuteReader())
            {
                reader.Read();
            }
        }
    }
}

Вот простое консольное приложение, которое демонстрирует пользовательские транзакции:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Custom Transactions");
            var t = new CustomTransaction();
            for (int i = 0; i < 100; ++i )
                t.StartTransaction();
        }
    }
    class CustomTransaction
    {
        public void StartTransaction()
        {
            Console.WriteLine("StartTransaction");     
            Dummy();
        }
        void Dummy()
        {
            System.Threading.Thread.Sleep(5000);
        }
    }

}

Используйте следующий файл пользовательских инструментов:

<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
    <instrumentation>
        <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Background/CustomTransaction">
          <match assemblyName="ConsoleApplication1" className="ConsoleApplication1.CustomTransaction">
            <exactMethodMatcher methodName="StartTransaction" />
          </match>
        </tracerFactory>
        <tracerFactory metricName="Custom/Dummy">
          <match assemblyName="ConsoleApplication1" className="ConsoleApplication1.CustomTransaction">
            <exactMethodMatcher methodName="Dummy" />
          </match>
        </tracerFactory>
    </instrumentation>
</extension>
Другие вопросы по тегам