report-generator: reafactor process generator 44/184844/3
authorLukasz Stanislawski <l.stanislaws@samsung.com>
Mon, 23 Jul 2018 12:35:43 +0000 (14:35 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Tue, 24 Jul 2018 14:52:48 +0000 (16:52 +0200)
Change-Id: Ic1664627b6562f78e7b34d70a2bbdb45f0e07f4a

14 files changed:
src/config-deserializer.c
src/config-deserializer.h
src/config.h
src/json-schema-defs.h
src/process.c
src/process.h
src/report-generator.c
src/report-generator.h
src/report-json-serializer.c
src/report-json-serializer.h
src/report.h
src/task-factory.c
src/task-worker.c
src/task.h

index d753fe5..6e8e233 100644 (file)
@@ -16,7 +16,9 @@
 
 #include <stdio.h>
 #include <glib.h>
+#include <stdlib.h>
 #include <json-glib/json-glib.h>
+
 #include "json-schema-defs.h"
 #include "config-deserializer.h"
 #include "config.h"
@@ -28,6 +30,7 @@ static void config_array_iterate_func(JsonArray *array, guint index, JsonNode *e
 static config_options_e config_parse_options(const char *option);
 static int calculate_task_counter(int frequency);
 static config_top_subject_e config_parse_top_subject(const char *option);
+static config_data_process_t config_parse_process_data(JsonArray *obj);
 
 static struct _cfg_data
 {
@@ -112,13 +115,9 @@ static void config_array_iterate_func(JsonArray *array, guint index, JsonNode *e
     }
     else if (g_strcmp0(type, SCHEMA_TYPE_PROCESS) == 0)
     {
-        configs[index].scope = APPS;
-
-        const gchar *target = json_object_get_string_member(entry, SCHEMA_TARGET);
-        configs[index].data.process.options = config_parse_options(target);
+        configs[index].scope = PROCESS;
 
-        const gchar *app_id = json_object_get_string_member(entry, SCHEMA_ID);
-        snprintf(configs[index].data.process.app_id, APP_ID_REGEX_MAX_LEN + 1, "%s", app_id);
+               configs[index].data.process = config_parse_process_data(json_object_get_array_member(entry, SCHEMA_REQUEST_DATA_MATCHERS));
     }
     else if (g_strcmp0(type, SCHEMA_TYPE_LOAD_AVG) == 0)
     {
@@ -126,6 +125,46 @@ static void config_array_iterate_func(JsonArray *array, guint index, JsonNode *e
     }
 }
 
+static const char *json_object_safe_get_string_member(JsonObject *obj, const char *member)
+{
+       if (json_object_has_member(obj, member))
+               return json_object_get_string_member(obj, member);
+       return NULL;
+}
+
+static void _process_foreach_matcher(JsonArray *array, guint index,
+               JsonNode *node, gpointer user_data)
+{
+       config_data_process_t *ret = user_data;
+       struct matcher match;
+
+       JsonObject *elem = json_node_get_object(node);
+       if (!elem) return;
+
+       const char *appid = json_object_safe_get_string_member(elem, SCHEMA_RESULT_APP_ID);
+       const char *exe = json_object_safe_get_string_member(elem, SCHEMA_RESULT_EXE);
+
+       match.app_id = appid ? strdup(appid) : NULL;
+       match.exe = exe ? strdup(exe) : NULL;
+
+       ret->matchers[ret->n_matchers++] = match;
+}
+
+static config_data_process_t config_parse_process_data(JsonArray *array)
+{
+       config_data_process_t ret = {0,};
+
+       int len = json_array_get_length(array);
+       if (len == 0) return ret;
+
+       ret.matchers = calloc(len, sizeof(struct matcher));
+       ret.n_matchers = 0;
+
+       json_array_foreach_element(array, _process_foreach_matcher, &ret);
+
+       return ret;
+}
+
 static config_options_e config_parse_options(const char *option)
 {
     if (g_strcmp0(option, SCHEMA_TARGET_CPU) == 0)
@@ -158,3 +197,16 @@ static config_top_subject_e config_parse_top_subject(const char *option)
 
     return -1;
 }
+
+void free_configs(config_t *configs, int len)
+{
+       for (int i=0; i < len; ++i) {
+               switch (configs[i].scope) {
+                       case PROCESS:
+                               free(configs[i].data.process.matchers);
+                               break;
+                       default:
+                               break;
+               }
+       }
+}
index 6793e85..1b44cdd 100644 (file)
  * @param[out] task_counter The number of tasks to be executed.
  *
  * @return Dynamically allocated config_t array.
- * @note Returned array should be released with free.
+ * @note Returned array should be released with @free_configs.
  */
 config_t *deserialize_configs(const char *config_json, int *size, int *task_counter);
 
-#endif
\ No newline at end of file
+/**
+ * @brief Releases memory allocated on @deserialize_configs
+ *
+ * @param[in] config value returned from @deserialize_configs
+ * @param[in] size size of the config. Value returned from @deserialize_configs.
+ */
+void free_configs(config_t *config, int size);
+
+#endif
index 578a91e..dc163f7 100644 (file)
@@ -30,9 +30,9 @@ typedef enum config_scope
     SYSTEM,
 
     /**
-     * @brief Observe system resources used by one or more app.
+     * @brief Observe system resources used by processes.
      */
-    APPS,
+    PROCESS,
 
     /**
      * @brief Observe top usage of memory or cpu.
@@ -58,22 +58,24 @@ typedef enum config_options
     /**
      * @brief Observe memory usage.
      */
-    OBSERVE_MEMORY } config_options_e;
+    OBSERVE_MEMORY
+} config_options_e;
+
+/**
+ * @brief Matcher data
+ */
+struct matcher {
+       const char *app_id;
+       const char *exe;
+};
 
 /**
  * @brief Config app data structure.
  */
-typedef struct config_data_app
+typedef struct config_data_process
 {
-    /**
-     * @brief Config options.
-     */
-    config_options_e options;
-
-    /**
-     * @brief String containing regular expression with app id.
-     */
-    char app_id[APP_ID_REGEX_MAX_LEN+1];
+       struct matcher *matchers;
+       int n_matchers;
 } config_data_process_t;
 
 typedef enum config_top_subject {
index 3492e29..38e15b1 100644 (file)
 #define SCHEMA_TOP "top"
 #define SCHEMA_ID "id"
 
+#define SCHEMA_REQUEST_DATA_MATCHERS "matchers"
+
 #define SCHEMA_RESULT_DATA_SYSTEM "system_data"
 #define SCHEMA_RESULT_DATA_LOAD_AVG "load_avg_data"
 #define SCHEMA_RESULT_DATA_PROCESS "process_data"
 #define SCHEMA_RESULT_DATA_TOP "top_data"
 
+#define SCHEMA_RESULT_APP_ID "app_id"
 #define SCHEMA_RESULT_PID "pid"
+#define SCHEMA_RESULT_EXE "exe"
 #define SCHEMA_RESULT_TIME "time"
 #define SCHEMA_RESULT_USAGE "usage"
 #define SCHEMA_RESULT_CPU "cpu"
index 17159f7..610735e 100644 (file)
@@ -8,6 +8,7 @@
 #include "err-check.h"
 #include "procfs.h"
 #include "appinfo-provider.h"
+#include "json-schema-defs.h"
 
 static struct sys_stats sys;
 static int pagesize;
@@ -126,3 +127,26 @@ int process_init()
        pagesize = getpagesize();
        return 0;
 }
+
+void process_serialize(struct process *proc, JsonBuilder *builder)
+{
+       ON_NULL_RETURN(proc);
+
+       float tmp;
+       json_builder_begin_object(builder);
+
+       json_builder_set_member_name(builder, SCHEMA_RESULT_APP_ID);
+       json_builder_add_string_value(builder, process_get_appid(proc));
+       json_builder_set_member_name(builder, SCHEMA_RESULT_EXE);
+       json_builder_add_string_value(builder, process_get_exe(proc));
+       json_builder_set_member_name(builder, SCHEMA_RESULT_PID);
+       json_builder_add_int_value(builder, process_get_pid(proc));
+       json_builder_set_member_name(builder, SCHEMA_RESULT_CPU);
+       process_get_cpu_usage_percentage(proc, &tmp);
+       json_builder_add_double_value(builder, tmp);
+       json_builder_set_member_name(builder, SCHEMA_RESULT_MEMORY);
+       process_get_memory_usage_percentage(proc, &tmp);
+       json_builder_add_double_value(builder, tmp);
+
+       json_builder_end_object(builder);
+}
index 12344ee..0f7558b 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef __PROCESS_H
 #define __PROCESS_H
 
+#include <json-glib/json-glib.h>
+
 /**
  * @brief The process structure.
  *
@@ -145,4 +147,12 @@ int process_get_cpu_usage_percentage(struct process *proc, float *usage);
  */
 int process_get_memory_usage_percentage(struct process *dst, float *usage);
 
+/**
+ * @brief Serializes process object as json
+ *
+ * @param[in]: proc process
+ * @param[in/out]: the json builder object.
+ */
+void process_serialize(struct process *dst, JsonBuilder *builer);
+
 #endif
index 9a0f680..9869bcb 100644 (file)
@@ -28,6 +28,7 @@
 #include "clock.h"
 #include "proc-scanner.h"
 #include "process.h"
+#include "json-schema-defs.h"
 
 struct report_generator_system {
        /** system cpu usage statistics */
@@ -36,18 +37,10 @@ struct report_generator_system {
 
 struct report_generator_process
 {
-       /** process pid */
-       int pid;
-       /** process statistics */
-       struct process proc;
-       /** update time */
-       float proc_update_time;
-};
-
-struct report_generator_app
-{
-       char *app_id;
-       report_generator_process_t *process_gen;
+       proc_scanner_t *scanner;
+       report_generator_filter_cb filter;
+       void *user_data;
+       JsonBuilder *current_builder;
 };
 
 struct report_generator_top
@@ -60,12 +53,10 @@ struct report_generator_top
 
 struct report_generator_top_closure {
        struct sys_stats sys_stats;
-       int current_index;
-       int max_index;
+       int current_index; int max_index;
        struct process_usage_report *usage_report;
 };
 
-int _app_report_generator_setup_process_generator(report_generator_app_t *generator);
 static int _report_generator_top_report_generator_scan(report_generator_top_t *generator);
 
 report_generator_system_t *report_generator_new_system_report_generator()
@@ -91,195 +82,115 @@ void report_generator_free_system_generator(report_generator_system_t *generator
        free(generator);
 }
 
-report_generator_process_t *report_generator_new_process_report_generator(int pid)
+report_generator_process_t *report_generator_new_process_report_generator()
 {
-       ON_TRUE_RETURN_VAL(pid <= 0, NULL);
-
        report_generator_process_t *ret = calloc(1, sizeof(struct report_generator_process));
        if (!ret)
                return NULL;
 
-       process_init(pid, &ret->proc);
-
-       if (process_update(&ret->proc) != 0) {
-               ERR("process_update failed.");
-               free(ret);
-               return NULL;
-       };
-
-       ret->proc_update_time = clock_monotonic_get();
-       ret->pid = pid;
-
-       return ret;
-}
+       ret->scanner = proc_scanner_new();
+       if (!ret->scanner) goto err;
 
-void report_generator_free_process_generator(report_generator_process_t *generator)
-{
-       if (!generator)
-               return;
-
-       free(generator);
-}
-
-report_generator_app_t *report_generator_new_app_report_generator(const char *app_id)
-{
-       ON_NULL_RETURN_VAL(app_id, NULL);
-
-       report_generator_app_t *ret = calloc(1, sizeof(struct report_generator_app));
-       if (!ret) {
-               ERR("malloc failed");
-               return NULL;
+       if (proc_scanner_scan(ret->scanner) != 0) {
+               ERR("proc_scanner_scan failed");
+               goto err;
        }
 
-       ret->app_id = strdup(app_id);
-       _app_report_generator_setup_process_generator(ret);
        return ret;
+
+err:
+       proc_scanner_free(ret->scanner);
+       free(ret);
+       return NULL;
 }
 
-void report_generator_free_app_generator(report_generator_app_t *generator)
+void report_generator_free_process_generator(report_generator_process_t *generator)
 {
        if (!generator) return;
-       report_generator_free_process_generator(generator->process_gen);
-       free(generator->app_id);
+       proc_scanner_free(generator->scanner);
        free(generator);
 }
 
-int report_generator_generate_system_report(
-               report_generator_system_t *generator,
-               struct system_report *report)
+static bool _match_proc_and_append(struct process *proc, void *data)
 {
-       ON_NULL_RETURN_VAL(generator, -1);
-       ON_NULL_RETURN_VAL(report, -1);
+       report_generator_process_t *gen = data;
 
-       if (sys_stats_update(&generator->stats) != 0) {
-               ERR("stats_update_system_stats failed.");
-               return -1;
+       if (gen->filter && gen->filter(proc, gen->user_data)) {
+               process_serialize(proc, gen->current_builder);
        }
 
-       if (sys_stats_get_cpu_usage_percentage(&generator->stats, &report->cpu))
-       {
-               ERR("stats_get_system_cpu_usage_average failed");
-               return -1;
-       }
-
-       if (sys_stats_get_memory_usage_percentage(&generator->stats, &report->memory) != 0) {
-               ERR("stats_get_system_memory_usage failed.");
-               return -1;
-       }
-
-
-       report->time = clock_realtime_get();
-
-       return 0;
+       return true;
 }
 
-int report_generator_generate_process_cpu_usage_report(
+int report_generator_generate_process_report(
                report_generator_process_t *generator,
-               struct process_usage_report *report)
+               JsonBuilder *builder)
 {
        ON_NULL_RETURN_VAL(generator, -1);
-       ON_NULL_RETURN_VAL(report, -1);
-
-       float usage;
+       ON_NULL_RETURN_VAL(builder, -1);
 
-       if (process_update(&generator->proc) != 0) {
-               ERR("process_update failed.");
+       // refresh data
+       if (proc_scanner_scan(generator->scanner) != 0) {
+               ERR("proc_scanner_scan failed");
                return -1;
        }
 
-       if (process_get_cpu_usage_percentage(&generator->proc, &usage) != 0) {
-               ERR("process_get_cpu_usage_percentage failed.");
-               return -1;
-       }
+       generator->current_builder = builder;
+       json_builder_begin_object(builder);
 
-       report->time = clock_realtime_get();
-       report->pid = generator->pid;
-       report->usage = usage;
+       json_builder_set_member_name(builder, SCHEMA_TYPE);
+       json_builder_add_string_value(builder, SCHEMA_TYPE_PROCESS);
 
-       return 0;
-}
+       json_builder_set_member_name(builder, "time");
+       json_builder_add_int_value(builder, clock_realtime_get());
 
-int report_generator_generate_process_memory_usage_report(
-               report_generator_process_t *generator,
-               struct process_usage_report *report)
-{
-       ON_NULL_RETURN_VAL(generator, -1);
-       ON_NULL_RETURN_VAL(report, -1);
+       json_builder_set_member_name(builder, SCHEMA_RESULT_DATA_PROCESS);
+       json_builder_begin_array(builder);
 
-       float usage;
+       proc_scanner_foreach_process(generator->scanner, _match_proc_and_append, generator);
+       json_builder_end_array(builder);
 
-       if (process_get_memory_usage_percentage(&generator->proc, &usage) != 0) {
-               ERR("process_get_memory_usage_percentage failed.");
-               return -1;
-       }
-
-       report->time = clock_realtime_get();
-       report->usage = usage;
+       json_builder_end_object(builder); // end report
 
+       generator->current_builder = NULL;
        return 0;
 }
 
-int _app_report_generator_setup_process_generator(report_generator_app_t *generator)
+void report_generator_set_filter(
+               report_generator_process_t *generator,
+               report_generator_filter_cb cb, const void *user_data)
 {
-       int pid = app_info_provider_find_main_pid(generator->app_id);
-       if (pid < 0) {
-               return -1;
-       }
+       ON_NULL_RETURN(generator);
+       ON_NULL_RETURN(cb);
 
-       if (!generator->process_gen || generator->process_gen->pid != pid) {
-               if (generator->process_gen)
-                       report_generator_free_process_generator(generator->process_gen);
-               generator->process_gen = report_generator_new_process_report_generator(pid);
-       }
-       return 0;
+       generator->filter = cb;
+       generator->user_data = (void*)user_data;
 }
 
-int report_generator_generate_app_cpu_usage_report(
-               report_generator_app_t *generator,
-               struct process_usage_report *report)
+int report_generator_generate_system_report(
+               report_generator_system_t *generator,
+               struct system_report *report)
 {
        ON_NULL_RETURN_VAL(generator, -1);
        ON_NULL_RETURN_VAL(report, -1);
 
-       if (_app_report_generator_setup_process_generator(generator) != 0) {
-               ERR("_app_report_generator_setup_process_generator failed.");
+       if (sys_stats_update(&generator->stats) != 0) {
+               ERR("stats_update_system_stats failed.");
                return -1;
        }
 
-       if (report_generator_generate_process_cpu_usage_report(
-                               generator->process_gen, report) != 0)
+       if (sys_stats_get_cpu_usage_percentage(&generator->stats, &report->cpu))
        {
-               ERR("report_generator_generate_process_cpu_usage_report failed.");
-               return 0;
-       }
-
-       strncpy(report->app_id, generator->app_id, sizeof(report->app_id));
-       report->pid = generator->process_gen->pid;
-
-       return 0;
-}
-
-int report_generator_generate_app_memory_usage_report(
-               report_generator_app_t *generator,
-               struct process_usage_report *report)
-{
-       ON_NULL_RETURN_VAL(generator, -1);
-       ON_NULL_RETURN_VAL(report, -1);
-
-       if (_app_report_generator_setup_process_generator(generator)) {
-               ERR("_app_report_generator_setup_process_generator failed.");
+               ERR("stats_get_system_cpu_usage_average failed");
                return -1;
        }
 
-       if (report_generator_generate_process_memory_usage_report(
-                               generator->process_gen, report) != 0)
-       {
-               ERR("report_generator_generate_process_memory_usage_report failed.");
-               return 0;
+       if (sys_stats_get_memory_usage_percentage(&generator->stats, &report->memory) != 0) {
+               ERR("stats_get_system_memory_usage failed.");
+               return -1;
        }
 
-       strncpy(report->app_id, generator->app_id, sizeof(report->app_id));
-       report->pid = generator->process_gen->pid;
+       report->time = clock_realtime_get();
 
        return 0;
 }
index b720379..ac31de0 100644 (file)
 #ifndef __REPORT_GENERATOR_H_
 #define __REPORT_GENERATOR_H_
 
+#include <json-glib/json-glib.h>
+#include <stdbool.h>
+
+#include "process.h"
 #include "report.h"
 
 /** Generator for system-wide reports */
@@ -25,9 +29,6 @@ typedef struct report_generator_system report_generator_system_t;
 /** Generator for per process report */
 typedef struct report_generator_process report_generator_process_t;
 
-/** Generator for app report */
-typedef struct report_generator_app report_generator_app_t;
-
 /** Top report generator yt*/
 typedef enum report_generator_top_type
 {
@@ -56,13 +57,12 @@ void report_generator_free_system_generator(report_generator_system_t *generator
 /**
  * @brief Creates new instance of report_generator_process_t
  *
- * @param[in] process PID
  * @return new report_generator_system_t object, or NULL on error
  *
  * @remark return value should be released with
  * @report_generator_free_process_generator
  */
-report_generator_process_t *report_generator_new_process_report_generator(int pid);
+report_generator_process_t *report_generator_new_process_report_generator();
 
 /**
  * @brief Release report_generator_process_t created with
@@ -71,23 +71,6 @@ report_generator_process_t *report_generator_new_process_report_generator(int pi
 void report_generator_free_process_generator(report_generator_process_t *generator);
 
 /**
- * @brief Creates new instance of report_generator_app_t
- *
- * @param[in] Apps id.
- * @return New report_generator_app_t object, or NULL on error
- *
- * @remark return value should be released with
- * @report_generator_free_app_generator
- */
-report_generator_app_t *report_generator_new_app_report_generator(const char *app_id);
-
-/**
- * @brief Release report_generator_app_t created with
- * @report_generator_new_app_report_generator
- */
-void report_generator_free_app_generator(report_generator_app_t *generator);
-
-/**
  * @brief Creates new instance of report_generator_top_h
  *
  * @param[in] type Type of apps to track in generator.
@@ -123,59 +106,25 @@ int report_generator_generate_system_report(
                struct system_report *report);
 
 /**
- * @brief Fills process_usage_report.
+ * @brief Get process_report.
  *
  * return report with process cpu usage calculated as average between current
- * time and last call to report_generator_generate_process_cpu_usage_report for
+ * time and last call to report_generator_generate_process_report for
  * generator
  *
  * @param[in] generator process generator
- * @param[out] report
  *
- * @return 0 on success, other value on failure
+ * @return 0 on success, other value on error.
  */
-int report_generator_generate_process_cpu_usage_report(
+int report_generator_generate_process_report(
                report_generator_process_t *generator,
-               struct process_usage_report *report);
+               JsonBuilder *builder);
 
-/**
- * @brief Fills process_usage_report.
- *
- * @param[in] generator process generator
- * @param[out] report
- * @return 0 on success, other value on failure
- */
-int report_generator_generate_proccess_memory_usage_report(
-               report_generator_process_t *generator,
-               struct process_usage_report *report);
+typedef bool (*report_generator_filter_cb)(struct process *proc, void *user_data);
 
-/**
- * @brief Fills apps_cpu_usage_report.
- *
- * return report with apps cpu usage calculated as average between current time
- * and last call to report_generator_generate_process_cpu_usage_report for
- * generator
- *
- * @param[in] generator apps generator
- * @param[out] report
- *
- * @return 0 on success, other value on failure
- * @remarks Returned value should be freed.
- */
-int report_generator_generate_app_cpu_usage_report(
-               report_generator_app_t *generator,
-               struct process_usage_report *report);
-
-/**
- * @brief Fills process_usage_report.
- *
- * @param[in] generator apps generator
- * @param[out] report
- * @return 0 on success, other value on failure
- */
-int report_generator_generate_app_memory_usage_report(
-               report_generator_app_t *generator,
-               struct process_usage_report *report);
+void report_generator_set_filter(
+               report_generator_process_t *generator,
+               report_generator_filter_cb cb, const void *user_data);
 
 /**
  * @brief Fills system_load_average_report
index 659fd71..949d82c 100644 (file)
@@ -186,64 +186,37 @@ static void top_memory_usage_reports_to_json_object(JsonBuilder *builder, struct
        json_builder_end_object(builder);
 }
 
-static void apps_cpu_usage_report_to_json_object(JsonBuilder *builder, struct process_usage_report *report)
+static void process_report_to_json_object(JsonBuilder *builder, struct process_report *report)
 {
        json_builder_begin_object(builder);
 
        json_builder_set_member_name(builder, SCHEMA_TYPE);
        json_builder_add_string_value(builder, SCHEMA_TYPE_PROCESS);
 
-       json_builder_set_member_name(builder, SCHEMA_TARGET);
-       json_builder_add_string_value(builder, SCHEMA_TARGET_CPU);
-
-       json_builder_set_member_name(builder, SCHEMA_RESULT_DATA_PROCESS);
-       json_builder_begin_object(builder);
-
-       json_builder_set_member_name(builder, SCHEMA_ID);
-       json_builder_add_string_value(builder, report->app_id);
-       json_builder_set_member_name(builder, SCHEMA_RESULT_PID);
-       json_builder_add_int_value(builder, report->pid);
-
-       json_builder_set_member_name(builder, SCHEMA_RESULT_RESULT);
-       json_builder_begin_object(builder);
        json_builder_set_member_name(builder, SCHEMA_RESULT_TIME);
        json_builder_add_int_value(builder, report->time);
-       json_builder_set_member_name(builder, SCHEMA_RESULT_USAGE);
-       json_builder_add_double_value(builder, report->usage);
-
-       json_builder_end_object(builder);
-       json_builder_end_object(builder);
-       json_builder_end_object(builder);
-}
-
-static void apps_memory_usage_report_to_json_object(JsonBuilder *builder, struct process_usage_report *report)
-{
-       json_builder_begin_object(builder);
-
-       json_builder_set_member_name(builder, SCHEMA_TYPE);
-       json_builder_add_string_value(builder, SCHEMA_TYPE_PROCESS);
-
-       json_builder_set_member_name(builder, SCHEMA_TARGET);
-       json_builder_add_string_value(builder, SCHEMA_TARGET_MEMORY);
 
        json_builder_set_member_name(builder, SCHEMA_RESULT_DATA_PROCESS);
-       json_builder_begin_object(builder);
-
-       json_builder_set_member_name(builder, SCHEMA_ID);
-       json_builder_add_string_value(builder, report->app_id);
-       json_builder_set_member_name(builder, SCHEMA_RESULT_PID);
-       json_builder_add_int_value(builder, report->pid);
+       json_builder_begin_array(builder);
 
-       json_builder_set_member_name(builder, SCHEMA_RESULT_RESULT);
-       json_builder_begin_object(builder);
-       json_builder_set_member_name(builder, SCHEMA_RESULT_TIME);
-       json_builder_add_int_value(builder, report->time);
-       json_builder_set_member_name(builder, SCHEMA_RESULT_USAGE);
-       json_builder_add_double_value(builder, report->usage);
+       for (int i = 0; i < report->n_processes; ++i) {
+               json_builder_begin_object(builder);
+               json_builder_set_member_name(builder, SCHEMA_RESULT_APP_ID);
+               json_builder_add_string_value(builder, report->processes[i].app_id);
+               json_builder_set_member_name(builder, SCHEMA_RESULT_EXE);
+               json_builder_add_string_value(builder, report->processes[i].exe);
+               json_builder_set_member_name(builder, SCHEMA_RESULT_PID);
+               json_builder_add_int_value(builder, report->processes[i].pid);
+               json_builder_set_member_name(builder, SCHEMA_RESULT_CPU);
+               json_builder_add_double_value(builder, report->processes[i].cpu);
+               json_builder_set_member_name(builder, SCHEMA_RESULT_MEMORY);
+               json_builder_add_double_value(builder, report->processes[i].memory);
+               json_builder_end_object(builder);
+       }
+       json_builder_end_array(builder);
 
-       json_builder_end_object(builder);
-       json_builder_end_object(builder);
-       json_builder_end_object(builder);
+       json_builder_end_object(builder); // end data process
+       json_builder_end_object(builder); // end report
 }
 
 IMPLEMENT_SERIALIZER_FUNC(
@@ -257,14 +230,9 @@ IMPLEMENT_SERIALIZER_FUNC(
                system_report_to_json_object)
 
 IMPLEMENT_SERIALIZER_FUNC(
-               report_json_serializer_serialize_apps_cpu_usage_report,
-               struct process_usage_report,
-               apps_cpu_usage_report_to_json_object)
-
-IMPLEMENT_SERIALIZER_FUNC(
-               report_json_serializer_serialize_apps_memory_usage_report,
-               struct process_usage_report,
-               apps_memory_usage_report_to_json_object)
+               report_json_serializer_serialize_process_report,
+               struct process_report,
+               process_report_to_json_object)
 
 IMPLEMENT_ARRAY_SERIALIZER_FUNC(
                report_json_serializer_serialize_top_cpu_usage_reports,
index e607ca1..b236c8a 100644 (file)
@@ -40,14 +40,14 @@ char *report_json_serializer_serialize_system_load_average_report(struct system_
 char *report_json_serializer_serialize_system_report(struct system_report *report);
 
 /**
- * @brief Serializes process_usage_report to json string
+ * @brief Serializes process_report to json string
  *
  * @param[in] report Report structure with usage data.
  *
  * @return dynamically allocated string on NULL on error.
  * @remark returned value should be released with @free
  */
-char *report_json_serializer_serialize_process_cpu_usage_report(struct process_usage_report *report);
+char *report_json_serializer_serialize_process_report(struct process_report *report);
 
 /**
  * @brief Serializes process_usage_report to json string
index 4b511e1..dc717c4 100644 (file)
@@ -50,5 +50,19 @@ struct process_usage_report {
        char app_id[APP_ID_MAX_SIZE];
 };
 
+struct process_info {
+       const char *app_id;
+       const char *exe;
+       int pid;
+       float cpu; /** CPU utilization (Percent) */
+       float memory; /** Memory utilization (Percent) */
+};
+
+struct process_report {
+       time_t time; /** Number of seconds after the Epoch */
+       struct process_info *processes;
+       int n_processes;
+};
+
 #endif
 
index 3c9fcf6..c8c6751 100644 (file)
 
 static task_t *create_system_report_task();
 static task_t *create_load_avg_report_task();
-static task_t *create_app_report_task(config_options_e options, const char *regex);
+static task_t *create_process_report_task(config_data_process_t *config);
 static task_t *create_top_report_task(struct config_data_top options);
 
 static void execute_scan_system(task_t *task);
 static void execute_scan_load_avg(task_t *task);
-static void execute_scan_app_memory(task_t *task);
-static void execute_scan_apps_cpu(task_t *task);
+static void execute_scan_process(task_t *task);
 static void execute_scan_top_cpu(task_t *task);
 static void execute_scan_top_memory(task_t *task);
 
 static void release_system_task(task_t *task);
-static void release_app_task(task_t *task);
+static void release_process_task(task_t *task);
 static void release_top_task(task_t *task);
 
+/**
+ * @brief Process task structure.
+ */
+typedef struct process_task
+{
+    task_t task;
+    report_generator_process_t *report_generator;
+       JsonBuilder *builder;
+       JsonGenerator *generator;
+} process_task_t;
+
 task_t *task_factory_create_task(const config_t *config)
 {
-    switch(config->scope)
+    switch (config->scope)
     {
         case SYSTEM:
             return create_system_report_task();
         case LOAD_AVG:
             return create_load_avg_report_task();
-        case APPS:
-            return create_app_report_task(config->data.process.options, config->data.process.app_id);
+        case PROCESS:
+            return create_process_report_task(&config->data.process);
         case TOP:
             return create_top_report_task(config->data.top);
         default:
@@ -79,28 +89,39 @@ static task_t *create_load_avg_report_task()
     return _load_avg_task;
 }
 
-static task_t *create_app_report_task(config_options_e options, const char *app_id)
+static bool _report_generator_process_filter_cb(struct process *proc, void *user_data)
+{
+       config_data_process_t *data = user_data;
+
+       for (int i = 0; i < data->n_matchers; ++i) {
+               struct matcher *match = &data->matchers[i];
+               if (match->app_id && process_get_appid(proc)) {
+                       if (strcmp(match->app_id, process_get_appid(proc)) == 0)
+                               return true;
+               }
+               if (match->exe && process_get_exe(proc)) {
+                       if (strcmp(match->exe, process_get_exe(proc)) == 0)
+                               return true;
+               }
+       }
+       return false;
+}
+
+static task_t *create_process_report_task(config_data_process_t *config)
 {
-    app_task_t *_app_task = (app_task_t *)g_malloc(sizeof(app_task_t));
+    process_task_t *_process_task = (process_task_t *)g_malloc(sizeof(process_task_t));
 
-    _app_task->task.release = release_app_task;
-    _app_task->report_generator = report_generator_new_app_report_generator(app_id);
+    _process_task->task.release = release_process_task;
+    _process_task->report_generator = report_generator_new_process_report_generator();
+    _process_task->task.execute = execute_scan_process;
+       _process_task->builder = json_builder_new();
+       _process_task->generator = json_generator_new();
 
-    switch (options)
-    {
-        case OBSERVE_CPU:
-            _app_task->task.execute = execute_scan_apps_cpu;
-            break;
-        case OBSERVE_MEMORY:
-            _app_task->task.execute = execute_scan_app_memory;
-            break;
-        default:
-            report_generator_free_app_generator(_app_task->report_generator);
-            g_free(_app_task);
-            return NULL;
-    }
+       report_generator_set_filter(_process_task->report_generator,
+                       _report_generator_process_filter_cb,
+                       config);
 
-    return &_app_task->task;
+    return &_process_task->task;
 }
 
 static void execute_scan_system(task_t *task)
@@ -133,32 +154,22 @@ static void execute_scan_load_avg(task_t *task)
     g_free(json_report);
 }
 
-static void execute_scan_app_memory(task_t *task)
+static void execute_scan_process(task_t *task)
 {
     ON_NULL_RETURN(task);
 
-    app_task_t *_app_task = container_of(task, app_task_t, task);
-
-    struct process_usage_report report;
-
-    report_generator_generate_app_memory_usage_report(_app_task->report_generator, &report);
-
-    char *json_report = report_json_serializer_serialize_apps_memory_usage_report(&report);
-    ipc_send_report(json_report);
-    g_free(json_report);
-}
-
-static void execute_scan_apps_cpu(task_t *task)
-{
-    ON_NULL_RETURN(task);
+    process_task_t *_process_task = container_of(task, process_task_t, task);
 
-    app_task_t *_app_task = container_of(task, app_task_t, task);
+       json_builder_reset(_process_task->builder);
 
-    struct process_usage_report reports;
+    if (report_generator_generate_process_report(_process_task->report_generator, _process_task->builder) != 0) {
+               return;
+       }
 
-    report_generator_generate_app_cpu_usage_report(_app_task->report_generator, &reports);
+       JsonNode *root = json_builder_get_root(_process_task->builder);
+       json_generator_set_root(_process_task->generator, root);
+       char *json_report = json_generator_to_data(_process_task->generator, NULL);
 
-    char *json_report = report_json_serializer_serialize_apps_cpu_usage_report(&reports);
     ipc_send_report(json_report);
     g_free(json_report);
 }
@@ -173,14 +184,16 @@ static void release_system_task(task_t *task)
     g_free(_system_task);
 }
 
-static void release_app_task(task_t *task)
+static void release_process_task(task_t *task)
 {
     ON_NULL_RETURN(task);
 
-    app_task_t *_app_task = container_of(task, app_task_t, task);
+    process_task_t *_process_task = container_of(task, process_task_t, task);
 
-    report_generator_free_app_generator(_app_task->report_generator);
-    g_free(_app_task);
+    report_generator_free_process_generator(_process_task->report_generator);
+       g_object_unref(_process_task->builder);
+       g_object_unref(_process_task->generator);
+    g_free(_process_task);
 }
 
 static task_t *create_top_report_task(struct config_data_top options)
index 6f6a9d3..425d582 100644 (file)
@@ -80,7 +80,7 @@ int main(int argc, char *argv[])
        scheduler_destroy(data.scheduler);
        app_provider_shutdown();
        ipc_shutdown();
-       g_free(data.current_config);
+       free_configs(data.current_config, cfg_size);
 
        return 0;
 }
index 22f8823..3156f21 100644 (file)
@@ -54,24 +54,6 @@ typedef struct system_task
 } system_task_t;
 
 /**
- * @brief Application task structure.
- */
-typedef struct app_task
-{
-    task_t task;
-    report_generator_app_t *report_generator;
-} app_task_t;
-
-/**
- * @brief Process task structure.
- */
-typedef struct process_task
-{
-    task_t task;
-    report_generator_process_t *report_generator;
-} process_task_t;
-
-/**
  * @brief Top task structure.
  */
 typedef struct top_task