xref: /spdk/lib/event/log_rpc.c (revision 6f338d4bf3a8a91b7abe377a605a321ea2b05bf7)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/rpc.h"
7 #include "spdk/util.h"
8 
9 #include "spdk/log.h"
10 
11 struct rpc_log_flag {
12 	char *flag;
13 };
14 
15 struct rpc_log_level {
16 	char *level;
17 };
18 
19 static void
20 free_rpc_log_flag(struct rpc_log_flag *p)
21 {
22 	free(p->flag);
23 }
24 
25 static void
26 free_rpc_log_level(struct rpc_log_level *p)
27 {
28 	free(p->level);
29 }
30 
31 static const struct spdk_json_object_decoder rpc_log_flag_decoders[] = {
32 	{"flag", offsetof(struct rpc_log_flag, flag), spdk_json_decode_string},
33 };
34 
35 static const struct spdk_json_object_decoder rpc_log_level_decoders[] = {
36 	{"level", offsetof(struct rpc_log_level, level), spdk_json_decode_string},
37 };
38 
39 static int
40 _parse_log_level(char *level)
41 {
42 	if (!strcasecmp(level, "ERROR")) {
43 		return SPDK_LOG_ERROR;
44 	} else if (!strcasecmp(level, "WARNING")) {
45 		return SPDK_LOG_WARN;
46 	} else if (!strcasecmp(level, "NOTICE")) {
47 		return SPDK_LOG_NOTICE;
48 	} else if (!strcasecmp(level, "INFO")) {
49 		return SPDK_LOG_INFO;
50 	} else if (!strcasecmp(level, "DEBUG")) {
51 		return SPDK_LOG_DEBUG;
52 	}
53 	return -1;
54 }
55 
56 static const char *
57 _log_get_level_name(int level)
58 {
59 	if (level == SPDK_LOG_ERROR) {
60 		return "ERROR";
61 	} else if (level == SPDK_LOG_WARN) {
62 		return "WARNING";
63 	} else if (level == SPDK_LOG_NOTICE) {
64 		return "NOTICE";
65 	} else if (level == SPDK_LOG_INFO) {
66 		return "INFO";
67 	} else if (level == SPDK_LOG_DEBUG) {
68 		return "DEBUG";
69 	}
70 	return NULL;
71 }
72 
73 static void
74 rpc_log_set_print_level(struct spdk_jsonrpc_request *request,
75 			const struct spdk_json_val *params)
76 {
77 	struct rpc_log_level req = {};
78 	int level;
79 
80 	if (spdk_json_decode_object(params, rpc_log_level_decoders,
81 				    SPDK_COUNTOF(rpc_log_level_decoders), &req)) {
82 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
83 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
84 						 "spdk_json_decode_object failed");
85 		goto end;
86 	}
87 
88 	level = _parse_log_level(req.level);
89 	if (level == -1) {
90 		SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n");
91 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
92 						 "invalid log level");
93 		goto end;
94 	}
95 
96 	spdk_log_set_print_level(level);
97 	spdk_jsonrpc_send_bool_response(request, true);
98 end:
99 	free_rpc_log_level(&req);
100 }
101 SPDK_RPC_REGISTER("log_set_print_level", rpc_log_set_print_level,
102 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
103 
104 static void
105 rpc_log_get_print_level(struct spdk_jsonrpc_request *request,
106 			const struct spdk_json_val *params)
107 {
108 	struct spdk_json_write_ctx *w;
109 	int level;
110 	const char *name;
111 
112 	if (params != NULL) {
113 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
114 						 "log_get_print_level requires no parameters");
115 		return;
116 	}
117 
118 	level = spdk_log_get_print_level();
119 	name = _log_get_level_name(level);
120 	if (name == NULL) {
121 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
122 						 "invalid log level");
123 		return;
124 	}
125 
126 	w = spdk_jsonrpc_begin_result(request);
127 	spdk_json_write_string(w, name);
128 
129 	spdk_jsonrpc_end_result(request, w);
130 }
131 SPDK_RPC_REGISTER("log_get_print_level", rpc_log_get_print_level,
132 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
133 
134 static void
135 rpc_log_set_level(struct spdk_jsonrpc_request *request,
136 		  const struct spdk_json_val *params)
137 {
138 	struct rpc_log_level req = {};
139 	int level;
140 
141 	if (spdk_json_decode_object(params, rpc_log_level_decoders,
142 				    SPDK_COUNTOF(rpc_log_level_decoders), &req)) {
143 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
144 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
145 						 "spdk_json_decode_object failed");
146 		goto end;
147 	}
148 
149 	level = _parse_log_level(req.level);
150 	if (level == -1) {
151 		SPDK_DEBUGLOG(log_rpc, "tried to set invalid log level\n");
152 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
153 						 "invalid log level");
154 		goto end;
155 	}
156 
157 
158 	spdk_log_set_level(level);
159 	spdk_jsonrpc_send_bool_response(request, true);
160 end:
161 	free_rpc_log_level(&req);
162 }
163 SPDK_RPC_REGISTER("log_set_level", rpc_log_set_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
164 
165 static void
166 rpc_log_get_level(struct spdk_jsonrpc_request *request,
167 		  const struct spdk_json_val *params)
168 {
169 	struct spdk_json_write_ctx *w;
170 	int level;
171 	const char *name;
172 
173 	if (params != NULL) {
174 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
175 						 "log_get_level requires no parameters");
176 		return;
177 	}
178 
179 	level = spdk_log_get_level();
180 	name = _log_get_level_name(level);
181 	if (name == NULL) {
182 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
183 						 "invalid log level");
184 		return;
185 	}
186 
187 	w = spdk_jsonrpc_begin_result(request);
188 	spdk_json_write_string(w, name);
189 
190 	spdk_jsonrpc_end_result(request, w);
191 }
192 SPDK_RPC_REGISTER("log_get_level", rpc_log_get_level, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
193 
194 static void
195 rpc_log_set_flag(struct spdk_jsonrpc_request *request,
196 		 const struct spdk_json_val *params)
197 {
198 	struct rpc_log_flag req = {};
199 
200 	if (spdk_json_decode_object(params, rpc_log_flag_decoders,
201 				    SPDK_COUNTOF(rpc_log_flag_decoders), &req)) {
202 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
203 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
204 						 "spdk_json_decode_object failed");
205 		goto end;
206 	}
207 
208 	if (req.flag == 0) {
209 		SPDK_DEBUGLOG(log_rpc, "invalid flag 0\n");
210 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
211 						 "invalid flag 0");
212 		goto end;
213 	}
214 
215 	spdk_log_set_flag(req.flag);
216 	spdk_jsonrpc_send_bool_response(request, true);
217 end:
218 	free_rpc_log_flag(&req);
219 }
220 SPDK_RPC_REGISTER("log_set_flag", rpc_log_set_flag, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
221 
222 static void
223 rpc_log_clear_flag(struct spdk_jsonrpc_request *request,
224 		   const struct spdk_json_val *params)
225 {
226 	struct rpc_log_flag req = {};
227 
228 	if (spdk_json_decode_object(params, rpc_log_flag_decoders,
229 				    SPDK_COUNTOF(rpc_log_flag_decoders), &req)) {
230 		SPDK_DEBUGLOG(log_rpc, "spdk_json_decode_object failed\n");
231 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INTERNAL_ERROR,
232 						 "spdk_json_decode_object failed");
233 		goto end;
234 	}
235 
236 	if (req.flag == 0) {
237 		SPDK_DEBUGLOG(log_rpc, "Invalid flag 0\n");
238 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
239 						 "invalid flag 0");
240 		goto end;
241 	}
242 
243 	spdk_log_clear_flag(req.flag);
244 	spdk_jsonrpc_send_bool_response(request, true);
245 end:
246 	free_rpc_log_flag(&req);
247 }
248 SPDK_RPC_REGISTER("log_clear_flag", rpc_log_clear_flag,
249 		  SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
250 
251 static void
252 rpc_log_get_flags(struct spdk_jsonrpc_request *request,
253 		  const struct spdk_json_val *params)
254 {
255 	struct spdk_json_write_ctx *w;
256 	struct spdk_log_flag *flag;
257 
258 	if (params != NULL) {
259 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
260 						 "log_get_flags requires no parameters");
261 		return;
262 	}
263 
264 	w = spdk_jsonrpc_begin_result(request);
265 	spdk_json_write_object_begin(w);
266 	flag = spdk_log_get_first_flag();
267 	while (flag) {
268 		spdk_json_write_name(w, flag->name);
269 		spdk_json_write_bool(w, flag->enabled);
270 		flag = spdk_log_get_next_flag(flag);
271 	}
272 	spdk_json_write_object_end(w);
273 	spdk_jsonrpc_end_result(request, w);
274 }
275 SPDK_RPC_REGISTER("log_get_flags", rpc_log_get_flags, SPDK_RPC_STARTUP | SPDK_RPC_RUNTIME)
276 
277 struct rpc_log_enable_timestamps {
278 	bool enabled;
279 };
280 
281 static const struct spdk_json_object_decoder rpc_log_enable_timestamps_decoders[] = {
282 	{"enabled", offsetof(struct rpc_log_enable_timestamps, enabled), spdk_json_decode_bool},
283 };
284 
285 static void
286 rpc_log_enable_timestamps(struct spdk_jsonrpc_request *request,
287 			  const struct spdk_json_val *params)
288 {
289 	struct rpc_log_enable_timestamps req = {};
290 
291 	if (spdk_json_decode_object(params, rpc_log_enable_timestamps_decoders,
292 				    SPDK_COUNTOF(rpc_log_enable_timestamps_decoders),
293 				    &req)) {
294 		SPDK_ERRLOG("spdk_json_decode_object failed\n");
295 		spdk_jsonrpc_send_error_response(request, SPDK_JSONRPC_ERROR_INVALID_PARAMS,
296 						 "spdk_json_decode_object failed");
297 		return;
298 	}
299 
300 	spdk_log_enable_timestamps(req.enabled);
301 
302 	spdk_jsonrpc_send_bool_response(request, true);
303 }
304 SPDK_RPC_REGISTER("log_enable_timestamps", rpc_log_enable_timestamps, SPDK_RPC_RUNTIME)
305 SPDK_LOG_REGISTER_COMPONENT(log_rpc)
306