2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.1 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include "report-generator.h"
25 #include "err-check.h"
26 #include "appinfo-provider.h"
29 struct report_generator_system {
30 /** system cpu usage statistics */
31 struct stats_system previous;
34 struct report_generator_process
38 /** process cpu usage statistics */
39 struct stats_process previous;
42 struct report_generator_app
45 report_generator_process_t *process_gen;
48 int _app_report_generator_setup_process_generator(report_generator_app_t *generator);
50 static struct timespec clock_get_monotonic()
52 struct timespec ret = {0,};
54 if (clock_gettime(CLOCK_MONOTONIC, &ret) != 0) {
55 ERR("Platform do not support monotonic clock type");
56 //TODO consider adding first init function to evaluate
57 //if clock_gettime can be used, so calling module could
58 //handle cases without monotonic clock gracefully.
65 report_generator_system_t *report_generator_new_system_report_generator()
67 report_generator_system_t *ret = calloc(1, sizeof(struct report_generator_system));
71 if (stats_update_system_stats(&ret->previous) != 0) {
72 ERR("stats_update_system_stats failed");
80 void report_generator_free_system_generator(report_generator_system_t *generator)
88 report_generator_process_t *report_generator_new_process_report_generator(int pid)
90 ON_TRUE_RETURN_VAL(pid <= 0, NULL);
92 report_generator_process_t *ret = calloc(1, sizeof(struct report_generator_process));
96 if (stats_update_process_stats(pid, &ret->previous) != 0) {
97 ERR("stats_update_process_stats failed.");
107 void report_generator_free_process_generator(report_generator_process_t *generator)
115 report_generator_app_t *report_generator_new_app_report_generator(const char *app_id)
117 ON_NULL_RETURN_VAL(app_id, NULL);
119 report_generator_app_t *ret = malloc(sizeof(struct report_generator_app));
121 ERR("malloc failed");
125 ret->app_id = strdup(app_id);
126 _app_report_generator_setup_process_generator(ret);
130 void report_generator_free_app_generator(report_generator_app_t *generator)
132 if (!generator) return;
133 report_generator_free_process_generator(generator->process_gen);
134 free(generator->app_id);
138 int report_generator_generate_system_cpu_usage_report(
139 report_generator_system_t *generator,
141 struct system_cpu_usage_report *report)
143 ON_NULL_RETURN_VAL(generator, -1);
144 ON_TRUE_RETURN_VAL(interval < 0, -1);
145 ON_NULL_RETURN_VAL(report, -1);
148 bool block = interval > 0;
149 struct stats_system current;
152 if (stats_update_system_stats(&generator->previous) != 0) {
153 ERR("stats_update_system_stats failed.");
159 if (stats_update_system_stats(¤t) != 0) {
160 ERR("stats_update_system_stats failed.");
164 if (stats_get_system_cpu_usage_average(&generator->previous, ¤t, &usage))
166 ERR("stats_get_system_cpu_usage_average failed");
170 report->usage = usage;
171 report->time = clock_get_monotonic().tv_sec;
173 generator->previous = current;
178 int report_generator_generate_system_memory_usage_report(
179 report_generator_system_t *generator,
180 struct system_memory_usage_report *report) {
181 ON_NULL_RETURN_VAL(generator, -1);
182 ON_NULL_RETURN_VAL(report, -1);
186 if (stats_get_system_memory_usage(&usage) != 0) {
187 ERR("stats_get_system_memory_usage failed.");
191 report->time = clock_get_monotonic().tv_sec;
192 report->usage = usage;
197 int report_generator_generate_process_cpu_usage_report(
198 report_generator_process_t *generator,
200 struct process_cpu_usage_report *report)
202 ON_NULL_RETURN_VAL(generator, -1);
203 ON_TRUE_RETURN_VAL(interval < 0, -1);
204 ON_NULL_RETURN_VAL(report, -1);
206 struct stats_process current = {0,};
207 bool block = interval > 0;
211 if (stats_update_process_stats(generator->pid, &generator->previous) != 0) {
212 ERR("stats_update_process_stats failed.");
218 if (stats_update_process_stats(generator->pid, ¤t) != 0) {
219 ERR("stats_update_process_stats failed.");
223 if (stats_get_process_cpu_usage_average(&generator->previous, ¤t, &usage) ) {
224 ERR("stats_update_process_stats failed.");
228 report->time = clock_get_monotonic().tv_sec;
229 report->pid = generator->pid;
230 report->usage = usage;
232 generator->previous = current;
237 int report_generator_generate_process_memory_usage_report(
238 report_generator_process_t *generator,
239 struct process_memory_usage_report *report)
241 ON_NULL_RETURN_VAL(generator, -1);
242 ON_NULL_RETURN_VAL(report, -1);
246 if (stats_get_process_memory_usage(generator->pid, &usage) != 0) {
247 ERR("stats_get_process_memory_usage failed.");
251 report->time = clock_get_monotonic().tv_sec;
252 report->usage = usage;
257 int _app_report_generator_setup_process_generator(report_generator_app_t *generator)
259 int pid = app_info_provider_find_main_pid(generator->app_id);
264 if (!generator->process_gen || generator->process_gen->pid != pid) {
265 if (generator->process_gen)
266 report_generator_free_process_generator(generator->process_gen);
267 generator->process_gen = report_generator_new_process_report_generator(pid);
272 int report_generator_generate_app_cpu_usage_report(
273 report_generator_app_t *generator,
275 struct app_cpu_usage_report *report)
277 ON_NULL_RETURN_VAL(generator, -1);
278 ON_TRUE_RETURN_VAL(interval < 0, -1);
279 ON_NULL_RETURN_VAL(report, -1);
281 if (_app_report_generator_setup_process_generator(generator) != 0) {
282 ERR("_app_report_generator_setup_process_generator failed.");
286 if (report_generator_generate_process_cpu_usage_report(
287 generator->process_gen, interval, &report->process_report) != 0)
289 ERR("report_generator_generate_process_cpu_usage_report failed.");
293 strncpy(report->app_id, generator->app_id, sizeof(report->app_id));
298 int report_generator_generate_app_memory_usage_report(
299 report_generator_app_t *generator,
300 struct app_memory_usage_report *report)
302 ON_NULL_RETURN_VAL(generator, -1);
303 ON_NULL_RETURN_VAL(report, -1);
305 if (_app_report_generator_setup_process_generator(generator)) {
306 ERR("_app_report_generator_setup_process_generator failed.");
310 if (report_generator_generate_process_memory_usage_report(
311 generator->process_gen, &report->process_report) != 0)
313 ERR("report_generator_generate_process_memory_usage_report failed.");
317 strncpy(report->app_id, generator->app_id, sizeof(report->app_id));
322 int report_generator_generate_load_average_report(struct system_load_average_report *report)
324 ON_NULL_RETURN_VAL(report, -1);
328 if (stats_get_load_averages(&a1, &a5, &a15) != 0) {
329 ERR("stats_get_load_averages failed.");
333 report->time = clock_get_monotonic().tv_sec;
334 report->one_min_avg = a1;
335 report->five_min_avg = a5;
336 report->fifteen_min_avg = a15;