report-generator: reafactor process generator
[apps/native/ttsd-worker-task.git] / src / report-generator.c
index e442523..9869bcb 100644 (file)
 #include "log.h"
 #include "err-check.h"
 #include "appinfo-provider.h"
-#include "stats.h"
+#include "sys-stats.h"
 #include "clock.h"
 #include "proc-scanner.h"
+#include "process.h"
+#include "json-schema-defs.h"
 
 struct report_generator_system {
        /** system cpu usage statistics */
-       struct stats_system previous;
+       struct sys_stats stats;
 };
 
 struct report_generator_process
 {
-       /** process pid */
-       int pid;
-       /** process cpu usage statistics */
-       struct stats_process previous;
-};
-
-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
 {
-       struct stats_system sys_stats;
+       struct sys_stats sys_stats;
        proc_scanner_t *scanner;
        report_generator_top_type_e type;
        int limit;
 };
 
 struct report_generator_top_closure {
-       struct stats_system sys_stats;
-       int current_index;
-       int max_index;
-       struct app_cpu_usage_report *cpu_report;
-       struct app_memory_usage_report *mem_report;
+       struct sys_stats sys_stats;
+       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()
@@ -72,7 +65,7 @@ report_generator_system_t *report_generator_new_system_report_generator()
        if (!ret)
                return NULL;
 
-       if (stats_update_system_stats(&ret->previous) != 0) {
+       if (sys_stats_update(&ret->stats) != 0) {
                ERR("stats_update_system_stats failed");
                free(ret);
                return NULL;
@@ -89,243 +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;
 
-       if (stats_update_process_stats(pid, &ret->previous) != 0) {
-               ERR("stats_update_process_stats failed.");
-               free(ret);
-               return NULL;
-       };
+       ret->scanner = proc_scanner_new();
+       if (!ret->scanner) goto err;
 
-       ret->pid = pid;
-
-       return ret;
-}
-
-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_cpu_usage_report(
-               report_generator_system_t *generator,
-               int interval,
-               struct system_usage_report *report)
+static bool _match_proc_and_append(struct process *proc, void *data)
 {
-       ON_NULL_RETURN_VAL(generator, -1);
-       ON_TRUE_RETURN_VAL(interval < 0, -1);
-       ON_NULL_RETURN_VAL(report, -1);
-
-       float usage;
-       bool block = interval > 0;
-       struct stats_system current;
-
-       if (block) {
-               if (stats_update_system_stats(&generator->previous) != 0) {
-                       ERR("stats_update_system_stats failed.");
-                       return -1;
-               }
-               sleep(interval);
-       }
-
-       if (stats_update_system_stats(&current) != 0) {
-               ERR("stats_update_system_stats failed.");
-               return -1;
-       }
-
-       if (stats_get_system_cpu_usage_average(&generator->previous, &current, &usage))
-       {
-               ERR("stats_get_system_cpu_usage_average failed");
-               return -1;
-       }
-
-       report->usage = usage;
-       report->time = clock_realtime_get().tv_sec;
-
-       generator->previous = current;
-
-       return 0;
-}
-
-int report_generator_generate_system_memory_usage_report(
-               report_generator_system_t *generator,
-               struct system_usage_report *report) {
-       ON_NULL_RETURN_VAL(generator, -1);
-       ON_NULL_RETURN_VAL(report, -1);
+       report_generator_process_t *gen = data;
 
-       float usage;
-
-       if (stats_update_system_stats(&generator->previous) != 0) {
-               ERR("stats_update_system_stats failed.");
-               return -1;
-       }
-
-       if (stats_get_system_memory_usage(&generator->previous, &usage) != 0) {
-               ERR("stats_get_system_memory_usage failed.");
-               return -1;
+       if (gen->filter && gen->filter(proc, gen->user_data)) {
+               process_serialize(proc, gen->current_builder);
        }
 
-       report->time = clock_realtime_get().tv_sec;
-       report->usage = usage;
-
-       return 0;
+       return true;
 }
 
-int report_generator_generate_process_cpu_usage_report(
+int report_generator_generate_process_report(
                report_generator_process_t *generator,
-               int interval,
-               struct process_cpu_usage_report *report)
+               JsonBuilder *builder)
 {
        ON_NULL_RETURN_VAL(generator, -1);
-       ON_TRUE_RETURN_VAL(interval < 0, -1);
-       ON_NULL_RETURN_VAL(report, -1);
-
-       struct stats_process current = {0,};
-       bool block = interval > 0;
-       float usage;
+       ON_NULL_RETURN_VAL(builder, -1);
 
-       if (block) {
-               if (stats_update_process_stats(generator->pid, &generator->previous) != 0) {
-                       ERR("stats_update_process_stats failed.");
-                       return -1;
-               }
-               sleep(interval);
-       }
-
-       if (stats_update_process_stats(generator->pid, &current) != 0) {
-               ERR("stats_update_process_stats failed.");
-               return -1;
-       }
-
-       if (stats_get_process_cpu_usage_average(&generator->previous, &current, &usage) ) {
-               ERR("stats_update_process_stats failed.");
+       // refresh data
+       if (proc_scanner_scan(generator->scanner) != 0) {
+               ERR("proc_scanner_scan failed");
                return -1;
        }
 
-       report->time = clock_realtime_get().tv_sec;
-       report->pid = generator->pid;
-       report->usage = usage;
+       generator->current_builder = builder;
+       json_builder_begin_object(builder);
 
-       generator->previous = current;
+       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_memory_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 (stats_get_process_memory_usage(generator->pid, &usage) != 0) {
-               ERR("stats_get_process_memory_usage failed.");
-               return -1;
-       }
-
-       report->time = clock_realtime_get().tv_sec;
-       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,
-               int interval,
-               struct app_cpu_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_TRUE_RETURN_VAL(interval < 0, -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, interval, &report->process_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->process_report.pid = generator->process_gen->pid;
-
-       return 0;
-}
-
-int report_generator_generate_app_memory_usage_report(
-               report_generator_app_t *generator,
-               struct app_memory_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->process_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->process_report.pid = generator->process_gen->pid;
+       report->time = clock_realtime_get();
 
        return 0;
 }
@@ -336,12 +201,12 @@ int report_generator_generate_load_average_report(struct system_load_average_rep
 
        float a1, a5, a15;
 
-       if (stats_get_load_averages(&a1, &a5, &a15) != 0) {
+       if (sys_stats_get_load_averages(&a1, &a5, &a15) != 0) {
                ERR("stats_get_load_averages failed.");
                return -1;
        }
 
-       report->time = clock_realtime_get().tv_sec;
+       report->time = clock_realtime_get();
        report->one_min_avg = a1;
        report->five_min_avg = a5;
        report->fifteen_min_avg = a15;
@@ -369,7 +234,7 @@ report_generator_top_t *report_generator_new_top_report_generator(report_generat
                report_generator_free_top_generator(gen);
                return NULL;
        }
-       if (stats_update_system_stats(&gen->sys_stats) != 0) {
+       if (sys_stats_update(&gen->sys_stats) != 0) {
                report_generator_free_top_generator(gen);
                return NULL;
        }
@@ -387,7 +252,7 @@ void report_generator_free_top_generator(report_generator_top_t *generator)
 static bool _append_to_mem_report(struct process *proc, void *data)
 {
        struct report_generator_top_closure *closure = data;
-       struct app_memory_usage_report report = {0,};
+       struct process_usage_report report = {0,};
        const char *appid;
        int mem;
 
@@ -395,16 +260,16 @@ static bool _append_to_mem_report(struct process *proc, void *data)
                return false;
 
        if (process_get_memory_usage(proc, &mem) != 0) {
-               report.process_report.usage = NAN;
+               report.usage = NAN;
        } else {
-               report.process_report.usage = (float)mem / closure->sys_stats.total_memory;
+               report.usage = (float)mem / closure->sys_stats.total_memory;
        }
 
        appid = process_get_appid(proc);
        if (appid) strncpy(report.app_id, appid, sizeof(report.app_id));
-       report.process_report.pid = process_get_pid(proc);
-       report.process_report.time = clock_realtime_get().tv_sec;
-       closure->mem_report[closure->current_index++] = report;
+       report.pid = process_get_pid(proc);
+       report.time = clock_realtime_get();
+       closure->usage_report[closure->current_index++] = report;
 
        return true;
 }
@@ -412,24 +277,21 @@ static bool _append_to_mem_report(struct process *proc, void *data)
 static bool _append_to_cpu_report(struct process *proc, void *data)
 {
        struct report_generator_top_closure *closure = data;
-       struct app_cpu_usage_report report = {0,};
+       struct process_usage_report report = {0,};
        const char *appid;
-       unsigned long long ticks = 0;
 
        if (closure->current_index >= closure->max_index)
                return false;
 
-       if (process_get_cpu_usage(proc, &ticks) != 0) {
-               report.process_report.usage = NAN;
-       } else {
-               report.process_report.usage = stats_get_cpu_usage_percentage(ticks, closure->sys_stats.frame_time);
+       if (process_get_cpu_usage_percentage(proc, &report.usage) != 0) {
+               report.usage = NAN;
        }
 
        appid = process_get_appid(proc);
        if (appid) strncpy(report.app_id, appid, sizeof(report.app_id));
-       report.process_report.pid = process_get_pid(proc);
-       report.process_report.time = clock_realtime_get().tv_sec;
-       closure->cpu_report[closure->current_index++] = report;
+       report.pid = process_get_pid(proc);
+       report.time = clock_realtime_get();
+       closure->usage_report[closure->current_index++] = report;
 
        return true;
 }
@@ -487,7 +349,9 @@ static int _report_generator_top_report_generator_scan_apps(
 
        app_info_iterator_free(iter);
 
-       return proc_scanner_scan_pids(generator->scanner, pids, count);
+       int ret = proc_scanner_scan_pids(generator->scanner, pids, i);
+       free(pids);
+       return ret;
 }
 
 static int _report_generator_top_report_generator_scan_all(
@@ -512,7 +376,7 @@ static int _report_generator_top_report_generator_scan(
 
 int report_generator_generate_top_cpu_report(
                report_generator_top_t *generator,
-               struct app_cpu_usage_report **report,
+               struct process_usage_report **report,
                int *n_reports)
 {
        ON_NULL_RETURN_VAL(generator, -1);
@@ -521,7 +385,7 @@ int report_generator_generate_top_cpu_report(
 
        struct report_generator_top_closure closure = {0,};
 
-       if (stats_update_system_stats(&generator->sys_stats) != 0) {
+       if (sys_stats_update(&generator->sys_stats) != 0) {
                return -1;
        }
 
@@ -535,17 +399,17 @@ int report_generator_generate_top_cpu_report(
 
        closure.max_index = generator->limit;
        closure.sys_stats = generator->sys_stats;
-       closure.cpu_report = calloc(generator->limit, sizeof(struct app_cpu_usage_report));
-       if (!closure.cpu_report) {
+       closure.usage_report = calloc(generator->limit, sizeof(struct process_usage_report));
+       if (!closure.usage_report) {
                return -1;
        }
 
        if (proc_scanner_foreach_process(generator->scanner, _append_to_cpu_report, &closure) != 0) {
-               free(closure.cpu_report);
+               free(closure.usage_report);
                return -1;
        }
 
-       *report = closure.cpu_report;
+       *report = closure.usage_report;
        *n_reports = closure.current_index;
 
        return 0;
@@ -553,7 +417,7 @@ int report_generator_generate_top_cpu_report(
 
 int report_generator_generate_top_memory_report(
                report_generator_top_t *generator,
-               struct app_memory_usage_report **report,
+               struct process_usage_report **report,
                int *n_reports)
 {
        ON_NULL_RETURN_VAL(generator, -1);
@@ -562,7 +426,7 @@ int report_generator_generate_top_memory_report(
 
        struct report_generator_top_closure closure = {0,};
 
-       if (stats_update_system_stats(&generator->sys_stats) != 0) {
+       if (sys_stats_update(&generator->sys_stats) != 0) {
                return -1;
        }
 
@@ -576,17 +440,17 @@ int report_generator_generate_top_memory_report(
 
        closure.max_index = generator->limit;
        closure.sys_stats = generator->sys_stats;
-       closure.mem_report = calloc(generator->limit, sizeof(struct app_memory_usage_report));
-       if (!closure.mem_report) {
+       closure.usage_report = calloc(generator->limit, sizeof(struct process_usage_report));
+       if (!closure.usage_report) {
                return -1;
        }
 
        if (proc_scanner_foreach_process(generator->scanner, _append_to_mem_report, &closure) != 0) {
-               free(closure.mem_report);
+               free(closure.usage_report);
                return -1;
        }
 
-       *report = closure.mem_report;
+       *report = closure.usage_report;
        *n_reports = closure.current_index;
 
        return 0;