[2/2] kernel-shark-qt: Add Json I/O for filter configurations.
diff mbox series

Message ID 20180807160013.11537-2-y.karadz@gmail.com
State New, archived
Headers show
Series
  • [1/2] kernel-shark-qt: Add Json-C as a third party dependency.
Related show

Commit Message

Yordan Karadzhov (VMware) Aug. 7, 2018, 4 p.m. UTC
Add to the C API of KernelShark instruments for saving/loading of
filter configuration to/from Json files.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark-qt/src/CMakeLists.txt   |   1 +
 kernel-shark-qt/src/libkshark-json.c | 601 +++++++++++++++++++++++++++
 kernel-shark-qt/src/libkshark.h      |  49 +++
 3 files changed, 651 insertions(+)
 create mode 100644 kernel-shark-qt/src/libkshark-json.c

Comments

Steven Rostedt Aug. 8, 2018, 1:21 a.m. UTC | #1
On Tue,  7 Aug 2018 19:00:13 +0300
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:

> Add to the C API of KernelShark instruments for saving/loading of
> filter configuration to/from Json files.
> 
> Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
> ---
>  kernel-shark-qt/src/CMakeLists.txt   |   1 +
>  kernel-shark-qt/src/libkshark-json.c | 601 +++++++++++++++++++++++++++
>  kernel-shark-qt/src/libkshark.h      |  49 +++
>  3 files changed, 651 insertions(+)
>  create mode 100644 kernel-shark-qt/src/libkshark-json.c
> 
> diff --git a/kernel-shark-qt/src/CMakeLists.txt b/kernel-shark-qt/src/CMakeLists.txt
> index ea5dbda..b3de765 100644
> --- a/kernel-shark-qt/src/CMakeLists.txt
> +++ b/kernel-shark-qt/src/CMakeLists.txt
> @@ -2,6 +2,7 @@ message("\n src ...")
>  
>  message(STATUS "libkshark")
>  add_library(kshark SHARED libkshark.c
> +                          libkshark-json.c
>                            libkshark-model.c
>                            libkshark-collection.c)
>  
> diff --git a/kernel-shark-qt/src/libkshark-json.c b/kernel-shark-qt/src/libkshark-json.c
> new file mode 100644
> index 0000000..d06488e
> --- /dev/null
> +++ b/kernel-shark-qt/src/libkshark-json.c
> @@ -0,0 +1,601 @@
> +// SPDX-License-Identifier: LGPL-2.1
> +
> +/*
> + * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <y.karadz@gmail.com>
> + */
> +
> + /**
> +  *  @file    libkshark-json.c
> +  *  @brief   Json Confoguration I/O.
> +  */
> +
> +// C
> +/** Use GNU C Library. */
> +#define _GNU_SOURCE
> +#include <stdio.h>
> +
> +// KernelShark
> +#include "libkshark.h"
> +
> +/**
> + * @brief Create an empty Json document and set its type description.
> + *
> + * @param type: String describing the type of the document,
> + *		e.g. "kshark.record.config" or "kshark.filter.config".
> + *
> + * @returns json_object instance. Use json_object_put() to free the object.

I wonder if we should add handlers like:

	kshark_config_free(struct json_object *jobj);

and call that instead? Perhaps even create our own object that may
contain extra state that the json object does not, and return that?


> + */
> +struct json_object *kshark_config_alloc(const char *type)
> +{
> +	json_object *jobj, *jtype;
> +
> +	jobj = json_object_new_object();
> +	jtype = json_object_new_string(type);
> +
> +	if (!jobj || !jtype)
> +		goto fail;
> +
> +	/* Set the type of this Json document. */
> +	json_object_object_add(jobj, "type", jtype);
> +
> +	return jobj;
> +
> + fail:
> +	fprintf(stderr, "Failed to allocate memory for json_object.\n");
> +	json_object_put(jobj);
> +	json_object_put(jtype);
> +
> +	return NULL;
> +}
> +
> +/**
> + * @brief Create an empty Record Configuration document. The type description
> + *	  is set to "kshark.record.config".
> + *
> + * @returns json_object instance. Use json_object_put() to free the object.
> + */
> +struct json_object *kshark_record_config_alloc()
> +{
> +	return kshark_config_alloc("kshark.record.config");
> +}
> +
> +/**
> + * @brief Create an empty Filter Configuration document. The type description
> + *	  is set to "kshark.filter.config".
> + *
> + * @returns json_object instance. Use json_object_put() to free the object.
> + */
> +struct json_object *kshark_filter_config_alloc()
> +{
> +	return kshark_config_alloc("kshark.filter.config");;
> +}
> +
> +/**
> + * @brief Record the current configuration of an Event Id filter into a Json
> + *	  document.
> + *
> + * @param pevt: Input location for the Page event.
> + * @param filter: Input location for an Id filter.
> + * @param filter_name: The name of the filter to show up in the Json document.
> + * @param jobj: Input location for the json_object instance.
> + */
> +void kshark_event_filter_to_json(struct pevent *pevt,

Please call "struct pevent" variables "pevent". Need to stay
consistent. Ideally, we should pick a single name for types of data
structures. This will be useful when we rename pevent to something else
as well.


> +				 struct tracecmd_filter_id *filter,
> +				 const char *filter_name,
> +				 struct json_object *jobj)
> +{
> +	json_object *jfilter_data, *jevent, *jsystem, *jname;
> +	int i, evt, *ids;
> +	char *temp;
> +
> +	/* Get the array of Ids to be fitered. */
> +	ids = tracecmd_filter_ids(filter);

ids needs to be freed. And tracecmd_filter_ids() needs documentation
describing it :-/  (that's my fault, hmm Tzvetomir could fix this ;-).

It also needs to be checked for NULL.

> +
> +	/* Create a Json array and fill the Id values into it. */
> +	jfilter_data = json_object_new_array();
> +	if (!jfilter_data)
> +		goto fail;
> +
> +	for (i = 0; i < filter->count; ++i) {
> +		for (evt = 0; evt < pevt->nr_events; ++evt) {
> +			if (pevt->events[evt]->id == ids[i]) {
> +				jevent = json_object_new_object();
> +
> +				temp = pevt->events[evt]->system;
> +				jsystem = json_object_new_string(temp);
> +
> +				temp = pevt->events[evt]->name;
> +				jname = json_object_new_string(temp);
> +
> +				if (!jevent || !jsystem || !jname)
> +					goto fail;
> +
> +				json_object_object_add(jevent, "system",
> +							       jsystem);
> +
> +				json_object_object_add(jevent, "name",
> +							       jname);
> +
> +				json_object_array_add(jfilter_data, jevent);
> +
> +				break;
> +			}
> +		}
> +	}
> +
> +	/* Add the array of Ids to the filter config document. */
> +	json_object_object_add(jobj, filter_name, jfilter_data);
> +
> +	return;
> +
> + fail:
> +	fprintf(stderr, "Failed to allocate memory for json_object.\n");
> +	json_object_put(jfilter_data);
> +	json_object_put(jevent);
> +	json_object_put(jsystem);
> +	json_object_put(jname);
> +}
> +
> +/**
> + * @brief Load from Json document the configuration of an Event Id filter.
> + *
> + * @param pevt: Input location for the Page event.
> + * @param filter: Input location for an Id filter.
> + * @param filter_name: The name of the filter as showing up in the Json
> + *	               document.
> + * @param jobj: Input location for the json_object instance.
> + *
> + * @returns True, if a filter has been loaded. If the filter configuration
> + *	    document contains no data for this particular filter or in a case
> + *	    of an error, the function returns False.
> + */
> +bool kshark_event_filter_from_json(struct pevent *pevt,
> +				   struct tracecmd_filter_id *filter,
> +				   const char *filter_name,
> +				   struct json_object *jobj)
> +{
> +	json_object *jfilter, *jevent, *jsystem, *jname;
> +	const char *system_str, *name_str;
> +	struct event_format *event;
> +	int i, length;
> +
> +	/*
> +	 * Use the name of the filter to find the array of events associated
> +	 * with this filter. Notice that the filter config document may
> +	 * contain no data for this particular filter.
> +	 */
> +	json_object_object_get_ex(jobj, filter_name, &jfilter);

Shouldn't you add a check of the return value of the above. Looking at
the documentation:

  http://json-c.github.io/json-c/json-c-0.12/doc/html/json__object_8h.html#af3f38b3395b1af8e9d3ac73818c3a936

You could have:

	ret = json_object_object_get_ex(jobj, filter_name, &jfilter);

	if (!ret || json_object_get_type(jfilter) != ...


> +	if (!jfilter || json_object_get_type(jfilter) != json_type_array)
> +		return false;
> +
> +	/* Set the filter. */
> +	length = json_object_array_length(jfilter);
> +	for (i = 0; i < length; ++i) {
> +		jevent = json_object_array_get_idx(jfilter, i);
> +
> +		json_object_object_get_ex(jevent, "system", &jsystem);
> +		json_object_object_get_ex(jevent, "name", &jname);

Same here.

> +		if (!jsystem || !jname)
> +			goto fail;
> +
> +		system_str = json_object_get_string(jsystem);
> +		name_str = json_object_get_string(jname);
> +
> +		event = pevent_find_event_by_name(pevt, system_str, name_str);
> +		if (!event)
> +			goto fail;
> +
> +		tracecmd_filter_id_add(filter, event->id);
> +	}
> +
> +	return true;
> +
> + fail:
> +	fprintf(stderr, "Failed to load event filter from json_object.\n");
> +	return false;
> +}
> +
> +static void kshark_task_filter_to_json(struct tracecmd_filter_id *filter,
> +				       const char *filter_name,
> +				       struct json_object *jobj)
> +{
> +	json_object *jfilter_data, *jpid;
> +	int i, *ids;
> +
> +	/* Get the array of Ids to be fitered. */
> +	ids = tracecmd_filter_ids(filter);

Again, ids need to be freed.

> +
> +	/* Create a Json array and fill the Id values into it. */
> +	jfilter_data = json_object_new_array();
> +	if (!jfilter_data)

Hmm, can json_object_put() take a NULL pointer?

> +		goto fail;
> +
> +	for (i = 0; i < filter->count; ++i) {
> +		jpid = json_object_new_int(ids[i]);
> +		if (!jpid)
> +			goto fail;
> +
> +		json_object_array_add(jfilter_data, jpid);
> +	}
> +
> +	/* Add the array of Ids to the filter config document. */
> +	json_object_object_add(jobj, filter_name, jfilter_data);
> +
> +	return;
> +
> + fail:
> +	fprintf(stderr, "Failed to allocate memory for json_object.\n");
> +	json_object_put(jfilter_data);
> +	json_object_put(jpid);
> +}
> +
> +static bool kshark_task_filter_from_json(struct tracecmd_filter_id *filter,
> +					 const char *filter_name,
> +					 struct json_object *jobj)
> +{
> +	json_object *jfilter, *jpid;
> +	int i, length;
> +
> +	/*
> +	 * Use the name of the filter to find the array of events associated
> +	 * with this filter. Notice that the filter config document may
> +	 * contain no data for this particular filter.
> +	 */
> +	json_object_object_get_ex(jobj, filter_name, &jfilter);
> +	if (!jfilter || json_object_get_type(jfilter) != json_type_array)
> +		return false;
> +
> +	/* Set the filter. */
> +	length = json_object_array_length(jfilter);
> +	for (i = 0; i < length; ++i) {
> +		jpid = json_object_array_get_idx(jfilter, i);
> +		if (!jpid)
> +			goto fail;
> +
> +		tracecmd_filter_id_add(filter, json_object_get_int(jpid));
> +	}
> +
> +	return true;
> +
> + fail:
> +	fprintf(stderr, "Failed to load task filter from json_object.\n");
> +	return false;
> +}
> +
> +/**
> + * @brief Record the current configuration of the advanced filter into a Json
> + *	  document.
> + *
> + * @param kshark_ctx: Input location for session context pointer.
> + * @param jobj: Input location for the json_object instance.
> + */
> +void kshark_adv_filters_to_json(struct kshark_context *kshark_ctx,
> +				struct json_object *jobj)
> +{
> +	struct event_filter *adv_filter = kshark_ctx->advanced_event_filter;
> +	json_object *jfilter_data, *jevent, *jsystem, *jname, *jfilter;
> +	struct event_format **events;
> +	char *str;
> +	int i;
> +
> +	if (!kshark_ctx->advanced_event_filter->filters)

Should we also check if advanced_event_filter is NULL?

> +		return;
> +
> +	/* Create a Json array and fill the Id values into it. */
> +	jfilter_data = json_object_new_array();
> +	if (!jfilter_data)
> +		goto fail;
> +
> +	events = pevent_list_events(kshark_ctx->pevent, EVENT_SORT_SYSTEM);

events returned could be NULL. Need to check that.

(will review the rest tomorrow)

-- Steve

> +
> +	for (i = 0; events[i]; i++) {
> +		str = pevent_filter_make_string(adv_filter,
> +						events[i]->id);
> +		if (!str)
> +			continue;
> +
> +		jevent = json_object_new_object();
> +		jsystem = json_object_new_string(events[i]->system);
> +		jname = json_object_new_string(events[i]->name);
> +		jfilter = json_object_new_string(str);
> +		if (!jevent || !jsystem || !jname || !jfilter)
> +			goto fail;
> +
> +		json_object_object_add(jevent, "system", jsystem);
> +		json_object_object_add(jevent, "name", jname);
> +		json_object_object_add(jevent, "condition", jfilter);
> +
> +		json_object_array_add(jfilter_data, jevent);
> +	}
> +
> +	/* Add the array of advanced filters to the filter config document. */
> +	json_object_object_add(jobj, "adv event filter", jfilter_data);
> +
> +	return;
> +
Yordan Karadzhov (VMware) Aug. 8, 2018, 11:48 a.m. UTC | #2
Hi Steven,

On  8.08.2018 04:21, Steven Rostedt wrote:
>> /**
>> + * @brief Create an empty Json document and set its type description.
>> + *
>> + * @param type: String describing the type of the document,
>> + *		e.g. "kshark.record.config" or "kshark.filter.config".
>> + *
>> + * @returns json_object instance. Use json_object_put() to free the object.
> I wonder if we should add handlers like:
> 
> 	kshark_config_free(struct json_object *jobj);
> 
> and call that instead? Perhaps even create our own object that may
> contain extra state that the json object does not, and return that?
> 
> 

What do we gain by doing it this way?

Thanks!
Yordan
Yordan Karadzhov (VMware) Aug. 8, 2018, 11:48 a.m. UTC | #3
On  8.08.2018 04:21, Steven Rostedt wrote:
>> +
>> +	/* Create a Json array and fill the Id values into it. */
>> +	jfilter_data = json_object_new_array();
>> +	if (!jfilter_data)
> Hmm, can json_object_put() take a NULL pointer?
> 

Yes, see here:

https://github.com/json-c/json-c/blob/master/json_object.c#L185

Thanks!
Yordan
Steven Rostedt Aug. 8, 2018, 12:32 p.m. UTC | #4
On Wed, 8 Aug 2018 14:48:10 +0300
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:

> Hi Steven,
> 
> On  8.08.2018 04:21, Steven Rostedt wrote:
> >> /**
> >> + * @brief Create an empty Json document and set its type description.
> >> + *
> >> + * @param type: String describing the type of the document,
> >> + *		e.g. "kshark.record.config" or "kshark.filter.config".
> >> + *
> >> + * @returns json_object instance. Use json_object_put() to free the object.  
> > I wonder if we should add handlers like:
> > 
> > 	kshark_config_free(struct json_object *jobj);
> > 
> > and call that instead? Perhaps even create our own object that may
> > contain extra state that the json object does not, and return that?
> > 
> >   
> 
> What do we gain by doing it this way?
> 

   CONTROL!!!!! :-) :-)


But seriously, if we had our own abstraction for the json objects, we
could carry extra data along with it if need be. In fact, we could
abstract out completely that we use json. We could just add our own
wrappers, and if some day in the future, something else comes along
that's better than json, we could switch to that.

I'm not strongly committed to doing this abstraction, but I want us to
think about it before we commit to anything. Like I said, forward
compatibility is the difficult part. I don't know exactly how this is
all going to end up being used, but I like to keep my options open.

-- Steve
Steven Rostedt Aug. 8, 2018, 12:33 p.m. UTC | #5
On Wed, 8 Aug 2018 14:48:53 +0300
"Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:

> On  8.08.2018 04:21, Steven Rostedt wrote:
> >> +
> >> +	/* Create a Json array and fill the Id values into it. */
> >> +	jfilter_data = json_object_new_array();
> >> +	if (!jfilter_data)  
> > Hmm, can json_object_put() take a NULL pointer?
> >   
> 
> Yes, see here:
> 
> https://github.com/json-c/json-c/blob/master/json_object.c#L185
> 

Sadly they don't appear to document this fact :-/

 http://json-c.github.io/json-c/json-c-0.12/doc/html/json__object_8h.html#a1bb50e2d17832c404c3d5f13fbde5bf5

-- Steve
Yordan Karadzhov (VMware) Aug. 8, 2018, 12:59 p.m. UTC | #6
On  8.08.2018 15:32, Steven Rostedt wrote:
> On Wed, 8 Aug 2018 14:48:10 +0300
> "Yordan Karadzhov (VMware)" <y.karadz@gmail.com> wrote:
> 
>> Hi Steven,
>>
>> On  8.08.2018 04:21, Steven Rostedt wrote:
>>>> /**
>>>> + * @brief Create an empty Json document and set its type description.
>>>> + *
>>>> + * @param type: String describing the type of the document,
>>>> + *		e.g. "kshark.record.config" or "kshark.filter.config".
>>>> + *
>>>> + * @returns json_object instance. Use json_object_put() to free the object.
>>> I wonder if we should add handlers like:
>>>
>>> 	kshark_config_free(struct json_object *jobj);
>>>
>>> and call that instead? Perhaps even create our own object that may
>>> contain extra state that the json object does not, and return that?
>>>
>>>    
>>
>> What do we gain by doing it this way?
>>
> 
>     CONTROL!!!!! :-) :-)
> 
> 
> But seriously, if we had our own abstraction for the json objects, we
> could carry extra data along with it if need be. In fact, we could
> abstract out completely that we use json. We could just add our own
> wrappers, and if some day in the future, something else comes along
> that's better than json, we could switch to that.
> 

OK will try to implement a wrapper and abstract out the use json.

Thanks!
Yordan


> I'm not strongly committed to doing this abstraction, but I want us to
> think about it before we commit to anything. Like I said, forward
> compatibility is the difficult part. I don't know exactly how this is
> all going to end up being used, but I like to keep my options open.
> 
> -- Steve
>

Patch
diff mbox series

diff --git a/kernel-shark-qt/src/CMakeLists.txt b/kernel-shark-qt/src/CMakeLists.txt
index ea5dbda..b3de765 100644
--- a/kernel-shark-qt/src/CMakeLists.txt
+++ b/kernel-shark-qt/src/CMakeLists.txt
@@ -2,6 +2,7 @@  message("\n src ...")
 
 message(STATUS "libkshark")
 add_library(kshark SHARED libkshark.c
+                          libkshark-json.c
                           libkshark-model.c
                           libkshark-collection.c)
 
diff --git a/kernel-shark-qt/src/libkshark-json.c b/kernel-shark-qt/src/libkshark-json.c
new file mode 100644
index 0000000..d06488e
--- /dev/null
+++ b/kernel-shark-qt/src/libkshark-json.c
@@ -0,0 +1,601 @@ 
+// SPDX-License-Identifier: LGPL-2.1
+
+/*
+ * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <y.karadz@gmail.com>
+ */
+
+ /**
+  *  @file    libkshark-json.c
+  *  @brief   Json Confoguration I/O.
+  */
+
+// C
+/** Use GNU C Library. */
+#define _GNU_SOURCE
+#include <stdio.h>
+
+// KernelShark
+#include "libkshark.h"
+
+/**
+ * @brief Create an empty Json document and set its type description.
+ *
+ * @param type: String describing the type of the document,
+ *		e.g. "kshark.record.config" or "kshark.filter.config".
+ *
+ * @returns json_object instance. Use json_object_put() to free the object.
+ */
+struct json_object *kshark_config_alloc(const char *type)
+{
+	json_object *jobj, *jtype;
+
+	jobj = json_object_new_object();
+	jtype = json_object_new_string(type);
+
+	if (!jobj || !jtype)
+		goto fail;
+
+	/* Set the type of this Json document. */
+	json_object_object_add(jobj, "type", jtype);
+
+	return jobj;
+
+ fail:
+	fprintf(stderr, "Failed to allocate memory for json_object.\n");
+	json_object_put(jobj);
+	json_object_put(jtype);
+
+	return NULL;
+}
+
+/**
+ * @brief Create an empty Record Configuration document. The type description
+ *	  is set to "kshark.record.config".
+ *
+ * @returns json_object instance. Use json_object_put() to free the object.
+ */
+struct json_object *kshark_record_config_alloc()
+{
+	return kshark_config_alloc("kshark.record.config");
+}
+
+/**
+ * @brief Create an empty Filter Configuration document. The type description
+ *	  is set to "kshark.filter.config".
+ *
+ * @returns json_object instance. Use json_object_put() to free the object.
+ */
+struct json_object *kshark_filter_config_alloc()
+{
+	return kshark_config_alloc("kshark.filter.config");;
+}
+
+/**
+ * @brief Record the current configuration of an Event Id filter into a Json
+ *	  document.
+ *
+ * @param pevt: Input location for the Page event.
+ * @param filter: Input location for an Id filter.
+ * @param filter_name: The name of the filter to show up in the Json document.
+ * @param jobj: Input location for the json_object instance.
+ */
+void kshark_event_filter_to_json(struct pevent *pevt,
+				 struct tracecmd_filter_id *filter,
+				 const char *filter_name,
+				 struct json_object *jobj)
+{
+	json_object *jfilter_data, *jevent, *jsystem, *jname;
+	int i, evt, *ids;
+	char *temp;
+
+	/* Get the array of Ids to be fitered. */
+	ids = tracecmd_filter_ids(filter);
+
+	/* Create a Json array and fill the Id values into it. */
+	jfilter_data = json_object_new_array();
+	if (!jfilter_data)
+		goto fail;
+
+	for (i = 0; i < filter->count; ++i) {
+		for (evt = 0; evt < pevt->nr_events; ++evt) {
+			if (pevt->events[evt]->id == ids[i]) {
+				jevent = json_object_new_object();
+
+				temp = pevt->events[evt]->system;
+				jsystem = json_object_new_string(temp);
+
+				temp = pevt->events[evt]->name;
+				jname = json_object_new_string(temp);
+
+				if (!jevent || !jsystem || !jname)
+					goto fail;
+
+				json_object_object_add(jevent, "system",
+							       jsystem);
+
+				json_object_object_add(jevent, "name",
+							       jname);
+
+				json_object_array_add(jfilter_data, jevent);
+
+				break;
+			}
+		}
+	}
+
+	/* Add the array of Ids to the filter config document. */
+	json_object_object_add(jobj, filter_name, jfilter_data);
+
+	return;
+
+ fail:
+	fprintf(stderr, "Failed to allocate memory for json_object.\n");
+	json_object_put(jfilter_data);
+	json_object_put(jevent);
+	json_object_put(jsystem);
+	json_object_put(jname);
+}
+
+/**
+ * @brief Load from Json document the configuration of an Event Id filter.
+ *
+ * @param pevt: Input location for the Page event.
+ * @param filter: Input location for an Id filter.
+ * @param filter_name: The name of the filter as showing up in the Json
+ *	               document.
+ * @param jobj: Input location for the json_object instance.
+ *
+ * @returns True, if a filter has been loaded. If the filter configuration
+ *	    document contains no data for this particular filter or in a case
+ *	    of an error, the function returns False.
+ */
+bool kshark_event_filter_from_json(struct pevent *pevt,
+				   struct tracecmd_filter_id *filter,
+				   const char *filter_name,
+				   struct json_object *jobj)
+{
+	json_object *jfilter, *jevent, *jsystem, *jname;
+	const char *system_str, *name_str;
+	struct event_format *event;
+	int i, length;
+
+	/*
+	 * Use the name of the filter to find the array of events associated
+	 * with this filter. Notice that the filter config document may
+	 * contain no data for this particular filter.
+	 */
+	json_object_object_get_ex(jobj, filter_name, &jfilter);
+	if (!jfilter || json_object_get_type(jfilter) != json_type_array)
+		return false;
+
+	/* Set the filter. */
+	length = json_object_array_length(jfilter);
+	for (i = 0; i < length; ++i) {
+		jevent = json_object_array_get_idx(jfilter, i);
+
+		json_object_object_get_ex(jevent, "system", &jsystem);
+		json_object_object_get_ex(jevent, "name", &jname);
+		if (!jsystem || !jname)
+			goto fail;
+
+		system_str = json_object_get_string(jsystem);
+		name_str = json_object_get_string(jname);
+
+		event = pevent_find_event_by_name(pevt, system_str, name_str);
+		if (!event)
+			goto fail;
+
+		tracecmd_filter_id_add(filter, event->id);
+	}
+
+	return true;
+
+ fail:
+	fprintf(stderr, "Failed to load event filter from json_object.\n");
+	return false;
+}
+
+static void kshark_task_filter_to_json(struct tracecmd_filter_id *filter,
+				       const char *filter_name,
+				       struct json_object *jobj)
+{
+	json_object *jfilter_data, *jpid;
+	int i, *ids;
+
+	/* Get the array of Ids to be fitered. */
+	ids = tracecmd_filter_ids(filter);
+
+	/* Create a Json array and fill the Id values into it. */
+	jfilter_data = json_object_new_array();
+	if (!jfilter_data)
+		goto fail;
+
+	for (i = 0; i < filter->count; ++i) {
+		jpid = json_object_new_int(ids[i]);
+		if (!jpid)
+			goto fail;
+
+		json_object_array_add(jfilter_data, jpid);
+	}
+
+	/* Add the array of Ids to the filter config document. */
+	json_object_object_add(jobj, filter_name, jfilter_data);
+
+	return;
+
+ fail:
+	fprintf(stderr, "Failed to allocate memory for json_object.\n");
+	json_object_put(jfilter_data);
+	json_object_put(jpid);
+}
+
+static bool kshark_task_filter_from_json(struct tracecmd_filter_id *filter,
+					 const char *filter_name,
+					 struct json_object *jobj)
+{
+	json_object *jfilter, *jpid;
+	int i, length;
+
+	/*
+	 * Use the name of the filter to find the array of events associated
+	 * with this filter. Notice that the filter config document may
+	 * contain no data for this particular filter.
+	 */
+	json_object_object_get_ex(jobj, filter_name, &jfilter);
+	if (!jfilter || json_object_get_type(jfilter) != json_type_array)
+		return false;
+
+	/* Set the filter. */
+	length = json_object_array_length(jfilter);
+	for (i = 0; i < length; ++i) {
+		jpid = json_object_array_get_idx(jfilter, i);
+		if (!jpid)
+			goto fail;
+
+		tracecmd_filter_id_add(filter, json_object_get_int(jpid));
+	}
+
+	return true;
+
+ fail:
+	fprintf(stderr, "Failed to load task filter from json_object.\n");
+	return false;
+}
+
+/**
+ * @brief Record the current configuration of the advanced filter into a Json
+ *	  document.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance.
+ */
+void kshark_adv_filters_to_json(struct kshark_context *kshark_ctx,
+				struct json_object *jobj)
+{
+	struct event_filter *adv_filter = kshark_ctx->advanced_event_filter;
+	json_object *jfilter_data, *jevent, *jsystem, *jname, *jfilter;
+	struct event_format **events;
+	char *str;
+	int i;
+
+	if (!kshark_ctx->advanced_event_filter->filters)
+		return;
+
+	/* Create a Json array and fill the Id values into it. */
+	jfilter_data = json_object_new_array();
+	if (!jfilter_data)
+		goto fail;
+
+	events = pevent_list_events(kshark_ctx->pevent, EVENT_SORT_SYSTEM);
+
+	for (i = 0; events[i]; i++) {
+		str = pevent_filter_make_string(adv_filter,
+						events[i]->id);
+		if (!str)
+			continue;
+
+		jevent = json_object_new_object();
+		jsystem = json_object_new_string(events[i]->system);
+		jname = json_object_new_string(events[i]->name);
+		jfilter = json_object_new_string(str);
+		if (!jevent || !jsystem || !jname || !jfilter)
+			goto fail;
+
+		json_object_object_add(jevent, "system", jsystem);
+		json_object_object_add(jevent, "name", jname);
+		json_object_object_add(jevent, "condition", jfilter);
+
+		json_object_array_add(jfilter_data, jevent);
+	}
+
+	/* Add the array of advanced filters to the filter config document. */
+	json_object_object_add(jobj, "adv event filter", jfilter_data);
+
+	return;
+
+ fail:
+	fprintf(stderr, "Failed to allocate memory for json_object.\n");
+	json_object_put(jfilter_data);
+	json_object_put(jevent);
+	json_object_put(jsystem);
+	json_object_put(jname);
+	json_object_put(jfilter);
+}
+
+/**
+ * @brief Load from Json document the configuration of the advanced filter.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance.
+ *
+ * @returns True, if a filter has been loaded. If the filter configuration
+ *	    document contains no data for this particular filter or in a case
+ *	    of an error, the function returns False.
+ */
+bool kshark_adv_filters_from_json(struct kshark_context *kshark_ctx,
+				  struct json_object *jobj)
+{
+	struct event_filter *adv_filter = kshark_ctx->advanced_event_filter;
+	json_object *jfilter, *jsystem, *jname, *jcond;
+	int i, length, ret;
+	char *filter_str;
+
+	/*
+	 * Use the name of the filter to find the array of events associated
+	 * with this filter. Notice that the filter config document may
+	 * contain no data for this particular filter.
+	 */
+	json_object_object_get_ex(jobj, "adv event filter", &jfilter);
+	if (!jfilter || json_object_get_type(jfilter) != json_type_array) {
+		return false;
+	}
+
+	/* Set the filter. */
+	length = json_object_array_length(jfilter);
+	for (i = 0; i < length; ++i) {
+		jfilter = json_object_array_get_idx(jfilter, i);
+		json_object_object_get_ex(jfilter, "system", &jsystem);
+		json_object_object_get_ex(jfilter, "name", &jname);
+		json_object_object_get_ex(jfilter, "condition", &jcond);
+		if (!jsystem || !jname || !jcond)
+			goto fail;
+
+		asprintf(&filter_str, "%s/%s:%s",
+			 json_object_get_string(jsystem),
+			 json_object_get_string(jname),
+			 json_object_get_string(jcond));
+
+		ret = pevent_filter_add_filter_str(adv_filter,
+						   filter_str);
+		if (ret < 0)
+			goto fail;
+	}
+
+	return true;
+
+ fail:
+	fprintf(stderr, "Failed to laod Advanced filters.\n");
+	char error_str[200];
+	int error_status =
+		pevent_strerror(kshark_ctx->pevent, ret, error_str,
+							 sizeof(error_str));
+
+	if (error_status == 0)
+		fprintf(stderr, "filter failed due to: %s\n", error_str);
+
+	free(filter_str);
+	return false;
+}
+
+static bool filter_is_set(struct tracecmd_filter_id *filter)
+{
+	return filter && filter->count;
+}
+
+/**
+ * @brief Record the current configuration of "show task" and "hide task"
+ *	  filters into a Json document.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance. If NULL a new
+ *		Filter Configuration document will be created.
+ */
+void kshark_all_event_filters_to_json(struct kshark_context *kshark_ctx,
+				      struct json_object **jobj)
+{
+	if (!*jobj)
+		*jobj = kshark_filter_config_alloc();
+
+	/* Save a filter only if it contains Id values. */
+	if (filter_is_set(kshark_ctx->show_event_filter))
+		kshark_event_filter_to_json(kshark_ctx->pevent,
+					    kshark_ctx->show_event_filter,
+					    "show event filter",
+					    *jobj);
+
+	if (filter_is_set(kshark_ctx->hide_event_filter))
+		kshark_event_filter_to_json(kshark_ctx->pevent,
+					    kshark_ctx->hide_event_filter,
+					    "hide event filter",
+					    *jobj);
+}
+
+/**
+ * @brief Record the current configuration of "show task" and "hide task"
+ *	  filters into a Json document.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance. If NULL a new
+ *		Filter Configuration document will be created.
+ */
+void kshark_all_task_filters_to_json(struct kshark_context *kshark_ctx,
+				     struct json_object **jobj)
+{
+	if (!*jobj)
+		*jobj = kshark_filter_config_alloc();
+
+	/* Save a filter only if it contains Id values. */
+	if (filter_is_set(kshark_ctx->show_task_filter))
+		kshark_task_filter_to_json(kshark_ctx->show_task_filter,
+					   "show task filter",
+					   *jobj);
+
+	if (filter_is_set(kshark_ctx->hide_task_filter))
+		kshark_task_filter_to_json(kshark_ctx->hide_task_filter,
+					   "hide task filter",
+					   *jobj);
+}
+
+/**
+ * @brief Load from Json document the configuration of "show event" and
+ *	 "hide event" filters.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance.
+ *
+ * @returns True, if a filter has been loaded. If the filter configuration
+ *	    document contains no data for any event filter or in a case
+ *	    of an error, the function returns False.
+ */
+bool kshark_all_event_filters_from_json(struct kshark_context *kshark_ctx,
+					struct json_object *jobj)
+{
+	bool status;
+
+	status = kshark_event_filter_from_json(kshark_ctx->pevent,
+					       kshark_ctx->hide_event_filter,
+					       "hide event filter",
+					       jobj);
+
+	status |= kshark_event_filter_from_json(kshark_ctx->pevent,
+						kshark_ctx->show_event_filter,
+						"show event filter",
+						jobj);
+
+	return status;
+}
+
+/**
+ * @brief Load from Json document the configuration of "show task" and
+ *	 "hide task" filters.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance.
+ *
+ * @returns True, if a filter has been loaded. If the filter configuration
+ *	    document contains no data for any task filter or in a case of an
+ *	    error, the function returns False.
+ */
+bool kshark_all_task_filters_from_json(struct kshark_context *kshark_ctx,
+				       struct json_object *jobj)
+{
+	bool status;
+
+	status = kshark_task_filter_from_json(kshark_ctx->hide_task_filter,
+					      "hide task filter",
+					      jobj);
+
+	status |= kshark_task_filter_from_json(kshark_ctx->show_task_filter,
+					       "show task filter",
+					       jobj);
+
+	return status;
+}
+
+/**
+ * @brief Create a Filter Configuration document containing the current
+ *	  configuration of all filters.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ *
+ * @returns json_object instance. Use json_object_put() to free the object.
+ */
+struct json_object *
+kshark_all_filters_to_json(struct kshark_context *kshark_ctx)
+{
+	struct json_object *jobj;
+
+	/*  Create a new Json document. */
+	jobj = kshark_filter_config_alloc();
+
+	/* Save a filter only if it contains Id values. */
+	kshark_all_event_filters_to_json(kshark_ctx, &jobj);
+	kshark_all_task_filters_to_json(kshark_ctx, &jobj);
+	kshark_adv_filters_to_json(kshark_ctx, jobj);
+
+	return jobj;
+}
+
+/**
+ * @brief Load from Json document the configuration of all filters.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param jobj: Input location for the json_object instance.
+ *
+ * @returns True, if a filter has been loaded. If the filter configuration
+ *	    document contains no data for any filter or in a case of an error,
+ *	    the function returns False.
+ */
+bool kshark_all_filters_from_json(struct kshark_context *kshark_ctx,
+				  struct json_object *jobj)
+{
+	bool status;
+	status = kshark_all_task_filters_from_json(kshark_ctx, jobj);
+	status |= kshark_all_event_filters_from_json(kshark_ctx, jobj);
+	status |= kshark_adv_filters_from_json(kshark_ctx, jobj);
+
+	return status;
+}
+
+/**
+ * @brief Save a Json Configuration document into a file.
+ *
+ * @param file_name: The name of the file.
+ * @param jobj: Input location for the json_object instance.
+ */
+void kshark_save_json_file(const char *file_name,
+			   struct json_object *jobj)
+{
+	int flags;
+
+	/* Save the file in a human-readable form. */
+	flags = JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY;
+	json_object_to_file_ext(file_name, jobj, flags);
+}
+
+/**
+ * @brief Open a Jason file and check if it has the expected type.
+ *
+ * @param file_name: The name of the file.
+ * @param type: String describing the expected type of the document,
+ *		e.g. "kshark.record.config" or "kshark.filter.config".
+ *
+ * @returns json_object instance on success, or NULL on failure. Use
+ *	    json_object_put() to free the object.
+ */
+struct json_object *kshark_open_json_file(const char *file_name,
+					  const char *type)
+{
+	struct json_object *jobj, *var;
+	const char *type_var;
+
+	jobj = json_object_from_file(file_name);
+
+	if (!jobj)
+		return NULL;
+
+	/* Get the type of the document. */
+	json_object_object_get_ex(jobj, "type", &var);
+	type_var = json_object_get_string(var);
+
+	if (strcmp(type, type_var) != 0) {
+		/* The document has a wrong type. */
+		fprintf(stderr, "Failed to open Json file %s\n.", file_name);
+		fprintf(stderr, "The document has a wrong type.\n");
+
+		json_object_put(jobj);
+		return NULL;
+	}
+
+	return jobj;
+}
diff --git a/kernel-shark-qt/src/libkshark.h b/kernel-shark-qt/src/libkshark.h
index ff09da3..cdf6cbc 100644
--- a/kernel-shark-qt/src/libkshark.h
+++ b/kernel-shark-qt/src/libkshark.h
@@ -16,6 +16,9 @@ 
 #include <stdint.h>
 #include <pthread.h>
 
+// Json-C
+#include <json.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -367,6 +370,52 @@  kshark_get_collection_entry_back(struct kshark_entry_request **req,
 				 const struct kshark_entry_collection *col,
 				 ssize_t *index);
 
+struct json_object *kshark_config_alloc(const char *type);
+
+struct json_object *kshark_record_config_alloc();
+
+struct json_object *kshark_filter_config_alloc();
+
+void kshark_adv_filters_to_json(struct kshark_context *kshark_ctx,
+				struct json_object *jobj);
+
+bool kshark_adv_filters_from_json(struct kshark_context *kshark_ctx,
+				  struct json_object *jobj);
+
+void kshark_event_filter_to_json(struct pevent *pevt,
+				 struct tracecmd_filter_id *filter,
+				 const char *filter_name,
+				 struct json_object *jobj);
+
+bool kshark_event_filter_from_json(struct pevent *pevt,
+				   struct tracecmd_filter_id *filter,
+				   const char *filter_name,
+				   struct json_object *jobj);
+
+void kshark_all_event_filters_to_json(struct kshark_context *kshark_ctx,
+				      struct json_object **jobj);
+
+void kshark_all_task_filters_to_json(struct kshark_context *kshark_ctx,
+				     struct json_object **jobj);
+
+struct json_object *
+kshark_all_filters_to_json(struct kshark_context *kshark_ctx);
+
+bool kshark_all_event_filters_from_json(struct kshark_context *kshark_ctx,
+					struct json_object *jobj);
+
+bool kshark_all_task_filters_from_json(struct kshark_context *kshark_ctx,
+					struct json_object *jobj);
+
+bool kshark_all_filters_from_json(struct kshark_context *kshark_ctx,
+				  struct json_object *jobj);
+
+void kshark_save_json_file(const char *filter_name,
+			   struct json_object *jobj);
+
+struct json_object *kshark_open_json_file(const char *filter_name,
+					  const char *type);
+
 #ifdef __cplusplus
 }
 #endif