Мониторинг производительности для автономного настольного приложения.NET с New Relic
Я хотел бы знать, есть ли способ контролировать производительность автономного настольного приложения.NET? (Например, foobar.exe
)
Это клиентское приложение, которое в конечном итоге может взаимодействовать с веб-службой или базой данных, поэтому в случае подключения к базе данных, в идеале, я бы хотел;
- контролировать производительность приложения (например, затраченное время или количество вызванных методов и т. д.)
- отслеживать запросы / процедуры 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>