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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7b7da9cf7cc2a13ab9973f7c94b5d95eaf31c351
4
- data.tar.gz: dd9a83a80fa8ee7614900ee4be39877d26d66682
3
+ metadata.gz: 21fceb6ebc1d01718e444441471d809eb0e6ccb5
4
+ data.tar.gz: 2781fbf13fbc283b8eca04db991aaacb48fe1d1e
5
5
  SHA512:
6
- metadata.gz: 6527fe6f2b9fd4ce89a081db47b6b358cd0dbf4132543f76d1903313a8fe8849e4c440d6067f8e61ee5567396f67f290c6e903c22728b20f0d79de7293af31d7
7
- data.tar.gz: 4eb8144063b44ad94807c7134331195913294f38573c3668462f3db3666ca477f2c29609076faf5a6cac533b0fc16a1afc561298d99645cc53fbc69d51586234
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