ProcfsParser.h 4.75 KB
Newer Older
Alessio Netti's avatar
Alessio Netti committed
1
2
3
4
5
6
7
8
9
10
11
12
//
//  ProcfsParser.h
//  dcdbpusher
//
//  Created by Netti, Alessio on 15.10.18.
//  Copyright © 2018 LRZ. All rights reserved.
//

#ifndef PROCFSPARSER_H_
#define PROCFSPARSER_H_

#include "../../includes/SensorBase.h"
Alessio Netti's avatar
Alessio Netti committed
13
#include <boost/regex.hpp>
Alessio Netti's avatar
Alessio Netti committed
14
15
#include <vector>
#include <string>
Alessio Netti's avatar
Alessio Netti committed
16
#include <string.h>
Alessio Netti's avatar
Alessio Netti committed
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <exception>

/**
 * The ProcfsParser class provides an interface to parse metrics (and their values) from files in the /proc filesystem.
 *
 */
class ProcfsParser {
    
public:
    // Constructor and destructor
    ProcfsParser(std::string path);
    ~ProcfsParser();
    
    // Init/close methods
    bool init();
    virtual void close();
    
    // Setters and getters
    std::string getPath() { return this->_path; }
    void setPath(std::string new_path) { this->_path = new_path; this->close(); }
    unsigned int getNumMetrics() { return this->_numMetrics; }
    unsigned int getNumCPUs() { return this->_numCPUs; }
    
    // Public parsing methods
    std::vector<std::string> *readNames();
    std::vector<reading_t> *readMetrics();
    std::vector<short> *readCPUs();
    
protected:
    // Private parsing methods that implement all necessary logic to parse metrics' names (and associated CPU cores, if any)
    // and values. MUST be overridden by children classes
    virtual std::vector<std::string> *_readNames() { return NULL; };
    virtual std::vector<reading_t> *_readMetrics() { return NULL; };
    
    // Vectors containing the names of parsed metrics, associated CPU cores (if any), and values.
    // After initialization, _metricsNames and _metricsReadings are always non-NULL.
    // _metricsCores can be NULL if the file does not contain any CPU information (like in vmstat or meminfo)
    std::vector<std::string> *_metricsNames;
    std::vector<short> *_metricsCores;
    std::vector<reading_t> *_metricsReadings;
    
    // Internal variables
    bool _initialized;
    unsigned int _numMetrics;
    unsigned int _numCPUs;
    std::string _path;
    FILE *_metricsFile;
    char *_stringBuffer;
    size_t _chars_read;
    // C string containing the delimiters used to split single lines during parsing
    const char *LINE_SEP;
};

// **************************************************************
/**
 * The VmstatParser class allows for parsing and reading values from a /proc/vmstat file.
 *
 */
class VmstatParser : public ProcfsParser {
    
public:
    VmstatParser(const std::string path = "") : ProcfsParser(path) { this->LINE_SEP = " \t"; if(path == "") this->_path = "/proc/vmstat"; else this->_path = path; }
    
protected:
    std::vector<std::string> *_readNames() override;
    std::vector<reading_t> *_readMetrics() override;
};

// **************************************************************
/**
 * The MeminfoParser class allows for parsing and reading values from a /proc/meminfo file.
 *
 * The meminfo parser is identical to the vmstat one. The only difference lies in some tokens to be discarded
 * (the ':' after the metrics' names) which can be handled by strtok without any alteration to the code
 */
class MeminfoParser : public VmstatParser {
    
public:
    MeminfoParser(const std::string path = "") : VmstatParser(path) { this->LINE_SEP = " :\t"; if(path == "") this->_path = "/proc/meminfo"; else this->_path = path; }
};

// **************************************************************
/**
 * The ProcstatParser class allows for parsing and reading values from a /proc/stat file.
 *
 * The proc/stat parser is slightly different compared to the vmstat and meminfo ones. It provides additional logic to distinguish
 * the CPUs to which each metric belongs, and the _metricsCores vector is in this class set to a non-NULL value after initialization
 */
class ProcstatParser : public ProcfsParser {

public:
    ProcstatParser(const std::string path = "") : ProcfsParser(path) { this->LINE_SEP = " \t"; if(path == "") this->_path = "/proc/stat"; else this->_path = path; }
    
protected:
    std::vector<std::string> *_readNames() override;
    std::vector<reading_t> *_readMetrics() override;
    
    // Internal variables
    unsigned short _actualMetrics;
Alessio Netti's avatar
Alessio Netti committed
116
    boost::cmatch _match;
Alessio Netti's avatar
Alessio Netti committed
117
118
119
120
    // The number of known metrics in each "cpu" line together with their names, as of Oct. 2018
    enum { DEFAULTMETRICS = 10 };
    const std::string DEFAULT_NAMES[DEFAULTMETRICS] = {"user", "nice", "system", "idle", "iowait", "irq", "softirq", "steal", "guest", "guest_nice"};
    // Regex to match strings beginning with the "cpu" keyword
Alessio Netti's avatar
Alessio Netti committed
121
122
123
124

    // C strings that encode the prefixes of cpu-related lines
    const char *_cpu_prefix = "cpu";
    const short _cpu_prefix_len = strlen(this->_cpu_prefix);
Alessio Netti's avatar
Alessio Netti committed
125
    // Regex to match strings ending with integer numbers (in this case, CPU core IDs)
Alessio Netti's avatar
Alessio Netti committed
126
    const boost::regex reg_exp_num = boost::regex("[0-9]+$");
Alessio Netti's avatar
Alessio Netti committed
127
128
129
};

#endif /* PROCFSPARSER_H_ */