MIDAS
Loading...
Searching...
No Matches
msysmon.cxx File Reference
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <ctype.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#include "midas.h"
#include "mfe.h"
#include "mstrlcpy.h"
#include "msystem.h"
#include <fstream>
Include dependency graph for msysmon.cxx:

Go to the source code of this file.

Classes

struct  CPUData_
 
struct  NetStat
 

Macros

#define PROCSTATFILE   "/proc/stat"
 
#define PROCMEMINFOFILE   "/proc/meminfo"
 
#define PROCNETSTATFILE   "/proc/net/dev"
 
#define String_startsWith(s, match)   (strstr((s), (match)) == (s))
 
#define EVID_MONITOR   63
 

Typedefs

typedef struct CPUData_ CPUData
 

Functions

INT frontend_init ()
 Frontend initialization.
 
INT frontend_exit ()
 Frontend exit.
 
INT begin_of_run (INT run_number, char *error)
 Begin of Run.
 
INT end_of_run (INT run_number, char *error)
 End of Run.
 
INT pause_run (INT run_number, char *error)
 Pause Run.
 
INT resume_run (INT run_number, char *error)
 Resume Run.
 
INT frontend_loop ()
 Frontend loop.
 
INT poll_event (INT source, INT count, BOOL test)
 
INT interrupt_configure (INT cmd, INT source, PTYPE adr)
 
int read_system_load (char *pevent, int off)
 
void ReadCPUData ()
 
void ReadNetData ()
 
INT rpc_callback (INT index, void *prpc_param[])
 
void BuildHostHistoryPlot ()
 
void BuildHostCPUPlot ()
 
void BuildHostNetPlot ()
 
void InitGPU ()
 

Variables

const charfrontend_name = "msysmon"
 
const charfrontend_file_name = __FILE__
 
BOOL frontend_call_loop = TRUE
 
INT display_period = 0
 
INT max_event_size = 4*1024*1024
 
INT max_event_size_frag = 4*1024*1024
 
INT event_buffer_size = 10*1024*1024
 
BOOL equipment_common_overwrite = FALSE
 
EQUIPMENT equipment []
 
int cpuCount
 
std::vector< CPUData * > cpus
 
unsigned long long int usertime
 
unsigned long long int nicetime
 
unsigned long long int systemtime
 
unsigned long long int idletime
 
int networkInterfaceCount =0
 
std::vector< NetStat * > NetReceive
 
std::vector< NetStat * > NetTransmit
 
std::string colours [16]
 
int event_size = 10*1024
 
HNDLE hSet
 
int test_rb_wait_sleep = 1
 
timeval tv
 
timeval old_tv
 
timeval new_tv
 

Macro Definition Documentation

◆ EVID_MONITOR

#define EVID_MONITOR   63

Definition at line 97 of file msysmon.cxx.

◆ PROCMEMINFOFILE

#define PROCMEMINFOFILE   "/proc/meminfo"

Definition at line 23 of file msysmon.cxx.

◆ PROCNETSTATFILE

#define PROCNETSTATFILE   "/proc/net/dev"

Definition at line 27 of file msysmon.cxx.

◆ PROCSTATFILE

#define PROCSTATFILE   "/proc/stat"

Definition at line 19 of file msysmon.cxx.

◆ String_startsWith

#define String_startsWith (   s,
  match 
)    (strstr((s), (match)) == (s))

Definition at line 30 of file msysmon.cxx.

Typedef Documentation

◆ CPUData

Function Documentation

◆ begin_of_run()

INT begin_of_run ( INT  run_number,
char error 
)

Begin of Run.

Called every run start transition. Set equipment status in ODB, start acquisition on the modules.

Parameters
[in]run_numberNumber of the run being started
[out]errorCan be used to write a message string to midas.log

Definition at line 956 of file msysmon.cxx.

957{
958 return SUCCESS;
959}
#define SUCCESS
Definition mcstd.h:54

◆ BuildHostCPUPlot()

void BuildHostCPUPlot ( )

Definition at line 634 of file msysmon.cxx.

