2 * Copyright (C) 2016, 2017 "IoT.bzh"
3 * Author José Bollo <jose.bollo@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #define AFB_BINDING_PRAGMA_NO_VERBOSE_MACRO
23 #include <json-c/json.h>
24 #include <afb/afb-binding-v2.h>
27 #include "afb-apiset.h"
28 #include "afb-api-so-v2.h"
32 #include "wrap-json.h"
34 #include "monitor-api.inc"
36 extern struct afb_apiset *main_apiset;
38 static struct afb_binding_data_v2 datav2;
40 int afb_monitor_init()
42 return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &datav2);
45 /******************************************************************************
46 **** Monitoring verbosity
47 ******************************************************************************/
49 static const char _debug_[] = "debug";
50 static const char _info_[] = "info";
51 static const char _notice_[] = "notice";
52 static const char _warning_[] = "warning";
53 static const char _error_[] = "error";
56 * Translate verbosity indication to an integer value.
57 * @param v the verbosity indication
58 * @return the verbosity level (0, 1, 2 or 3) or -1 in case of error
60 static int decode_verbosity(struct json_object *v)
65 if (!wrap_json_unpack(v, "i", &level)) {
66 level = level < 0 ? 0 : level > 3 ? 3 : level;
67 } else if (!wrap_json_unpack(v, "s", &s)) {
70 if (!strcasecmp(s, _debug_))
74 if (!strcasecmp(s, _info_))
78 if (!strcasecmp(s, _notice_))
82 if (!strcasecmp(s, _warning_))
86 if (!strcasecmp(s, _error_))
95 * callback for setting verbosity on all apis
96 * @param set the apiset
97 * @param the name of the api to set
98 * @param closure the verbosity to set as an integer casted to a pointer
100 static void set_verbosity_to_all_cb(struct afb_apiset *set, const char *name, void *closure)
102 afb_apiset_set_verbosity(set, name, (int)(intptr_t)closure);
106 * set the verbosity 'level' of the api of 'name'
107 * @param name the api name or "*" for any api or NULL or "" for global verbosity
108 * @param level the verbosity level to set
110 static void set_verbosity_to(const char *name, int level)
112 if (!name || !name[0])
114 else if (name[0] == '*' && !name[1])
115 afb_apiset_enum(main_apiset, set_verbosity_to_all_cb, (void*)(intptr_t)level);
117 afb_apiset_set_verbosity(main_apiset, name, level);
121 * Set verbosities accordling to specification in 'spec'
122 * @param spec specification of the verbosity to set
124 static void set_verbosity(struct json_object *spec)
127 struct json_object_iterator it, end;
129 if (json_object_is_type(spec, json_type_object)) {
130 it = json_object_iter_begin(spec);
131 end = json_object_iter_end(spec);
132 while (!json_object_iter_equal(&it, &end)) {
133 l = decode_verbosity(json_object_iter_peek_value(&it));
135 set_verbosity_to(json_object_iter_peek_name(&it), l);
136 json_object_iter_next(&it);
139 l = decode_verbosity(spec);
141 set_verbosity_to("", l);
142 set_verbosity_to("*", l);
148 * Translate verbosity level to a protocol indication.
149 * @param level the verbosity
150 * @return the encoded verbosity
152 static struct json_object *encode_verbosity(int level)
155 case 0: return json_object_new_string(_error_);
156 case 1: return json_object_new_string(_notice_);
157 case 2: return json_object_new_string(_info_);
158 case 3: return json_object_new_string(_debug_);
159 default: return json_object_new_int(level);
164 * callback for getting verbosity of all apis
165 * @param set the apiset
166 * @param the name of the api to set
167 * @param closure the json object to build
169 static void get_verbosity_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
171 struct json_object *resu = closure;
172 int l = afb_apiset_get_verbosity(set, name);
174 json_object_object_add(resu, name, encode_verbosity(l));
178 * get in resu the verbosity of the api of 'name'
179 * @param resu the json object to build
180 * @param name the api name or "*" for any api or NULL or "" for global verbosity
182 static void get_verbosity_of(struct json_object *resu, const char *name)
185 if (!name || !name[0])
186 json_object_object_add(resu, "", encode_verbosity(verbosity));
187 else if (name[0] == '*' && !name[1])
188 afb_apiset_enum(main_apiset, get_verbosity_of_all_cb, resu);
190 l = afb_apiset_get_verbosity(main_apiset, name);
192 json_object_object_add(resu, name, encode_verbosity(l));
197 * get verbosities accordling to specification in 'spec'
198 * @param resu the json object to build
199 * @param spec specification of the verbosity to set
201 static struct json_object *get_verbosity(struct json_object *spec)
204 struct json_object *resu;
205 struct json_object_iterator it, end;
207 resu = json_object_new_object();
208 if (json_object_is_type(spec, json_type_object)) {
209 it = json_object_iter_begin(spec);
210 end = json_object_iter_end(spec);
211 while (!json_object_iter_equal(&it, &end)) {
212 get_verbosity_of(resu, json_object_iter_peek_name(&it));
213 json_object_iter_next(&it);
215 } else if (json_object_is_type(spec, json_type_array)) {
216 n = json_object_array_length(spec);
217 for (i = 0 ; i < n ; i++)
218 get_verbosity_of(resu, json_object_get_string(json_object_array_get_idx(spec, i)));
219 } else if (json_object_is_type(spec, json_type_string)) {
220 get_verbosity_of(resu, json_object_get_string(spec));
221 } else if (json_object_get_boolean(spec)) {
222 get_verbosity_of(resu, "");
223 get_verbosity_of(resu, "*");
228 /******************************************************************************
230 ******************************************************************************/
233 * get apis accordling to specification in 'spec'
234 * @param resu the json object to build
235 * @param spec specification of the verbosity to set
237 static void get_one_api(struct json_object *resu, const char *name, struct json_object *spec)
239 struct json_object *o;
243 rc = afb_apiset_lookup(main_apiset, name, &api);
245 o = api.itf->describe ? api.itf->describe(api.closure) : NULL;
246 json_object_object_add(resu, name, o);
251 * callback for getting verbosity of all apis
252 * @param set the apiset
253 * @param the name of the api to set
254 * @param closure the json object to build
256 static void get_apis_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
258 struct json_object *resu = closure;
259 get_one_api(resu, name, NULL);
263 * get apis accordling to specification in 'spec'
264 * @param resu the json object to build
265 * @param spec specification of the verbosity to set
267 static struct json_object *get_apis(struct json_object *spec)
270 struct json_object *resu;
271 struct json_object_iterator it, end;
273 resu = json_object_new_object();
274 if (json_object_is_type(spec, json_type_object)) {
275 it = json_object_iter_begin(spec);
276 end = json_object_iter_end(spec);
277 while (!json_object_iter_equal(&it, &end)) {
278 get_one_api(resu, json_object_iter_peek_name(&it), json_object_iter_peek_value(&it));
279 json_object_iter_next(&it);
281 } else if (json_object_is_type(spec, json_type_array)) {
282 n = json_object_array_length(spec);
283 for (i = 0 ; i < n ; i++)
284 get_one_api(resu, json_object_get_string(json_object_array_get_idx(spec, i)), NULL);
285 } else if (json_object_is_type(spec, json_type_string)) {
286 get_one_api(resu, json_object_get_string(spec), NULL);
287 } else if (json_object_get_boolean(spec)) {
288 afb_apiset_enum(main_apiset, get_apis_of_all_cb, resu);
293 /******************************************************************************
294 **** Implementation monitoring verbs
295 ******************************************************************************/
297 static const char _verbosity_[] = "verbosity";
298 static const char _apis_[] = "apis";
300 static void f_get(struct afb_req req)
302 struct json_object *r;
303 struct json_object *apis = NULL;
304 struct json_object *verbosity = NULL;
306 wrap_json_unpack(afb_req_json(req), "{s?:o,s?:o}", _verbosity_, &verbosity, _apis_, &apis);
308 verbosity = get_verbosity(verbosity);
310 apis = get_apis(apis);
312 wrap_json_pack(&r, "{s:o*,s:o*}", _verbosity_, verbosity, _apis_, apis);
313 afb_req_success(req, r, NULL);
316 static void f_set(struct afb_req req)
318 struct json_object *verbosity = NULL;
320 wrap_json_unpack(afb_req_json(req), "{s?:o}", _verbosity_, &verbosity);
322 set_verbosity(verbosity);
324 afb_req_success(req, NULL, NULL);
328 static void f_hook(struct afb_xreq *xreq)
330 struct json_object *o, *v;
332 o = afb_xreq_json(xreq);
333 if (json_object_object_get_ex(o, _verbosity_, &v)) {
338 afb_xreq_success(xreq, NULL, NULL);