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>
25 #include <afb/afb-binding-v2.h>
28 #include "afb-apiset.h"
29 #include "afb-api-so-v2.h"
33 #include "afb-trace.h"
35 #include "wrap-json.h"
37 #include "monitor-api.inc"
39 extern struct afb_apiset *main_apiset;
41 static struct afb_binding_data_v2 datav2;
43 int afb_monitor_init()
45 return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &datav2);
48 /******************************************************************************
49 **** Monitoring verbosity
50 ******************************************************************************/
52 static const char _debug_[] = "debug";
53 static const char _info_[] = "info";
54 static const char _notice_[] = "notice";
55 static const char _warning_[] = "warning";
56 static const char _error_[] = "error";
59 * Translate verbosity indication to an integer value.
60 * @param v the verbosity indication
61 * @return the verbosity level (0, 1, 2 or 3) or -1 in case of error
63 static int decode_verbosity(struct json_object *v)
68 if (!wrap_json_unpack(v, "i", &level)) {
69 level = level < 0 ? 0 : level > 3 ? 3 : level;
70 } else if (!wrap_json_unpack(v, "s", &s)) {
73 if (!strcasecmp(s, _debug_))
77 if (!strcasecmp(s, _info_))
81 if (!strcasecmp(s, _notice_))
85 if (!strcasecmp(s, _warning_))
89 if (!strcasecmp(s, _error_))
98 * callback for setting verbosity on all apis
99 * @param set the apiset
100 * @param the name of the api to set
101 * @param closure the verbosity to set as an integer casted to a pointer
103 static void set_verbosity_to_all_cb(struct afb_apiset *set, const char *name, void *closure)
105 afb_apiset_set_verbosity(set, name, (int)(intptr_t)closure);
109 * set the verbosity 'level' of the api of 'name'
110 * @param name the api name or "*" for any api or NULL or "" for global verbosity
111 * @param level the verbosity level to set
113 static void set_verbosity_to(const char *name, int level)
115 if (!name || !name[0])
117 else if (name[0] == '*' && !name[1])
118 afb_apiset_enum(main_apiset, set_verbosity_to_all_cb, (void*)(intptr_t)level);
120 afb_apiset_set_verbosity(main_apiset, name, level);
124 * Set verbosities accordling to specification in 'spec'
125 * @param spec specification of the verbosity to set
127 static void set_verbosity(struct json_object *spec)
130 struct json_object_iterator it, end;
132 if (json_object_is_type(spec, json_type_object)) {
133 it = json_object_iter_begin(spec);
134 end = json_object_iter_end(spec);
135 while (!json_object_iter_equal(&it, &end)) {
136 l = decode_verbosity(json_object_iter_peek_value(&it));
138 set_verbosity_to(json_object_iter_peek_name(&it), l);
139 json_object_iter_next(&it);
142 l = decode_verbosity(spec);
144 set_verbosity_to("", l);
145 set_verbosity_to("*", l);
151 * Translate verbosity level to a protocol indication.
152 * @param level the verbosity
153 * @return the encoded verbosity
155 static struct json_object *encode_verbosity(int level)
158 case 0: return json_object_new_string(_error_);
159 case 1: return json_object_new_string(_notice_);
160 case 2: return json_object_new_string(_info_);
161 case 3: return json_object_new_string(_debug_);
162 default: return json_object_new_int(level);
167 * callback for getting verbosity of all apis
168 * @param set the apiset
169 * @param the name of the api to set
170 * @param closure the json object to build
172 static void get_verbosity_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
174 struct json_object *resu = closure;
175 int l = afb_apiset_get_verbosity(set, name);
177 json_object_object_add(resu, name, encode_verbosity(l));
181 * get in resu the verbosity of the api of 'name'
182 * @param resu the json object to build
183 * @param name the api name or "*" for any api or NULL or "" for global verbosity
185 static void get_verbosity_of(struct json_object *resu, const char *name)
188 if (!name || !name[0])
189 json_object_object_add(resu, "", encode_verbosity(verbosity));
190 else if (name[0] == '*' && !name[1])
191 afb_apiset_enum(main_apiset, get_verbosity_of_all_cb, resu);
193 l = afb_apiset_get_verbosity(main_apiset, name);
195 json_object_object_add(resu, name, encode_verbosity(l));
200 * get verbosities accordling to specification in 'spec'
201 * @param resu the json object to build
202 * @param spec specification of the verbosity to set
204 static struct json_object *get_verbosity(struct json_object *spec)
207 struct json_object *resu;
208 struct json_object_iterator it, end;
210 resu = json_object_new_object();
211 if (json_object_is_type(spec, json_type_object)) {
212 it = json_object_iter_begin(spec);
213 end = json_object_iter_end(spec);
214 while (!json_object_iter_equal(&it, &end)) {
215 get_verbosity_of(resu, json_object_iter_peek_name(&it));
216 json_object_iter_next(&it);
218 } else if (json_object_is_type(spec, json_type_array)) {
219 n = json_object_array_length(spec);
220 for (i = 0 ; i < n ; i++)
221 get_verbosity_of(resu, json_object_get_string(json_object_array_get_idx(spec, i)));
222 } else if (json_object_is_type(spec, json_type_string)) {
223 get_verbosity_of(resu, json_object_get_string(spec));
224 } else if (json_object_get_boolean(spec)) {
225 get_verbosity_of(resu, "");
226 get_verbosity_of(resu, "*");
231 /******************************************************************************
233 ******************************************************************************/
236 * get apis accordling to specification in 'spec'
237 * @param resu the json object to build
238 * @param spec specification of the verbosity to set
240 static void get_one_api(struct json_object *resu, const char *name, struct json_object *spec)
242 struct json_object *o;
244 o = afb_apiset_describe(main_apiset, name);
245 if (o || afb_apiset_has(main_apiset, name))
246 json_object_object_add(resu, name, o);
250 * callback for getting verbosity of all apis
251 * @param set the apiset
252 * @param the name of the api to set
253 * @param closure the json object to build
255 static void get_apis_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
257 struct json_object *resu = closure;
258 get_one_api(resu, name, NULL);
262 * get apis accordling to specification in 'spec'
263 * @param resu the json object to build
264 * @param spec specification of the verbosity to set
266 static struct json_object *get_apis(struct json_object *spec)
269 struct json_object *resu;
270 struct json_object_iterator it, end;
272 resu = json_object_new_object();
273 if (json_object_is_type(spec, json_type_object)) {
274 it = json_object_iter_begin(spec);
275 end = json_object_iter_end(spec);
276 while (!json_object_iter_equal(&it, &end)) {
277 get_one_api(resu, json_object_iter_peek_name(&it), json_object_iter_peek_value(&it));
278 json_object_iter_next(&it);
280 } else if (json_object_is_type(spec, json_type_array)) {
281 n = json_object_array_length(spec);
282 for (i = 0 ; i < n ; i++)
283 get_one_api(resu, json_object_get_string(json_object_array_get_idx(spec, i)), NULL);
284 } else if (json_object_is_type(spec, json_type_string)) {
285 get_one_api(resu, json_object_get_string(spec), NULL);
286 } else if (json_object_get_boolean(spec)) {
287 afb_apiset_enum(main_apiset, get_apis_of_all_cb, resu);
292 /******************************************************************************
293 **** Implementation monitoring verbs
294 ******************************************************************************/
296 static const char _verbosity_[] = "verbosity";
297 static const char _apis_[] = "apis";
299 static void f_get(struct afb_req req)
301 struct json_object *r;
302 struct json_object *apis = NULL;
303 struct json_object *verbosity = NULL;
305 wrap_json_unpack(afb_req_json(req), "{s?:o,s?:o}", _verbosity_, &verbosity, _apis_, &apis);
307 verbosity = get_verbosity(verbosity);
309 apis = get_apis(apis);
311 wrap_json_pack(&r, "{s:o*,s:o*}", _verbosity_, verbosity, _apis_, apis);
312 afb_req_success(req, r, NULL);
315 static void f_set(struct afb_req req)
317 struct json_object *verbosity = NULL;
319 wrap_json_unpack(afb_req_json(req), "{s?:o}", _verbosity_, &verbosity);
321 set_verbosity(verbosity);
323 afb_req_success(req, NULL, NULL);
326 static void *context_create()
328 return afb_trace_create(&datav2.daemon, NULL);
331 static void context_destroy(void *pointer)
333 struct afb_trace *trace = pointer;
334 afb_trace_unref(trace);
337 static void f_trace(struct afb_req req)
340 struct json_object *add = NULL;
341 struct json_object *drop = NULL;
342 struct afb_trace *trace;
344 trace = afb_req_context(req, context_create, context_destroy);
345 wrap_json_unpack(afb_req_json(req), "{s?o s?o}", "add", &add, "drop", &drop);
347 rc = afb_trace_add(req, add, trace);
352 rc = afb_trace_drop(req, drop, trace);
356 afb_req_success(req, NULL, NULL);
358 afb_apiset_update_hooks(main_apiset, NULL);
359 afb_evt_update_hooks();