2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

GpfsmonSensorGroup.cpp 4.81 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
 */

#include "GpfsmonSensorGroup.h"

#include "timestamp.h"
#include <algorithm>
#include <fstream>
13
#include <sys/stat.h>
lu43jih's avatar
lu43jih committed
14
15
16

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

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

GpfsmonSensorGroup::GpfsmonSensorGroup(const GpfsmonSensorGroup& other):
lu43jih's avatar
lu43jih committed
28
                SensorGroupTemplate<GpfsmonSensorBase>(other){
29
	_data.resize(GPFS_METRIC::SIZE);
30
	if(!fileExists(TMP_GPFSMON)) createTempFile();
lu43jih's avatar
lu43jih committed
31
32
33
}

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

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() {
56
	ureading_t reading;
lu43jih's avatar
lu43jih committed
57
58
59
	reading.timestamp = getTimestamp();
	try {
		std::string  toparse;
lu43jih's avatar
lu43jih committed
60
		FILE *pf = popen(_cmd_io.c_str(),"r");
lu43jih's avatar
lu43jih committed
61
62
63
		if (pf != nullptr) {
			char buf[BUFFER_SIZE];
			while (fgets(buf, BUFFER_SIZE, pf) != nullptr) {
64
65
66
				if(parseLine(std::string(buf))){
					for(auto & s: _sensors){
						reading.value = _data[s->getMetricType()];
lu43jih's avatar
lu43jih committed
67
68
69
		#ifdef DEBUG
					LOG(debug) << _groupName << "::" << s->getName() << ": \"" << reading.value << "\"";
		#endif
70
						s->storeReading(reading);
lu43jih's avatar
lu43jih committed
71
					}
72
73
				} else {
					LOG(error) << "Sensorgroup" << _groupName << " could not parse line" << buf;
74
75
					//assume there was a problem with the temp file
					if(!fileExists(TMP_GPFSMON)) createTempFile();
lu43jih's avatar
lu43jih committed
76
77
				}
			}
78
79
		} else {
			LOG(error) << "Sensorgroup" << _groupName << " popen failed, check if you have enough file descriptors.";
lu43jih's avatar
lu43jih committed
80
81
82
83
84
85
86
87
88
89
		}
	} 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
90
		_timer->expires_at(timestamp2ptime(nextReadingTime()));
lu43jih's avatar
lu43jih committed
91
92
93
94
95
96
		_pendingTasks++;
		_timer->async_wait(std::bind(&GpfsmonSensorGroup::readAsync, this));
	}
	_pendingTasks--;
}

97
void GpfsmonSensorGroup::printConfig(LOG_LEVEL ll) {
98
    LOG_VAR(ll) << "            No other specific attributes";
99
100
}

lu43jih's avatar
lu43jih committed
101
102
void GpfsmonSensorGroup::createTempFile(){
	std::ofstream gpfsmonFile;
103
	gpfsmonFile.open(TMP_GPFSMON);
lu43jih's avatar
lu43jih committed
104
105
106
107
108
109
110
	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
111

112
113
114
115
116
117
118
119
120
121
122
123
void GpfsmonSensorGroup::init(boost::asio::io_service& io) {
	SensorGroupTemplate::init(io);
	if(!fileExists(TMP_GPFSMON)) createTempFile();
	_data.resize(GPFS_METRIC::SIZE);
}

bool GpfsmonSensorGroup::fileExists(const char* filename){
	//https://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c
	struct stat buffer;
	return (stat (filename, &buffer) == 0);
}

124
bool GpfsmonSensorGroup::parseLine(std::string &&toparse){
lu43jih's avatar
lu43jih committed
125
126
127
128
	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){
129
		_data[IOBYTESREAD] = std::stoull(toparse.substr(bytereads_pos + 5, bytewrite_pos - bytereads_pos));
lu43jih's avatar
lu43jih committed
130
	} else {
131
		return false;
lu43jih's avatar
lu43jih committed
132
133
134
	}
	std::string::size_type opens_pos = toparse.find(" _oc_ ");
	if( opens_pos !=  std::string::npos ){
135
		_data[IOBYTESWRITE] = std::stoull(toparse.substr(bytewrite_pos + 6, opens_pos - bytewrite_pos));
lu43jih's avatar
lu43jih committed
136
	} else {
137
		return false;
lu43jih's avatar
lu43jih committed
138
139
140
	}
	std::string::size_type closes_pos = toparse.find(" _cc_ ");
	if( closes_pos !=  std::string::npos){
141
		_data[IOOPENS] = std::stoull(toparse.substr(opens_pos + 6, closes_pos - opens_pos));
lu43jih's avatar
lu43jih committed
142
	} else {
143
		return false;
lu43jih's avatar
lu43jih committed
144
145
146
	}
	std::string::size_type reads_pos = toparse.find(" _rdc_ ");
	if( reads_pos !=  std::string::npos ){
147
		_data[IOCLOSES] = std::stoull(toparse.substr(closes_pos + 6, reads_pos - closes_pos));
lu43jih's avatar
lu43jih committed
148
	} else {
149
		return false;
lu43jih's avatar
lu43jih committed
150
151
152
	}
	std::string::size_type writes_pos = toparse.find(" _wc_ ");
	if( writes_pos !=  std::string::npos ){
153
		_data[IOREADS] = std::stoull(toparse.substr(reads_pos + 7, writes_pos - reads_pos));
lu43jih's avatar
lu43jih committed
154
	} else {
155
		return false;
lu43jih's avatar
lu43jih committed
156
157
158
	}
	std::string::size_type dir_pos = toparse.find(" _dir_");
	if( dir_pos !=  std::string::npos ){
159
		_data[IOWRITES] = std::stoull(toparse.substr(writes_pos + 6, dir_pos - writes_pos));
lu43jih's avatar
lu43jih committed
160
	} else {
161
		return false;
lu43jih's avatar
lu43jih committed
162
	}
163
	return true;
lu43jih's avatar
lu43jih committed
164
}