Elastic AMP监控.NET程序性能

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elastic AMP监控.NET程序性能相关的知识,希望对你有一定的参考价值。

什么是Elastic AMP

Elastic APM 是一个应用程序性能监控系统。它可以请求的响应时间、数据库查询、对缓存的调用、外部 HTTP 请求等的详细性能信息,可以实时监控软件服务和应用程序。这可以帮助我们快速查明和修复性能问题。

Elastic APM 还会自动收集未处理的错误和异常。因此我们可以在出现新错误时识别它们并密切关注特定错误发生的次数。

服务器指标是另一个重要的信息来源。Elastic APM 代理会自动获取基本的主机级别指标和特定于代理的指标。

Elastic APM 目前支持 Node.js, Python, Ruby, php, Java, Go, RUM (JS), 和.NET.

工作原理

  • Elastic AMP 通过Agent收集应用程序的指标信息

  • Agent将收集的信息上传至AMP Server

  • AMP Server对数据进行聚合后,存储至Elasticsearch

  • 通过Kibana查看指标信息

环境安装

我们通过Docker搭建一个单机的环境来演示Elastic APM的功能。

  1.安装ElasticSearch

docker network create elastic
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.2
docker run -d --name es01-test --net elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.15.2
2.安装Kibana
docker pull docker.elastic.co/kibana/kibana:7.15.2
docker run -d --name kib01-test --net elastic -p 5601:5601 -e "ELASTICSEARCH_HOSTS=http://es01-test:9200" docker.elastic.co/kibana/kibana:7.15.2

3.安装ElasticAPM

docker run -d  -p 8200:8200  --name=apm-server --net elastic  --user=apm-server  docker.elastic.co/apm/apm-server:7.15.2  --strict.perms=false -e  -E output.elasticsearch.hosts=["es01-test:9200"]

代码演示

Elastic AMP支持.NET Framwork4.6.1+和.NET Core2.1+,支持的组件有:

GRPC,HttpClient,EF6,EFCore,ElasticSearch,mysql,Mongo,Redis,Kafka,RabbitMQ等,具体详见https://www.elastic.co/guide/en/apm/agent/dotnet/master/supported-technologies.html。我们这次使用.NET Framwork新建一个Web项目来演示

1.新增Web项目

 2.新增Nuget包

<package id="Elastic.Apm" version="1.12.1" targetFramework="net472" />
  <package id="Elastic.Apm.AspNetFullFramework" version="1.12.1" targetFramework="net472" />
  <package id="Elastic.Apm.SqlClient" version="1.12.1" targetFramework="net472" />
  <package id="Elastic.Apm.StackExchange.Redis" version="1.12.1" targetFramework="net472" />
  <package id="StackExchange.Redis" version="2.2.88" targetFramework="net472" />

3.配置HttpModule

web.config中的system.webServer中新增以下节点

<modules>
    <add name="ElasticApmModule" type="Elastic.Apm.AspNetFullFramework.ElasticApmModule, Elastic.Apm.AspNetFullFramework" />
</modules>

4.配置Agent

我们可以通过环境变量配置Agent的信息

protected void Application_Start()

    Environment.SetEnvironmentVariable("ELASTIC_APM_SERVICE_NAME", "TestFromworkSite");  //服务名
    Environment.SetEnvironmentVariable("ELASTIC_APM_ENVIRONMENT", "Dev");    //环境
    Environment.SetEnvironmentVariable("ELASTIC_APM_SERVER_URL", "http://localhost:8200"); // APM server
    Environment.SetEnvironmentVariable("ELASTIC_APM_FLUSH_INTERVAL", "5s");  //上传数据的周期
    Environment.SetEnvironmentVariable("ELASTIC_APM_LOG_LEVEL", "Trace");
    //..........

5.启动网站

直接启动网站即可在Kibana中看到对应的Service:TestFromworkSite

Elastic APM核心模块

1.Transaction:我们通过Transaction可以看其中Api的调用信息

 2. Dependencies:通过Dependencies看到服务依赖关系

3. Error: 能通过Error看到程序中的错误信息

 4. Matrics: 可以通过Matrics看到服务气的内存与CPU信息

Elastic监控MSSql与Redis等组件

新增MSSqlHelper

