statgrab_health.cpp

00001 /*
00002  *  This program is free software; you can redistribute it and/or modify
00003  *  it under the terms of the GNU General Public License as published by
00004  *  the Free Software Foundation; either version 2 of the License, or
00005  *  (at your option) any later version.
00006  *
00007  *  This program is distributed in the hope that it will be useful,
00008  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00009  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010  *  GNU General Public License for more details.
00011  *
00012  *  You should have received a copy of the GNU General Public License
00013  *  along with this program; if not, write to the Free Software
00014  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00015  *
00016  */
00017 
00058 #include "statgrab_health.h"
00059 
00060 #include <unistd.h>
00061 #include <string.h>
00062 #include <netinet/in.h>
00063 #include <libplayercore/playercore.h>
00064 #include <libplayercore/error.h>
00065 
00066 #include <stdio.h>
00067 #include <stdlib.h>
00068 
00069 #include <iostream>
00070 #include <stdint.h>
00071 
00072 using namespace std;
00073 
00075 // Now the driver
00076 
00077 // A factory creation function, declared outside of the class so that it
00078 // can be invoked without any object context (alternatively, you can
00079 // declare it static in the class).  In this function, we create and return
00080 // (as a generic Driver*) a pointer to a new instance of this driver.
00081 Driver*
00082 StatGrabDriver_Init(ConfigFile* cf, int section)
00083 {
00084   // Create and return a new instance of this driver
00085   return((Driver*)(new StatGrabDriver(cf, section)));
00086 
00087 }
00088 
00089 // A driver registration function, again declared outside of the class so
00090 // that it can be invoked without object context.  In this function, we add
00091 // the driver into the given driver table, indicating which interface the
00092 // driver can support and how to create a driver instance.
00093 void StatGrabDriver_Register(DriverTable* table)
00094 {
00095   table->AddDriver("statgrabdriver", StatGrabDriver_Init);
00096 }
00097 
00099 // Constructor.  Retrieve options from the configuration file and do any
00100 // pre-Setup() setup.
00101 StatGrabDriver::StatGrabDriver(ConfigFile* cf, int section)
00102     : Driver(cf, section)
00103 {
00104 
00105   // For Health Interface
00106   if(cf->ReadDeviceAddr(&mHealthId, section, "provides",
00107                         PLAYER_HEALTH_CODE, -1, NULL) == 0)
00108   {
00109     if(this->AddInterface(mHealthId))
00110     {
00111       this->SetError(-1);
00112       return;
00113     }
00114   }
00115 
00116 
00117   // Allow to just have to change the config file if you want to adjust the sleep
00118   // duration.
00119   mSleep = static_cast<int32_t>((1e6/cf->ReadInt(section, "frequency", 100)));
00120 
00121   return;
00122 }
00123 
00125 // Set up the device.  Return 0 if things go well, and -1 otherwise.
00126 int StatGrabDriver::Setup()
00127 {
00128   // Initialise statgrab
00129   sg_init();
00130   /* Drop setuid/setgid privileges. */
00131   if (sg_drop_privileges() != 0)
00132   {
00133     perror("Error. Failed to drop privileges");
00134    return 1;
00135   }
00136 
00137   puts("Health driver ready");
00138 
00139   StartThread();
00140 
00141   return(0);
00142 }
00143 
00145 // Shutdown the device
00146 int StatGrabDriver::Shutdown()
00147 {
00148 
00149   puts("Shutting health driver down");
00150 
00151   // Stop and join the driver thread
00152   StopThread();
00153 
00154   puts("Health driver has been shutdown");
00155 
00156   return(0);
00157 }
00158 
00160 // Main function for device thread
00161 void StatGrabDriver::Main()
00162 {
00163 
00164   // The main loop; interact with the device here
00165   for(;;)
00166   {
00167     // test if we are supposed to cancel
00168     pthread_testcancel();
00169 
00170     usleep(mSleep);
00171 
00172     ProcessMessages();
00173 
00174     // Write outgoing data
00175     RefreshData();
00176 
00177 
00178   }
00179   return;
00180 }
00181 
00183 void StatGrabDriver::RefreshData()
00184 {
00185   //double receivedCpu;
00186   float cpuIdle, cpuServer, cpuUser ;
00187         //CPU
00188         cpu_percent = sg_get_cpu_percents();
00189 
00190         cpuIdle =  cpu_percent->idle;
00191         mHealth.cpu_usage.idle = cpuIdle;
00192         cpuServer = cpu_percent->kernel + cpu_percent->iowait + cpu_percent->swap;
00193         mHealth.cpu_usage.system = cpuServer;
00194         cpuUser = cpu_percent->nice+ cpu_percent->user;
00195         mHealth.cpu_usage.user = cpuUser;
00196 
00197 
00198 
00199         //Virtual Memory
00200         mem_data     = sg_get_mem_stats();
00201         swap_stats   = sg_get_swap_stats();
00202 
00203         mHealth.mem.total = mem_data->total;
00204         mHealth.mem.used =  mem_data->used;
00205         mHealth.mem.free = mem_data->free;
00206 
00207         mHealth.swap.total = swap_stats->total;
00208         mHealth.swap.used = swap_stats->used;
00209         mHealth.swap.free = swap_stats->free;
00210 
00211    // Other data which should be retrieved here!
00212 
00213     Publish(device_addr, PLAYER_MSGTYPE_DATA, PLAYER_HEALTH_DATA_STATE  ,
00214             reinterpret_cast<void*>(&mHealth));
00215 
00216 
00217 }
00218 
00220 // Extra stuff for building a shared object.
00221 
00222 // leftover from when this was a standalone plugin
00223 
00224 /* need the extern to avoid C++ name-mangling  */
00225 //extern "C" {
00226 //  int player_driver_init(DriverTable* table)
00227 //  {
00228 //    puts("StatGrab driver initializing");
00229 //    StatGrabDriver_Register(table);
00230 //    puts("StatGrab driver done");
00231 //    return(0);
00232 //  }
00233 //}

Last updated 12 September 2005 21:38:45