Silverlight實現對Sql Server Profiler的SQL即時監控

來源:互聯網
上載者:User

      Sql Server Profiler作為Microsoft Sql Server資料庫系列的效能工具,通過它可以對資料庫的健全狀態進行即時跟蹤,從中可以找到慢查詢或者死結的SQL語句,從而去最佳化系統。本文介紹如果通過Silverlight來對Sql Server Profiler進行即時監控(資料庫環境以Sql Server 2005為例)

 

      首先,先來看下SqlServer資料庫內建的效能工具Sql Server Profiler,建立一個跟蹤:

我們選擇預設的模板Standard,其他都不變,點擊運行:

從中可以看到資料庫中的SQL的運行狀態,EventClass作為事件類型,TextData作為啟動並執行SQL指令碼,ApplicationName作為一個應用程式的執行源的名稱,比如說,從.Net應用程式執行的SQL指令碼就是.Net SqlClient Data Provider,再比如說,我直接從資料庫用戶端工具執行一條SQL語句,可以看到ApplicationName為 ”Microsoft SQL Server Management Studio - 查詢“,因此我們通過ApplicationName欄位得到程式的執行源,LoginName作為一個資料庫的賬戶,一般系統使用者為sa,包括CPU/Reads/Writes在此上面也是一目瞭然,Duration比較有用,可以查看執行語句的耗時,後面還包括StartTime的開始時間和EndTime的結束時間,當然一些隱藏的列我就不一一列舉了,有興趣大家可以勾選查看下。

      如果我要定義一個符合自己需要的模板呢,那麼可以通過建立/編輯模板來實現:

上面有很多的事件類型的選擇,可以根據自己的需要定製Event,這裡我以最簡單的方式,就選擇了TSQL:SQL BatchCompleted:

並且列選擇一個資料庫DatabaseName,類似於編輯 MyEnt,這樣該模板檔案只會在MyEnt為名稱的資料庫中進行SQL執行跟蹤了:

最後點擊儲存即可

 

      那麼,在.Net上怎麼實現對於Sql Server Profiler的使用和監控,實際上,Sql ServerProfiler本身為.Net開發的,後來我在SqlServer2005資料庫的安裝目錄 C:\Program Files\Microsoft SQL Server\90\SDK\Assemblies 中,找到一個Microsoft.SqlServer.ConnectionInfo.dll,這個dll就可以實現執行Sql的監控。

      開始建立項目,其中,監控程式是一個控制台程式,而Silverlight用戶端程式是一個對於SqlServerProfiler即時監控的展示,Silverlight的用戶端程式通過Socket和監控程式進行通訊。由於Silverlight對於TCP通訊的限制,必須往監控程式發送策略請求,並且對於TCP通訊來說,目前Silverlight的使用連接埠必須為4502-4530,於是必須在監控端先設定一個Policy.xml的策略檔案:

<?xml version="1.0" encoding ="utf-8"?> 
<access-policy> 
  <cross-domain-access> 
    <policy> 
      <allow-from> 
        <domain uri="*" /> 
      </allow-from> 
      <grant-to> 
        <socket-resource port="4502-4530" protocol="tcp" /> 
      </grant-to> 
    </policy> 
  </cross-domain-access> 
</access-policy>

現在我將策略請求,監聽SL用戶端串連/資料收發請求,資料庫監聽跟蹤請求,分別建立3個線程:

//建立Socket來監聽策略請求和發送

this._policyThread = this.CreateThread(this.PolicyRequest); 
//建立Socket來監聽資訊請求和發送 
this._infoThread = this.CreateThread(this.InfoRequest); 
//建立Socket來監聽資料庫跟蹤請求和發送 
this._traceServerThread = this.CreateThread(this.TraceServerRequest); 

PolicyRequest,InfoRequest的方法具體看文章末尾的附件原始碼,這裡主要說一下TraceServerRequest的方法:

