pcp_easy 0.0.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4b614f442db11a712d65f2ecba4018eac61894f9
4
+ data.tar.gz: 16f2c37d9769f45b5039bf711d3d5bb60cdfc9c5
5
+ SHA512:
6
+ metadata.gz: f0b87a279801efb5a6073024660258b197c06ad905b4354bd0af06cd7f4c49268e9764b7b4b5fdd1ae77237be0c22cfb9ed16b6e02c0d9f6d27999cbc21c601d
7
+ data.tar.gz: 6b632132c7978506d09bd5db674534e765ddc171fc4dcd6bc5674c336f1e5d7ec452aad424ad7d195431ba7e971896be440f0034288e28fe6976849ad52121fc
@@ -0,0 +1,213 @@
1
+ /*
2
+ * Copyright (C) 2016 Ryan Doyle
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ *
17
+ */
18
+
19
+ #include "exceptions.h"
20
+
21
+ #include <ruby.h>
22
+ #include <pcp/pmapi.h>
23
+
24
+ /* Error classes */
25
+ VALUE pcpeasy_error = Qnil;
26
+ VALUE pcpeasy_pmns_error = Qnil;
27
+ VALUE pcpeasy_no_pmns_error = Qnil;
28
+ VALUE pcpeasy_dup_pmns_error = Qnil;
29
+ VALUE pcpeasy_text_error = Qnil;
30
+ VALUE pcpeasy_app_version_error = Qnil;
31
+ VALUE pcpeasy_value_error = Qnil;
32
+ VALUE pcpeasy_timeout_error = Qnil;
33
+ VALUE pcpeasy_no_data_error = Qnil;
34
+ VALUE pcpeasy_reset_error = Qnil;
35
+ VALUE pcpeasy_name_error = Qnil;
36
+ VALUE pcpeasy_pmid_error = Qnil;
37
+ VALUE pcpeasy_indom_error = Qnil;
38
+ VALUE pcpeasy_inst_error = Qnil;
39
+ VALUE pcpeasy_unit_error = Qnil;
40
+ VALUE pcpeasy_conv_error = Qnil;
41
+ VALUE pcpeasy_trunc_error = Qnil;
42
+ VALUE pcpeasy_sign_error = Qnil;
43
+ VALUE pcpeasy_profile_error = Qnil;
44
+ VALUE pcpeasy_ipc_error = Qnil;
45
+ VALUE pcpeasy_eof_error = Qnil;
46
+ VALUE pcpeasy_not_host_error = Qnil;
47
+ VALUE pcpeasy_eol_error = Qnil;
48
+ VALUE pcpeasy_mode_error = Qnil;
49
+ VALUE pcpeasy_label_error = Qnil;
50
+ VALUE pcpeasy_log_rec_error = Qnil;
51
+ VALUE pcpeasy_not_archive_error = Qnil;
52
+ VALUE pcpeasy_log_file_error = Qnil;
53
+ VALUE pcpeasy_no_context_error = Qnil;
54
+ VALUE pcpeasy_profile_spec_error = Qnil;
55
+ VALUE pcpeasy_pmid_log_error = Qnil;
56
+ VALUE pcpeasy_indom_log_error = Qnil;
57
+ VALUE pcpeasy_inst_log_error = Qnil;
58
+ VALUE pcpeasy_no_profile_error = Qnil;
59
+ VALUE pcpeasy_no_agent_error = Qnil;
60
+ VALUE pcpeasy_permission_error = Qnil;
61
+ VALUE pcpeasy_connlimit_error = Qnil;
62
+ VALUE pcpeasy_again_error = Qnil;
63
+ VALUE pcpeasy_is_conn_error = Qnil;
64
+ VALUE pcpeasy_not_conn_error = Qnil;
65
+ VALUE pcpeasy_need_port_error = Qnil;
66
+ VALUE pcpeasy_non_leaf_error = Qnil;
67
+ VALUE pcpeasy_type_error = Qnil;
68
+ VALUE pcpeasy_thread_error = Qnil;
69
+ VALUE pcpeasy_no_container_error = Qnil;
70
+ VALUE pcpeasy_bad_store_error = Qnil;
71
+ VALUE pcpeasy_too_small_error = Qnil;
72
+ VALUE pcpeasy_too_big_error = Qnil;
73
+ VALUE pcpeasy_fault_error = Qnil;
74
+ VALUE pcpeasy_pmda_ready_error = Qnil;
75
+ VALUE pcpeasy_pmda_not_ready_error = Qnil;
76
+ VALUE pcpeasy_nyi_error = Qnil;
77
+
78
+
79
+ static const struct pmapi_to_ruby_exception {
80
+ int pmapi_error;
81
+ VALUE *ruby_exception;
82
+ } pmapi_to_ruby_exception_map[] = {
83
+ {PM_ERR_GENERIC, &pcpeasy_error},
84
+ {PM_ERR_PMNS, &pcpeasy_pmns_error},
85
+ {PM_ERR_NOPMNS, &pcpeasy_no_pmns_error},
86
+ {PM_ERR_DUPPMNS, &pcpeasy_dup_pmns_error},
87
+ {PM_ERR_TEXT, &pcpeasy_text_error},
88
+ {PM_ERR_APPVERSION, &pcpeasy_app_version_error},
89
+ {PM_ERR_VALUE, &pcpeasy_value_error},
90
+ {PM_ERR_TIMEOUT, &pcpeasy_timeout_error},
91
+ {PM_ERR_NODATA, &pcpeasy_no_data_error},
92
+ {PM_ERR_RESET, &pcpeasy_reset_error},
93
+ {PM_ERR_NAME, &pcpeasy_name_error},
94
+ {PM_ERR_PMID, &pcpeasy_pmid_error},
95
+ {PM_ERR_INDOM, &pcpeasy_indom_error},
96
+ {PM_ERR_INST, &pcpeasy_inst_error},
97
+ {PM_ERR_UNIT, &pcpeasy_unit_error},
98
+ {PM_ERR_CONV, &pcpeasy_conv_error},
99
+ {PM_ERR_TRUNC, &pcpeasy_trunc_error},
100
+ {PM_ERR_SIGN, &pcpeasy_sign_error},
101
+ {PM_ERR_PROFILE, &pcpeasy_profile_error},
102
+ {PM_ERR_IPC, &pcpeasy_ipc_error},
103
+ {PM_ERR_EOF, &pcpeasy_eof_error},
104
+ {PM_ERR_NOTHOST, &pcpeasy_not_host_error},
105
+ {PM_ERR_EOL, &pcpeasy_eol_error},
106
+ {PM_ERR_MODE, &pcpeasy_mode_error},
107
+ {PM_ERR_LABEL, &pcpeasy_label_error},
108
+ {PM_ERR_LOGREC, &pcpeasy_log_rec_error},
109
+ {PM_ERR_NOTARCHIVE, &pcpeasy_not_archive_error},
110
+ {PM_ERR_LOGFILE, &pcpeasy_log_file_error},
111
+ {PM_ERR_NOCONTEXT, &pcpeasy_no_context_error},
112
+ {PM_ERR_PROFILESPEC, &pcpeasy_profile_spec_error},
113
+ {PM_ERR_PMID_LOG, &pcpeasy_pmid_log_error},
114
+ {PM_ERR_INDOM_LOG, &pcpeasy_indom_log_error},
115
+ {PM_ERR_INST_LOG, &pcpeasy_inst_log_error},
116
+ {PM_ERR_NOPROFILE, &pcpeasy_no_profile_error},
117
+ {PM_ERR_NOAGENT, &pcpeasy_no_agent_error},
118
+ {PM_ERR_PERMISSION, &pcpeasy_permission_error},
119
+ {PM_ERR_CONNLIMIT, &pcpeasy_connlimit_error},
120
+ {PM_ERR_AGAIN, &pcpeasy_again_error},
121
+ {PM_ERR_ISCONN, &pcpeasy_is_conn_error},
122
+ {PM_ERR_NOTCONN, &pcpeasy_not_conn_error},
123
+ {PM_ERR_NEEDPORT, &pcpeasy_need_port_error},
124
+ {PM_ERR_NONLEAF, &pcpeasy_non_leaf_error},
125
+ {PM_ERR_TYPE, &pcpeasy_type_error},
126
+ {PM_ERR_THREAD, &pcpeasy_thread_error},
127
+ {PM_ERR_NOCONTAINER, &pcpeasy_no_container_error},
128
+ {PM_ERR_BADSTORE, &pcpeasy_bad_store_error},
129
+ {PM_ERR_TOOSMALL, &pcpeasy_too_small_error},
130
+ {PM_ERR_TOOBIG, &pcpeasy_too_big_error},
131
+ {PM_ERR_FAULT, &pcpeasy_fault_error},
132
+ {PM_ERR_PMDAREADY, &pcpeasy_pmda_ready_error},
133
+ {PM_ERR_PMDANOTREADY, &pcpeasy_pmda_not_ready_error},
134
+ {PM_ERR_NYI, &pcpeasy_nyi_error},
135
+ };
136
+
137
+ static VALUE get_exception_from_pmapi_error_code(int error_code) {
138
+ int i, number_of_pmapi_to_ruby_errors;
139
+ number_of_pmapi_to_ruby_errors = sizeof(pmapi_to_ruby_exception_map) / sizeof(struct pmapi_to_ruby_exception);
140
+
141
+ for(i=0; i < number_of_pmapi_to_ruby_errors; i++) {
142
+ if(pmapi_to_ruby_exception_map[i].pmapi_error == error_code) {
143
+ return *pmapi_to_ruby_exception_map[i].ruby_exception;
144
+ }
145
+ }
146
+ /* Default to a generic error */
147
+ return pcpeasy_error;
148
+ }
149
+
150
+ void pcpeasy_raise_from_pmapi_error(int error_number) {
151
+ char errmsg[PM_MAXERRMSGLEN];
152
+ VALUE exception_to_raise;
153
+
154
+ exception_to_raise = get_exception_from_pmapi_error_code(error_number);
155
+
156
+ rb_raise(exception_to_raise, (const char *)pmErrStr_r(error_number, (char *)&errmsg, sizeof(errmsg)));
157
+ }
158
+
159
+
160
+ void pcpeasy_exceptions_init(VALUE pcpeasy_class) {
161
+ pcpeasy_error = rb_define_class_under(pcpeasy_class, "Error", rb_eStandardError);
162
+ pcpeasy_pmns_error = rb_define_class_under(pcpeasy_class, "PMNSError", pcpeasy_error);
163
+ pcpeasy_no_pmns_error = rb_define_class_under(pcpeasy_class, "NoPMNSError", pcpeasy_error);
164
+ pcpeasy_dup_pmns_error = rb_define_class_under(pcpeasy_class, "DupPMNSError", pcpeasy_error);
165
+ pcpeasy_text_error = rb_define_class_under(pcpeasy_class, "TextError", pcpeasy_error);
166
+ pcpeasy_app_version_error = rb_define_class_under(pcpeasy_class, "AppVersionError", pcpeasy_error);
167
+ pcpeasy_value_error = rb_define_class_under(pcpeasy_class, "ValueError", pcpeasy_error);
168
+ pcpeasy_timeout_error = rb_define_class_under(pcpeasy_class, "TimeoutError", pcpeasy_error);
169
+ pcpeasy_no_data_error = rb_define_class_under(pcpeasy_class, "NoDataError", pcpeasy_error);
170
+ pcpeasy_reset_error = rb_define_class_under(pcpeasy_class, "ResetError", pcpeasy_error);
171
+ pcpeasy_name_error = rb_define_class_under(pcpeasy_class, "NameError", pcpeasy_error);
172
+ pcpeasy_pmid_error = rb_define_class_under(pcpeasy_class, "PMIDError", pcpeasy_error);
173
+ pcpeasy_indom_error = rb_define_class_under(pcpeasy_class, "InDomError", pcpeasy_error);
174
+ pcpeasy_inst_error = rb_define_class_under(pcpeasy_class, "InstError", pcpeasy_error);
175
+ pcpeasy_unit_error = rb_define_class_under(pcpeasy_class, "UnitError", pcpeasy_error);
176
+ pcpeasy_conv_error = rb_define_class_under(pcpeasy_class, "ConvError", pcpeasy_error);
177
+ pcpeasy_trunc_error = rb_define_class_under(pcpeasy_class, "TruncError", pcpeasy_error);
178
+ pcpeasy_sign_error = rb_define_class_under(pcpeasy_class, "SignError", pcpeasy_error);
179
+ pcpeasy_profile_error = rb_define_class_under(pcpeasy_class, "ProfileError", pcpeasy_error);
180
+ pcpeasy_ipc_error = rb_define_class_under(pcpeasy_class, "IPCError", pcpeasy_error);
181
+ pcpeasy_eof_error = rb_define_class_under(pcpeasy_class, "EOFError", pcpeasy_error);
182
+ pcpeasy_not_host_error = rb_define_class_under(pcpeasy_class, "NotHostError", pcpeasy_error);
183
+ pcpeasy_eol_error = rb_define_class_under(pcpeasy_class, "EOLError", pcpeasy_error);
184
+ pcpeasy_mode_error = rb_define_class_under(pcpeasy_class, "ModeError", pcpeasy_error);
185
+ pcpeasy_label_error = rb_define_class_under(pcpeasy_class, "LabelError", pcpeasy_error);
186
+ pcpeasy_log_rec_error = rb_define_class_under(pcpeasy_class, "LogRecError", pcpeasy_error);
187
+ pcpeasy_not_archive_error = rb_define_class_under(pcpeasy_class, "NotArchiveError", pcpeasy_error);
188
+ pcpeasy_log_file_error = rb_define_class_under(pcpeasy_class, "LogFileError", pcpeasy_error);
189
+ pcpeasy_no_context_error = rb_define_class_under(pcpeasy_class, "NoContextError", pcpeasy_error);
190
+ pcpeasy_profile_spec_error = rb_define_class_under(pcpeasy_class, "ProfileSpecError", pcpeasy_error);
191
+ pcpeasy_pmid_log_error = rb_define_class_under(pcpeasy_class, "PMIDLogError", pcpeasy_error);
192
+ pcpeasy_indom_log_error = rb_define_class_under(pcpeasy_class, "InDomLogError", pcpeasy_error);
193
+ pcpeasy_inst_log_error = rb_define_class_under(pcpeasy_class, "InstLogError", pcpeasy_error);
194
+ pcpeasy_no_profile_error = rb_define_class_under(pcpeasy_class, "NoProfileError", pcpeasy_error);
195
+ pcpeasy_no_agent_error = rb_define_class_under(pcpeasy_class, "NoAgentError", pcpeasy_error);
196
+ pcpeasy_permission_error = rb_define_class_under(pcpeasy_class, "PermissionError", pcpeasy_error);
197
+ pcpeasy_connlimit_error = rb_define_class_under(pcpeasy_class, "ConnLimitError", pcpeasy_error);
198
+ pcpeasy_again_error = rb_define_class_under(pcpeasy_class, "AgainError", pcpeasy_error);
199
+ pcpeasy_is_conn_error = rb_define_class_under(pcpeasy_class, "IsConnError", pcpeasy_error);
200
+ pcpeasy_not_conn_error = rb_define_class_under(pcpeasy_class, "NotConnError", pcpeasy_error);
201
+ pcpeasy_need_port_error = rb_define_class_under(pcpeasy_class, "NeedPortError", pcpeasy_error);
202
+ pcpeasy_non_leaf_error = rb_define_class_under(pcpeasy_class, "NonLeafError", pcpeasy_error);
203
+ pcpeasy_type_error = rb_define_class_under(pcpeasy_class, "TypeError", pcpeasy_error);
204
+ pcpeasy_thread_error = rb_define_class_under(pcpeasy_class, "ThreadError", pcpeasy_error);
205
+ pcpeasy_no_container_error = rb_define_class_under(pcpeasy_class, "NoContainerError", pcpeasy_error);
206
+ pcpeasy_bad_store_error = rb_define_class_under(pcpeasy_class, "BadStoreError", pcpeasy_error);
207
+ pcpeasy_too_small_error = rb_define_class_under(pcpeasy_class, "TooSmallError", pcpeasy_error);
208
+ pcpeasy_too_big_error = rb_define_class_under(pcpeasy_class, "TooBigError", pcpeasy_error);
209
+ pcpeasy_fault_error = rb_define_class_under(pcpeasy_class, "FaultError", pcpeasy_error);
210
+ pcpeasy_pmda_ready_error = rb_define_class_under(pcpeasy_class, "PMDAReadyError", pcpeasy_error);
211
+ pcpeasy_pmda_not_ready_error = rb_define_class_under(pcpeasy_class, "PMDANotReadyError", pcpeasy_error);
212
+ pcpeasy_nyi_error = rb_define_class_under(pcpeasy_class, "NYIError", pcpeasy_error);
213
+ }
@@ -0,0 +1,27 @@
1
+ /*
2
+ * Copyright (C) 2016 Ryan Doyle
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ *
17
+ */
18
+
19
+ #ifndef PCPEASY_RUBY_EXCEPTIONS_H
20
+ #define PCPEASY_RUBY_EXCEPTIONS_H 1
21
+
22
+ #include <ruby.h>
23
+ VALUE pcpeasy_error;
24
+ void pcpeasy_exceptions_init(VALUE pcpeasy_class);
25
+ void pcpeasy_raise_from_pmapi_error(int error_number);
26
+
27
+ #endif
@@ -0,0 +1,5 @@
1
+ require 'mkmf'
2
+ extension_name = 'pcp_easy'
3
+ asplode('pcp') unless find_library('pcp', 'pmNewContext')
4
+ dir_config(extension_name)
5
+ create_makefile(extension_name)
@@ -0,0 +1,133 @@
1
+ /*
2
+ * Copyright (C) 2016 Ryan Doyle
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ *
17
+ */
18
+
19
+ #include <ruby.h>
20
+ #include <pcp/pmapi.h>
21
+
22
+ #include "exceptions.h"
23
+
24
+ #define READ_ONLY 1, 0
25
+ #define CONSTRUCTOR_ARGS 4
26
+
27
+ VALUE pcpeasy_metric_class;
28
+ VALUE pcpeasy_metric_semantics_counter;
29
+ VALUE pcpeasy_metric_semantics_instant;
30
+ VALUE pcpeasy_metric_semantics_discrete;
31
+ VALUE pcpeasy_metric_semantics_unknown;
32
+
33
+ static VALUE initialize(VALUE self, VALUE name, VALUE value, VALUE instance, VALUE semantics) {
34
+ rb_iv_set(self, "@name", name);
35
+ rb_iv_set(self, "@value", value);
36
+ rb_iv_set(self, "@instance", instance);
37
+ rb_iv_set(self, "@semantics", semantics);
38
+
39
+ return self;
40
+ }
41
+
42
+ static VALUE semantics_symbol(int semantics) {
43
+ switch(semantics) {
44
+ case PM_SEM_COUNTER:
45
+ return pcpeasy_metric_semantics_counter;
46
+ case PM_SEM_DISCRETE:
47
+ return pcpeasy_metric_semantics_discrete;
48
+ case PM_SEM_INSTANT:
49
+ return pcpeasy_metric_semantics_instant;
50
+ default:
51
+ return pcpeasy_metric_semantics_unknown;
52
+ }
53
+ }
54
+
55
+ static VALUE instance_name(char *instance) {
56
+ if(instance == NULL) {
57
+ return Qnil;
58
+ }
59
+ return rb_tainted_str_new_cstr(instance);
60
+ }
61
+
62
+ static VALUE value(int value_format, pmValue *pm_value, int type) {
63
+ pmAtomValue pm_atom_value;
64
+ int error;
65
+
66
+ if((error = pmExtractValue(value_format, pm_value, type, &pm_atom_value, type)) < 0) {
67
+ pcpeasy_raise_from_pmapi_error(error);
68
+ }
69
+
70
+ switch(type) {
71
+ case PM_TYPE_32:
72
+ return LONG2NUM(pm_atom_value.l);
73
+ case PM_TYPE_U32:
74
+ return ULONG2NUM(pm_atom_value.ul);
75
+ case PM_TYPE_64:
76
+ return LL2NUM(pm_atom_value.ll);
77
+ case PM_TYPE_U64:
78
+ return ULL2NUM(pm_atom_value.ull);
79
+ case PM_TYPE_FLOAT:
80
+ return DBL2NUM(pm_atom_value.f);
81
+ case PM_TYPE_DOUBLE:
82
+ return DBL2NUM(pm_atom_value.d);
83
+ case PM_TYPE_STRING:
84
+ return rb_tainted_str_new_cstr(pm_atom_value.vbp->vbuf);
85
+ default:
86
+ rb_raise(pcpeasy_error, "Metric type %d not supported", type);
87
+ }
88
+ }
89
+
90
+ static int is_field_equal(const char *name, VALUE self, VALUE other) {
91
+ return TYPE(rb_funcall(rb_iv_get(self, name), rb_intern("=="), 1, rb_iv_get(other, name))) == T_TRUE;
92
+ }
93
+
94
+ static VALUE equal(VALUE self, VALUE other) {
95
+ if(rb_class_of(other) != pcpeasy_metric_class)
96
+ return Qfalse;
97
+ if(!is_field_equal("@name", self, other))
98
+ return Qfalse;
99
+ if(!is_field_equal("@value", self, other))
100
+ return Qfalse;
101
+ if(!is_field_equal("@instance", self, other))
102
+ return Qfalse;
103
+ if(!is_field_equal("@semantics", self, other))
104
+ return Qfalse;
105
+
106
+ return Qtrue;
107
+ }
108
+
109
+ VALUE pcpeasy_metric_new(char *metric_name, char *instance, pmValue *pm_value, pmDesc *pm_desc, int value_format) {
110
+ VALUE args[CONSTRUCTOR_ARGS];
111
+ args[0] = rb_tainted_str_new_cstr(metric_name);
112
+ args[1] = value(value_format, pm_value, pm_desc->type);
113
+ args[2] = instance_name(instance);
114
+ args[3] = semantics_symbol(pm_desc->sem);
115
+
116
+ return rb_class_new_instance(CONSTRUCTOR_ARGS, args, pcpeasy_metric_class);
117
+ }
118
+
119
+ void pcpeasy_metric_init(VALUE pcpeasy_class) {
120
+ pcpeasy_metric_class = rb_define_class_under(pcpeasy_class, "Metric", rb_cObject);
121
+
122
+ pcpeasy_metric_semantics_counter = ID2SYM(rb_intern("counter"));
123
+ pcpeasy_metric_semantics_discrete = ID2SYM(rb_intern("discrete"));
124
+ pcpeasy_metric_semantics_instant = ID2SYM(rb_intern("instant"));
125
+ pcpeasy_metric_semantics_unknown = ID2SYM(rb_intern("unknown"));
126
+
127
+ rb_define_method(pcpeasy_metric_class, "initialize", initialize, CONSTRUCTOR_ARGS);
128
+ rb_define_method(pcpeasy_metric_class, "==", equal, 1);
129
+ rb_define_attr(pcpeasy_metric_class, "name", READ_ONLY);
130
+ rb_define_attr(pcpeasy_metric_class, "value", READ_ONLY);
131
+ rb_define_attr(pcpeasy_metric_class, "instance", READ_ONLY);
132
+ rb_define_attr(pcpeasy_metric_class, "semantics", READ_ONLY);
133
+ }
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (C) 2016 Ryan Doyle
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ *
17
+ */
18
+
19
+ #ifndef PCPEASY_RUBY_METRIC_H
20
+ #define PCPEASY_RUBY_METRIC_H 1
21
+
22
+ #include <ruby.h>
23
+ #include <pcp/pmapi.h>
24
+
25
+ void pcpeasy_metric_init(VALUE pcpeasy_class);
26
+ VALUE pcpeasy_metric_new(char *metric_name, char *instance, pmValue *pm_value, pmDesc *pm_desc, int value_format);
27
+
28
+ #endif
@@ -0,0 +1,181 @@
1
+ /*
2
+ * Copyright (C) 2016 Ryan Doyle
3
+ *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License as published by
6
+ * the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+ *
17
+ */
18
+
19
+ #include <ruby.h>
20
+ #include <pcp/pmapi.h>
21
+
22
+ #include "exceptions.h"
23
+ #include "metric.h"
24
+
25
+ VALUE pcpeasy_class = Qnil;
26
+ VALUE pcpeasy_agent_class = Qnil;
27
+
28
+
29
+ typedef struct {
30
+ int pm_context;
31
+ } PcpEasyAgent;
32
+
33
+ static void pcpeasy_agent_deallocate(void *untyped_pcpeasy_agent) {
34
+ PcpEasyAgent *pcpqz_agent = (PcpEasyAgent*)untyped_pcpeasy_agent;
35
+ pmDestroyContext(pcpqz_agent->pm_context);
36
+ xfree(pcpqz_agent);
37
+ }
38
+
39
+ static VALUE pcpeasy_agent_allocate(VALUE self) {
40
+ PcpEasyAgent *pcpeasy_agent;
41
+ return Data_Make_Struct(self, PcpEasyAgent, 0, pcpeasy_agent_deallocate, pcpeasy_agent);
42
+ };
43
+
44
+ static VALUE pcpeasy_agent_initialize(VALUE self, VALUE hostname_rb) {
45
+ PcpEasyAgent *pcpeasy_agent;
46
+ const char *hostname;
47
+ int pm_context;
48
+
49
+ Data_Get_Struct(self, PcpEasyAgent, pcpeasy_agent);
50
+ hostname = StringValueCStr(hostname_rb);
51
+
52
+ if((pm_context = pmNewContext(PM_CONTEXT_HOST, hostname)) < 0) {
53
+ pcpeasy_raise_from_pmapi_error(pm_context);
54
+ }
55
+
56
+ rb_iv_set(self, "@host", hostname_rb);
57
+
58
+ /* Store away with this instance */
59
+ pcpeasy_agent->pm_context = pm_context;
60
+
61
+ return self;
62
+ }
63
+
64
+ static char* get_name_from_instance_id(int instance_id, int maximum_instances, int *instance_ids, char **instance_names) {
65
+ int i;
66
+ for(i=0; i<maximum_instances; i++) {
67
+ if(instance_id == instance_ids[i]) {
68
+ return instance_names[i];
69
+ }
70
+ }
71
+ return NULL;
72
+ }
73
+
74
+ static VALUE decode_multiple_instances(pmDesc pm_desc, pmValueSet *pm_value_set, char *metric_name) {
75
+ int error, i;
76
+ int number_of_instances = pm_value_set->numval;
77
+ int *instances = NULL;
78
+ char **instance_names = NULL;
79
+ VALUE result = rb_ary_new2(number_of_instances);
80
+
81
+
82
+ if((error = pmGetInDom(pm_desc.indom, &instances, &instance_names)) < 0) {
83
+ pcpeasy_raise_from_pmapi_error(error);
84
+ }
85
+
86
+ for(i = 0; i < number_of_instances; i++) {
87
+ char *instance_name = get_name_from_instance_id(pm_value_set->vlist[i].inst, number_of_instances, instances, instance_names);
88
+ rb_ary_push(result, pcpeasy_metric_new(metric_name, instance_name, &pm_value_set->vlist[i], &pm_desc, pm_value_set->valfmt));
89
+ }
90
+
91
+ free(instances);
92
+ free(instance_names);
93
+
94
+ return result;
95
+ }
96
+
97
+ static VALUE decode_single_instance(pmDesc pm_desc, pmValueSet *pm_value_set, char *metric_name) {
98
+ return pcpeasy_metric_new(metric_name, NULL, &pm_value_set->vlist[0], &pm_desc, pm_value_set->valfmt);
99
+ }
100
+
101
+ static VALUE decode_single_metric(pmID pmid, pmValueSet *pm_value_set, char *metric_name) {
102
+ int error;
103
+ pmDesc pm_desc;
104
+
105
+ /* No values, bail out */
106
+ if(pm_value_set->numval == 0) {
107
+ return Qnil;
108
+ }
109
+
110
+ /* Find out how to decode the metric */
111
+ if((error = pmLookupDesc(pmid, &pm_desc))) {
112
+ pcpeasy_raise_from_pmapi_error(error);
113
+ }
114
+
115
+ /* Do we have instances? */
116
+ if(pm_desc.indom == PM_INDOM_NULL) {
117
+ return decode_single_instance(pm_desc, pm_value_set, metric_name);
118
+ } else {
119
+ return decode_multiple_instances(pm_desc, pm_value_set, metric_name);
120
+ }
121
+
122
+ }
123
+
124
+ static VALUE decode_pm_result(pmID pmid, pmResult *pm_result, char *metric_name) {
125
+ /* No values (or somehow more than 1) */
126
+ if (pm_result->numpmid != 1) {
127
+ return Qnil;
128
+ }
129
+
130
+ return decode_single_metric(pmid, pm_result->vset[0], metric_name);
131
+ }
132
+
133
+ static VALUE pcpeasy_agent_metric(VALUE self, VALUE metric_string_rb) {
134
+ /* Get our context */
135
+ PcpEasyAgent *pcpeasy_agent;
136
+ Data_Get_Struct(self, PcpEasyAgent, pcpeasy_agent);
137
+ pmUseContext(pcpeasy_agent->pm_context);
138
+
139
+ /* Get the pmID */
140
+ int error;
141
+ pmID pmid;
142
+ pmID *pmid_list = ALLOC(pmID);
143
+ char **metric_list = ALLOC(char*);
144
+ char *metric_name = StringValueCStr(metric_string_rb);
145
+ metric_list[0] = metric_name;
146
+ if((error = pmLookupName(1, metric_list, pmid_list)) < 0) {
147
+ xfree(pmid_list);
148
+ xfree(metric_list);
149
+ pcpeasy_raise_from_pmapi_error(error);
150
+ }
151
+ pmid = pmid_list[0];
152
+ xfree(pmid_list);
153
+ xfree(metric_list);
154
+
155
+
156
+ /* Do the fetch */
157
+ pmResult *pm_result;
158
+ VALUE result;
159
+ if((error = pmFetch(1, &pmid, &pm_result))) {
160
+ pcpeasy_raise_from_pmapi_error(error);
161
+ }
162
+
163
+ /* Decode the result */
164
+ result = decode_pm_result(pmid, pm_result, metric_name);
165
+ pmFreeResult(pm_result);
166
+
167
+ return result;
168
+ }
169
+
170
+ void Init_pcp_easy() {
171
+ pcpeasy_class = rb_define_module("PCPEasy");
172
+ pcpeasy_agent_class = rb_define_class_under(pcpeasy_class, "Agent", rb_cObject);
173
+ pcpeasy_exceptions_init(pcpeasy_class);
174
+ pcpeasy_metric_init(pcpeasy_class);
175
+
176
+ rb_define_alloc_func(pcpeasy_agent_class, pcpeasy_agent_allocate);
177
+ rb_define_method(pcpeasy_agent_class, "initialize", pcpeasy_agent_initialize, 1);
178
+ rb_define_method(pcpeasy_agent_class, "metric", pcpeasy_agent_metric, 1);
179
+ rb_define_attr(pcpeasy_agent_class, "host", 1, 0);
180
+
181
+ }
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pcp_easy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Ryan Doyle
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ executables: []
44
+ extensions:
45
+ - ext/pcp_easy/extconf.rb
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ext/pcp_easy/exceptions.c
49
+ - ext/pcp_easy/exceptions.h
50
+ - ext/pcp_easy/extconf.rb
51
+ - ext/pcp_easy/metric.c
52
+ - ext/pcp_easy/metric.h
53
+ - ext/pcp_easy/pcp_easy.c
54
+ homepage:
55
+ licenses: []
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubyforge_project:
73
+ rubygems_version: 2.2.2
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: Simple query interface for Performance Co-Pilot
77
+ test_files: []