dlog_logger: QoS contained by aggregation 99/287699/2
authorMichal Bloch <m.bloch@samsung.com>
Thu, 2 Feb 2023 15:02:36 +0000 (16:02 +0100)
committerMichal Bloch <m.bloch@samsung.com>
Thu, 2 Feb 2023 16:50:18 +0000 (17:50 +0100)
The server struct in dlog_logger now contains a pointer
to the QoS module struct (aggregation) instead of being
a member field (composition).

This lets multiple server structs share the same QoS module.

Change-Id: I573318cb74f76374a3cd93ad03d89b7892b7dcb3
Signed-off-by: Michal Bloch <m.bloch@samsung.com>
src/logger/log_buffer.c
src/logger/logger.c
src/logger/logger_internal.h
src/logger/qos.c
src/logger/qos.h

index 7365045..6ff7b19 100644 (file)
@@ -56,8 +56,8 @@ static int service_writer_pipe(struct logger *server, struct writer *wr, struct
                        add_recv_timestamp(&lem.header, now);
 
                        fixup_pipe_msg(&lem, payload_size);
-                       if (qos_is_enabled(&server->qos))
-                               qos_add_log(&server->qos, &lem.header);
+                       if (server->qos)
+                               qos_add_log(server->qos, &lem.header);
                        r = buffer_append(&lem.header, wr->buf_ptr);
                        wr->readed -= ple->len;
                        memmove(wr->buffer, wr->buffer + ple->len, sizeof wr->buffer - ple->len);
@@ -164,8 +164,8 @@ static int service_writer_stdout(struct logger *server, struct writer *wr, struc
                assert(lem.header.len <= sizeof(lem));
                assert(((char *)&lem)[lem.header.len - 1] == '\0');
 
-               if (qos_is_enabled(&server->qos))
-                       qos_add_log(&server->qos, &lem.header);
+               if (server->qos)
+                       qos_add_log(server->qos, &lem.header);
 
                r = buffer_append(&lem.header, wr->buf_ptr);
                if (r != 0)
index 63bfb8c..0f8394e 100644 (file)
@@ -78,28 +78,6 @@ int get_now(struct now_t *now)
        return 0;
 }
 
-void qos_periodic_check(struct logger *server)
-{
-       struct qos_module *const qos = &server->qos;
-       struct timespec ts_mono;
-       if (clock_gettime(CLOCK_MONOTONIC, &ts_mono))
-               return;
-
-       if (ts_mono.tv_sec < qos->cancel_limits_at.tv_sec)
-               return;
-       if (ts_mono.tv_sec == qos->cancel_limits_at.tv_sec
-       &&  ts_mono.tv_nsec < qos->cancel_limits_at.tv_nsec)
-               return;
-
-       if (metrics_get_total(qos->log_metrics) >= qos->threshold)
-               qos_apply_limits(qos);
-       else
-               qos_relax_limits(qos);
-
-       qos_set_next_update_time(qos, ts_mono);
-       metrics_clear(qos->log_metrics);
-}
-
 /**
  * @brief FD limit handler
  * @details Checks whether the FD limit was reached and leaves logs about it if so
@@ -698,17 +676,14 @@ int logger_create(struct logger_config_data *data, struct logger *l)
 
        l->buf_params = data->buf_params;
 
-       l->qos.log_metrics = metrics_create();
-       if (!l->qos.log_metrics)
-               return -ENOMEM;
+       if (data->qos) {
+               l->qos = data->qos;
+               data->qos = NULL;
 
-       l->qos.max_throughput = data->qos_max_throughput;
-       l->qos.threshold = data->qos_threshold;
-       l->qos.threshold_reapply = data->qos_threshold_reapply;
-       l->qos.limit_duration = data->qos_limit_duration;
-       l->qos.file_path = data->qos_file_path;
-       l->qos.distribution_func = data->distribution_func;
-       data->qos_file_path = NULL;
+               l->qos->log_metrics = metrics_create();
+               if (!l->qos->log_metrics)
+                       return -ENOMEM;
+       }
 
        // Check if the daemon is being launched for the first time since reboot
        bool first_time;
@@ -738,8 +713,8 @@ int logger_create(struct logger_config_data *data, struct logger *l)
                        if (!g_backend.logger_readers[id])
                                continue;
 
-                       if (qos_is_enabled(&l->qos)) {
-                               r = reader_add_subreader_metrics(&g_backend.logger_readers[id]->common, &l->qos);
+                       if (l->qos) {
+                               r = reader_add_subreader_metrics(&g_backend.logger_readers[id]->common, l->qos);
                                if (r < 0) {
                                        reader_free(&g_backend.logger_readers[id]->common);
                                        g_backend.logger_readers[id] = NULL;
@@ -815,7 +790,7 @@ void logger_free(struct logger *l)
        epoll_metadata_destroy(&l->epoll_common);
        epoll_metadata_destroy(&l->epoll_socket);
 
-       qos_free(&l->qos);
+       qos_free(l->qos);
 }
 
 /**
@@ -930,7 +905,10 @@ static bool do_logger_one_iteration(struct logger *server, bool *use_lazy_pollin
                return false;
 
        service_all_readers(server);
-       qos_periodic_check(server);
+
+       if (server->qos)
+               qos_periodic_check(server->qos);
+
        return true;
 }
 
@@ -1120,14 +1098,30 @@ int prepare_config_data(struct logger_config_data *data)
        data->epoll_time = log_config_get_int(&conf, "epoll_time_ms", DEFAULT_EPOLL_TIME_MS);
        g_backend.lazy_polling_total = 0; // Android Logger backend only, read below
 
-       const char *const qos_file_path = log_config_get(&conf, "qos_file_path");
-       data->qos_file_path = qos_file_path ? strdup(qos_file_path) : NULL;
+       struct qos_module qos = {0, };
+
+       qos.file_path = (char *) log_config_get(&conf, "qos_file_path");
+       qos.limit_duration = log_config_get_int(&conf, "qos_refresh_rate_s", DEFAULT_QOS_LIMIT_DURATION_S);
+       qos.max_throughput = log_config_get_int(&conf, "qos_max_throughput_logs", DEFAULT_QOS_THROUGHPUT_LOGS);
+       qos.threshold = log_config_get_int(&conf, "qos_threshold_logs", DEFAULT_QOS_THRESHOLD_LOGS);
+       qos.threshold_reapply = log_config_get_int(&conf, "qos_threshold_reapply_logs", DEFAULT_QOS_THRESHOLD_REAPPLY_LOGS);
+       qos.distribution_func = qos_get_distribution_func_by_name(log_config_get(&conf, "qos_method"));
 
-       data->qos_limit_duration = log_config_get_int(&conf, "qos_refresh_rate_s", DEFAULT_QOS_LIMIT_DURATION_S);
-       data->qos_max_throughput = log_config_get_int(&conf, "qos_max_throughput_logs", DEFAULT_QOS_THROUGHPUT_LOGS);
-       data->qos_threshold = log_config_get_int(&conf, "qos_threshold_logs", DEFAULT_QOS_THRESHOLD_LOGS);
-       data->qos_threshold_reapply = log_config_get_int(&conf, "qos_threshold_reapply_logs", DEFAULT_QOS_THRESHOLD_REAPPLY_LOGS);
-       data->distribution_func = qos_get_distribution_func_by_name(log_config_get(&conf, "qos_method"));
+       if (qos.threshold > 0
+       &&  qos.max_throughput > 0
+       &&  qos.file_path && strlen(qos.file_path) > 0) {
+               data->qos = malloc(sizeof *data->qos);
+               if (!data->qos) {
+                       ret = -ENOMEM;
+                       goto end;
+               }
+               *data->qos = qos;
+               data->qos->file_path = strdup(qos.file_path);
+               if (!data->qos->file_path) {
+                       ret = -ENOMEM;
+                       goto end;
+               }
+       }
 
        const char *const first_time_file_path = log_config_get(&conf, "first_time_file_path");
        data->first_time_file_path = first_time_file_path ? strdup(first_time_file_path) : NULL;
@@ -1203,7 +1197,7 @@ void free_config_data(struct logger_config_data *data)
 {
        list_remove_if(&data->logfile_configs, NULL, cond_string_free);
        free(data->dynamic_config_dir);
-       free(data->qos_file_path);
+       qos_free(data->qos);
        free(data->first_time_file_path);
 }
 
index ef3fab7..686fbbd 100644 (file)
@@ -146,7 +146,7 @@ struct logger {
        struct log_buffer*    buffers[LOG_ID_MAX];
        struct buf_params     buf_params;
        int                   exiting;
-       struct qos_module     qos;
+       struct qos_module*    qos;
        list_head             compressed_memories;
 };
 
@@ -157,12 +157,7 @@ struct logger_config_data {
        int is_buffer_enabled[LOG_ID_MAX];
        struct buffer_config_data buffers[LOG_ID_MAX];
        char *dynamic_config_dir;
-       char *qos_file_path;
-       int qos_max_throughput;
-       int qos_limit_duration;
-       int qos_threshold;
-       int qos_threshold_reapply;
-       qos_distribution_func distribution_func;
+       struct qos_module* qos;
        char *first_time_file_path;
        log_print_format default_format;
 };
index a8ddfc6..b5b7f3b 100644 (file)
 #include <stdlib.h>
 #include <logcommon.h>
 
-bool qos_is_enabled(const struct qos_module *qos)
-{
-       assert(qos);
-       return qos->threshold > 0 && qos->max_throughput > 0 && qos->file_path && strlen(qos->file_path) > 0;
-}
-
 void qos_create_limits_file(struct qos_module *qos, bool is_limiting)
 {
        __attribute__((cleanup(close_fd))) int fd = creat(qos->file_path, 0644);
@@ -91,6 +85,27 @@ void qos_relax_limits(struct qos_module *qos)
        qos_create_limits_file(qos, false);
 }
 
+void qos_periodic_check(struct qos_module *qos)
+{
+       struct timespec ts_mono;
+       if (clock_gettime(CLOCK_MONOTONIC, &ts_mono))
+               return;
+
+       if (ts_mono.tv_sec < qos->cancel_limits_at.tv_sec)
+               return;
+       if (ts_mono.tv_sec == qos->cancel_limits_at.tv_sec
+       &&  ts_mono.tv_nsec < qos->cancel_limits_at.tv_nsec)
+               return;
+
+       if (metrics_get_total(qos->log_metrics) >= qos->threshold)
+               qos_apply_limits(qos);
+       else
+               qos_relax_limits(qos);
+
+       qos_set_next_update_time(qos, ts_mono);
+       metrics_clear(qos->log_metrics);
+}
+
 void qos_add_log(struct qos_module *qos, const struct dlogutil_entry *due)
 {
        assert(qos);
@@ -112,7 +127,11 @@ void qos_add_log(struct qos_module *qos, const struct dlogutil_entry *due)
 
 void qos_free(struct qos_module *qos)
 {
+       if (!qos)
+               return;
+
        metrics_destroy(qos->log_metrics);
        free(qos->file_path);
+       free(qos);
 }
 
index 650207d..441f374 100644 (file)
@@ -43,7 +43,7 @@ struct qos_module {
 
 qos_distribution_func qos_get_distribution_func_by_name(const char *name);
 
-bool qos_is_enabled(const struct qos_module *qos);
+void qos_periodic_check(struct qos_module *qos);
 void qos_create_limits_file(struct qos_module *qos, bool is_limiting);
 void qos_set_next_update_time(struct qos_module *qos, struct timespec now);
 void qos_apply_limits(struct qos_module *qos);