MiniProfiler使用點滴記錄-2017年6月23日11:08:23

来源:http://www.cnblogs.com/x-poior/archive/2017/06/23/7068977.html
-Advertisement-
Play Games

1.看似針對同樣一段查詢表ef達式,重覆執行卻沒有被記錄下來。其實這是正常情況,因為ef並沒有重覆去執行 相同sql查詢。 2.MiniProfiler結合MVC過濾器進行 攔截記錄Sql,示例代碼: 3.以上的miniprofiler並不能 攔截到 sql語句查詢,需要使用 minprofiler ...


1.看似針對同樣一段查詢表ef達式,重覆執行卻沒有被記錄下來。其實這是正常情況,因為ef並沒有重覆去執行 相同sql查詢。

 

2.MiniProfiler結合MVC過濾器進行 攔截記錄Sql,示例代碼:

using Mobile360.Core;
using Mobile360.Core.Interfaces;
using Mobile360.Core.Models;
using Mobile360.Web.Common;
using Newtonsoft.Json.Linq;
using StackExchange.Profiling;
using StackExchange.Profiling.Storage;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;

namespace Mobile360.Web
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
    public class OperationHandlerAttribute : FilterAttribute,IActionFilter, IExceptionFilter 
    {
        private IRepository repo;

        /// <summary>
        /// 模塊描述
        /// </summary>
        public string ModuleName { get; set; }

        /// <summary>
        /// 方法名稱
        /// </summary>
        public string ActionName { get; set; }

        /// <summary>
        /// 方法描述
        /// </summary>
        public string ActionDescription { get; set; }

        /// <summary>
        /// 控制器名稱
        /// </summary>
        public string ControllerName { get; set; }

        /// <summary>
        /// 方法參數
        /// </summary>
        public string ActionParameters { get; set; }

        /// <summary>
        /// 訪問時間
        /// </summary>
        public DateTime AccessDate { get; set; }
 
        /// <summary>
        /// 操作備註
        /// </summary>
        public string OperationRemark { get; set; }

        /// <summary>
        /// 是否記錄入庫
        /// </summary>
        public bool IsLog { get; set; } 

        /// <summary>
        /// 操作人id
        /// </summary>
        public int OperatorId { get; set; }

        /// <summary>
        /// 操作人名
        /// </summary>
        public string OperatorName { get; set; }
 

        public OperationHandlerAttribute()
        {
            this.AccessDate = DateTime.Now;
            this.IsLog = true;
            this.repo = DependencyResolver.Current.GetService<IRepository>();
        }

        /// <summary>
        /// 操作日誌記錄
        /// </summary>
        /// <param name="option">操作動作描述</param>
        /// <param name="remark">其他備註</param>
        public OperationHandlerAttribute(string actionDescription , string remark = "")
        {
            this.AccessDate = DateTime.Now;
            this.IsLog = true;
            //this.ModuleName = moduleName; 
            this.OperationRemark = remark;
            this.ActionDescription = actionDescription;
            this.repo = DependencyResolver.Current.GetService<IRepository>();
        }
        void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (this.IsLog)
            {
                MiniProfiler.Start();
                 
                this.OperatorName =  filterContext.HttpContext.User.Identity.Name;  

                this.ActionName = filterContext.ActionDescriptor.ActionName; 
                this.ControllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; 
                IDictionary<string, object> dic = filterContext.ActionParameters; 
                var parameters = new System.Text.StringBuilder();
                foreach (var item in dic)
                {
                    parameters.Append(item.Key + "=" +  Json.Encode(item.Value) + "|");
                }
                this.ActionParameters = parameters.ToString(); 
                  
            }
        }

        void IActionFilter.OnActionExecuted(ActionExecutedContext context)
        {
            if (this.IsLog)
            {
                MiniProfiler.Stop(); 
                string efSqlStr2Json = MiniProfiler.Current.Root.CustomTimingsJson; 

                AuditLog log = new AuditLog();
                log.AuditAccount = string.IsNullOrEmpty(this.OperatorName)?"(未登錄用戶)": this.OperatorName;
                log.Action = this.ActionName;
                log.ActionDescription = this.ActionDescription;
                log.Controller = this.ControllerName;
                log.Parameters = this.ActionParameters;
                log.StartTime = this.AccessDate;
                log.SqlQuery = efSqlStr2Json; 
                log.EndTime = DateTime.Now;
                log.Result = true;
                log.IP = IPHelper.GetRealIP();

                repo.Insert<AuditLog>(log); 
                repo.SaveChanges();
            }
        }



        #region IExceptionFilter 成員
        void IExceptionFilter.OnException(ExceptionContext context)
        {
            if (ConfigurationManager.AppSettings["IsDev"] == "true")
            {
                throw new Exception(context.Exception.Message, context.Exception);
            }

            SystemLog slog = new SystemLog();
            slog.Action = this.ActionName;
            slog.Level = (int)SystemLogType.ERROR;
            slog.LoginAccount = this.OperatorName;
            slog.Message = BuildExceptionInfo(context);
            slog.OccurTime = DateTime.Now;

            repo.Insert<SystemLog>(slog); 
            repo.SaveChanges();


            JObject jsonResult = new JObject(); //返回的json數據
            jsonResult.Add(new JProperty("Code", -1));
            jsonResult.Add(new JProperty("Msg", "系統發生異常,請查看內部日誌"));
            ContentResult cr = new ContentResult();
            cr.Content = jsonResult.ToString();
            cr.ContentType = "application/json";
            context.Result = cr;
            context.ExceptionHandled = true;
        }

        private string BuildExceptionInfo(ExceptionContext context)
        {
            var sb = new StringBuilder();
            var req = context.HttpContext.Request;
            sb.AppendLine(String.Format("處理對“{0}”的“{1}”請求時發生了異常", req.RawUrl, req.HttpMethod));
            sb.AppendLine("以下是參數的信息:");
            this.AppendRequestLine(sb, req.QueryString);
            this.AppendRequestLine(sb, req.Form);
            sb.AppendLine("以下是異常的信息:");
            sb.AppendLine(context.Exception.ToString());
            //sb.AppendLine(context.Exception.StackTrace.ToString());

            return sb.ToString();
        }

        private void AppendRequestLine(StringBuilder sb, NameValueCollection coll)
        {
            for (int i = 0; i < coll.Count; i++)
            {
                sb.AppendFormat("{0}: {1}", coll.Keys[i], coll[i]);
                sb.AppendLine();
            }
        }

        #endregion 

    }
}

 

