pcp_easy 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/pcp_easy.rb +11 -0
- data/lib/pcp_easy/agent.rb +58 -0
- data/lib/pcp_easy/error.rb +120 -0
- data/lib/pcp_easy/metric.rb +153 -0
- data/lib/pcp_easy/metric/value.rb +19 -0
- data/lib/pcp_easy/pmapi.rb +248 -0
- data/lib/pcp_easy/pmapi/pm_atom_value.rb +49 -0
- data/lib/pcp_easy/pmapi/pm_desc.rb +49 -0
- data/lib/pcp_easy/pmapi/pm_result.rb +36 -0
- data/lib/pcp_easy/pmapi/pm_units.rb +62 -0
- data/lib/pcp_easy/pmapi/pm_value.rb +34 -0
- data/lib/pcp_easy/pmapi/pm_value_set.rb +38 -0
- data/lib/pcp_easy/pmapi/timeval.rb +16 -0
- metadata +33 -17
- data/ext/pcp_easy/agent.c +0 -117
- data/ext/pcp_easy/agent.h +0 -26
- data/ext/pcp_easy/exceptions.c +0 -213
- data/ext/pcp_easy/exceptions.h +0 -27
- data/ext/pcp_easy/extconf.rb +0 -5
- data/ext/pcp_easy/metric.c +0 -273
- data/ext/pcp_easy/metric.h +0 -28
- data/ext/pcp_easy/metric_value.c +0 -102
- data/ext/pcp_easy/metric_value.h +0 -28
- data/ext/pcp_easy/pcp_easy.c +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21fceb6ebc1d01718e444441471d809eb0e6ccb5
|
4
|
+
data.tar.gz: 2781fbf13fbc283b8eca04db991aaacb48fe1d1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 999efdb3455919f84d53a64cabeb2ae52465eb80b7163c889de09c27dbfba4137057413f3ea147a2bd82fb0beb3ca455aee67f7458f74c69d59669b82decfab0
|
7
|
+
data.tar.gz: 5a8915017b4d16586227255d48a9b38346b71ebc94c7872265416bc1e7f74efb71f3cb54542fbede0a86db07f1b40523f17f0700605dd6bfd6b04f5812c2ad84
|
data/lib/pcp_easy.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
module PCPEasy; end
|
2
|
+
require 'pcp_easy/error'
|
3
|
+
require 'pcp_easy/pmapi'
|
4
|
+
require 'pcp_easy/agent'
|
5
|
+
require 'pcp_easy/metric'
|
6
|
+
require 'pcp_easy/metric/value'
|
7
|
+
require 'pcp_easy/pmapi/pm_value_set'
|
8
|
+
require 'pcp_easy/pmapi/pm_result'
|
9
|
+
require 'pcp_easy/pmapi/pm_value'
|
10
|
+
require 'pcp_easy/pmapi/timeval'
|
11
|
+
require 'pcp_easy/pmapi/pm_atom_value'
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'pcp_easy/pmapi'
|
2
|
+
|
3
|
+
module PCPEasy
|
4
|
+
class Agent
|
5
|
+
|
6
|
+
attr_reader :host
|
7
|
+
|
8
|
+
def initialize(host)
|
9
|
+
@host = host
|
10
|
+
end
|
11
|
+
|
12
|
+
def metric(name)
|
13
|
+
metrics([name]).first
|
14
|
+
end
|
15
|
+
|
16
|
+
def metrics(names)
|
17
|
+
raise ArgumentError, "array required for metrics" unless names.is_a? Array
|
18
|
+
pmids = pmapi.pmLookupName(names)
|
19
|
+
pmids_names = Hash[pmids.zip(names)]
|
20
|
+
pmapi.pmFetch(pmids).vset.collect {|v| metric_from_vset(v, pmids_names)}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def metric_from_vset(pm_value_set, pmid_names)
|
26
|
+
pm_desc = pmapi.pmLookupDesc pm_value_set.pmid
|
27
|
+
name = pmid_names[pm_value_set.pmid]
|
28
|
+
|
29
|
+
if pm_desc.indom == PCPEasy::PMAPI::PM_INDOM_NULL
|
30
|
+
metric_values = metric_value_for_no_indom(pm_value_set, pm_desc)
|
31
|
+
else
|
32
|
+
metric_values = metric_value_for_indoms(pm_value_set, pm_desc)
|
33
|
+
end
|
34
|
+
PCPEasy::Metric.new(name, pm_desc, metric_values)
|
35
|
+
end
|
36
|
+
|
37
|
+
def metric_value_for_no_indom(pm_value_set, pm_desc)
|
38
|
+
value = pmapi.pmExtractValue(pm_value_set.valfmt, pm_desc, pm_value_set.vlist.first)
|
39
|
+
[PCPEasy::Metric::Value.new(value, nil)]
|
40
|
+
end
|
41
|
+
|
42
|
+
def metric_value_for_indoms(pm_value_set, pm_desc)
|
43
|
+
indoms = pmapi.pmGetInDom(pm_desc.indom)
|
44
|
+
pm_value_set.vlist.collect do |v|
|
45
|
+
value = pmapi.pmExtractValue(pm_value_set.valfmt, pm_desc, v)
|
46
|
+
PCPEasy::Metric::Value.new(value, indoms[v.inst])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
def pmapi
|
53
|
+
@pmapi ||= PCPEasy::PMAPI.new(@host)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'pcp_easy/pmapi'
|
2
|
+
|
3
|
+
|
4
|
+
module PCPEasy
|
5
|
+
class Error < StandardError
|
6
|
+
|
7
|
+
GenericError = Class.new(self)
|
8
|
+
PMNSError = Class.new(self)
|
9
|
+
NoPMNSError = Class.new(self)
|
10
|
+
DupPMNSError = Class.new(self)
|
11
|
+
TextError = Class.new(self)
|
12
|
+
AppVersionError = Class.new(self)
|
13
|
+
ValueError = Class.new(self)
|
14
|
+
TimeoutError = Class.new(self)
|
15
|
+
NoDataError = Class.new(self)
|
16
|
+
ResetError = Class.new(self)
|
17
|
+
NameError = Class.new(self)
|
18
|
+
PMIDError = Class.new(self)
|
19
|
+
InDomError = Class.new(self)
|
20
|
+
InstError = Class.new(self)
|
21
|
+
UnitError = Class.new(self)
|
22
|
+
ConvError = Class.new(self)
|
23
|
+
TruncError = Class.new(self)
|
24
|
+
SignError = Class.new(self)
|
25
|
+
ProfileError = Class.new(self)
|
26
|
+
IPCError = Class.new(self)
|
27
|
+
EOFError = Class.new(self)
|
28
|
+
NotHostError = Class.new(self)
|
29
|
+
EOLError = Class.new(self)
|
30
|
+
ModeError = Class.new(self)
|
31
|
+
LabelError = Class.new(self)
|
32
|
+
LogRecError = Class.new(self)
|
33
|
+
NotArchiveError = Class.new(self)
|
34
|
+
LogFileError = Class.new(self)
|
35
|
+
NoContextError = Class.new(self)
|
36
|
+
ProfileSpecError = Class.new(self)
|
37
|
+
PMIDLogError = Class.new(self)
|
38
|
+
InDomLogError = Class.new(self)
|
39
|
+
InstLogError = Class.new(self)
|
40
|
+
NoProfileError = Class.new(self)
|
41
|
+
NoAgentError = Class.new(self)
|
42
|
+
PermissionError = Class.new(self)
|
43
|
+
ConnLimitError = Class.new(self)
|
44
|
+
AgainError = Class.new(self)
|
45
|
+
IsConnError = Class.new(self)
|
46
|
+
NotConnError = Class.new(self)
|
47
|
+
NeedPortError = Class.new(self)
|
48
|
+
NonLeafError = Class.new(self)
|
49
|
+
TypeError = Class.new(self)
|
50
|
+
ThreadError = Class.new(self)
|
51
|
+
NoContainerError = Class.new(self)
|
52
|
+
BadStoreError = Class.new(self)
|
53
|
+
TooSmallError = Class.new(self)
|
54
|
+
TooBigError = Class.new(self)
|
55
|
+
FaultError = Class.new(self)
|
56
|
+
PMDAReadyError = Class.new(self)
|
57
|
+
PMDANotReadyError = Class.new(self)
|
58
|
+
NYIError = Class.new(self)
|
59
|
+
|
60
|
+
ERRORS = {
|
61
|
+
PCPEasy::PMAPI::PM_ERR_GENERIC => GenericError,
|
62
|
+
PCPEasy::PMAPI::PM_ERR_PMNS => PMNSError,
|
63
|
+
PCPEasy::PMAPI::PM_ERR_NOPMNS => NoPMNSError,
|
64
|
+
PCPEasy::PMAPI::PM_ERR_DUPPMNS=> DupPMNSError,
|
65
|
+
PCPEasy::PMAPI::PM_ERR_TEXT => TextError,
|
66
|
+
PCPEasy::PMAPI::PM_ERR_APPVERSION => AppVersionError,
|
67
|
+
PCPEasy::PMAPI::PM_ERR_VALUE => ValueError,
|
68
|
+
PCPEasy::PMAPI::PM_ERR_TIMEOUT => TimeoutError,
|
69
|
+
PCPEasy::PMAPI::PM_ERR_NODATA => NoDataError,
|
70
|
+
PCPEasy::PMAPI::PM_ERR_RESET=> ResetError,
|
71
|
+
PCPEasy::PMAPI::PM_ERR_NAME => NameError,
|
72
|
+
PCPEasy::PMAPI::PM_ERR_PMID => PMIDError,
|
73
|
+
PCPEasy::PMAPI::PM_ERR_INDOM => InDomError,
|
74
|
+
PCPEasy::PMAPI::PM_ERR_INST => InstError,
|
75
|
+
PCPEasy::PMAPI::PM_ERR_UNIT => UnitError,
|
76
|
+
PCPEasy::PMAPI::PM_ERR_CONV => ConvError,
|
77
|
+
PCPEasy::PMAPI::PM_ERR_CONV => TruncError,
|
78
|
+
PCPEasy::PMAPI::PM_ERR_SIGN => SignError,
|
79
|
+
PCPEasy::PMAPI::PM_ERR_PROFILE => ProfileError,
|
80
|
+
PCPEasy::PMAPI::PM_ERR_IPC => IPCError,
|
81
|
+
PCPEasy::PMAPI::PM_ERR_EOF => EOFError,
|
82
|
+
PCPEasy::PMAPI::PM_ERR_NOTHOST => NotHostError,
|
83
|
+
PCPEasy::PMAPI::PM_ERR_EOL => EOLError,
|
84
|
+
PCPEasy::PMAPI::PM_ERR_MODE => ModeError,
|
85
|
+
PCPEasy::PMAPI::PM_ERR_LABEL => LabelError,
|
86
|
+
PCPEasy::PMAPI::PM_ERR_LOGREC => LogRecError,
|
87
|
+
PCPEasy::PMAPI::PM_ERR_NOTARCHIVE => NotArchiveError,
|
88
|
+
PCPEasy::PMAPI::PM_ERR_LOGFILE => LogFileError,
|
89
|
+
PCPEasy::PMAPI::PM_ERR_NOCONTEXT => NoContextError,
|
90
|
+
PCPEasy::PMAPI::PM_ERR_PROFILESPEC => ProfileSpecError,
|
91
|
+
PCPEasy::PMAPI::PM_ERR_PMID_LOG => PMIDLogError,
|
92
|
+
PCPEasy::PMAPI::PM_ERR_INDOM_LOG => InDomLogError,
|
93
|
+
PCPEasy::PMAPI::PM_ERR_INST_LOG => InstLogError,
|
94
|
+
PCPEasy::PMAPI::PM_ERR_NOPROFILE => NoProfileError,
|
95
|
+
PCPEasy::PMAPI::PM_ERR_NOAGENT => NoAgentError,
|
96
|
+
PCPEasy::PMAPI::PM_ERR_PERMISSION => PermissionError,
|
97
|
+
PCPEasy::PMAPI::PM_ERR_CONNLIMIT => ConnLimitError,
|
98
|
+
PCPEasy::PMAPI::PM_ERR_AGAIN => AgainError,
|
99
|
+
PCPEasy::PMAPI::PM_ERR_ISCONN => IsConnError,
|
100
|
+
PCPEasy::PMAPI::PM_ERR_NOTCONN => NotConnError,
|
101
|
+
PCPEasy::PMAPI::PM_ERR_NEEDPORT => NeedPortError,
|
102
|
+
PCPEasy::PMAPI::PM_ERR_NONLEAF => NonLeafError,
|
103
|
+
PCPEasy::PMAPI::PM_ERR_TYPE => TypeError,
|
104
|
+
PCPEasy::PMAPI::PM_ERR_THREAD => ThreadError,
|
105
|
+
PCPEasy::PMAPI::PM_ERR_NOCONTAINER => NoContainerError,
|
106
|
+
PCPEasy::PMAPI::PM_ERR_BADSTORE => BadStoreError,
|
107
|
+
PCPEasy::PMAPI::PM_ERR_TOOSMALL => TooSmallError,
|
108
|
+
PCPEasy::PMAPI::PM_ERR_TOOBIG => TooBigError,
|
109
|
+
PCPEasy::PMAPI::PM_ERR_FAULT => FaultError,
|
110
|
+
PCPEasy::PMAPI::PM_ERR_PMDAREADY => PMDAReadyError,
|
111
|
+
PCPEasy::PMAPI::PM_ERR_PMDANOTREADY => PMDANotReadyError,
|
112
|
+
PCPEasy::PMAPI::PM_ERR_NYI => NYIError,
|
113
|
+
}
|
114
|
+
|
115
|
+
def self.from_pmapi_error_number(number)
|
116
|
+
error_class = ERRORS[number] ||= self
|
117
|
+
error_class.new PMAPI.pmErrStr(number)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'pcp_easy/pmapi'
|
2
|
+
|
3
|
+
module PCPEasy
|
4
|
+
class Metric
|
5
|
+
|
6
|
+
def initialize(name, pm_desc, metric_values)
|
7
|
+
@name = name
|
8
|
+
@pm_desc = pm_desc
|
9
|
+
@metric_values = metric_values
|
10
|
+
end
|
11
|
+
|
12
|
+
def name
|
13
|
+
@name
|
14
|
+
end
|
15
|
+
|
16
|
+
def values
|
17
|
+
@metric_values
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(other)
|
21
|
+
self.class == other.class && \
|
22
|
+
name == other.name && \
|
23
|
+
values == other.values && \
|
24
|
+
semantics == other.semantics && \
|
25
|
+
type == other.type && \
|
26
|
+
units == other.units
|
27
|
+
end
|
28
|
+
|
29
|
+
def semantics
|
30
|
+
case @pm_desc.sem
|
31
|
+
when PCPEasy::PMAPI::PM_SEM_COUNTER
|
32
|
+
:counter
|
33
|
+
when PCPEasy::PMAPI::PM_SEM_INSTANT
|
34
|
+
:instant
|
35
|
+
when PCPEasy::PMAPI::PM_SEM_DISCRETE
|
36
|
+
:discrete
|
37
|
+
else
|
38
|
+
:unknown
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def type
|
44
|
+
case @pm_desc.type
|
45
|
+
when PCPEasy::PMAPI::PM_TYPE_NOSUPPORT
|
46
|
+
:no_support
|
47
|
+
when PCPEasy::PMAPI::PM_TYPE_32
|
48
|
+
:int32
|
49
|
+
when PCPEasy::PMAPI::PM_TYPE_U32
|
50
|
+
:uint32
|
51
|
+
when PCPEasy::PMAPI::PM_TYPE_64
|
52
|
+
:int64
|
53
|
+
when PCPEasy::PMAPI::PM_TYPE_U64
|
54
|
+
:uint64
|
55
|
+
when PCPEasy::PMAPI::PM_TYPE_FLOAT
|
56
|
+
:float
|
57
|
+
when PCPEasy::PMAPI::PM_TYPE_DOUBLE
|
58
|
+
:double
|
59
|
+
when PCPEasy::PMAPI::PM_TYPE_STRING
|
60
|
+
:string
|
61
|
+
when PCPEasy::PMAPI::PM_TYPE_AGGREGATE
|
62
|
+
:aggregate
|
63
|
+
when PCPEasy::PMAPI::PM_TYPE_AGGREGATE_STATIC
|
64
|
+
:aggregate_static
|
65
|
+
when PCPEasy::PMAPI::PM_TYPE_EVENT
|
66
|
+
:event
|
67
|
+
when PCPEasy::PMAPI::PM_TYPE_HIGHRES_EVENT
|
68
|
+
:highres_event
|
69
|
+
else
|
70
|
+
:unknown
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def units
|
75
|
+
pm_units = @pm_desc.units
|
76
|
+
|
77
|
+
if pm_units.dim_space == 1 && pm_units.dim_time == 0 && pm_units.dim_count == 0
|
78
|
+
{:domain => space_unit(pm_units.scale_space), :range => nil}
|
79
|
+
elsif pm_units.dim_space == 1 && pm_units.dim_time == -1 && pm_units.dim_count == 0
|
80
|
+
{:domain => space_unit(pm_units.scale_space), :range => time_unit(pm_units.scale_time)}
|
81
|
+
elsif pm_units.dim_space == 1 && pm_units.dim_time == 0 && pm_units.dim_count == -1
|
82
|
+
{:domain => space_unit(pm_units.scale_space), :range => count_unit(pm_units.scale_count)}
|
83
|
+
|
84
|
+
elsif pm_units.dim_space == 0 && pm_units.dim_time == 1 && pm_units.dim_count == 0
|
85
|
+
{:domain => time_unit(pm_units.scale_time), :range => nil}
|
86
|
+
elsif pm_units.dim_space == -1 && pm_units.dim_time == 1 && pm_units.dim_count == 0
|
87
|
+
{:domain => time_unit(pm_units.scale_time), :range => space_unit(pm_units.scale_space)}
|
88
|
+
elsif pm_units.dim_space == 0 && pm_units.dim_time == 1 && pm_units.dim_count == -1
|
89
|
+
{:domain => time_unit(pm_units.scale_time), :range => count_unit(pm_units.scale_count)}
|
90
|
+
|
91
|
+
elsif pm_units.dim_space == 0 && pm_units.dim_time == 0 && pm_units.dim_count == 1
|
92
|
+
{:domain => count_unit(pm_units.scale_count), :range => nil}
|
93
|
+
elsif pm_units.dim_space == -1 && pm_units.dim_time == 0 && pm_units.dim_count == 1
|
94
|
+
{:domain => count_unit(pm_units.scale_count), :range => space_unit(pm_units.scale_space)}
|
95
|
+
elsif pm_units.dim_space == 0 && pm_units.dim_time == -1 && pm_units.dim_count == 1
|
96
|
+
{:domain => count_unit(pm_units.scale_count), :range => time_unit(pm_units.scale_time)}
|
97
|
+
else
|
98
|
+
{:domain => nil, :range => nil}
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def inspect
|
103
|
+
"<#{self.class.to_s} name=#{name} values=#{values} semantics=#{semantics} type=#{type} units=#{units}>"
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def count_unit(exponent)
|
109
|
+
"count#{exponent}".to_sym
|
110
|
+
end
|
111
|
+
|
112
|
+
def space_unit(unit)
|
113
|
+
case unit
|
114
|
+
when PCPEasy::PMAPI::PM_SPACE_BYTE
|
115
|
+
:bytes
|
116
|
+
when PCPEasy::PMAPI::PM_SPACE_KBYTE
|
117
|
+
:kilobytes
|
118
|
+
when PCPEasy::PMAPI::PM_SPACE_MBYTE
|
119
|
+
:megabytes
|
120
|
+
when PCPEasy::PMAPI::PM_SPACE_GBYTE
|
121
|
+
:gigabytes
|
122
|
+
when PCPEasy::PMAPI::PM_SPACE_TBYTE
|
123
|
+
:terabytes
|
124
|
+
when PCPEasy::PMAPI::PM_SPACE_PBYTE
|
125
|
+
:petabytes
|
126
|
+
when PCPEasy::PMAPI::PM_SPACE_EBYTE
|
127
|
+
:exabytes
|
128
|
+
else
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def time_unit(unit)
|
134
|
+
case unit
|
135
|
+
when PCPEasy::PMAPI::PM_TIME_NSEC
|
136
|
+
:nanoseconds
|
137
|
+
when PCPEasy::PMAPI::PM_TIME_USEC
|
138
|
+
:microseconds
|
139
|
+
when PCPEasy::PMAPI::PM_TIME_MSEC
|
140
|
+
:milliseconds
|
141
|
+
when PCPEasy::PMAPI::PM_TIME_SEC
|
142
|
+
:seconds
|
143
|
+
when PCPEasy::PMAPI::PM_TIME_MIN
|
144
|
+
:minutes
|
145
|
+
when PCPEasy::PMAPI::PM_TIME_HOUR
|
146
|
+
:hours
|
147
|
+
else
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module PCPEasy; class Metric
|
2
|
+
class Value
|
3
|
+
|
4
|
+
attr_reader :value, :instance
|
5
|
+
|
6
|
+
def initialize(value, instance)
|
7
|
+
@value = value
|
8
|
+
@instance = instance
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other)
|
12
|
+
self.class == other.class && \
|
13
|
+
value == other.value && \
|
14
|
+
instance == other.instance
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'pcp_easy/error'
|
3
|
+
require 'pcp_easy/pmapi/pm_desc'
|
4
|
+
require 'pcp_easy/pmapi/pm_result'
|
5
|
+
require 'pcp_easy/pmapi/pm_value'
|
6
|
+
require 'pcp_easy/pmapi/pm_atom_value'
|
7
|
+
|
8
|
+
module PCPEasy
|
9
|
+
module FFIInternal
|
10
|
+
extend FFI::Library
|
11
|
+
ffi_lib 'libpcp.so.3'
|
12
|
+
|
13
|
+
typedef :uint, :pmid
|
14
|
+
typedef :uint, :indom
|
15
|
+
|
16
|
+
attach_function :pmNewContext, [:int, :string], :int
|
17
|
+
attach_function :pmErrStr_r, [:int, :pointer, :int], :string
|
18
|
+
attach_function :pmUseContext, [:int], :void
|
19
|
+
attach_function :pmLookupName, [:int, :pointer, :pointer], :int
|
20
|
+
attach_function :pmLookupDesc, [:pmid, :pointer], :int
|
21
|
+
attach_function :pmDestroyContext, [:int], :int
|
22
|
+
attach_function :pmFetch, [:int, :pointer, :pointer], :int
|
23
|
+
attach_function :pmFreeResult, [:pointer], :void
|
24
|
+
attach_function :pmGetInDom, [:indom, :pointer, :pointer], :int
|
25
|
+
attach_function :pmExtractValue, [:int, PMAPI::PmValue, :int, PMAPI::PmAtomValue, :int], :int
|
26
|
+
end
|
27
|
+
module LibC
|
28
|
+
extend FFI::Library
|
29
|
+
ffi_lib FFI::Library::LIBC
|
30
|
+
attach_function :free, [:pointer], :void
|
31
|
+
end
|
32
|
+
|
33
|
+
class PMAPI
|
34
|
+
extend Forwardable
|
35
|
+
|
36
|
+
PM_CONTEXT_HOST = 1
|
37
|
+
|
38
|
+
PM_MAXERRMSGLEN = 128
|
39
|
+
|
40
|
+
PM_TYPE_NOSUPPORT = -1
|
41
|
+
PM_TYPE_32 = 0
|
42
|
+
PM_TYPE_U32 = 1
|
43
|
+
PM_TYPE_64 = 2
|
44
|
+
PM_TYPE_U64 = 3
|
45
|
+
PM_TYPE_FLOAT = 4
|
46
|
+
PM_TYPE_DOUBLE = 5
|
47
|
+
PM_TYPE_STRING = 6
|
48
|
+
PM_TYPE_AGGREGATE = 7
|
49
|
+
PM_TYPE_AGGREGATE_STATIC = 8
|
50
|
+
PM_TYPE_EVENT = 9
|
51
|
+
PM_TYPE_HIGHRES_EVENT = 10
|
52
|
+
PM_TYPE_UNKNOWN = 255
|
53
|
+
|
54
|
+
PM_VAL_INSITU = 0
|
55
|
+
PM_VAL_DPTR = 1
|
56
|
+
PM_VAL_SPTR = 2
|
57
|
+
|
58
|
+
|
59
|
+
PM_INDOM_NULL = 0xffffffff
|
60
|
+
|
61
|
+
PM_SEM_COUNTER = 1
|
62
|
+
PM_SEM_INSTANT = 3
|
63
|
+
PM_SEM_DISCRETE = 4
|
64
|
+
|
65
|
+
PM_SPACE_BYTE = 0
|
66
|
+
PM_SPACE_KBYTE = 1
|
67
|
+
PM_SPACE_MBYTE = 2
|
68
|
+
PM_SPACE_GBYTE = 3
|
69
|
+
PM_SPACE_TBYTE = 4
|
70
|
+
PM_SPACE_PBYTE = 5
|
71
|
+
PM_SPACE_EBYTE = 6
|
72
|
+
|
73
|
+
PM_TIME_NSEC = 0
|
74
|
+
PM_TIME_USEC = 1
|
75
|
+
PM_TIME_MSEC = 2
|
76
|
+
PM_TIME_SEC = 3
|
77
|
+
PM_TIME_MIN = 4
|
78
|
+
PM_TIME_HOUR = 5
|
79
|
+
|
80
|
+
PM_COUNT_ONE = 0
|
81
|
+
|
82
|
+
PM_ERR_BASE2 = 12345
|
83
|
+
PM_ERR_BASE = PM_ERR_BASE2
|
84
|
+
|
85
|
+
PM_ERR_GENERIC = (-PM_ERR_BASE-0)
|
86
|
+
PM_ERR_PMNS = (-PM_ERR_BASE-1)
|
87
|
+
PM_ERR_NOPMNS = (-PM_ERR_BASE-2)
|
88
|
+
PM_ERR_DUPPMNS = (-PM_ERR_BASE-3)
|
89
|
+
PM_ERR_TEXT = (-PM_ERR_BASE-4)
|
90
|
+
PM_ERR_APPVERSION = (-PM_ERR_BASE-5)
|
91
|
+
PM_ERR_VALUE = (-PM_ERR_BASE-6)
|
92
|
+
PM_ERR_TIMEOUT = (-PM_ERR_BASE-8)
|
93
|
+
PM_ERR_NODATA = (-PM_ERR_BASE-9)
|
94
|
+
PM_ERR_RESET = (-PM_ERR_BASE-10)
|
95
|
+
PM_ERR_NAME = (-PM_ERR_BASE-12)
|
96
|
+
PM_ERR_PMID = (-PM_ERR_BASE-13)
|
97
|
+
PM_ERR_INDOM = (-PM_ERR_BASE-14)
|
98
|
+
PM_ERR_INST = (-PM_ERR_BASE-15)
|
99
|
+
PM_ERR_UNIT = (-PM_ERR_BASE-16)
|
100
|
+
PM_ERR_CONV = (-PM_ERR_BASE-17)
|
101
|
+
PM_ERR_TRUNC = (-PM_ERR_BASE-18)
|
102
|
+
PM_ERR_SIGN = (-PM_ERR_BASE-19)
|
103
|
+
PM_ERR_PROFILE = (-PM_ERR_BASE-20)
|
104
|
+
PM_ERR_IPC = (-PM_ERR_BASE-21)
|
105
|
+
PM_ERR_EOF = (-PM_ERR_BASE-23)
|
106
|
+
PM_ERR_NOTHOST = (-PM_ERR_BASE-24)
|
107
|
+
PM_ERR_EOL = (-PM_ERR_BASE-25)
|
108
|
+
PM_ERR_MODE = (-PM_ERR_BASE-26)
|
109
|
+
PM_ERR_LABEL = (-PM_ERR_BASE-27)
|
110
|
+
PM_ERR_LOGREC = (-PM_ERR_BASE-28)
|
111
|
+
PM_ERR_NOTARCHIVE = (-PM_ERR_BASE-29)
|
112
|
+
PM_ERR_LOGFILE = (-PM_ERR_BASE-30)
|
113
|
+
PM_ERR_NOCONTEXT = (-PM_ERR_BASE-31)
|
114
|
+
PM_ERR_PROFILESPEC = (-PM_ERR_BASE-32)
|
115
|
+
PM_ERR_PMID_LOG = (-PM_ERR_BASE-33)
|
116
|
+
PM_ERR_INDOM_LOG = (-PM_ERR_BASE-34)
|
117
|
+
PM_ERR_INST_LOG = (-PM_ERR_BASE-35)
|
118
|
+
PM_ERR_NOPROFILE = (-PM_ERR_BASE-36)
|
119
|
+
PM_ERR_NOAGENT = (-PM_ERR_BASE-41)
|
120
|
+
PM_ERR_PERMISSION = (-PM_ERR_BASE-42)
|
121
|
+
PM_ERR_CONNLIMIT = (-PM_ERR_BASE-43)
|
122
|
+
PM_ERR_AGAIN = (-PM_ERR_BASE-44)
|
123
|
+
PM_ERR_ISCONN = (-PM_ERR_BASE-45)
|
124
|
+
PM_ERR_NOTCONN = (-PM_ERR_BASE-46)
|
125
|
+
PM_ERR_NEEDPORT = (-PM_ERR_BASE-47)
|
126
|
+
PM_ERR_NONLEAF = (-PM_ERR_BASE-49)
|
127
|
+
PM_ERR_TYPE = (-PM_ERR_BASE-52)
|
128
|
+
PM_ERR_THREAD = (-PM_ERR_BASE-53)
|
129
|
+
PM_ERR_NOCONTAINER = (-PM_ERR_BASE-54)
|
130
|
+
PM_ERR_BADSTORE = (-PM_ERR_BASE-55)
|
131
|
+
PM_ERR_TOOSMALL = (-PM_ERR_BASE-98)
|
132
|
+
PM_ERR_TOOBIG = (-PM_ERR_BASE-99)
|
133
|
+
PM_ERR_FAULT = (-PM_ERR_BASE-100)
|
134
|
+
PM_ERR_PMDAREADY = (-PM_ERR_BASE-1048)
|
135
|
+
PM_ERR_PMDANOTREADY = (-PM_ERR_BASE-1049)
|
136
|
+
PM_ERR_NYI = (-PM_ERR_BASE-8999)
|
137
|
+
|
138
|
+
|
139
|
+
def_delegator self, :pmExtractValue
|
140
|
+
|
141
|
+
def initialize(host)
|
142
|
+
@context = FFIInternal.pmNewContext PM_CONTEXT_HOST, host
|
143
|
+
raise PCPEasy::Error.from_pmapi_error_number(@context) if @context < 0
|
144
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(@context) )
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.pmErrStr(number)
|
148
|
+
buffer = FFI::MemoryPointer.new(:char, PM_MAXERRMSGLEN)
|
149
|
+
FFIInternal.pmErrStr_r number, buffer, PM_MAXERRMSGLEN
|
150
|
+
end
|
151
|
+
|
152
|
+
def pmLookupName(names)
|
153
|
+
pmUseContext
|
154
|
+
|
155
|
+
names_ptr = FFI::MemoryPointer.new(:pointer, names.size)
|
156
|
+
names_ptr.write_array_of_pointer names.collect {|n| FFI::MemoryPointer.from_string n}
|
157
|
+
pmid_ptr = FFI::MemoryPointer.new(:uint, names.size)
|
158
|
+
|
159
|
+
error_code = FFIInternal.pmLookupName names.size, names_ptr, pmid_ptr
|
160
|
+
raise PCPEasy::Error.from_pmapi_error_number(error_code) if error_code < 0
|
161
|
+
|
162
|
+
pmid_ptr.get_array_of_uint 0, names.size
|
163
|
+
end
|
164
|
+
|
165
|
+
def pmLookupDesc(pmid)
|
166
|
+
pmUseContext
|
167
|
+
|
168
|
+
pm_desc = PCPEasy::PMAPI::PmDesc.new
|
169
|
+
error_code = FFIInternal.pmLookupDesc(pmid, pm_desc.to_ptr)
|
170
|
+
raise PCPEasy::Error.from_pmapi_error_number(error_code) if error_code < 0
|
171
|
+
|
172
|
+
pm_desc
|
173
|
+
end
|
174
|
+
|
175
|
+
def pmFetch(pmids)
|
176
|
+
pmUseContext
|
177
|
+
|
178
|
+
pmids_ptr = FFI::MemoryPointer.new(:uint, pmids.size)
|
179
|
+
pmids_ptr.write_array_of_uint pmids
|
180
|
+
pm_result_ptr = FFI::MemoryPointer.new :pointer
|
181
|
+
|
182
|
+
error_code = FFIInternal.pmFetch(pmids.size, pmids_ptr, pm_result_ptr)
|
183
|
+
raise PCPEasy::Error.from_pmapi_error_number(error_code) if error_code < 0
|
184
|
+
|
185
|
+
pm_result_ptr = FFI::AutoPointer.new(pm_result_ptr.get_pointer(0), FFIInternal.method(:pmFreeResult))
|
186
|
+
|
187
|
+
PCPEasy::PMAPI::PmResult.new(pm_result_ptr)
|
188
|
+
end
|
189
|
+
|
190
|
+
def pmGetInDom(indom)
|
191
|
+
pmUseContext
|
192
|
+
|
193
|
+
internal_ids = FFI::MemoryPointer.new :pointer
|
194
|
+
external_names = FFI::MemoryPointer.new :pointer
|
195
|
+
|
196
|
+
error_or_num_results = FFIInternal.pmGetInDom indom, internal_ids, external_names
|
197
|
+
raise PCPEasy::Error.from_pmapi_error_number(error_or_num_results) if error_or_num_results < 0
|
198
|
+
|
199
|
+
ids = internal_ids.get_pointer(0).get_array_of_int(0, error_or_num_results)
|
200
|
+
names = external_names.get_pointer(0).get_array_of_string(0, error_or_num_results)
|
201
|
+
Hash[ids.zip(names)]
|
202
|
+
end
|
203
|
+
|
204
|
+
def self.pmExtractValue(value_format, pm_desc, pm_value)
|
205
|
+
|
206
|
+
atom = PCPEasy::PMAPI::PmAtomValue.new
|
207
|
+
error_code = FFIInternal.pmExtractValue(value_format, pm_value.pointer, pm_desc.type, atom.pointer, pm_desc.type)
|
208
|
+
raise PCPEasy::Error.from_pmapi_error_number(error_code) if error_code < 0
|
209
|
+
|
210
|
+
case pm_desc.type
|
211
|
+
when PM_TYPE_32
|
212
|
+
atom.l
|
213
|
+
when PM_TYPE_U32
|
214
|
+
atom.ul
|
215
|
+
when PM_TYPE_64
|
216
|
+
atom.ll
|
217
|
+
when PM_TYPE_U64
|
218
|
+
atom.ull
|
219
|
+
when PM_TYPE_FLOAT
|
220
|
+
atom.f
|
221
|
+
when PM_TYPE_DOUBLE
|
222
|
+
atom.d
|
223
|
+
when PM_TYPE_STRING
|
224
|
+
str = atom.cp.read_string
|
225
|
+
LibC.free(atom.cp) if atom.cp
|
226
|
+
str
|
227
|
+
when PM_TYPE_AGGREGATE || PM_TYPE_EVENT || PM_TYPE_HIGHRES_EVENT
|
228
|
+
# No support, make sure we free the pointer
|
229
|
+
LibC.free(atom.vbp) if atom.vbp
|
230
|
+
raise PCPEasy::Error.new "Metric type #{pm_desc.type} not supported"
|
231
|
+
else
|
232
|
+
raise ArgumentError.new "Type #{pm_desc.type} not valid"
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
private
|
237
|
+
|
238
|
+
def pmUseContext
|
239
|
+
FFIInternal.pmUseContext @context
|
240
|
+
end
|
241
|
+
|
242
|
+
def self.finalize(context)
|
243
|
+
proc { FFIInternal.pmDestroyContext(context) }
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
end
|