635{
636 //Insert per CPU graphs into the history
637 int status, size;
638 char path[256];
639 int NVARS=cpuCount;
641 // Setup variables to plot:
643 size = 64;
644 sprintf(path,"/History/Display/msysmon/%s-CPU/Variables",equipment[0].info.frontend_host);
645 {
646 char vars[size*NVARS];
647 memset(vars, 0, size*NVARS);
648#ifdef CLASSIC_CPU_VARS
649 for (int i=0; i<cpuCount; i++)
650 {
651 int icpu=i+1;
652 int h='0'+icpu/100;
653 int t='0'+(icpu%100)/10;
654 int u='0'+icpu%10;
655 if (icpu<10)
656 sprintf(vars+size*i,"%s:CPU%c[3]",equipment[0].name,u);
657 else if (icpu<100)
658 sprintf(vars+size*i,"%s:CP%c%c[3]",equipment[0].name,t,u);
659 else if (icpu<1000)
660 sprintf(vars+size*i,"%s:C%c%c%c[3]",equipment[0].name,h,t,u);
661 else
662 {
663 cm_msg(MERROR, frontend_name, "Cannot handle a system with more than 1000 CPUs");
664 exit(FE_ERR_HW);
665 }
666 }
667#else
668 for (int i=0; i<cpuCount; i++)
669 {
670 sprintf(vars+size*i,"%s:CPUA[%d]",equipment[0].name,i);
671 }
672#endif
673 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
674 }
675 assert(status == DB_SUCCESS);
676
678 // Setup labels
680 size = 32;
681 sprintf(path,"/History/Display/msysmon/%s-CPU/Label",equipment[0].info.frontend_host);
682 {
683 char vars[size*NVARS];
684 memset(vars, 0, size*NVARS);
685 for (int i=0; i<cpuCount; i++)
686 sprintf(vars+size*i,"CPU%d Load (%%)",i+1);
687 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
688 }
689 assert(status == DB_SUCCESS);
690
692 // Setup colours:
694 size = 32;
695 sprintf(path,"/History/Display/msysmon/%s-CPU/Colour",equipment[0].info.frontend_host);
696 {
697 char vars[size*NVARS];
698 memset(vars, 0, size*NVARS);
699 for (int i=0; i<NVARS; i++)
700 sprintf(vars+size*i,"%s",(colours[i%16]).c_str());
701 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
702 }
703 assert(status == DB_SUCCESS);
705 // Setup time scale and range:
707 sprintf(path,"/History/Display/msysmon/%s-CPU/Timescale",equipment[0].info.frontend_host);
708 status = db_set_value(hDB,0,path,"1h",3,1,TID_STRING);
709 double *m=new double();
710 *m=0.;
711 sprintf(path,"/History/Display/msysmon/%s-CPU/Minimum",equipment[0].info.frontend_host);
712 status = db_set_value(hDB,0,path,m,sizeof(double),1,TID_DOUBLE);
713 *m=100.;
714 sprintf(path,"/History/Display/msysmon/%s-CPU/Maximum",equipment[0].info.frontend_host);
715 status = db_set_value(hDB,0,path,m,sizeof(double),1,TID_DOUBLE);
716 delete m;
717}
#define DB_SUCCESS
Definition midas.h:631
#define FE_ERR_HW
Definition midas.h:719
#define TID_DOUBLE
Definition midas.h:343
#define TID_STRING
Definition midas.h:346
#define MERROR
Definition midas.h:559
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:915
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5261
void ** info
Definition fesimdaq.cxx:41
HNDLE hDB
main ODB handle
Definition mana.cxx:207
INT i
Definition mdump.cxx:32
#define name(x)
Definition midas_macro.h:24
std::string colours[16]
Definition msysmon.cxx:311
EQUIPMENT equipment[]
Definition msysmon.cxx:101
const char * frontend_name
Definition msysmon.cxx:62
int cpuCount
Definition msysmon.cxx:150
DWORD status
Definition odbhist.cxx:39
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ BuildHostHistoryPlot()

void BuildHostHistoryPlot ( )

Definition at line 562 of file msysmon.cxx.

563{
564 //Insert myself into the history
565
566 char path[256];
567 int status;
568 int size;
569 int NVARS=5;
570
572 // Setup variables to plot:
574 size = 64; // String length in ODB
575 sprintf(path,"/History/Display/msysmon/%s/Variables",equipment[0].info.frontend_host);
576 {
577 char vars[size*NVARS];
578 memset(vars, 0, size*NVARS);
579 sprintf(vars+size*0,"%s:LOAD[%d]",equipment[0].name,0);
580 sprintf(vars+size*1,"%s:LOAD[%d]",equipment[0].name,1);
581 sprintf(vars+size*2,"%s:LOAD[%d]",equipment[0].name,2);
582 sprintf(vars+size*3,"%s:MEMP",equipment[0].name);
583 sprintf(vars+size*4,"%s:SWAP",equipment[0].name);
584 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
585 }
586 assert(status == DB_SUCCESS);
587
589 // Setup labels
591 size = 32;
592 sprintf(path,"/History/Display/msysmon/%s/Label",equipment[0].info.frontend_host);
593 {
594 char vars[size*NVARS];
595 memset(vars, 0, size*NVARS);
596 sprintf(vars+size*0,"NICE CPU Load (%%)");
597 sprintf(vars+size*1,"USER CPU Load (%%)");
598 sprintf(vars+size*2,"SYSTEM CPU Load (%%)");
599 sprintf(vars+size*3,"Memory Usage (%%)");
600 sprintf(vars+size*4,"Swap Usage (%%)");
601 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
602 }
603 assert(status == DB_SUCCESS);
604
606 // Setup colours:
608 size = 32;
609 sprintf(path,"/History/Display/msysmon/%s/Colour",equipment[0].info.frontend_host);
610 {
611 char vars[size*NVARS];
612 memset(vars, 0, size*NVARS);
613 for (int i=0; i<NVARS; i++)
614 sprintf(vars+size*i,"%s",(colours[i%16]).c_str());
615 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
616 }
617 assert(status == DB_SUCCESS);
618
620 // Setup time scale and range:
622 sprintf(path,"/History/Display/msysmon/%s/Timescale",equipment[0].info.frontend_host);
623 status = db_set_value(hDB,0,path,"1h",3,1,TID_STRING);
624 double *m=new double();
625 *m=0.;
626 sprintf(path,"/History/Display/msysmon/%s/Minimum",equipment[0].info.frontend_host);
627 status = db_set_value(hDB,0,path,m,sizeof(double),1,TID_DOUBLE);
628 *m=100.;
629 sprintf(path,"/History/Display/msysmon/%s/Maximum",equipment[0].info.frontend_host);
630 status = db_set_value(hDB,0,path,m,sizeof(double),1,TID_DOUBLE);
631 delete m;
632}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ BuildHostNetPlot()

void BuildHostNetPlot ( )

Definition at line 719 of file msysmon.cxx.

