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"
32 #include "afb-trace.h"
34 #include "wrap-json.h"
36 #include "monitor-api.inc"
38 extern struct afb_apiset *main_apiset;
40 static struct afb_binding_data_v2 datav2;
42 int afb_monitor_init()
44 return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &datav2);
47 /******************************************************************************
48 **** Monitoring verbosity
49 ******************************************************************************/
51 static const char _debug_[] = "debug";
52 static const char _info_[] = "info";
53 static const char _notice_[] = "notice";
54 static const char _warning_[] = "warning";
55 static const char _error_[] = "error";
58 * Translate verbosity indication to an integer value.
59 * @param v the verbosity indication
60 * @return the verbosity level (0, 1, 2 or 3) or -1 in case of error
62 static int decode_verbosity(struct json_object *v)
67 if (!wrap_json_unpack(v, "i", &level)) {
68 level = level < 0 ? 0 : level > 3 ? 3 : level;
69 } else if (!wrap_json_unpack(v, "s", &s)) {
72 if (!strcasecmp(s, _debug_))
76 if (!strcasecmp(s, _info_))
80 if (!strcasecmp(s, _notice_))
84 if (!strcasecmp(s, _warning_))
88 if (!strcasecmp(s, _error_))
97 * callback for setting verbosity on all apis
98 * @param set the apiset
99 * @param the name of the api to set
100 * @param closure the verbosity to set as an integer casted to a pointer
102 static void set_verbosity_to_all_cb(struct afb_apiset *set, const char *name, void *closure)
104 afb_apiset_set_verbosity(set, name, (int)(intptr_t)closure);
108 * set the verbosity 'level' of the api of 'name'
109 * @param name the api name or "*" for any api or NULL or "" for global verbosity
110 * @param level the verbosity level to set
112 static void set_verbosity_to(const char *name, int level)
114 if (!name || !name[0])
116 else if (name[0] == '*' && !name[1])
117 afb_apiset_enum(main_apiset, set_verbosity_to_all_cb, (void*)(intptr_t)level);
119 afb_apiset_set_verbosity(main_apiset, name, level);
123 * Set verbosities accordling to specification in 'spec'
124 * @param spec specification of the verbosity to set
126 static void set_verbosity(struct json_object *spec)
129 struct json_object_iterator it, end;
131 if (json_object_is_type(spec, json_type_object)) {
132 it = json_object_iter_begin(spec);
133 end = json_object_iter_end(spec);
134 while (!json_object_iter_equal(&it, &end)) {
135 l = decode_verbosity(json_object_iter_peek_value(&it));
137 set_verbosity_to(json_object_iter_peek_name(&it), l);
138 json_object_iter_next(&it);
141 l = decode_verbosity(spec);
143 set_verbosity_to("", l);
144 set_verbosity_to("*", l);
150 * Translate verbosity level to a protocol indication.
151 * @param level the verbosity
152 * @return the encoded verbosity
154 static struct json_object *encode_verbosity(int level)
157 case 0: return json_object_new_string(_error_);
158 case 1: return json_object_new_string(_notice_);
159 case 2: return json_object_new_string(_info_);
160 case 3: return json_object_new_string(_debug_);
161 default: return json_object_new_int(level);
166 * callback for getting verbosity of all apis
167 * @param set the apiset
168 * @param the name of the api to set
169 * @param closure the json object to build
171 static void get_verbosity_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
173 struct json_object *resu = closure;
174 int l = afb_apiset_get_verbosity(set, name);
176 json_object_object_add(resu, name, encode_verbosity(l));
180 * get in resu the verbosity of the api of 'name'
181 * @param resu the json object to build
182 * @param name the api name or "*" for any api or NULL or "" for global verbosity
184 static void get_verbosity_of(struct json_object *resu, const char *name)
187 if (!name || !name[0])
188 json_object_object_add(resu, "", encode_verbosity(verbosity));
189 else if (name[0] == '*' && !name[1])
190 afb_apiset_enum(main_apiset, get_verbosity_of_all_cb, resu);
192 l = afb_apiset_get_verbosity(main_apiset, name);
194 json_object_object_add(resu, name, encode_verbosity(l));
199 * get verbosities accordling to specification in 'spec'
200 * @param resu the json object to build
201 * @param spec specification of the verbosity to set
203 static struct json_object *get_verbosity(struct json_object *spec)
206 struct json_object *resu;
207 struct json_object_iterator it, end;
209 resu = json_object_new_object();
210 if (json_object_is_type(spec, json_type_object)) {
211 it = json_object_iter_begin(spec);
212 end = json_object_iter_end(spec);
213 while (!json_object_iter_equal(&it, &end)) {
214 get_verbosity_of(resu, json_object_iter_peek_name(&it));
215 json_object_iter_next(&it);
217 } else if (json_object_is_type(spec, json_type_array)) {
218 n = json_object_array_length(spec);
219 for (i = 0 ; i < n ; i++)
220 get_verbosity_of(resu, json_object_get_string(json_object_array_get_idx(spec, i)));
221 } else if (json_object_is_type(spec, json_type_string)) {
222 get_verbosity_of(resu, json_object_get_string(spec));
223 } else if (json_object_get_boolean(spec)) {
224 get_verbosity_of(resu, "");
225 get_verbosity_of(resu, "*");
230 /******************************************************************************
232 ******************************************************************************/
235 * get apis accordling to specification in 'spec'
236 * @param resu the json object to build
237 * @param spec specification of the verbosity to set
239 static void get_one_api(struct json_object *resu, const char *name, struct json_object *spec)
241 struct json_object *o;
243 o = afb_apiset_describe(main_apiset, name);
244 if (o || afb_apiset_has(main_apiset, name))
245 json_object_object_add(resu, name, o);
249 * callback for getting verbosity of all apis
250 * @param set the apiset
251 * @param the name of the api to set
252 * @param closure the json object to build
254 static void get_apis_of_all_cb(struct afb_apiset *set, const char *name, void *closure)
256 struct json_object *resu = closure;
257 get_one_api(resu, name, NULL);
261 * get apis accordling to specification in 'spec'
262 * @param resu the json object to build
263 * @param spec specification of the verbosity to set
265 static struct json_object *get_apis(struct json_object *spec)
268 struct json_object *resu;
269 struct json_object_iterator it, end;
271 resu = json_object_new_object();
272 if (json_object_is_type(spec, json_type_object)) {
273 it = json_object_iter_begin(spec);
274 end = json_object_iter_end(spec);
275 while (!json_object_iter_equal(&it, &end)) {
276 get_one_api(resu, json_object_iter_peek_name(&it), json_object_iter_peek_value(&it));
277 json_object_iter_next(&it);
279 } else if (json_object_is_type(spec, json_type_array)) {
280 n = json_object_array_length(spec);
281 for (i = 0 ; i < n ; i++)
282 get_one_api(resu, json_object_get_string(json_object_array_get_idx(spec, i)), NULL);
283 } else if (json_object_is_type(spec, json_type_string)) {
284 get_one_api(resu, json_object_get_string(spec), NULL);
285 } else if (json_object_get_boolean(spec)) {
286 afb_apiset_enum(main_apiset, get_apis_of_all_cb, resu);
291 /******************************************************************************
292 **** Implementation monitoring verbs
293 ******************************************************************************/
295 static const char _verbosity_[] = "verbosity";
296 static const char _apis_[] = "apis";
298 static void f_get(struct afb_req req)
300 struct json_object *r;
301 struct json_object *apis = NULL;
302 struct json_object *verbosity = NULL;
304 wrap_json_unpack(afb_req_json(req), "{s?:o,s?:o}", _verbosity_, &verbosity, _apis_, &apis);
306 verbosity = get_verbosity(verbosity);
308 apis = get_apis(apis);
310 wrap_json_pack(&r, "{s:o*,s:o*}", _verbosity_, verbosity, _apis_, apis);
311 afb_req_success(req, r, NULL);
314 static void f_set(struct afb_req req)
316 struct json_object *verbosity = NULL;
318 wrap_json_unpack(afb_req_json(req), "{s?:o}", _verbosity_, &verbosity);
320 set_verbosity(verbosity);
322 afb_req_success(req, NULL, NULL);
325 static void *context_create()
327 return afb_trace_create(&datav2.daemon, NULL);
330 static void context_destroy(void *pointer)
332 struct afb_trace *trace = pointer;
333 afb_trace_unref(trace);
336 static void f_trace(struct afb_req req)
339 struct json_object *add = NULL;
340 struct json_object *drop = NULL;
341 struct afb_trace *trace;
343 trace = afb_req_context(req, context_create, context_destroy);
344 wrap_json_unpack(afb_req_json(req), "{s?o s?o}", "add", &add, "drop", &drop);
346 rc = afb_trace_add(req, add, trace);
351 rc = afb_trace_drop(req, drop, trace);
355 afb_req_success(req, NULL, NULL);