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.
22 #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 "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 < Verbosity_Level_Error ? Verbosity_Level_Error : level > Verbosity_Level_Debug ? Verbosity_Level_Debug : level;
69 } else if (!wrap_json_unpack(v, "s", &s)) {
72 if (!strcasecmp(s, _debug_))
73 level = Verbosity_Level_Debug;
76 if (!strcasecmp(s, _info_))
77 level = Verbosity_Level_Info;
80 if (!strcasecmp(s, _notice_))
81 level = Verbosity_Level_Notice;
84 if (!strcasecmp(s, _warning_))
85 level = Verbosity_Level_Warning;
88 if (!strcasecmp(s, _error_))
89 level = Verbosity_Level_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, 1, 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 Verbosity_Level_Error: return json_object_new_string(_error_);
158 case Verbosity_Level_Warning: return json_object_new_string(_warning_);
159 case Verbosity_Level_Notice: return json_object_new_string(_notice_);
160 case Verbosity_Level_Info: return json_object_new_string(_info_);
161 case Verbosity_Level_Debug: 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, 1, 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_lookup(main_apiset, name, 1))
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, 1, 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();