720{
721 //Insert per CPU graphs into the history
722 int status, size;
723 char path[256];
726 // Setup variables to plot:
728 size = 64;
729 sprintf(path,"/History/Display/msysmon/%s-net/Variables",equipment[0].info.frontend_host);
730 {
731 char vars[size*NVARS];
732 memset(vars, 0, size*NVARS);
733 for (int i=0; i<networkInterfaceCount; i++)
734 sprintf(vars+size*i,"%s:NETR[%d]",equipment[0].name,i);
735 for (int i=networkInterfaceCount; i<NVARS; i++)
736 sprintf(vars+size*i,"%s:NETT[%d]",equipment[0].name,i-networkInterfaceCount);
737 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
738 }
739 assert(status == DB_SUCCESS);
740
742 // Setup labels
744 size = 32;
745 sprintf(path,"/History/Display/msysmon/%s-net/Label",equipment[0].info.frontend_host);
746 {
747 char vars[size*NVARS];
748 memset(vars, 0, size*NVARS);
749 for (int i=0; i<networkInterfaceCount; i++)
750 sprintf(vars+size*i,"%s Received (Mbps)",NetReceive.at(i)->face.c_str());
751 for (int i=networkInterfaceCount; i<NVARS; i++)
752 sprintf(vars+size*i,"%s Transmitted (Mbps)",NetReceive.at(i-networkInterfaceCount)->face.c_str());
753 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
754 }
755 assert(status == DB_SUCCESS);
756
758 // Setup colours:
760 size = 32;
761 sprintf(path,"/History/Display/msysmon/%s-net/Colour",equipment[0].info.frontend_host);
762 {
763 char vars[size*NVARS];
764 memset(vars, 0, size*NVARS);
765 for (int i=0; i<NVARS; i++)
766 sprintf(vars+size*i,"%s",(colours[i%16]).c_str());
767 status = db_set_value(hDB, 0, path, vars, size*NVARS, NVARS, TID_STRING);
768 }
769 assert(status == DB_SUCCESS);
771 // Setup time scale and range:
773 sprintf(path,"/History/Display/msysmon/%s-net/Timescale",equipment[0].info.frontend_host);
774 status = db_set_value(hDB,0,path,"1h",3,1,TID_STRING);
775 double *m=new double();
776 *m=0.;
777 sprintf(path,"/History/Display/msysmon/%s-net/Minimum",equipment[0].info.frontend_host);
778 status = db_set_value(hDB,0,path,m,sizeof(double),1,TID_DOUBLE);
779 *m=1.0/0.0; //infinity
780 sprintf(path,"/History/Display/msysmon/%s-net/Maximum",equipment[0].info.frontend_host);
781 status = db_set_value(hDB,0,path,m,sizeof(double),1,TID_DOUBLE);
782 delete m;
783}
std::vector< NetStat * > NetReceive
Definition msysmon.cxx:178
int networkInterfaceCount
Definition msysmon.cxx:177
Here is the call graph for this function:
Here is the caller graph for this function:

◆ end_of_run()

INT end_of_run ( INT  run_number,
char error 
)

End of Run.

Called every stop run transition. Set equipment status in ODB, stop acquisition on the modules.

Parameters
[in]run_numberNumber of the run being ended
[out]errorCan be used to write a message string to midas.log

Definition at line 963 of file msysmon.cxx.

964{
965 return SUCCESS;
966}

◆ frontend_exit()

INT frontend_exit ( void  )

Frontend exit.

Runs at frontend shutdown. Disconnect hardware and set equipment status in ODB

Returns
Midas status code

Definition at line 949 of file msysmon.cxx.

950{
951 return SUCCESS;
952}

◆ frontend_init()

INT frontend_init ( void  )

Frontend initialization.

Runs once at application startup. We initialize the hardware and optical interfaces and set the equipment status in ODB. We also lock the frontend to once physical cpu core.

Returns
Midas status code

Definition at line 868 of file msysmon.cxx.

869{
870 int status;
871 printf("frontend_init!\n");
872
873 FILE* file = fopen(PROCSTATFILE, "r");
874 if (file == NULL) {
875 cm_msg(MERROR, frontend_name, "Cannot open " PROCSTATFILE);
876 return FE_ERR_HW;
877 }
878 char buffer[256];
879 int Ncpus = -1;
880 do {
881 Ncpus++;
882 const char*s = fgets(buffer, 255, file);
883 if (!s) // EOF
884 break;
885 } while (String_startsWith(buffer, "cpu"));
886 fclose(file);
887 cpuCount = MAX(Ncpus - 1, 1);
888 printf("%d CPUs found\n",cpuCount);
889 //Note, cpus[0] is a total for all CPUs
890 for (int i = 0; i <= cpuCount; i++) {
891 cpus.push_back(new CPUData);
892 }
893
894 file = fopen(PROCNETSTATFILE, "r");
895 if (file == NULL) {
896 cm_msg(MERROR, frontend_name, "Cannot open " PROCNETSTATFILE);
897 return FE_ERR_HW;
898 }
899 do {
900 if (!fgets(buffer, 255, file)) break;
901 for (int i=0; i<255; i++)
902 {
903 if (!buffer[i]) break;
904 if (buffer[i]==':')
905 {
906 NetStat* r=new NetStat;
907 r->face=std::string(buffer,&buffer[i]);
908 NetReceive.push_back(r);
909
910 NetStat* t=new NetStat;
911 t->face=std::string(buffer,&buffer[i]);
912 NetTransmit.push_back(t);
913
915 }
916 }
917 } while (1);
918 fclose(file);
919 printf("%d network inferfaces found\n",networkInterfaceCount);
920
921 ReadCPUData();
922 ReadNetData();
926
927#ifdef HAVE_NVIDIA
929 InitGPU();
930#endif
931
932#ifdef HAVE_LM_SENSORS
933 if (!sensors)
934 sensors= new LM_Sensors();
935 sensors->BuildHostTemperaturePlot();
936
937#endif
938
939#ifdef RPC_JRPC
941 assert(status == SUCCESS);
942#endif
943
944 return SUCCESS;
945}
INT cm_register_function(INT id, INT(*func)(INT, void **))
Definition midas.cxx:5798
#define MAX(a, b)
Definition midas.h:509
#define RPC_JRPC
Definition mrpc.h:130
#define PROCNETSTATFILE
Definition msysmon.cxx:27
INT rpc_callback(INT index, void *prpc_param[])
Definition msysmon.cxx:536
void ReadNetData()
Definition msysmon.cxx:1096
std::vector< CPUData * > cpus
Definition msysmon.cxx:151
#define String_startsWith(s, match)
Definition msysmon.cxx:30
void ReadCPUData()
Definition msysmon.cxx:1031
void InitGPU()
void BuildHostCPUPlot()
Definition msysmon.cxx:634
void BuildHostHistoryPlot()
Definition msysmon.cxx:562
void BuildHostNetPlot()
Definition msysmon.cxx:719
std::vector< NetStat * > NetTransmit
Definition msysmon.cxx:179
#define PROCSTATFILE
Definition msysmon.cxx:19
std::string face
Definition msysmon.cxx:158
Here is the call graph for this function:

◆ frontend_loop()

INT frontend_loop ( void  )

Frontend loop.

If frontend_call_loop is true, this routine gets called when the frontend is idle or once between every event.

Returns
Midas status code

Definition at line 984 of file msysmon.cxx.

985{
986 /* if frontend_call_loop is true, this routine gets called when
987 the frontend is idle or once between every event */
988 ss_sleep(100); // don't eat all CPU
989 return SUCCESS;
990}
INT ss_sleep(INT millisec)
Definition system.cxx:3628
Here is the call graph for this function:

◆ InitGPU()

void InitGPU ( )
Here is the caller graph for this function:

◆ interrupt_configure()

INT interrupt_configure ( INT  cmd,
INT  source,
PTYPE  adr 
)

Definition at line 1013 of file msysmon.cxx.

1014{
1015 printf("interrupt_configure!\n");
1016
1017 switch(cmd)
1018 {
1020 break;
1022 break;
1024 break;
1026 break;
1027 }
1028 return SUCCESS;
1029}
#define CMD_INTERRUPT_ATTACH
Definition midas.h:822
#define CMD_INTERRUPT_DISABLE
Definition midas.h:821
#define CMD_INTERRUPT_ENABLE
Definition midas.h:820
#define CMD_INTERRUPT_DETACH
Definition midas.h:823
Here is the call graph for this function:

◆ pause_run()

INT pause_run ( INT  run_number,
char error 
)

Pause Run.

Called every pause run transition.

Parameters
[in]run_numberNumber of the run being ended
[out]errorCan be used to write a message string to midas.log
Returns
Midas status code

Definition at line 970 of file msysmon.cxx.

971{
972 return SUCCESS;
973}

◆ poll_event()

INT poll_event ( INT  source,
INT  count,
BOOL  test 
)

Definition at line 1000 of file msysmon.cxx.

1004{
1005 if (test) {
1006 ss_sleep (count);
1007 }
1008 return (0);
1009}
double count
Definition mdump.cxx:33
program test
Definition miniana.f:6
Here is the call graph for this function:

◆ read_system_load()

int read_system_load ( char pevent,
int  off 
)

Definition at line 1275 of file msysmon.cxx.