3.以上的miniprofiler並不能 攔截到 sql語句查詢,需要使用 minprofiler 封裝的ado.net對象。

 /// <summary>
        /// 執行自定義SQL(創建、更新、刪除操作)
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="commandText"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public async Task<int> ExecuteSqlCommandAsync(string commandText, params object[] parameters)
        {
            var connection1 = this.Database.Connection;//使用EF的sql連接對象。統一管理。
            if (connection1 != null)
            {
                DbCommand command = new SqlCommand();
                ProfiledDbCommand prcommand = new ProfiledDbCommand(command, connection1, MiniProfiler.Current);
                prcommand.CommandType = CommandType.Text;
                prcommand.CommandText = commandText;
                prcommand.Parameters.AddRange(parameters);
                prcommand.Connection = connection1;

                if (connection1.State == ConnectionState.Closed)
                    connection1.Open();

                return await prcommand.ExecuteNonQueryAsync();
            }
            return 0;
        }
ProfiledDbCommand,
ProfiledDbConnection等對象都是MiniProfiler的對象。這樣才能抓到 Sql語句。

4.由於miniprofiler是用來性能調優的,用來做審計日誌記錄(包括哪個用戶最終生成的sql查詢)看似並不合適,非常耗性能。
所以,我們並沒有準備去使用它來獲取Sql語句。

運用在
Application_BeginRequest和
Application_EndRequest
期間用EF6.0版本以上才有的 攔截器介面
DbCommandInterceptor

攔截的所有sql語句作為一次請求的sql查詢語句 來作為嘗試,不知道這樣有啥劣勢不? 希望有嘗試過的 前輩 指點。





您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 當添加一個新賬號後,我們可能會發現新賬號sudo 時會報告不在sudoers中,使用su -s時輸入密碼後也會認證失敗 上網搜索大部分都要求修改/etc/sudoers中的內容,但修改這個文件必須需要許可權,這就陷入了死迴圈,故而我們需要更改策略來迂迴更改文件: 1、使用另一個可以使用root許可權的賬 ...
  • composer Install 官網 https://getcomposer.org Composer 是 PHP 用來管理依賴(dependency)關係的工具。你可以在自己的項目中聲明所依賴的外部工具庫(libraries),Composer 會幫你安裝這些依賴的庫文件。 下麵使用比較簡單使用 ...
  • 串口初始化後第一次發送數據丟失第一個字元的問題,現象是在上電或者複位後調試串口的列印信息總是會丟掉第一個字母。 解決: 一直是在原有項目基礎上進行工作,一直沒有處理這個問題,今天有時間看了看,發現是因為fputc函數中用的是GetFlagStatus函數,嘗試改為while((USART3->SR& ...
  • 第一種:查看實時變化的日誌(比較吃記憶體) 最常用的: tail -f filename (預設最後10行,相當於增加參數 -n 10) Ctrl+c 是退出tail命令 其他情況: tail -n 20 filename (顯示filename最後20行) tail -n +5 filename ( ...
  • 本文目錄: 1.1 選項說明 1.2 嘗試一次掃描 1.3 掃描目標說明 1.4 埠狀態說明 1.5 時間參數優化 1.6 掃描操作系統類型 1.7 快速掃描存活的主機 1.8 快速掃描埠 nmap一般就用來掃描主機是否線上(特別是掃描區域網記憶體活的機器)、開放了哪些埠。其他的功能用的比較少, ...
  • 本文目錄: 1.1 tcpdump選項 1.2 tcpdump表達式 1.3 tcpdump示例 tcpdump採用命令行方式對介面的數據包進行篩選抓取,其豐富特性表現在靈活的表達式上。 不帶任何選項的tcpdump,預設會抓取第一個網路介面,且只有將tcpdump進程終止才會停止抓包。 例如: s ...
  • 轉載請註明出處:http://www.houxiurong.com/?post=27 Mac預設是安裝了ssh工具軟體的。 先用mac的 終端工具生成 id_rsa 和id_rsa.pub 秘鑰,生成方式如下: 1、當前用戶目錄下,檢查SSH公鑰 cd ~/.ssh 看看存不存在.ssh,如果存在的 ...
  • 學習單片機過程中遇到兩個問題: 1、寫好串口代碼,手邊沒有硬體調試; 2、串口收發出現奇怪的問題,無法定位; 經過百度,百度,再百度後,終於找到瞭解決方法,那就是:串口收發模擬。不多說,總結如下: 實驗需要的軟體:VSPD(Virtual Serial Port Driver)、串口調試助手、Kei ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...