summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Stanislawski <l.stanislaws@samsung.com>2018-07-23 14:35:43 +0200
committerLukasz Stanislawski <l.stanislaws@samsung.com>2018-07-24 16:52:48 +0200
commita7be9ea774634dc90b497acfd652366aae0a3bfe (patch)
tree2ee91f80c4965f7c51f73ac240910391267cdb9e
parent97b64e4a86eefa601f226334c7e6fe842156d5f1 (diff)
downloadttsd-worker-task-a7be9ea774634dc90b497acfd652366aae0a3bfe.tar.gz
ttsd-worker-task-a7be9ea774634dc90b497acfd652366aae0a3bfe.tar.bz2
ttsd-worker-task-a7be9ea774634dc90b497acfd652366aae0a3bfe.zip
report-generator: reafactor process generator
Change-Id: Ic1664627b6562f78e7b34d70a2bbdb45f0e07f4a
-rw-r--r--src/config-deserializer.c64
-rw-r--r--src/config-deserializer.h12
-rw-r--r--src/config.h28
-rw-r--r--src/json-schema-defs.h4
-rw-r--r--src/process.c24
-rw-r--r--src/process.h10
-rw-r--r--src/report-generator.c209
-rw-r--r--src/report-generator.h79
-rw-r--r--src/report-json-serializer.c76
-rw-r--r--src/report-json-serializer.h4
-rw-r--r--src/report.h14
-rw-r--r--src/task-factory.c109
-rw-r--r--src/task-worker.c2
-rw-r--r--src/task.h18
14 files changed, 295 insertions, 358 deletions
diff --git a/src/config-deserializer.c b/src/config-deserializer.c
index d753fe5..6e8e233 100644
--- a/src/config-deserializer.c
+++ b/src/config-deserializer.c
@@ -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;
+ }
+ }
+}
diff --git a/src/config-deserializer.h b/src/config-deserializer.h
index 6793e85..1b44cdd 100644
--- a/src/config-deserializer.h
+++ b/src/config-deserializer.h
@@ -27,8 +27,16 @@
* @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
diff --git a/src/config.h b/src/config.h
index 578a91e..dc163f7 100644
--- a/src/config.h
+++ b/src/config.h
@@ -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 {
diff --git a/src/json-schema-defs.h b/src/json-schema-defs.h
index 3492e29..38e15b1 100644
--- a/src/json-schema-defs.h
+++ b/src/json-schema-defs.h
@@ -38,12 +38,16 @@
#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"
diff --git a/src/process.c b/src/process.c
index 17159f7..610735e 100644
--- a/src/process.c
+++ b/src/process.c
@@ -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);
+}
diff --git a/src/process.h b/src/process.h
index 12344ee..0f7558b 100644
--- a/src/process.h
+++ b/src/process.h
@@ -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
diff --git a/src/report-generator.c b/src/report-generator.c
index 9a0f680..9869bcb 100644
--- a/src/report-generator.c
+++ b/src/report-generator.c
@@ -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;
}
diff --git a/src/report-generator.h b/src/report-generator.h
index b720379..ac31de0 100644
--- a/src/report-generator.h
+++ b/src/report-generator.h
@@ -17,6 +17,10 @@
#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
diff --git a/src/report-json-serializer.c b/src/report-json-serializer.c
index 659fd71..949d82c 100644
--- a/src/report-json-serializer.c
+++ b/src/report-json-serializer.c
@@ -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,
diff --git a/src/report-json-serializer.h b/src/report-json-serializer.h
index e607ca1..b236c8a 100644
--- a/src/report-json-serializer.h
+++ b/src/report-json-serializer.h
@@ -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
diff --git a/src/report.h b/src/report.h
index 4b511e1..dc717c4 100644
--- a/src/report.h
+++ b/src/report.h
@@ -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
diff --git a/src/task-factory.c b/src/task-factory.c
index 3c9fcf6..c8c6751 100644
--- a/src/task-factory.c
+++ b/src/task-factory.c
@@ -27,30 +27,40 @@
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)
diff --git a/src/task-worker.c b/src/task-worker.c
index 6f6a9d3..425d582 100644
--- a/src/task-worker.c
+++ b/src/task-worker.c
@@ -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;
}
diff --git a/src/task.h b/src/task.h
index 22f8823..3156f21 100644
--- a/src/task.h
+++ b/src/task.h
@@ -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