freeeyes 发表于 2013-8-8 09:22:24

ACE的性能监视者

ACE目录下的example中的readme.txt,其实并不全。那些没有说明的一些example往往有很强的功能。
今天就来说说Monitor这个非常有趣而且非常有用的例子。
Monitor,顾名思义,监控者。
Monitor用例包含了大概8个用例
分别实现了可以监控指定的进程,CPU,内存,网络IO输入,输出,线程数,消息队列数。
由于谷歌上找不到相应的资料,ace官网上也没有它的多少介绍(至多一两句不关痛痒的英文)
而通过实际的代码走查,发现其实还支持更多的参数,比如内存换页,命中率等。
在windows下,它会调用Windows_Monitor(实际是 PdhAddCounter性能计数器),在Linux下,它会获取/proc/stat文件下的参数。
来看看windows下的实现关键代码,以获取当前CPU为例
windows下是    void
    Windows_Monitor::init (void)
    {
      /// Create a query and a counter here so it doesn't have
      /// to be done with each update.

      this->status_ = ACE_TEXT_PdhOpenQuery (0, 0, &this->query_);

      if (ERROR_SUCCESS != this->status_)
      {
          ACELIB_ERROR ((LM_DEBUG, ACE_TEXT ("PdhOpenQuery failed\n")));
      }

      this->status_ =
      ACE_TEXT_PdhAddCounter (this->query_,
                              this->path_.c_str (),
                              0,
                              &this->counter_);

      if (ERROR_SUCCESS != this->status_)
      {
          ACELIB_ERROR ((LM_DEBUG,
                      ACE_TEXT ("PdhAddCounter %s failed\n"),
                      this->path_.c_str ()));
      }
    }这里是初始化一个性能计数器用例,非常清晰的代码。
然后是获得相关参数    void
    Windows_Monitor::update_i (void)
    {
      PdhCollectQueryData (this->query_);
      PDH_FMT_COUNTERVALUE pdh_value;

      PdhGetFormattedCounterValue (this->counter_,
                                 PDH_FMT_DOUBLE,
                                 0,
                                 &pdh_value);

      this->value_ = pdh_value.doubleValue;
    }在linux下获得的更简单。方法如下:    void
    CPU_Load_Monitor::access_proc_stat (unsigned long *which_idle)
    {
      this->file_ptr_ = ACE_OS::fopen (ACE_TEXT ("/proc/stat"),
                                       ACE_TEXT ("r"));

      if (this->file_ptr_ == 0)
      {
          ACELIB_ERROR ((LM_ERROR,
                      ACE_TEXT ("CPU load - opening /proc/stat failed\n")));
          return;
      }

      char *item = 0;
      char *arg = 0;

      while ((ACE_OS::fgets (buf_, sizeof (buf_), file_ptr_)) != 0)
      {
          item = ACE_OS::strtok (this->buf_, " \t\n");
          arg = ACE_OS::strtok (0, "\n");

          if (item == 0 || arg == 0)
            {
            continue;
            }

          if (ACE_OS::strcmp (item, "cpu") == 0)
            {
            sscanf (arg,
                      "%lu %lu %lu %lu",
                      &this->user_,
                      &this->wait_,
                      &this->kernel_,
                      which_idle);
            break;
            }
      }

      ACE_OS::fclose (this->file_ptr_);
    }代码就不一行行的解释了,有基本功的同学我想一看就懂。
因为这里ace也没有对此用例的相关文档,我在这里补全一下,并展现里面的关键实际调用。
用这个例子,完全可以实现一个监控指定进程各项参数的工具,关键代码例子里面都做好了,运维最喜欢的。
所以说,ACE的例子里面,还是有很多精华可以挖取的。
页: [1]
查看完整版本: ACE的性能监视者