1276{
1277 bk_init32(pevent);
1278
1279 ReadCPUData();
1280
1281 ReadNetData();
1282
1283 //Calculate load:
1284 // The classic layout of CPU variables would be to log a bank for 4 doubles for each CPU core. This will not scale with very high core counts in the future
1285#ifdef CLASSIC_CPU_VARS
1286 double CPULoadTotal[4]; //nice, user, system, total
1287 for (int j=0; j<4; j++)
1288 CPULoadTotal[j]=0;
1289
1290 double CPULoad[4]; //nice, user, system, total
1291 for (int i = 0; i <= cpuCount; i++) {
1292 CPUData* cpuData = (cpus[i]);
1293 double total = (double) ( cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod);
1294 CPULoad[0] = cpuData->nicePeriod / total * 100.0;
1295 CPULoad[1] = cpuData->userPeriod / total * 100.0;
1296 CPULoad[2] = cpuData->systemPeriod / total * 100.0;
1297 CPULoad[3]=CPULoad[0]+CPULoad[1]+CPULoad[2];
1298
1299 for (int j=0; j<4; j++)
1300 {
1302 }
1303
1304 // This is a little long for just setting a bank name, but it
1305 // avoids format-truncation warnings and supports machines with upto
1306 // 1000 CPUs... another case can be put in when we reach that new limit
1307 char name[5]="LOAD";
1308 //i==0 is a total for ALL Cpus
1309 if (i!=0)
1310 {
1311 int h='0'+i/100;
1312 int t='0'+(i%100)/10;
1313 int u='0'+i%10;
1314 if (i<10)
1315 snprintf(name,5,"CPU%c",u);
1316 else if (i<100)
1317 snprintf(name,5,"CP%c%c",t,u);
1318 else if (i<1000)
1319 snprintf(name,5,"C%c%c%c",h,t,u);
1320 else
1321 cm_msg(MERROR, frontend_name, "Cannot handle a system with more than 1000 CPUs");
1322 }
1323 double* a;
1324 bk_create(pevent, name, TID_DOUBLE, (void**)&a);
1325 for (int k=0; k<4; k++)
1326 {
1327 *a=CPULoad[k];
1328 a++;
1329 }
1330 bk_close(pevent,a);
1331
1332 }
1333#else
1334 //Instead of the 'Classic' variables. Log 4 banks with N doubles, where N is the number of CPUs
1335 double CPUN[cpuCount]; // % nice time
1336 double CPUU[cpuCount]; // % user time
1337 double CPUS[cpuCount]; // % system time
1338 double CPUA[cpuCount]; // % total CPU time
1339 for (int i = 0; i <= cpuCount; i++) {
1340 CPUData* cpuData = (cpus[i]);
1341 double total = (double) ( cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod);
1342 CPUN[i] = cpuData->nicePeriod / total * 100.0;
1343 CPUU[i] = cpuData->userPeriod / total * 100.0;
1344 CPUS[i] = cpuData->systemPeriod / total * 100.0;
1345 CPUA[i] = CPUN[i]+CPUU[i]+CPUS[i];
1346 }
1347 double* c;
1348 bk_create(pevent, "CPUN", TID_DOUBLE, (void**)&c);
1349 for (int k=0; k<cpuCount; k++)
1350 {
1351 *c=CPUN[k];
1352 c++;
1353 }
1354 bk_close(pevent,c);
1355 bk_create(pevent, "CPUU", TID_DOUBLE, (void**)&c);
1356 for (int k=0; k<cpuCount; k++)
1357 {
1358 *c=CPUU[k];
1359 c++;
1360 }
1361 bk_close(pevent,c);
1362
1363 bk_create(pevent, "CPUS", TID_DOUBLE, (void**)&c);
1364 for (int k=0; k<cpuCount; k++)
1365 {
1366 *c=CPUS[k];
1367 c++;
1368 }
1369 bk_close(pevent,c);
1370
1371 bk_create(pevent, "CPUA", TID_DOUBLE, (void**)&c);
1372 for (int k=0; k<cpuCount; k++)
1373 {
1374 *c=CPUA[k];
1375 c++;
1376 }
1377 bk_close(pevent,c);
1378 double TotalLoad[4]={0};
1379 for (int k=0; k<cpuCount; k++)
1380 {
1381 TotalLoad[0]+=CPUN[k];
1382 TotalLoad[1]+=CPUU[k];
1383 TotalLoad[2]+=CPUS[k];
1384 TotalLoad[3]+=CPUA[k];
1385 }
1386 bk_create(pevent, "LOAD", TID_DOUBLE, (void**)&c);
1387 for (int k=0; k<4; k++)
1388 {
1390 c++;
1391 }
1392 bk_close(pevent,c);
1393#endif
1394
1395
1396//Read and log system temperatures
1397#ifdef HAVE_LM_SENSORS
1398 pevent = sensors->ReadAndLogSensors(pevent);
1399#endif
1400
1401 double DataRecieve;
1402 double DataTransmit;
1403
1404 double* a;
1405 char name[5]="NETR";
1406 bk_create(pevent, name, TID_DOUBLE, (void**)&a);
1407 for (int i=0; i<networkInterfaceCount; i++)
1408 {
1409 NetStat* RData = NetReceive.at(i);
1410 double Rdt=RData->tv.tv_sec + (RData->tv.tv_usec * 1e-6);
1411 DataRecieve=(double)(RData->bytesPeriod)*8./1024./1024. / Rdt; //Megabits / s
1412 *a=DataRecieve;
1413 a++;
1414 }
1415 bk_close(pevent,a);
1416
1417 double* b;
1418 sprintf(name,"NETT");
1419 bk_create(pevent, name, TID_DOUBLE, (void**)&b);
1420 for (int i=0; i<networkInterfaceCount; i++)
1421 {
1422 NetStat* SData = NetTransmit.at(i);
1423 double Sdt=SData->tv.tv_sec + (SData->tv.tv_usec * 1e-6);
1424 DataTransmit=(double)(SData->bytesPeriod)*8./1024./1024. / Sdt; //Megabits /s
1425 *b=DataTransmit;
1426 b++;
1427 }
1428 bk_close(pevent,b);
1429
1430 //Again from htop:
1431 unsigned long long int totalMem;
1432 unsigned long long int usedMem;
1433 unsigned long long int freeMem;
1434 unsigned long long int sharedMem;
1435 unsigned long long int buffersMem;
1436 unsigned long long int cachedMem;
1437 unsigned long long int totalSwap;
1438 unsigned long long int usedSwap;
1439 unsigned long long int freeSwap;
1440 FILE* file = fopen(PROCMEMINFOFILE, "r");
1441 if (file == NULL) {
1442 cm_msg(MERROR, frontend_name, "Cannot open " PROCMEMINFOFILE);
1443 }
1444 char buffer[128];
1445 while (fgets(buffer, 128, file)) {
1446 switch (buffer[0]) {
1447 case 'M':
1448 if (String_startsWith(buffer, "MemTotal:"))
1449 sscanf(buffer, "MemTotal: %32llu kB", &totalMem);
1450 else if (String_startsWith(buffer, "MemFree:"))
1451 sscanf(buffer, "MemFree: %32llu kB", &freeMem);
1452 else if (String_startsWith(buffer, "MemShared:"))
1453 sscanf(buffer, "MemShared: %32llu kB", &sharedMem);
1454 break;
1455 case 'B':
1456 if (String_startsWith(buffer, "Buffers:"))
1457 sscanf(buffer, "Buffers: %32llu kB", &buffersMem);
1458 break;
1459 case 'C':
1460 if (String_startsWith(buffer, "Cached:"))
1461 sscanf(buffer, "Cached: %32llu kB", &cachedMem);
1462 break;
1463 case 'S':
1464 if (String_startsWith(buffer, "SwapTotal:"))
1465 sscanf(buffer, "SwapTotal: %32llu kB", &totalSwap);
1466 if (String_startsWith(buffer, "SwapFree:"))
1467 sscanf(buffer, "SwapFree: %32llu kB", &freeSwap);
1468 break;
1469 }
1470 }
1471 fclose(file);
1472 //end htop code
1473
1476 double mem_percent=100.*(double)usedMem/(double)totalMem;
1477 double swap_percent=100;
1478 if (totalSwap) //If there is an swap space, calculate... else always say 100% used
1480#ifdef FE_DEBUG
1481 printf("-----------------------------\n");
1482 printf("MemUsed: %lld kB (%lld GB) (%.2f%%)\n",usedMem,usedMem/1024/1024,mem_percent);
1483 printf("SwapUsed: %lld kB (%lld GB) (%.2f%%)\n",usedSwap,usedSwap/1024/1024,swap_percent);
1484 printf("-----------------------------\n");
1485#endif
1486 double* m;
1487 bk_create(pevent, "MEMP", TID_DOUBLE, (void**)&m);
1488 *m=mem_percent;
1489 bk_close(pevent,m+1);
1490
1491 if (totalSwap) //Only log SWAP if there is any
1492 {
1493 bk_create(pevent, "SWAP", TID_DOUBLE, (void**)&m);
1494 *m=swap_percent;
1495 bk_close(pevent,m+1);
1496 }
1497
1498#if HAVE_NVIDIA
1499 ReadGPUData();
1500 int* t;
1501
1502 //GPU Temperature
1503 bk_create(pevent, "GPUT", TID_INT, (void**)&t);
1504 for (unsigned i=0; i<nGPUs; i++)
1505 {
1506 *t=GPUs[i]->temperature;
1507 t++;
1508 }
1509 bk_close(pevent,t);
1510
1511 //GPU Fan speed
1512 bk_create(pevent, "GPUF", TID_INT, (void**)&t);
1513 for (unsigned i=0; i<nGPUs; i++)
1514 {
1515 *t=GPUs[i]->fan;
1516 t++;
1517 }
1518 bk_close(pevent,t);
1519
1520 //GPU Power (W)
1521 bk_create(pevent, "GPUP", TID_INT, (void**)&t);
1522 for (unsigned i=0; i<nGPUs; i++)
1523 {
1524 *t=GPUs[i]->power_usage/1000;
1525 t++;
1526 }
1527 bk_close(pevent,t);
1528
1529 //GPU Utilisiation (%)
1530 bk_create(pevent, "GPUU", TID_INT, (void**)&t);
1531 for (unsigned i=0; i<nGPUs; i++)
1532 {
1533 *t=GPUs[i]->util.gpu;
1534 t++;
1535 }
1536 bk_close(pevent,t);
1537
1538 //GPU Memory Utilisiation (%)
1539 bk_create(pevent, "GPUM", TID_DOUBLE, (void**)&m);
1540 for (unsigned i=0; i<nGPUs; i++)
1541 {
1542 *m=100.*(double)GPUs[i]->memory.used/(double)GPUs[i]->memory.total;
1543 m++;
1544 }
1545 bk_close(pevent,m);
1546
1547#endif
1548
1549 return bk_size(pevent);
1550}
INT bk_close(void *event, void *pdata)
Definition midas.cxx:16788
void bk_init32(void *event)
Definition midas.cxx:16477
void bk_create(void *event, const char *name, WORD type, void **pdata)
Definition midas.cxx:16569
INT bk_size(const void *event)
Definition midas.cxx:16503
#define TID_INT
Definition midas.h:338
#define PROCMEMINFOFILE
Definition msysmon.cxx:23
double total[100]
Definition odbhist.cxx:42
INT j
Definition odbhist.cxx:40
INT k
Definition odbhist.cxx:40
unsigned long long int nicePeriod
Definition msysmon.cxx:143
timeval tv
Definition msysmon.cxx:175
char c
Definition system.cxx:1310
static double e(void)
Definition tinyexpr.c:136
Here is the call graph for this function:

