欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用 MiniProfiler 来分析 ASP.NET Core 应用

程序员文章站 2022-03-25 23:01:22
使用 MiniProfiler 来分析 ASP.NET Core 应用 MiniProfiler( "https://miniprofiler.com/" )是一个轻量级且简单易用的分析工具库,它可以用来分析ASP.NET Core应用。 优点 针对ASP.NET Core MVC应用,使用Mini ......

使用 miniprofiler 来分析 asp.net core 应用

miniprofiler()是一个轻量级且简单易用的分析工具库,它可以用来分析asp.net core应用。

优点

针对asp.net core mvc应用,使用miniprofiler的优点是:它会把结果直接放在页面的左下角,随时可以点击查看;这样的话就可以感知出你的程序运行的怎么样;同时这也意味着,在你开发新功能的同时,可以很快速的得到反馈。

一、安装配置miniprofiler

在现有的asp.net core mvc项目里,通过nuget安装miniprofiler :

install-package miniprofiler.aspnetcore.mvc

当然也可以通过nuget package manager可视化工具安装

使用 MiniProfiler 来分析 ASP.NET Core 应用

接下来配置miniprofiler,总共分三步:

第一步,来到startup.csconfigureservices方法里,添加services.addminiprofiler();

    // this method gets called by the runtime. use this method to add services to the container.
    public void configureservices(iservicecollection services)
    {
        services.configure<cookiepolicyoptions>(options =>
        {
            // this lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.checkconsentneeded = context => true;
            options.minimumsamesitepolicy = samesitemode.none;
        });


        services.addmvc().setcompatibilityversion(compatibilityversion.version_2_2);

        // 当然这个方法还可以添加一个lambda表达式作为参数,从而做一些自定义的配置:
        services.addminiprofiler(options =>
        {
            // 设定弹出窗口的位置是左下角
            options.popuprenderposition = renderposition.bottomleft;
            // 设定在弹出的明细窗口里会显式time with children这列
            options.popupshowtimewithchildren = true;
        });
    }

第二步,来到来到startup.csconfigure方法里,添加app.useminiprofiler();

    // this method gets called by the runtime. use this method to configure the http request pipeline.
    public void configure(iapplicationbuilder app, ihostingenvironment env)
    {
        ...

        // 最重要的一点是就是配置中间件在管道中的位置,一定要把它放在usemvc()方法之前。 
        app.useminiprofiler();

        app.usemvc(routes =>
        {
            routes.maproute(
                name: "default",
                template: "{controller=home}/{action=index}/{id?}");
        });
    }

第三步,将miniprofilertag helper放到页面上

  • _viewimports 页面引入 miniprofiler 的 tag helper :
    ...

    @using stackexchange.profiling

    ...
    @addtaghelper *, miniprofiler.aspnetcore.mvc
  • 将 miniprofiler 的tag helper 放入 _layout.cshtml 中:
    ...

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2019 - miniprofilercoredemo - <a asp-area="" asp-controller="home" asp-action="privacy">privacy</a>
        </div>
    </footer>

    @* 其实放在页面的任意地方都应该可以,但是由于它会加载一些脚本文件,所以建议放在footer下面: *@@* 其实放在页面的任意地方都应该可以,但是由于它会加载一些脚本文件,所以建议放在footer下面: *@
    <mini-profiler />

    <environment include="development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
    </environment>

    ...

    @rendersection("scripts", required: false)
</body>
</html>

运行应用,可以看到左下角就是miniprofiler:

使用 MiniProfiler 来分析 ASP.NET Core 应用

点击它之后会弹出窗口,里面有每个步骤具体的耗用时间。

使用 MiniProfiler 来分析 ASP.NET Core 应用

二、miniprofiler 具体使用

分析局部代码

前面的例子里,我们使用miniprofiler分析了页面整个流程的时间。而miniprofiler也可以用来分析一段代码所耗用的时间。看例子:

    public async task<iactionresult> index()
    {
#if !debug
        // 这里我们使用了using语句,里面使用了 miniprofiler 类的 current 属性,在该属性上面有一个step()方法,
        // 它可以用来分析using语句里面的代码,在step方法里,要提供一个具有描述性的名称来表示该段代码做的是什么动作,这个名称会显示在结果里。
        using (miniprofiler.current.step("计算第一步"))
        {
            var users = await _context.users.tolistasync();
            return view(users);
        }
#else
        // 通常,我会使用 using 语句块来嵌套着使用

        using(miniprofiler.current.step("第1步"))
        {

            // ... 相关操作
            thread.sleep(30);

            using(miniprofiler.current.step("第1.1步"))
            {
                // ... 相关操作
                thread.sleep(30);
            }

            using(miniprofiler.current.step("第1.2步"))
            {
                // ... 相关操作
                thread.sleep(30);
            }
       }

        // 但是如果你只想分析一句话,那么使用using语句就显得太麻烦了,这种情况下可以使用 inline() 方法:
        var users = await miniprofiler.current.inline(async () => await _context.users.tolistasync(), "计算第一步");
        return view(users);
#endif
    }
  • 使用 using 语句块嵌套结果展示:
    使用 MiniProfiler 来分析 ASP.NET Core 应用

  • 使用 inline() 方法结果展示:
    使用 MiniProfiler 来分析 ASP.NET Core 应用

自定义分析 customtiming

有时候,分析一些例如请求外部动作的时候,上面讲的做法可能不太灵光,这里我们就可以使用customtime()方法

    public async task<iactionresult> privacy()
    {
        // 这个例子里,我们使用 miniprofiler.current.customtiming() 方法。
        //  第一个参数是一个用于分类的字符串,这里我用的是http请求,所以写了http;
        //  第二个参数是命令字符串,这里我用不上,暂时留空;
        //  第三个参数是执行类型,这里我用的是get请求,所以写了get;
        using (customtiming timing = miniprofiler.current.customtiming("http", string.empty, "get"))
        {
            var url = "http://27.24.159.155";
            var httpclient = new httpclient
            {
                baseaddress = new uri(url)
            };
            httpclient.defaultrequestheaders.clear();
            httpclient.defaultrequestheaders.accept.add(new mediatypewithqualityheadervalue("application/json"));

            var response = await httpclient.getasync("/system/resource/code/news/click/dynclicks.jsp?clickid=1478&owner=1220352265&clicktype=wbnews");

            timing.commandstring = $"url:{url}\n\r response code:{response.statuscode}";

            if (!response.issuccessstatuscode)
            {
                throw new exception("error fetching data from api");
            }

            var clicktimes = await response.content.readasstringasync();

            viewdata["clicktimes"] = clicktimes;
        }

        return view();
    }
  • 运行程序,可以看到窗口的右侧出现了http这一列:

使用 MiniProfiler 来分析 ASP.NET Core 应用

  • 点击 http 所在列的153.1 (1),这就是使用customtiming分析的那段代码,它请求的url和返回码都显示了出来。

使用 MiniProfiler 来分析 ASP.NET Core 应用

三、案例源码:

miniprofilercoredemo