public class MSSqlHelper

    public static DataSet SqlExecuteReader(string _sql, SqlParameter[] _parameters, CommandType _type = CommandType.Text, string _constring = @"Data Source=.\\SQLEXPRESS;Initial Catalog=dev;Integrated Security=True;")
    
        DataSet ds = new DataSet();
        try
        
            using (SqlConnection conn = new SqlConnection(_constring))
            
                SqlCommand cmd = new SqlCommand(_sql, conn);
                if (_parameters != null)
                
                    foreach (SqlParameter p in _parameters)
                     cmd.Parameters.Add(p); 
                
                cmd.CommandType = _type;
                cmd.CommandTimeout = 10;//超时时间,单位S
                conn.Open();
                using (SqlDataAdapter sda = new SqlDataAdapter())
                
                    sda.SelectCommand = cmd;
                    sda.Fill(ds);//填充dataset
                
            
            return ds;
        
        catch (Exception ex)
        
            throw;
        
    

新增RedisHelper

public class RedisHelper

    private static IDatabase database;


    public static void UseApmForRedis()
    
        var connection = ConnectionMultiplexer.Connect("127.0.0.1:6379");
        connection.UseElasticApm();
        database = connection.GetDatabase();
    


    public static void StringSet(string key,string value)
    
        database.StringSet(key,value);
    

在Application_Start()中开启SqlServer与Redis的监控

Agent.Subscribe(new SqlClientDiagnosticSubscriber());
RedisHelper.UseApmForRedis();

HomeController.Index接口中新增sqlserver与Redis的调用

public ActionResult Index()

    MSSqlHelper.SqlExecuteReader("select * from S_dev.UserObject", null);


    RedisHelper.StringSet("a", "a");

启动程序即可看到MSSql与Redis的相关数据

Elastic APM Api的深入使用

1.StartTransaction与StartSpan开启自定义transaction与span

一些定时任务同样可以使用Elastic APM的Agent.Tracer.StartTransaction和来监控,并且我们可以通过StartSpan来新增一个自定义节点,这种方式需要我们自己处理异常信息。我们新增一个Job

public class TestJob

    public void Run()
    
        while (true)
        
            var trans = Agent.Tracer.StartTransaction("TestJob", ApiConstants.TypeRequest);
            try
            
                MSSqlHelper.SqlExecuteReader("select * from S_dev.UserObject", null);


                RedisHelper.StringSet("a", "a");


                trans.SetLabel("name", "chester");


                var span = trans.StartSpan("自定义Span", ApiConstants.TypeExternal, ApiConstants.SubtypeHttp, ApiConstants.ActionQuery);
                try
                
                    //Http request
                
                catch (Exception e)
                
                    span.CaptureException(e);
                
                finally
                
                    span.End();
                
                Thread.Sleep(1000);
            
            catch (Exception ex)
            
                trans.CaptureException(ex);
                throw;
            
            finally
            
                trans.End();
            
        
    

Application_start中启动Testjob

Task.Run(() => new TestJob().Run());

启动程序即可看到对应的TestJob监控

 2.CaptureTransaction与CaptureSpan开启自定义transaction与span

CaptureTransaction与CaptureSpan相对于StartTransaction与StartSpan可以帮助我们结束Transaction与Span,也可以自动捕获异常,新增一个TestJob2

public class TestJob2

    public void Run()
    
        while (true)
        
            Agent.Tracer.CaptureTransaction("TestJob2", ApiConstants.TypeRequest, (trans) =>
            
                MSSqlHelper.SqlExecuteReader("select * from S_dev.UserObject", null);


                RedisHelper.StringSet("a", "a");


                trans.SetLabel("name", "chester");


                trans.CaptureSpan("自定义Span2", ApiConstants.TypeDb, (s) =>
                
                    //execute db query
                , ApiConstants.SubtypeMssql, ApiConstants.ActionQuery);


                Thread.Sleep(1000);
            );
        
    

Application_start中启动Testjob2

Task.Run(() => new TestJob2().Run());

启动程序即可看到对应的TestJob2监控

 3.Agent全局拦截

我们可以通过过滤器拦截Transaction与Span,并为其添加例如label等附加内容

Agent.AddFilter((ITransaction t) =>

    //t.SetLabel("foo", "bar");
    return t;
);
Agent.AddFilter((ISpan span) =>

    // ..
    return span;
);

以上是关于Elastic AMP监控.NET程序性能的主要内容,如果未能解决你的问题,请参考以下文章

Elastic:应用程序性能监控/管理(APM)实践

Observability:使用 Elastic APM 监控 Elastic Enterprise Search 性能

Observability:使用 Elastic APM 监控 Elastic Enterprise Search 性能

多语言应用性能监控系统:Elastic APM

Elasticsearch:使用 Elastic APM 监控 Android 应用程序

数据库监控&性能优化