◆ ReadCPUData()

void ReadCPUData ( )

Definition at line 1031 of file msysmon.cxx.

1032{
1033 //Largely from htop: https://github.com/hishamhm/htop (GNU licence)
1034 FILE* file = fopen(PROCSTATFILE, "r");
1035 if (file == NULL) {
1036 cm_msg(MERROR, frontend_name, "Cannot open " PROCSTATFILE);
1037 }
1038 for (int i = 0; i <= cpuCount; i++) {
1039 char buffer[256];
1040 int cpuid;
1041 unsigned long long int ioWait, irq, softIrq, steal, guest, guestnice;
1042 unsigned long long int systemalltime, idlealltime, totaltime, virtalltime;
1043 ioWait = irq = softIrq = steal = guest = guestnice = 0;
1044 // Dependending on your kernel version,
1045 // 5, 7, 8 or 9 of these fields will be set.
1046 // The rest will remain at zero.
1047 const char*s = fgets(buffer, 255, file);
1048 if (!s) // EOF
1049 break;
1050 if (i == 0)
1051 sscanf(buffer, "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
1052 else {
1053 sscanf(buffer, "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice);
1054 assert(cpuid == i - 1);
1055 }
1056 // Guest time is already accounted in usertime
1059 // Fields existing on kernels >= 2.6
1060 // (and RHEL's patched kernel 2.4...)
1065 CPUData* cpuData = cpus.at(i);
1066 cpuData->userPeriod = usertime - cpuData->userTime;
1067 cpuData->nicePeriod = nicetime - cpuData->niceTime;
1068 cpuData->systemPeriod = systemtime - cpuData->systemTime;
1069 cpuData->systemAllPeriod = systemalltime - cpuData->systemAllTime;
1070 cpuData->idleAllPeriod = idlealltime - cpuData->idleAllTime;
1071 cpuData->idlePeriod = idletime - cpuData->idleTime;
1072 cpuData->ioWaitPeriod = ioWait - cpuData->ioWaitTime;
1073 cpuData->irqPeriod = irq - cpuData->irqTime;
1074 cpuData->softIrqPeriod = softIrq - cpuData->softIrqTime;
1075 cpuData->stealPeriod = steal - cpuData->stealTime;
1076 cpuData->guestPeriod = virtalltime - cpuData->guestTime;
1077 cpuData->totalPeriod = totaltime - cpuData->totalTime;
1078 cpuData->userTime = usertime;
1079 cpuData->niceTime = nicetime;
1080 cpuData->systemTime = systemtime;
1081 cpuData->systemAllTime = systemalltime;
1082 cpuData->idleAllTime = idlealltime;
1083 cpuData->idleTime = idletime;
1084 cpuData->ioWaitTime = ioWait;
1085 cpuData->irqTime = irq;
1086 cpuData->softIrqTime = softIrq;
1087 cpuData->stealTime = steal;
1088 cpuData->guestTime = virtalltime;
1089 cpuData->totalTime = totaltime;
1090 }
1091 fclose(file);
1092 //end htop code
1093}
unsigned long long int nicetime
Definition msysmon.cxx:153
unsigned long long int idletime
Definition msysmon.cxx:153
unsigned long long int systemtime
Definition msysmon.cxx:153
unsigned long long int usertime
Definition msysmon.cxx:153
unsigned long long int userPeriod
Definition msysmon.cxx:138
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadNetData()

void ReadNetData ( )

Definition at line 1096 of file msysmon.cxx.

1097{
1098 FILE* file = fopen(PROCNETSTATFILE,"r");
1099 if (file == NULL) {
1100 cm_msg(MERROR, frontend_name, "Cannot open " PROCNETSTATFILE);
1101 }
1103 timersub(&new_tv, &old_tv, &tv);
1104 //Note, there are two title lines (hence +2)
1105 const int title_lines=2;
1106 for (int i = 0; i < networkInterfaceCount+title_lines; i++) {
1107 char buffer[256];
1108 char InterfaceName[20];
1109 unsigned long int rbytes, rpackets, rerrs, rdrop, rfifo, rframe, rcompressed, rmulticast;
1110 unsigned long int sbytes, spackets, serrs, sdrop, sfifo, sframe, scompressed, smulticast;
1111 // Dependending on your kernel version,
1112 // 5, 7, 8 or 9 of these fields will be set.
1113 // The rest will remain at zero.
1114 const char*s = fgets(buffer, 255, file);
1115 if (!s) // EOF
1116 break;
1117 if (i < 2)
1118 continue; //Title lines
1119 else
1120 sscanf(buffer, "%[^:]: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",InterfaceName, &rbytes, &rpackets, &rerrs, &rdrop, &rfifo, &rframe, &rcompressed, &rmulticast,&sbytes, &spackets, &serrs, &sdrop, &sfifo, &sframe, &scompressed, &smulticast);
1121#ifdef FE_DEBUG
1122 printf("--------------------Parsing line %d from " PROCNETSTATFILE "---------------------\n",i);
1123 printf("Intput: %s\n",buffer);
1124 printf("Output: %s: %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu %16lu\n\n",InterfaceName, rbytes, rpackets, rerrs, rdrop, rfifo, rframe, rcompressed, rmulticast,sbytes, spackets, serrs, sdrop, sfifo, sframe, scompressed, smulticast);
1125 printf("-------------------------------------------------------------------------------\n");
1126#endif
1129
1130 RData->bytesPeriod =rbytes-RData->bytes;
1131 RData->packetsPeriod =rpackets-RData->packets;
1132 RData->errsPeriod =rerrs-RData->errs;
1133 RData->dropPeriod =rdrop-RData->drop;
1134 RData->fifoPeriod =rfifo-RData->fifo;
1135 RData->framePeriod =rframe-RData->frame;
1136 RData->compressedPeriod =rcompressed-RData->compressed;
1137 RData->multicastPeriod =rmulticast-RData->multicast;
1138
1139 RData->bytes =rbytes;
1140 RData->packets =rpackets;
1141 RData->errs =rerrs;
1142 RData->drop =rdrop;
1143 RData->fifo =rfifo;
1144 RData->frame =rframe;
1145 RData->compressed =rcompressed;
1146 RData->multicast =rmulticast;
1147 RData->tv =tv;
1148
1149 SData->bytesPeriod =sbytes-SData->bytes;
1150 SData->packetsPeriod =spackets-SData->packets;
1151 SData->errsPeriod =serrs-SData->errs;
1152 SData->dropPeriod =sdrop-SData->drop;
1153 SData->fifoPeriod =sfifo-SData->fifo;
1154 SData->framePeriod =sframe-SData->frame;
1155 SData->compressedPeriod =scompressed-SData->compressed;
1156 SData->multicastPeriod =smulticast-SData->multicast;
1157
1158 SData->bytes =sbytes;
1159 SData->packets =spackets;
1160 SData->errs =serrs;
1161 SData->drop =sdrop;
1162 SData->fifo =sfifo;
1163 SData->frame =sframe;
1164 SData->compressed =scompressed;
1165 SData->multicast =smulticast;
1166 SData->tv =tv;
1167 }
1168 old_tv = new_tv;
1169 fclose(file);
1170}
int gettimeofday(struct timeval *tp, void *tzp)
timeval new_tv
Definition msysmon.cxx:1095
timeval old_tv
Definition msysmon.cxx:1095
timeval tv
Definition msysmon.cxx:1095
unsigned long int bytesPeriod
Definition msysmon.cxx:167
Here is the call graph for this function:
Here is the caller graph for this function:

◆ resume_run()

INT resume_run ( INT  run_number,
char error 
)

Resume Run.

Called every resume run transition.

Parameters
[in]run_numberNumber of the run being ended
[out]errorCan be used to write a message string to midas.log
Returns
Midas status code

Definition at line 977 of file msysmon.cxx.

978{
979 return SUCCESS;
980}

◆ rpc_callback()

INT rpc_callback ( INT  index,
void prpc_param[] 
)

Definition at line 536 of file msysmon.cxx.

537{
538 const char* cmd = CSTRING(0);
539 const char* args = CSTRING(1);
540 char* return_buf = CSTRING(2);
541 int return_max_length = CINT(3);
542
543 cm_msg(MINFO, "rpc_callback", "--------> rpc_callback: index %d, max_length %d, cmd [%s], args [%s]", index, return_max_length, cmd, args);
544
545 //int example_int = strtol(args, NULL, 0);
546 //int size = sizeof(int);
547 //int status = db_set_value(hDB, 0, "/Equipment/" EQ_NAME "/Settings/example_int", &example_int, size, 1, TID_INT);
548
549 char tmp[256];
550 time_t now = time(NULL);
551 sprintf(tmp, "{ \"current_time\" : [ %d, \"%s\"] }", (int)now, ctime(&now));
552
554
555 return RPC_SUCCESS;
556}
#define RPC_SUCCESS
Definition midas.h:698
#define MINFO
Definition midas.h:560
INT index
Definition mana.cxx:271
#define CINT(_i)
Definition midas.h:1620
#define CSTRING(_i)
Definition midas.h:1644
#define ctime
Definition msystem.h:264
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ colours

std::string colours[16]
Initial value:
={
"#00AAFF", "#FF9000", "#FF00A0", "#00C030",
"#A0C0D0", "#D0A060", "#C04010", "#807060",
"#F0C000", "#2090A0", "#D040D0", "#90B000",
"#B0B040", "#B0B0FF", "#FFA0A0", "#A0FFA0"}

Definition at line 311 of file msysmon.cxx.

311 {
312 "#00AAFF", "#FF9000", "#FF00A0", "#00C030",
313 "#A0C0D0", "#D0A060", "#C04010", "#807060",
314 "#F0C000", "#2090A0", "#D040D0", "#90B000",
315 "#B0B040", "#B0B0FF", "#FFA0A0", "#A0FFA0"};

◆ cpuCount

int cpuCount

Definition at line 150 of file msysmon.cxx.

◆ cpus

std::vector<CPUData*> cpus

Definition at line 151 of file msysmon.cxx.

◆ display_period

INT display_period = 0

Definition at line 72 of file msysmon.cxx.

◆ equipment

EQUIPMENT equipment[]
Initial value:
= {
{ "${HOSTNAME}_msysmon", {
"SYSTEM",
0,
"MIDAS",
TRUE,
10000,
0,
0,
1,
"", "", ""
},
},
{ "" }
}
#define RO_ODB
Definition midas.h:438
#define EQ_PERIODIC
Definition midas.h:414
#define RO_ALWAYS
Definition midas.h:436
#define TRUE
Definition midas.h:182
#define EVID_MONITOR
Definition msysmon.cxx:97
int read_system_load(char *pevent, int off)
Definition msysmon.cxx:1275

Definition at line 101 of file msysmon.cxx.

101 {
102
103 { "${HOSTNAME}_msysmon", /* equipment name */ {
104 EVID_MONITOR, 0, /* event ID, trigger mask */
105 "SYSTEM", /* event buffer */
106 EQ_PERIODIC, /* equipment type */
107 0, /* event source */
108 "MIDAS", /* format */
109 TRUE, /* enabled */
110 RO_ALWAYS | RO_ODB, /* Read when running */
111 10000, /* poll every so milliseconds */
112 0, /* stop run after this event limit */
113 0, /* number of sub events */
114 1, /* history period */
115 "", "", ""
116 },
117 read_system_load,/* readout routine */
118 },
119 { "" }
120};

◆ equipment_common_overwrite

BOOL equipment_common_overwrite = FALSE

Definition at line 99 of file msysmon.cxx.

◆ event_buffer_size

INT event_buffer_size = 10*1024*1024

Definition at line 79 of file msysmon.cxx.

◆ event_size

int event_size = 10*1024

Definition at line 527 of file msysmon.cxx.

◆ frontend_call_loop

BOOL frontend_call_loop = TRUE

Definition at line 68 of file msysmon.cxx.

◆ frontend_file_name

const char* frontend_file_name = __FILE__

Definition at line 65 of file msysmon.cxx.

◆ frontend_name

const char* frontend_name = "msysmon"

Definition at line 62 of file msysmon.cxx.

◆ hSet

HNDLE hSet

Definition at line 531 of file msysmon.cxx.

◆ idletime

unsigned long long int idletime

Definition at line 153 of file msysmon.cxx.

◆ max_event_size

INT max_event_size = 4*1024*1024

Definition at line 75 of file msysmon.cxx.

◆ max_event_size_frag

INT max_event_size_frag = 4*1024*1024

Definition at line 76 of file msysmon.cxx.

◆ NetReceive

std::vector<NetStat*> NetReceive

Definition at line 178 of file msysmon.cxx.

◆ NetTransmit

std::vector<NetStat*> NetTransmit

Definition at line 179 of file msysmon.cxx.

◆ networkInterfaceCount

int networkInterfaceCount =0

Definition at line 177 of file msysmon.cxx.

◆ new_tv

timeval new_tv

Definition at line 1095 of file msysmon.cxx.

◆ nicetime

unsigned long long int nicetime

Definition at line 153 of file msysmon.cxx.

◆ old_tv

timeval old_tv

Definition at line 1095 of file msysmon.cxx.

◆ systemtime

unsigned long long int systemtime

Definition at line 153 of file msysmon.cxx.

◆ test_rb_wait_sleep

int test_rb_wait_sleep = 1

Definition at line 532 of file msysmon.cxx.

◆ tv

timeval tv

Definition at line 1095 of file msysmon.cxx.

◆ usertime

unsigned long long int usertime

Definition at line 153 of file msysmon.cxx.