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"
31 #include "afb-trace.h"
33 #include "wrap-json.h"
35 #include "monitor-api.inc"
37 extern struct afb_apiset *main_apiset;
39 static struct afb_binding_data_v2 datav2;
41 int afb_monitor_init()
43 return afb_api_so_v2_add_binding(&_afb_binding_v2_monitor, NULL, main_apiset, &datav2);
46 /******************************************************************************
47 **** Monitoring verbosity
48 ******************************************************************************/
50 static const char _debug_[] = "debug";
51 static const char _info_[] = "info";
52 static const char _notice_[] = "notice";
53 static const char _warning_[] = "warning";
54 static const char _error_[] = "error";
57 * Translate verbosity indication to an integer value.
58 * @param v the verbosity indication
59 * @return the verbosity level (0, 1, 2 or 3) or -1 in case of error
61 static int decode_verbosity(struct json_object *v)
66 if (!wrap_json_unpack(v, "i", &level)) {
67 level = level < Verbosity_Level_Error ? Verbosity_Level_Error : level > Verbosity_Level_Debug ? Verbosity_Level_Debug : level;
68 } else if (!wrap_json_unpack(v, "s", &s)) {
71 if (!strcasecmp(s, _debug_))
72 level = Verbosity_Level_Debug;
75 if (!strcasecmp(s, _info_))
76 level = Verbosity_Level_Info;
79 if (!strcasecmp(s, _notice_))
80 level = Verbosity_Level_Notice;
83 if (!strcasecmp(s, _warning_))
84 level = Verbosity_Level_Warning;
87 if (!strcasecmp(s, _error_))
88 level = Verbosity_Level_Error;
96 * callback for setting verbosity on all apis
97 * @param set the apiset
98 * @param the name of the api to set
99 * @param closure the verbosity to set as an integer casted to a pointer
101 static void set_verbosity_to_all_cb(struct afb_apiset *set, const char *name, void *closure)
103 afb_apiset_set_verbosity(set, name, (int)(intptr_t)closure);
107 * set the verbosity 'level' of the api of 'name'
108 * @param name the api name or "*" for any api or NULL or "" for global verbosity
109 * @param level the verbosity level to set
111 static void set_verbosity_to(const char *name, int level)
113 if (!name || !name[0])
115 else if (name[0] == '*' && !name[1])
116 afb_apiset_enum(main_apiset, 1, set_verbosity_to_all_cb, (void*)(intptr_t)level);
118 afb_apiset_set_verbosity(main_apiset, name, level);
122 * Set verbosities accordling to specification in 'spec'
123 * @param spec specification of the verbosity to set
125 static void set_verbosity(struct json_object *spec)
128 struct json_object_iterator it, end;
130 if (json_object_is_type(spec, json_type_object)) {
131 it = json_object_iter_begin(spec);
132 end = json_object_iter_end(spec);
133 while (!json_object_iter_equal(&it, &end)) {
134 l = decode_verbosity(json_object_iter_peek_value(&it));
136 set_verbosity_to(json_object_iter_peek_name(&it), l);
137 json_object_iter_next(&it);
140 l = decode_verbosity(spec);
142 set_verbosity_to("", l);
143 set_verbosity_to("*", l);
149 * Translate verbosity level to a protocol indication.
150 * @param level the verbosity
151 * @return the encoded verbosity
153 static struct json_object *encode_verbosity(int level)
156 case Verbosity_Level_Error: return json_object_new_string(_error_);
157 case Verbosity_Level_Warning: return json_object_new_string(_warning_);
158 case Verbosity_Level_Notice: return json_object_new_string(_notice_);
159 case Verbosity_Level_Info: return json_object_new_string(_info_);
160 case Verbosity_Level_Debug: 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, 1, 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_lookup(main_apiset, name, 1))
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, 1, 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);
357 afb_apiset_update_hooks(main_apiset, NULL);
358 afb_evt_update_hooks();