<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      性能計數(shù)器數(shù)據(jù)收集服務(wù)

      本文演示了一個Windows服務(wù)收集性能計數(shù)器的數(shù)據(jù),將性能計數(shù)器數(shù)據(jù)寫入數(shù)據(jù)庫。Windows服務(wù)中調(diào)用WebAPI服務(wù)中。下面簡要介紹下我的改造,項目雖小,其中用到了眾多的開源項目Topshelf、NLog、Dapper,ASP.NET Web API,Newtonsoft.Json等等:

      1、數(shù)據(jù)庫模型,以下是MS SQL Server的模型:

         1:  USE [PerfmonCounter]
         2:  GO
         3:  /****** Object:  Table [dbo].[service_counter_snapshots]    Script Date: 01/25/2013 22:40:20 ******/
         4:  SET ANSI_NULLS ON
         5:  GO
         6:  SET QUOTED_IDENTIFIER ON
         7:  GO
         8:  SET ANSI_PADDING ON
         9:  GO
        10:  CREATE TABLE [dbo].[service_counter_snapshots](
        11:      [Id] [int] IDENTITY(1,1) NOT NULL,
        12:      [ServiceCounterId] [int] NOT NULL,
        13:      [SnapshotMachineName] [varchar](100) NULL,
        14:      [CreationTimeUtc] [datetime] NOT NULL,
        15:      [ServiceCounterValue] [float] NULL,
        16:  PRIMARY KEY CLUSTERED 
        17:  (
        18:      [Id] ASC
        19:  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        20:  ) ON [PRIMARY]
        21:  GO
        22:  SET ANSI_PADDING OFF
        23:  GO
        24:  /****** Object:  Table [dbo].[services]    Script Date: 01/25/2013 22:40:20 ******/
        25:  SET ANSI_NULLS ON
        26:  GO
        27:  SET QUOTED_IDENTIFIER ON
        28:  GO
        29:  SET ANSI_PADDING ON
        30:  GO
        31:  CREATE TABLE [dbo].[services](
        32:      [Name] [varchar](100) NOT NULL,
        33:      [DisplayName] [varchar](1000) NULL,
        34:  PRIMARY KEY CLUSTERED 
        35:  (
        36:      [Name] ASC
        37:  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        38:  ) ON [PRIMARY]
        39:  GO
        40:  SET ANSI_PADDING OFF
        41:  GO
        42:  /****** Object:  Table [dbo].[service_counters]    Script Date: 01/25/2013 22:40:20 ******/
        43:  SET ANSI_NULLS ON
        44:  GO
        45:  SET QUOTED_IDENTIFIER ON
        46:  GO
        47:  SET ANSI_PADDING ON
        48:  GO
        49:  CREATE TABLE [dbo].[service_counters](
        50:      [Id] [int] IDENTITY(1,1) NOT NULL,
        51:      [ServiceName] [varchar](100) NOT NULL,
        52:      [MachineName] [varchar](100) NULL,
        53:      [CategoryName] [varchar](100) NOT NULL,
        54:      [CounterName] [varchar](100) NOT NULL,
        55:      [InstanceName] [varchar](100) NULL,
        56:      [DisplayName] [varchar](1000) NULL,
        57:      [DisplayType] [varchar](7) NOT NULL,
        58:  PRIMARY KEY CLUSTERED 
        59:  (
        60:      [Id] ASC
        61:  )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
        62:  ) ON [PRIMARY]
        63:  GO
        64:  SET ANSI_PADDING OFF
        65:  GO
        66:  /****** Object:  Default [DF__service_c__Displ__08EA5793]    Script Date: 01/25/2013 22:40:20 ******/
        67:  ALTER TABLE [dbo].[service_counters] ADD  DEFAULT ('table') FOR [DisplayType]
        68:  GO
        69:  /****** Object:  ForeignKey [FK__service_c__Servi__09DE7BCC]    Script Date: 01/25/2013 22:40:20 ******/
        70:  ALTER TABLE [dbo].[service_counters]  WITH CHECK ADD FOREIGN KEY([ServiceName])
        71:  REFERENCES [dbo].[services] ([Name])
        72:  GO

      services表 存儲我們需要監(jiān)控的服務(wù)的進(jìn)程。 每個服務(wù)都需要監(jiān)控一系列的性能計數(shù)器 (存儲在 service_counters 表)。數(shù)據(jù)收集服務(wù)在啟動的時候根據(jù)service_counters 表創(chuàng)建 System.Diagnostics.PerformanceCounter class 的實(shí)例列表。 服務(wù)每隔一段時間收集一次性能計數(shù)器數(shù)據(jù)并把它存儲到service_counter_snapshots 表。

      所有的數(shù)據(jù)操作通過一個Restful服務(wù)接口DataCollectorController 進(jìn)行操作。

         1:  using System;
         2:  using System.Collections.Generic;
         3:  using System.Linq;
         4:  using System.Net;
         5:  using System.Net.Http;
         6:  using System.Web.Http;
         7:  using PerformanceCounterCollect.Models;
         8:  using PerformanceCounterCollect.Web.Models;
         9:   
        10:  namespace PerformanceCounterCollect.Web.Controllers
        11:  {
        12:      public class DataCollectorController : ApiController
        13:      {
        14:          private ServiceCounterRepository scRepository;
        15:          private ServiceCounterSnapshotRepository scSnapshotReposity;
        16:   
        17:          public DataCollectorController()
        18:          {
        19:              scRepository = new ServiceCounterRepository();
        20:              scSnapshotReposity = new ServiceCounterSnapshotRepository();
        21:          }
        22:   
        23:          // GET api/values/5
        24:          [HttpGet]
        25:          public IEnumerable<ServiceCounter> SelectServiceCounter(string machineName)
        26:          {
        27:              return scRepository.SelectServiceCounter(machineName);
        28:          }
        29:   
        30:          // POST api/values
        31:          [HttpPost]
        32:          public IEnumerable<ServiceCounterSnapshot> SaveServiceSnapshots([FromBody]IEnumerable<ServiceCounterSnapshot> value)
        33:          {
        34:              return scSnapshotReposity.SaveServiceSnapshots(value);
        35:          }
        36:      }
        37:        
        38:  }
      數(shù)據(jù)操作使用到了輕型的ORM類Dapper,使用了Repository模式。
         1:  using System;
         2:  using System.Data;
         3:  using System.Data.SqlClient;
         4:  using System.Linq;
         5:  using System.Web.Configuration;
         6:  using Dapper;
         7:   
         8:  namespace PerformanceCounterCollect.Web.Models
         9:  {
        10:      public abstract class BaseRepository
        11:      {
        12:          protected static void SetIdentity<T>(IDbConnection connection, Action<T> setId)
        13:          {
        14:              dynamic identity = connection.Query("SELECT @@IDENTITY AS Id").Single();
        15:              T newId = (T)identity.Id;
        16:              setId(newId);
        17:          }
        18:   
        19:          protected static IDbConnection OpenConnection()
        20:          {
        21:              IDbConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["SqlDiagnosticsDb"].ConnectionString);
        22:              connection.Open();
        23:              return connection;
        24:          }
        25:      }
        26:  }
       
         1:  using System;
         2:  using System.Collections.Generic;
         3:  using System.Data;
         4:  using System.Linq;
         5:  using System.Web;
         6:  using Dapper;
         7:  using PerformanceCounterCollect.Models;
         8:   
         9:   
        10:  namespace PerformanceCounterCollect.Web.Models
        11:  {
        12:      public class ServiceCounterRepository : BaseRepository
        13:      {
        14:          public IEnumerable<ServiceCounter> SelectServiceCounter(string machineName)
        15:          {
        16:              using (IDbConnection connection = OpenConnection())
        17:              {
        18:                  string query = "select Id,ServiceName,CategoryName,CounterName,InstanceName from service_counters where MachineName=@MachineName";
        19:                  return connection.Query<ServiceCounter>(query, new { MachineName = machineName });
        20:              }
        21:          }
        22:   
        23:   
        24:      }
        25:  }
       
       
         1:  using System;
         2:  using System.Collections.Generic;
         3:  using System.Data;
         4:  using System.Linq;
         5:  using System.Web;
         6:  using Dapper;
         7:  using PerformanceCounterCollect.Models;
         8:   
         9:  namespace PerformanceCounterCollect.Web.Models
        10:  {
        11:      public class ServiceCounterSnapshotRepository: BaseRepository
        12:      {
        13:          public IEnumerable<ServiceCounterSnapshot> SaveServiceSnapshots(IEnumerable<ServiceCounterSnapshot> snapshots)
        14:          {
        15:              using (IDbConnection connection = OpenConnection())
        16:              {
        17:                  foreach (var snapshot in snapshots)
        18:                  {
        19:                      // insert new snapshot to the database
        20:                      int retVal = connection.Execute(
        21:      @"insert into service_counter_snapshots(ServiceCounterId,SnapshotMachineName,CreationTimeUtc,ServiceCounterValue) values (
        22:          @ServiceCounterId,@SnapshotMachineName,@CreationTimeUtc,@ServiceCounterValue)", snapshot);
        23:                      SetIdentity<int>(connection, id => snapshot.Id = id);
        24:                  }
        25:              }
        26:              return snapshots;
        27:          }
        28:      }
        29:  }

      2、監(jiān)控服務(wù),也就是數(shù)據(jù)收集代理程序Monitoring Service:

         1:  using System;
         2:  using System.Collections.Generic;
         3:  using System.Linq;
         4:  using System.Text;
         5:  using System.Threading;
         6:  using System.Threading.Tasks;
         7:  using Topshelf;
         8:  using Topshelf.Logging;
         9:   
        10:  namespace PerformanceCounterCollect.Services
        11:  {
        12:      class PerfmonWorker: ServiceControl
        13:      {
        14:          private readonly LogWriter logger = HostLogger.Get<PerfmonWorker>();
        15:          public static bool ShouldStop { get; private set; }
        16:          private ManualResetEvent stopHandle;
        17:   
        18:          public bool Start(HostControl hostControl)
        19:          {
        20:              logger.Info("Starting PerfmonWorker...");
        21:   
        22:              stopHandle = new ManualResetEvent(false);
        23:   
        24:              ThreadPool.QueueUserWorkItem(new ServiceMonitor().Monitor, stopHandle);
        25:   
        26:              return true;
        27:          }
        28:   
        29:          public bool Stop(HostControl hostControl)
        30:          {
        31:              ShouldStop = true;
        32:              logger.Info("Stopping PerfmonWorker...");
        33:              // wait for all threads to finish
        34:              stopHandle.WaitOne(ServiceMonitor.SleepIntervalInMilliSecs + 10);
        35:   
        36:              return true;
        37:          }
        38:      }
        39:    
        40:  }

      服務(wù)使用了Topshelf和NLog,具體參看《使用Topshelf 5步創(chuàng)建Windows 服務(wù)》。在服務(wù)啟動的時候開啟監(jiān)控線程,執(zhí)行方法ServiceMonitor.Monitor:

         1:  using System;
         2:  using System.Collections.Generic;
         3:  using System.Diagnostics;
         4:  using System.Linq;
         5:  using System.Text;
         6:  using System.Threading;
         7:  using System.Threading.Tasks;
         8:  using PerformanceCounterCollect.Models;
         9:  using Topshelf.Logging;
        10:   
        11:  namespace PerformanceCounterCollect.Services
        12:  {
        13:      sealed class ServiceMonitor
        14:      {
        15:          public const int SleepIntervalInMilliSecs = 50000;
        16:   
        17:          private readonly LogWriter logger = HostLogger.Get<ServiceMonitor>();
        18:          private IList<Tuple<int, PerformanceCounter>> serviceCounters;
        19:   
        20:          public void Monitor(object state)
        21:          {
        22:              ManualResetEvent stopHandle = (ManualResetEvent)state;
        23:              String machineName = Environment.MachineName;
        24:              try
        25:              {
        26:                  Initialize(machineName);
        27:                  var snapshots = new ServiceCounterSnapshot[serviceCounters.Count];
        28:   
        29:                  while (!PerfmonWorker.ShouldStop)
        30:                  {
        31:                      Thread.Sleep(SleepIntervalInMilliSecs);
        32:   
        33:                      // this would be our timestamp value by which we will group the snapshots
        34:                      DateTime timeStamp = DateTime.UtcNow;
        35:                      // collect snapshots
        36:                      for (int i = 0; i < serviceCounters.Count; i++)
        37:                      {
        38:                          var snapshot = new ServiceCounterSnapshot();
        39:                          snapshot.CreationTimeUtc = timeStamp;
        40:                          snapshot.SnapshotMachineName = machineName;
        41:                          snapshot.ServiceCounterId = serviceCounters[i].Item1;
        42:                          try
        43:                          {
        44:                              snapshot.ServiceCounterValue = serviceCounters[i].Item2.NextValue();
        45:                              logger.DebugFormat("Performance counter {0} read value: {1}", GetPerfCounterPath(serviceCounters[i].Item2),
        46:                                                  snapshot.ServiceCounterValue);
        47:                          }
        48:                          catch (InvalidOperationException)
        49:                          {
        50:                              snapshot.ServiceCounterValue = null;
        51:                              logger.DebugFormat("Performance counter {0} didn't send any value.", GetPerfCounterPath(serviceCounters[i].Item2));
        52:                          }
        53:                          snapshots[i] = snapshot;
        54:                      }
        55:                      SaveServiceSnapshots(snapshots);
        56:                  }
        57:              }
        58:              finally
        59:              {
        60:                  stopHandle.Set();
        61:              }
        62:          }
        63:   
        64:          private void Initialize(String machineName)
        65:          {
        66:              try
        67:              {
        68:                  var counters = new List<Tuple<int, PerformanceCounter>>();
        69:   
        70:                  foreach (var counter in PerfmonClient.SelectServiceCounter(machineName))
        71:                  {
        72:                      logger.InfoFormat(@"Creating performance counter: {0}\{1}\{2}\{3}", counter.MachineName ?? ".", counter.CategoryName,
        73:                                          counter.CounterName, counter.InstanceName);
        74:                      var perfCounter = new PerformanceCounter(counter.CategoryName, counter.CounterName, counter.InstanceName, counter.MachineName ?? ".");
        75:                      counters.Add(new Tuple<int, PerformanceCounter>(counter.Id, perfCounter));
        76:                      // first value doesn't matter so we should call the counter at least once
        77:                      try { perfCounter.NextValue(); }
        78:                      catch { }
        79:                  }
        80:                 
        81:   
        82:                  serviceCounters = counters;
        83:              }
        84:              catch (Exception ex)
        85:              {
        86:                  logger.Error(ex);
        87:              }
        88:          }
        89:   
        90:          private void SaveServiceSnapshots(IEnumerable<ServiceCounterSnapshot> snapshots)
        91:          {
        92:              PerfmonClient.SaveServiceSnapshots(snapshots);
        93:          }
        94:   
        95:          private String GetPerfCounterPath(PerformanceCounter cnt)
        96:          {
        97:              return String.Format(@"{0}\{1}\{2}\{3}", cnt.MachineName, cnt.CategoryName, cnt.CounterName, cnt.InstanceName);
        98:          }
        99:      }
       100:  }

      Monitor 方法中初始化完要采集的性能計數(shù)器實(shí)例后開啟一個主循環(huán),定期的收集數(shù)據(jù),如果相關(guān)的性能計數(shù)器實(shí)例沒有運(yùn)行,計數(shù)器將會拋出InvalidOperationException 我們就把它設(shè)置為null。數(shù)據(jù)集的數(shù)據(jù)通過WebAPI發(fā)回服務(wù)器端存儲,這樣就可以實(shí)現(xiàn)性能計數(shù)器的集中存儲了。

      3、使用方法

      使用很簡單,首先定義我們要收集的數(shù)據(jù)

      insert into services values ('notepad', 'notepad process test');

      insert into service_counters values ( 'notepad', ‘GEFFZHANG-PC’, 'process', '% Processor Time', 'notepad', null, 'graph');

      insert into service_counters values ( 'notepad', ‘GEFFZHANG-PC’, 'process', 'working set', 'notepad', null, 'graph');

      然后啟動我們的性能計數(shù)器收集服務(wù)

      image

      代碼參見項目 https://github.com/geffzhang/PerformanceCounterCollect/

      WMI Performance Counter Logging Console App

      posted @ 2013-01-26 10:25  張善友  閱讀(3778)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 亚洲AVAV天堂AV在线网阿V| 内射极品少妇xxxxxhd| 国产精品中文字幕综合| 亚欧洲乱码视频一二三区| 国产综合久久99久久| 一本色道久久综合无码人妻| 99久久成人亚洲精品观看| 色猫咪av在线网址| 97人妻熟女成人免费视频色戒| 国产无遮挡又黄又爽不要vip软件| 国产成人永久免费av在线| 男人猛躁进女人免费播放| 国产精品人妻熟女男人的天堂| 国产蜜臀久久av一区二区| 亚洲av成人午夜福利| 亚洲日韩日本中文在线| 大埔区| 色综合久久一区二区三区| 国产不卡精品视频男人的天堂| 宁海县| 秋霞电影网| 精品夜恋影院亚洲欧洲| 四虎女优在线视频免费看| 18禁无遮挡啪啪无码网站| 久久夜色撩人国产综合av| 五月天中文字幕mv在线| 国产一区二区三区美女| 在线aⅴ亚洲中文字幕| 天天影视色香欲综合久久| 国产AV福利第一精品| 亚洲熟妇自偷自拍另类| 国产福利酱国产一区二区| 亚洲欧美人成电影在线观看 | 国内精品久久人妻无码妲| 无遮挡高潮国产免费观看| 欧洲尺码日本尺码专线美国又| 欧美色欧美亚洲高清在线观看| 日韩人妻精品中文字幕专区| 开心色怡人综合网站| 日本一道一区二区视频| 庆阳市|