SqlConnectionInfo conninfo = new SqlConnectionInfo(); 
conninfo.ServerName = "機器名"; 
conninfo.UserName = "資料庫賬戶"; 
conninfo.Password = "資料庫密碼"; 
conninfo.UseIntegratedSecurity = false;
TraceServer trace = new TraceServer(); 
trace.InitializeAsReader(conninfo, TDF_FILE); 
SqlConnectionInfo, TraceServer類來自於對Microsoft.SqlServer.ConnectionInfo的引用,其中TDF_FILE就是我前面說的跟蹤模板檔案名稱,它的檔案尾碼為tdf。
while (trace.Read()) 

    var eventData = new EventData() 
    { 
        EventClass = trace["EventClass"].ToString(), 
        TextData = trace["TextData"] != null ? trace["TextData"].ToString() : "", 
        ApplicationName = trace["ApplicationName"] != null ? trace["ApplicationName"].ToString() : "", 
        NTUserName = trace["NTUserName"] != null ? trace["NTUserName"].ToString() : "", 
        LoginName = trace["LoginName"] != null ? trace["LoginName"].ToString() : "", 
        CPU = trace["CPU"] != null ? trace["CPU"].ToString() : "", 
        Reads = trace["Reads"] != null ? trace["Reads"].ToString() : "", 
        Writes = trace["Writes"] != null ? trace["Writes"].ToString() : "", 
        Duration = trace["Duration"] != null ? trace["Duration"].ToString() : "", 
        ClientProcessID = trace["ClientProcessID"] != null ? trace["ClientProcessID"].ToString() : "", 
        SPID = trace["SPID"] != null ? trace["SPID"].ToString() : "", 
        StartTime = trace["StartTime"] != null ? trace["StartTime"].ToString() : "", 
        EndTime = trace["EndTime"] != null ? trace["EndTime"].ToString() : "", 
    }; 
    var sendData = JsonConvert.SerializeObject(eventData); 
    if (string.IsNullOrEmpty(sendData)) 
        continue; 
    lock (_lock) 
    { 
        this._queues.Enqueue(sendData); 
    } 

通過trace.Read()方法來得到trace的追蹤記錄,這裡我不會馬上通過Socket發送到SL用戶端,而是通過一個隊列對追蹤記錄進行人隊,通過InfoRequest從隊列中取出資料,發送給SL用戶端:

while (true) 

     lock (_lock) 
     { 
         if (this._queues.Count == 0) 
         { 
             Thread.Sleep(200); 
             continue; 
         } 
         var sendData = this._queues.Dequeue(); 
         Console.WriteLine(sendData);
         byte[] data = Encoding.GetEncoding("gb2312").GetBytes(sendData);
         // 移除已斷開的通訊端 
         this._clientList.RemoveAll(o => o.Connected == false); 
         foreach (Socket s in this._clientList) 
         {            
             if (s.Connected) 
             { 
                 try 
                 { 
                     //發送資料 
                     s.Send(data); 
                 } 

 

SL用戶端通過Socket非同步編程接收資料

/// <summary> 
/// 當接收完成 
/// </summary> 
/// <param name="e"></param> 
void ProcessReceive(SocketAsyncEventArgs e) 

     if (e.SocketError == SocketError.Success) 
     { 
         try 
         { 
             Gb2312Encoding encoding = new Gb2312Encoding(); 
    
             string data = Regex.Replace(encoding.GetString(e.Buffer, 0, e.Buffer.Length), @"\0", ""); 
    
             EventData eventData = JsonConvert.DeserializeObject<EventData>(data);
             byte[] bytes = new byte[1024]; 
             e.SetBuffer(bytes, 0, bytes.Length);
             this._syn.Send(this.GetText, eventData);
             //執行串連 
             this._socket.ReceiveAsync(this._socketArgs);    
         } 

//同步上下文調用的方法 
private void GetText(object data) 

    if (data == null) 
        return; 
    EventData eventData = (EventData)data; 
    _list.Add(eventData); 
    this.Dispatcher.BeginInvoke(new Action(() => 
    { 
        this.dataGridRecords.ItemsSource = null; 
        this.dataGridRecords.ItemsSource = _list;
        this.dataGridRecords.UpdateLayout(); 
        this.dataGridRecords.SelectedIndex = _list.Count - 1; 
        this.dataGridRecords.ScrollIntoView(this.dataGridRecords.SelectedItem, null); 
    })); 

這樣就實現了Silverlight用戶端對於Sql Server Profiler的即時監控。

兩個項目很簡單:

先運行 SqlServerProfier.Host程式:

正在對外發送監控資料,

然後運行宿主SL用戶端程式的Web端:

如果是慢查詢的部分,我會用紅色把它標紅,從而確定慢查詢語句,最佳化系統

 

總結:

      當然,你還可以在監控程式中,對於追蹤記錄進行Log寫入或者一個特定Log表的插入,通過Web端(不管是Silverlight還是asp.net mvc均可以查詢相關的追蹤記錄),從而達到對於資料庫SQL執行的監控。

 

附上原始碼:SqlServerProfiler.rar

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.