GpfsmonSensorGroup.cpp 4.06 KB
Newer Older
lu43jih's avatar
lu43jih committed
1
/*
lu43jih's avatar
lu43jih committed
2
 * GpfsmonSensorGroup.cpp
lu43jih's avatar
lu43jih committed
3
4
 *
 *  Created on: 26.11.2018
lu43jih's avatar
lu43jih committed
5
 *      Author: Carla Guillen
lu43jih's avatar
lu43jih committed
6
7
8
9
10
11
12
13
14
15
16
 */

#include "GpfsmonSensorGroup.h"

#include "timestamp.h"
#include <algorithm>
#include <fstream>

GpfsmonSensorGroup::GpfsmonSensorGroup(const std::string& name) :
	SensorGroupTemplate(name) {
	createTempFile();
17
	_data.resize(GPFS_METRIC::SIZE);
lu43jih's avatar
lu43jih committed
18
19
20
}

GpfsmonSensorGroup& GpfsmonSensorGroup::operator=(const GpfsmonSensorGroup& other){
lu43jih's avatar
lu43jih committed
21
        SensorGroupTemplate<GpfsmonSensorBase>::operator=(other);
22
        //no need to copy _data
lu43jih's avatar
lu43jih committed
23
        return *this;
lu43jih's avatar
lu43jih committed
24
25
26
}

GpfsmonSensorGroup::GpfsmonSensorGroup(const GpfsmonSensorGroup& other):
lu43jih's avatar
lu43jih committed
27
                SensorGroupTemplate<GpfsmonSensorBase>(other){
28
	_data.resize(GPFS_METRIC::SIZE);
lu43jih's avatar
lu43jih committed
29
30
31
}

GpfsmonSensorGroup::~GpfsmonSensorGroup() {
lu43jih's avatar
lu43jih committed
32
	_data.clear();
lu43jih's avatar
lu43jih committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
}

void GpfsmonSensorGroup::start() {
	if (_keepRunning) {
		//we have been started already
		LOG(info) << "Sensorgroup " << _groupName << " already running.";
		return;
	}

	_keepRunning = 1;
	_pendingTasks++;
	_timer->async_wait(std::bind(&GpfsmonSensorGroup::readAsync, this));
	LOG(info) << "Sensorgroup " << _groupName << " started.";
}

void GpfsmonSensorGroup::stop() {
	_keepRunning = 0;
	LOG(info) << "Sensorgroup " << _groupName << " stopped.";
}

void GpfsmonSensorGroup::read() {
	reading_t reading;
	reading.timestamp = getTimestamp();
	try {
		std::string  toparse;
lu43jih's avatar
lu43jih committed
58
		FILE *pf = popen(_cmd_io.c_str(),"r");
lu43jih's avatar
lu43jih committed
59
60
61
		if (pf != nullptr) {
			char buf[BUFFER_SIZE];
			while (fgets(buf, BUFFER_SIZE, pf) != nullptr) {
62
63
64
				if(parseLine(std::string(buf))){
					for(auto & s: _sensors){
						reading.value = _data[s->getMetricType()];
lu43jih's avatar
lu43jih committed
65
66
67
		#ifdef DEBUG
					LOG(debug) << _groupName << "::" << s->getName() << ": \"" << reading.value << "\"";
		#endif
68
						s->storeReading(reading);
lu43jih's avatar
lu43jih committed
69
					}
70
71
				} else {
					LOG(error) << "Sensorgroup" << _groupName << " could not parse line" << buf;
lu43jih's avatar
lu43jih committed
72
73
				}
			}
74
75
		} else { //assume there was a problem with the temp file
			createTempFile();
lu43jih's avatar
lu43jih committed
76
77
78
79
80
81
82
83
84
85
		}
	} catch (const std::exception& e) {
		LOG(error) << "Sensorgroup" << _groupName << " could not read value: " << e.what();
	}
}

void GpfsmonSensorGroup::readAsync() {
	uint64_t now = getTimestamp();
	read();
	if (_timer && _keepRunning) {
lu43jih's avatar
lu43jih committed
86
		_timer->expires_at(timestamp2ptime(nextReadingTime()));
lu43jih's avatar
lu43jih committed
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
		_pendingTasks++;
		_timer->async_wait(std::bind(&GpfsmonSensorGroup::readAsync, this));
	}
	_pendingTasks--;
}

void GpfsmonSensorGroup::createTempFile(){
	std::ofstream gpfsmonFile;
	gpfsmonFile.open("/tmp/gpfsmon");
	if(gpfsmonFile.is_open()){
		gpfsmonFile << "io_s\n";
		gpfsmonFile.close();
	} else {
		LOG(error) << "Gpfsmon: unable to create temporary file for mmpmon";
	}
}
lu43jih's avatar
lu43jih committed
103

104
bool GpfsmonSensorGroup::parseLine(std::string &&toparse){
lu43jih's avatar
lu43jih committed
105
106
107
108
109
110
	std::string::size_type bytereads_pos = toparse.find("_br_ ");
	std::string::size_type bytewrite_pos = toparse.find(" _bw_ ");

	if( bytereads_pos != std::string::npos && bytewrite_pos != std::string::npos){
		_data[IOBYTESREAD] = std::stoull(toparse.substr(bytereads_pos + 5, bytewrite_pos - bytereads_pos));
	} else {
111
		return false;
lu43jih's avatar
lu43jih committed
112
113
114
115
116
	}
	std::string::size_type opens_pos = toparse.find(" _oc_ ");
	if( opens_pos !=  std::string::npos ){
		_data[IOBYTESWRITE] = std::stoull(toparse.substr(bytewrite_pos + 6, opens_pos - bytewrite_pos));
	} else {
117
		return false;
lu43jih's avatar
lu43jih committed
118
119
120
121
122
	}
	std::string::size_type closes_pos = toparse.find(" _cc_ ");
	if( closes_pos !=  std::string::npos){
		_data[IOOPENS] = std::stoull(toparse.substr(opens_pos + 6, closes_pos - opens_pos));
	} else {
123
		return false;
lu43jih's avatar
lu43jih committed
124
125
126
127
128
	}
	std::string::size_type reads_pos = toparse.find(" _rdc_ ");
	if( reads_pos !=  std::string::npos ){
		_data[IOCLOSES] = std::stoull(toparse.substr(closes_pos + 6, reads_pos - closes_pos));
	} else {
129
		return false;
lu43jih's avatar
lu43jih committed
130
131
132
133
134
	}
	std::string::size_type writes_pos = toparse.find(" _wc_ ");
	if( writes_pos !=  std::string::npos ){
		_data[IOREADS] = std::stoull(toparse.substr(reads_pos + 7, writes_pos - reads_pos));
	} else {
135
		return false;
lu43jih's avatar
lu43jih committed
136
137
138
139
140
	}
	std::string::size_type dir_pos = toparse.find(" _dir_");
	if( dir_pos !=  std::string::npos ){
		_data[IOWRITES] = std::stoull(toparse.substr(writes_pos + 6, dir_pos - writes_pos));
	} else {
141
		return false;
lu43jih's avatar
lu43jih committed
142
	}
143
	return true;
lu43jih's avatar
lu43jih committed
144
}