summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fieldstat/fieldstat.h1
-rw-r--r--logs/jsontopk1cube.json44
-rw-r--r--src/fieldstat.c67
-rw-r--r--src/logging/log.c281
-rw-r--r--src/logging/log.h45
-rw-r--r--src/logging/logger_manage.c0
-rw-r--r--src/logging/logger_manage.h0
-rw-r--r--src/metrics/metric.c29
-rw-r--r--src/tags/cell_manager.c6
-rw-r--r--src/tags/heavy_keeper.c11
-rw-r--r--src/tags/my_ut_hash.c4
-rw-r--r--src/tags/sorted_set.c2
-rw-r--r--test/test_exporter_json.cpp2
-rw-r--r--test/test_fuzz_test.cpp1
-rw-r--r--test/test_merge.cpp7
-rw-r--r--test/unit_test_cell_manager.cpp9
16 files changed, 358 insertions, 151 deletions
diff --git a/include/fieldstat/fieldstat.h b/include/fieldstat/fieldstat.h
index acf086c..b1917eb 100644
--- a/include/fieldstat/fieldstat.h
+++ b/include/fieldstat/fieldstat.h
@@ -78,7 +78,6 @@ long long fieldstat_get_cube_version(const struct fieldstat *instance, int cube_
* @return metric id, if success; otherwise, return -1. Fail when cube is not registered, or the parameter is invalid.
*/
int fieldstat_register_counter(struct fieldstat *instance, int cube_id, const char *field_name, enum counter_mode mode);
-// is_gauge: merge 方法:最大 最小 求和
/*
* @brief add a metric to the cube of cube_id. One metric may have multiple sub-metric that are associated with different cells. other parameters are the same as fieldstat_register_counter.
diff --git a/logs/jsontopk1cube.json b/logs/jsontopk1cube.json
deleted file mode 100644
index 82db0e2..0000000
--- a/logs/jsontopk1cube.json
+++ /dev/null
@@ -1,44 +0,0 @@
-[
- {
- "name": "-",
- "tags": {
- "flow id key": 0,
- "test_tag_shared 1": 3,
- "test_tag_shared 2": 0.200000,
- "test_tag_shared 3": "1string"
- },
- "fields": {
- "topk1": 1000,
- "topk2": 2000
- },
- "timestamp": 1689560168
- },
- {
- "name": "-",
- "tags": {
- "flow id key": 1,
- "test_tag_shared 1": 3,
- "test_tag_shared 2": 0.200000,
- "test_tag_shared 3": "1string"
- },
- "fields": {
- "topk1": 1000,
- "topk2": 2000
- },
- "timestamp": 1689560168
- },
- {
- "name": "-",
- "tags": {
- "flow id key": 2,
- "test_tag_shared 1": 3,
- "test_tag_shared 2": 0.200000,
- "test_tag_shared 3": "1string"
- },
- "fields": {
- "topk1": 1000,
- "topk2": 2000
- },
- "timestamp": 1689560168
- }
-] \ No newline at end of file
diff --git a/src/fieldstat.c b/src/fieldstat.c
index f5f2f12..87b0a4d 100644
--- a/src/fieldstat.c
+++ b/src/fieldstat.c
@@ -96,7 +96,6 @@ void fieldstat_reset(struct fieldstat *instance)
unsigned long fieldstat_get_cell_version(const struct fieldstat *instance)
{
if (instance == NULL) {
- printf("ERR: instance is NULL\n");
return 0;
}
return instance->cell_version;
@@ -105,20 +104,16 @@ unsigned long fieldstat_get_cell_version(const struct fieldstat *instance)
int fieldstat_unregister_cube(struct fieldstat *instance, int cube_id)
{
if (instance == NULL) {
- printf("ERR: instance is NULL\n");
return -1;
}
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- //printf("ERR: cube_id is out of range, cube_id: %d\n", cube_id);
return -1;
}
if (instance->shared_tag_cube_manager != NULL) {
- printf("WARNING: This fieldstat instance is used as a merge destination. Please make sure merging has finished.\n");
cube_manager_free(instance->shared_tag_cube_manager);
instance->shared_tag_cube_manager = NULL;
}
if (instance->cube[cube_id] == NULL) {
- printf("ERR: cube_id is not registered\n");
return -1;
}
fieldstat_cube_free(instance, cube_id);
@@ -267,11 +262,9 @@ struct fs_cube *fieldstat_cube_new(const struct fieldstat_tag *shared_tags, size
int fieldstat_register_cube(struct fieldstat *instance, const struct fieldstat_tag *shared_tags, size_t n_tag, enum sampling_mode mode, size_t max_n_cell)
{
if (instance == NULL) {
- printf("ERR: fieldstat instance is NULL\n");
return -1;
}
if (n_tag == 0 || shared_tags == NULL) {
- printf("ERR: shared tags must not be empty\n");
return -1;
}
struct fs_cube *cube = fieldstat_cube_new(shared_tags, n_tag, mode, max_n_cell);
@@ -283,21 +276,17 @@ int fieldstat_register_cube(struct fieldstat *instance, const struct fieldstat_t
int fieldstat_cube_add(struct fieldstat *instance, int cube_id, const struct fieldstat_tag *tags, size_t n_tag, long long increment)
{
if (instance == NULL) {
- printf("ERR: fieldstat instance is NULL\n");
return -1;
}
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- //printf("ERR: cube_id is invalid, %d\n", cube_id);
return -1;
}
struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_cube_add cube is not registered yet\n");
return -1;
}
if (cube->sampling_mode == SAMPLING_MODE_TOPK && increment <= 0) {
- printf("ERR: increment cannot less than zero\n");
return -1;
}
@@ -365,16 +354,13 @@ static int append_metric_to_cube(struct fs_cube *cube, struct metric *metric)
int fieldstat_register_counter(struct fieldstat *instance, int cube_id, const char *field_name, enum counter_mode mode)
{
if (instance == NULL) {
- printf("ERR: fieldstat instance is NULL\n");
return -1;
}
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- printf("ERR: fieldstat_register_hist cube_id is invalid, %d\n", cube_id);
return -1;
}
struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_register_counter cube is not registered yet\n");
return -1;
}
struct metric *metric = metric_counter_new(field_name, mode);
@@ -385,20 +371,16 @@ int fieldstat_register_counter(struct fieldstat *instance, int cube_id, const ch
int fieldstat_register_hll(struct fieldstat *instance, int cube_id, const char *field_name, unsigned char precision)
{
if (instance == NULL) {
- printf("ERR: fieldstat instance is NULL\n");
return -1;
}
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- printf("ERR: fieldstat_register_hist cube_id is invalid, %d\n", cube_id);
return -1;
}
struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_register_hll cube is not registered yet\n");
return -1;
}
if (precision < 4 || precision > 18) {
- printf("ERR: precision must be between 4 and 18\n");
return -1;
}
struct metric *metric = metric_hll_new(field_name, precision);
@@ -409,29 +391,23 @@ int fieldstat_register_hll(struct fieldstat *instance, int cube_id, const char *
int fieldstat_register_hist(struct fieldstat *instance, int cube_id, const char *field_name, long long lowest_trackable_value, long long highest_trackable_value, int significant_figures)
{
if (instance == NULL) {
- printf("ERR: fieldstat instance is NULL\n");
return -1;
}
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- printf("ERR: fieldstat_register_hist cube_id is invalid, %d\n", cube_id);
return -1;
}
struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_register_histogram cube is not registered yet\n");
return -1;
}
if (lowest_trackable_value < 1) {
- printf("ERR: lowest_trackable_value not correct.\n");
return -1;
}
if (significant_figures < 1 || significant_figures > 5) {
- printf("ERR: significant_figures must be between 1 and 5\n");
return -1;
}
if (lowest_trackable_value * 2 > highest_trackable_value)
{
- printf("ERR: highest_trackable_value must be at least twice as large as lowest_trackable_value\n");
return -1;
}
@@ -446,12 +422,10 @@ int fieldstat_register_hist(struct fieldstat *instance, int cube_id, const char
static struct metric *fieldstat_find_metric(const struct fieldstat *instance, int cube_id, int metric_id)
{
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- printf("ERR: fieldstat_find_metric cube_id is not correct, input cube id: %d\n", cube_id);
return NULL;
}
struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_find_metric cube is not registered yet, input cube id: %d\n", cube_id);
return NULL;
}
return cube->metrics[metric_id];
@@ -460,29 +434,23 @@ static struct metric *fieldstat_find_metric(const struct fieldstat *instance, in
#define FIELDSTAT_GENERAL_CHECK(instance, cube_id, metric_id, cell_id, metric_type) \
do { \
if ((instance) == NULL) { \
- printf("ERR: [%s] fieldstat instance is NULL\n", __FUNCTION__); \
return -1; \
} \
if ((cube_id) < 0 || (cube_id) >= (instance)->valid_cube_arr_length) { \
- printf("ERR: [%s] cube_id is not correct, input cube id: %d\n", __FUNCTION__, (cube_id)); \
return -1; \
} \
const struct fs_cube *cube = (instance)->cube[(cube_id)]; \
if (cube == NULL) { \
- printf("ERR: [%s] cube is not registered yet, input cube id: %d\n", __FUNCTION__, (cube_id)); \
return -1; \
} \
if ((metric_id) < 0 || (metric_id) >= cube->n_metric) { \
- printf("ERR: [%s] metric_id is not correct, input metric id: %d\n", __FUNCTION__, (metric_id)); \
return -2; \
} \
const struct metric *metric = cube->metrics[(metric_id)]; \
if (metric == NULL || metric_get_type(metric) != (metric_type)) { \
- printf("ERR: [%s] metric is not registered yet, input metric id: %d\n", __FUNCTION__, (metric_id)); \
return -2; \
} \
if ((cell_id) < 0 || cell_manager_get_tag_by_cell_id(cube->cell_manager, cell_id) == NULL) { \
- printf("ERR: [%s] cell_id is not correct, input cell id: %d\n", __FUNCTION__, (cell_id)); \
return -3; \
} \
} while (0)
@@ -503,7 +471,6 @@ int fieldstat_counter_set(struct fieldstat *instance, int cube_id, int metric_id
int ret = metric_counter_set(metric, cell_id, value);
if (ret < 0) {
- printf("ERR: fieldstat_counter_set failed");
return -4;
}
return 0;
@@ -525,7 +492,6 @@ int fieldstat_hist_record(struct fieldstat *instance, int cube_id, int metric_id
int ret = metric_histogram_record(metric, cell_id, value);
if (ret < 0) {
- printf("ERR: fieldstat_histogram_record failed");
return -4;
}
return 0;
@@ -556,7 +522,6 @@ int fieldstat_hist_record(struct fieldstat *instance, int cube_id, int metric_id
int fieldstat_serialize(const struct fieldstat *instance, char **blob_out, size_t *blob_size_out)
{
if (instance == NULL) {
- printf("ERR: fieldstat_serialize input is NULL\n");
return -1;
}
mpack_writer_t writer;
@@ -609,7 +574,7 @@ int fieldstat_serialize(const struct fieldstat *instance, char **blob_out, size_
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: fieldstat_serialize: mpack_writer_destroy failed\n");
+ // todo: log
return -1;
}
@@ -624,7 +589,7 @@ struct fieldstat *fieldstat_deserialize(const char *blob, size_t blob_size)
mpack_node_t root = mpack_tree_root(&tree);
int ver = mpack_node_i32(mpack_node_map_cstr(root, "ver"));
if (ver != EXPORT_VER) {
- printf("ERR: fieldstat_deserialize: invalid version\n");
+ // todo: log
mpack_tree_destroy(&tree);
return NULL;
}
@@ -693,7 +658,7 @@ void fieldstat_cube_merge_comprehensive(struct fs_cube *dest, const struct fs_cu
const struct tag_hash_key *tag_src = tag_arr_src[cell_id_src];
if (tag_src == NULL) {
// the tag_src is continuous, so there may not be NULL in the middle
- printf("ERR: tag_src is NULL, id: %d\n", cell_id_src);
+ // TODO: log
continue;
}
@@ -704,9 +669,7 @@ void fieldstat_cube_merge_comprehensive(struct fs_cube *dest, const struct fs_cu
for (int metric_id_src = 0; metric_id_src < src->n_metric; metric_id_src++) {
int metric_id_dest = metric_id_src_dest_map[metric_id_src];
int tmp_ret = metric_merge_or_copy_cell(dest->metrics[metric_id_dest], src->metrics[metric_id_src], cell_id_final, cell_id_src);
- if (tmp_ret == -1) {
- printf("ERR: metric_merge_or_copy_cell failed\n");
- }
+ // todo: log
}
}
}
@@ -781,7 +744,6 @@ void fieldstat_cube_merge(struct fs_cube *dest, const struct fs_cube *src)
int fieldstat_merge(struct fieldstat *instance, struct fieldstat *src)
{
if (instance == NULL || src == NULL) {
- printf("ERR: fieldstat_merge: instance or src is NULL\n");
return -1;
}
size_t n_cube_dest = instance->valid_cube_arr_length;
@@ -817,7 +779,7 @@ int fieldstat_merge(struct fieldstat *instance, struct fieldstat *src)
cube_manager_add(tag_cube_id_map, shared_tag_key_src, cube_id);
} else {
if (instance->cube[cube_id_tmp]->sampling_mode != cube_src->sampling_mode) {
- printf("ERR: cube sampling mode not match\n");
+ // todo: log
ret = -1;
tag_hash_key_free(shared_tag_key_src);
continue;
@@ -868,12 +830,10 @@ void fieldstat_get_cubes(const struct fieldstat *instance, int **cube_ids, int *
int fieldstat_get_max_metric_id(const struct fieldstat *instance, int cube_id)
{
if (cube_id >= instance->valid_cube_arr_length || cube_id < 0) {
- printf("ERR: fieldstat_get_max_metric_id cube_id is invalid\n");
return -1;
}
const struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_get_max_metric_id cube is not registered yet\n");
return -1;
}
return cube->n_metric - 1;
@@ -883,12 +843,10 @@ void fieldstat_get_cells(const struct fieldstat *instance, int cube_id, int metr
int **cell_ids, struct fieldstat_tag_list **tag_list, size_t *n_cell)
{
if (cube_id >= instance->valid_cube_arr_length || cube_id < 0) {
- printf("ERR: fieldstat_get_cells cube_id is invalid\n");
return;
}
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL) {
- printf("ERR: metric or cube is not registered yet\n");
return;
}
@@ -905,7 +863,6 @@ void fieldstat_get_cells(const struct fieldstat *instance, int cube_id, int metr
for (int i = 0; i < n_cell_ret; i++) {
const struct tag_hash_key *tag_key = cell_manager_get_tag_by_cell_id(instance->cube[cube_id]->cell_manager, (*cell_ids)[i]);
if (tag_key == NULL) {
- printf("ERR: fieldstat_get_cells cell_manager_get_tag_by_cell_id failed, cube id: %d, metric id: %d, cell id: %d\n", cube_id, metric_id, (*cell_ids)[i]);
continue;
}
tag_hash_key_convert_to_fieldstat_tag(tag_key, &(tag_list_ret[i].tag), &(tag_list_ret[i].n_tag));
@@ -915,12 +872,10 @@ void fieldstat_get_cells(const struct fieldstat *instance, int cube_id, int metr
struct fieldstat_tag_list *fieldstat_get_shared_tags(const struct fieldstat *instance, int cube_id)
{
if (cube_id >= instance->valid_cube_arr_length || cube_id < 0) {
- printf("ERR: fieldstat_get_shared_tags cube_id is invalid\n");
return NULL;
}
struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_get_shared_tags cube is not registered yet\n");
return NULL;
}
@@ -942,7 +897,6 @@ struct fieldstat_tag_list *fieldstat_get_shared_tags(const struct fieldstat *ins
tag_dest->value_double = tag_src->value_double;
break;
default:
- printf("ERR: tag type not supported\n");
break;
}
}
@@ -955,7 +909,6 @@ long long fieldstat_counter_get(const struct fieldstat *instance, int cube_id, i
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_COUNTER) {
- printf("ERR: fieldstat_counter_get metrics is not registered yet\n");
return -1;
}
@@ -966,7 +919,6 @@ double fieldstat_hll_get(const struct fieldstat *instance, int cube_id, int metr
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HLL) {
- printf("ERR: fieldstat_hll_get metrics is not registered yet\n");
return -1;
}
@@ -977,7 +929,6 @@ long long fieldstat_hist_value_at_percentile(const struct fieldstat *instance, i
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HISTOGRAM) {
- printf("ERR: fieldstat_histogram_value_at_percentile metrics is not registered yet\n");
return -1;
}
@@ -988,7 +939,6 @@ long long fieldstat_hist_count_le_value(const struct fieldstat *instance, int cu
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL || metric_get_type(metric) != METRIC_TYPE_HISTOGRAM) {
- printf("ERR: fieldstat_histogram_value_le_value metrics is not registered yet\n");
return -1;
}
@@ -999,12 +949,10 @@ void fieldstat_get_serialized_blob(const struct fieldstat *instance, int cube_id
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL) {
- printf("ERR: fieldstat_get_serialized_blob metrics is not registered yet\n");
return;
}
enum metric_type type = metric_get_type(metric);
if (!(type == METRIC_TYPE_HLL || type == METRIC_TYPE_HISTOGRAM)) {
- printf("ERR: Only metric of hll and histogram support get serialized blob\n");
return;
}
@@ -1029,7 +977,6 @@ const char *fieldstat_get_metric_name(const struct fieldstat *instance, int cube
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL) {
- printf("ERR: metrics is not registered yet\n");
return NULL;
}
@@ -1040,7 +987,6 @@ enum metric_type fieldstat_get_metric_type(const struct fieldstat *instance, int
{
const struct metric *metric = fieldstat_find_metric(instance, cube_id, metric_id);
if (metric == NULL) {
- printf("ERR: metrics is not registered yet\n");
return (enum metric_type)-1;
}
@@ -1078,12 +1024,10 @@ struct fieldstat *fieldstat_dup(const struct fieldstat *instance)
void fieldstat_cube_read_cell(const struct fieldstat *instance, int cube_id, int **cell_ids, struct fieldstat_tag_list **tag_list, size_t *n_cell)
{
if (cube_id < 0 || cube_id >= instance->valid_cube_arr_length) {
- printf("ERR: fieldstat_cube_read_cell cube id is invalid, cube id: %d\n", cube_id);
return;
}
const struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_cube_read_cell cube is not registered yet, cube id: %d\n", cube_id);
return;
}
@@ -1127,7 +1071,6 @@ int fieldstat_get_max_cell_num(const struct fieldstat *instance, int cube_id)
{
const struct fs_cube *cube = instance->cube[cube_id];
if (cube == NULL) {
- printf("ERR: fieldstat_get_max_cell_num cube is not registered yet, cube id: %d\n", cube_id);
return -1;
}
diff --git a/src/logging/log.c b/src/logging/log.c
new file mode 100644
index 0000000..37038e6
--- /dev/null
+++ b/src/logging/log.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2020 rxi
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/stat.h>
+
+#include "log.h"
+
+#define ALLOC(type, number) ((type *)calloc(sizeof(type), number))
+
+typedef enum {
+ LOG_OP_IFACE_CONSOLE,
+ LOG_OP_IFACE_FILE,
+ RT_LOG_OP_IFACE_MAX,
+}log_op_iface;
+
+struct log_handle
+{
+ int level;
+ int enable;
+ FILE *fp;
+ va_list ap;
+ char defined_log_fn[1024];
+ char runtime_log_fn[1024];
+ pthread_mutex_t mutex;
+ log_op_iface iface;
+};
+
+static unsigned char weekday_str[7][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+
+static unsigned char month_str[12][4] = {"Jan", "Feb", "Mar", "Apr","May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+static int log_create_dir(const char *dir_path, int path_len)
+{
+ if(dir_path == NULL)
+ return -1;
+
+ char *buf = (char *)calloc(path_len+1, 1);
+ int ret = -1;
+
+ memcpy(buf, dir_path, path_len);
+ if(access(buf, R_OK) != 0)
+ {
+ if(mkdir(buf, 0755)!= 0)
+ ret = -1;
+ else
+ ret = 0;
+ }
+ else
+ ret = 1;
+ free(buf);
+ buf = NULL;
+ return ret;
+}
+
+static void log_close_file(struct log_handle *handle)
+{
+ pthread_mutex_lock(&handle->mutex);
+ if(handle->fp != NULL)
+ {
+ fclose(handle->fp);
+ handle->fp = NULL;
+ }
+ pthread_mutex_unlock(&handle->mutex);
+ return;
+}
+
+int log_open_file(char *file_name, struct log_handle *handle)
+{
+ FILE *fp = NULL;
+ log_close_file(handle);
+ if(NULL == (fp = fopen(file_name, "a")))
+ {
+ return -1;
+ }
+ memcpy(handle->runtime_log_fn, file_name, strlen(file_name));
+ handle->fp = fp;
+ return 0;
+}
+
+static int log_create_path(const char *file_path)
+{
+ FILE *fp = NULL;
+
+ if(file_path == NULL)
+ return 0;
+
+ char *p_path = rindex(file_path, '/');
+ if(p_path==0)
+ {
+ return 0;
+ }
+
+ const char *p_cur = file_path;
+ int path_len = p_path - file_path;
+ int i = 0;
+
+ if(log_create_dir(file_path, path_len) >= 0)
+ return 0;
+
+ for(;i<=path_len;i++,p_cur++)
+ {
+ if(*p_cur == '/')
+ {
+ if(log_create_dir(file_path, i+1) < 0)
+ return -1;
+ }
+ }
+ if(NULL == (fp = fopen(file_path, "w")))
+ {
+ return 0;
+ }
+ fclose(fp);
+ return 1;
+}
+
+int log_create_log_file(struct log_handle *handle)
+{
+ time_t t;
+ struct tm local_time;
+ char tmp_log_file_name[1024+128];
+
+ time(&t);
+ if(NULL == (localtime_r(&t, &local_time)))
+ {
+ return 0;
+ }
+ snprintf(tmp_log_file_name, sizeof(tmp_log_file_name), "%s.%04d-%02d-%02d", handle->defined_log_fn, local_time.tm_year + 1900, local_time.tm_mon + 1, local_time.tm_mday);
+
+ if(handle->fp == NULL)
+ {
+ if(0 != log_open_file(tmp_log_file_name, handle)) return 0;
+ }
+ else
+ {
+ if (0 != memcmp(tmp_log_file_name, handle->runtime_log_fn, strlen(tmp_log_file_name)))
+ {
+ if(0 != log_open_file(tmp_log_file_name, handle))return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void log_print_file(struct log_handle *handle, int level, const char *module, va_list ap, const char *fmt)
+{
+ char buf[64]={0};
+ time_t t;
+ struct tm local_time;
+ const char *level_str_map[]= {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
+
+ time(&t);
+ if(NULL == (localtime_r(&t, &local_time))) return;
+ snprintf(buf, sizeof(buf), "%s %s %d %02d:%02d:%02d %d", weekday_str[local_time.tm_wday],
+ month_str[local_time.tm_mon], local_time.tm_mday, local_time.tm_hour, local_time.tm_min, local_time.tm_sec, local_time.tm_year+1900);
+
+ log_create_log_file(handle);
+ fprintf(handle->fp, "%s, %s, %s, ", buf, level_str_map[level], module);
+
+ vfprintf(handle->fp, fmt, ap);
+ fprintf(handle->fp, "\n");
+ fflush(handle->fp);
+}
+
+static void log_print_console(struct log_handle *handle, int level, const char *module, va_list ap, const char *fmt)
+{
+ char buf[64]={0};
+ time_t t;
+ struct tm local_time;
+ const char *level_str_map[]= {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
+
+ time(&t);
+ if(NULL == (localtime_r(&t, &local_time))) return;
+ snprintf(buf, sizeof(buf), "%s %s %d %02d:%02d:%02d %d", weekday_str[local_time.tm_wday],
+ month_str[local_time.tm_mon], local_time.tm_mday, local_time.tm_hour, local_time.tm_min, local_time.tm_sec, local_time.tm_year+1900);
+ fprintf(handle->fp, "%s, %s, %s, ", buf, level_str_map[level], module);
+
+ vfprintf(handle->fp, fmt, ap);
+ fprintf(handle->fp, "\n");
+ fflush(handle->fp);
+}
+
+void log_options_set_level(struct log_handle * handle, int level)
+{
+ if(handle != NULL)
+ {
+ handle->level = level;
+ }
+}
+
+void log_options_set_enable(struct log_handle * handle, int enable)
+{
+ if(handle != NULL)
+ {
+ handle->enable = enable;
+ }
+}
+
+struct log_handle *log_handle_create(const char *file_path, int level)
+{
+ struct log_handle *handle = ALLOC(struct log_handle, 1);
+ if(!handle)
+ {
+ return NULL;
+ }
+ handle->enable=1;
+ handle->level = level;
+ strncpy(handle->defined_log_fn, file_path, 1024);
+ pthread_mutex_init(&handle->mutex,NULL);
+
+ if(handle->enable)
+ {
+ log_create_path(handle->defined_log_fn);
+ }
+
+ return handle;
+}
+
+void log_handle_destroy(struct log_handle * handle)
+{
+ if(!handle)
+ {
+ return;
+ }
+
+ if(handle->iface == LOG_OP_IFACE_FILE && handle->fp != NULL)
+ {
+ fclose(handle->fp);
+ handle->fp=NULL;
+ }
+
+ pthread_mutex_destroy(&(handle->mutex));
+ free(handle);
+ handle = NULL;
+ return;
+}
+
+void log_print(struct log_handle *handle, int level, const char *module, const char *fmt, ...)
+{
+ va_list ap;
+
+ if(handle->enable != 1 && level >= handle->level)
+ {
+ handle->fp = stdout;
+ handle->iface = LOG_OP_IFACE_CONSOLE;
+ va_start(handle->ap, fmt);
+ log_print_console(handle, level, module, ap, fmt);
+ va_end(handle->ap);
+ }
+ if (handle->enable == 1 && level >= handle->level)
+ {
+ handle->iface = LOG_OP_IFACE_FILE;
+ va_start(ap, fmt);
+ log_print_file(handle, level, module, ap, fmt);
+ va_end(ap);
+ }
+}
+
diff --git a/src/logging/log.h b/src/logging/log.h
new file mode 100644
index 0000000..285cf5a
--- /dev/null
+++ b/src/logging/log.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2020 rxi
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the MIT license. See `log.c` for details.
+ */
+
+#ifndef LOG_H
+#define LOG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <time.h>
+
+#define LOG_VERSION "0.1.0"
+
+struct log_handle;
+
+enum { LOG_TRACE, LOG_DEBUG, LOG_INFO, LOG_WARN, LOG_ERROR, LOG_FATAL };
+
+#define log_debug(handle, module, fmt, ...) log_print(handle, LOG_DEBUG, module, fmt, ##__VA_ARGS__)
+#define log_trace(handle, module, fmt, ...) log_print(handle, LOG_TRACE, module, fmt, ##__VA_ARGS__)
+#define log_info(handle, module, fmt, ...) log_print(handle, LOG_INFO, module, fmt, ##__VA_ARGS__)
+#define log_warn(handle, module, fmt, ...) log_print(handle, LOG_WARN, module, fmt, ##__VA_ARGS__)
+#define log_error(handle, module, fmt, ...) log_print(handle, LOG_ERROR, module, fmt, ##__VA_ARGS__)
+#define log_fatal(handle, module, fmt, ...) log_print(handle, LOG_FATAL, module, fmt, ##__VA_ARGS__)
+
+void log_print(struct log_handle *, int level, const char *module, const char *fmt, ...);
+void log_options_set_enable(struct log_handle *, int enable);
+void log_options_set_level(struct log_handle *, int level);
+
+struct log_handle * log_handle_create(const char *file_path, int level);
+void log_handle_destroy(struct log_handle *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/logging/logger_manage.c b/src/logging/logger_manage.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/logging/logger_manage.c
diff --git a/src/logging/logger_manage.h b/src/logging/logger_manage.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/logging/logger_manage.h
diff --git a/src/metrics/metric.c b/src/metrics/metric.c
index 97e166b..e5bdbf2 100644
--- a/src/metrics/metric.c
+++ b/src/metrics/metric.c
@@ -102,7 +102,8 @@ void metric_add_one_cell(struct metric *pthis, int id, struct metric_measure_dat
memset(pthis->data_array + pthis->n_array_item, 0, (pthis->max_n_array_item - pthis->n_array_item) * sizeof(struct metric_measure_data *));
}
if (pthis->data_array[id] != NULL) {
- printf("err, metric_add_one_cell, id: %d, data_array[id] is not NULL\n", id);
+ // todo: log
+ // printf("err, metric_add_one_cell, id: %d, data_array[id] is not NULL\n", id);
}
pthis->data_array[id] = data;
@@ -154,7 +155,7 @@ static void metric_scheme_counter_serialize(const struct metric_measure_data *da
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: An error occurred in counter_metric_serialize!\n");
+ // todo: log
}
}
@@ -164,7 +165,7 @@ static int metric_scheme_counter_merge(struct metric_measure_data *pthis, const
struct metric_counter_or_gauge *from_counter = from->counter;
if (counter->mode != from_counter->mode) {
- printf("ERR: counter type not match!\n");
+ //todo: log
return -1;
}
switch (counter->mode) {
@@ -178,7 +179,8 @@ static int metric_scheme_counter_merge(struct metric_measure_data *pthis, const
counter->value = counter->value < from_counter->value ? counter->value : from_counter->value;
break;
default:
- printf("ERR: unknown counter type\n");
+ // todo: log
+ // printf("ERR: unknown counter type\n");
return -1;
}
@@ -209,7 +211,8 @@ struct metric_measure_data *metric_scheme_counter_deserialize(const char *blob,
counter->mode = mpack_node_i8(mpack_node_map_cstr(content_root, "mode"));
if (mpack_tree_destroy(&content_tree) != mpack_ok) {
- printf("ERR: An error occurred in counter_metric_deserialize!\n");
+ // todo: log
+ // printf("ERR: An error occurred in counter_metric_deserialize!\n");
}
return ret;
}
@@ -262,7 +265,8 @@ struct metric_measure_data *metric_scheme_histogram_new(const struct metric_para
struct hdr_histogram* tmp_p_hdr = NULL;
int ret = hdr_init((int64_t)para->hdr.lowest_trackable_value, (int64_t)para->hdr.highest_trackable_value, para->hdr.significant_figures, &tmp_p_hdr);
if (ret != 0) {
- printf("ERR: hdr_init failed!\n");
+ // printf("ERR: hdr_init failed!\n");
+ // todo: log
return NULL;
}
struct metric_measure_data *data = (struct metric_measure_data *)malloc(sizeof(struct metric_measure_data));
@@ -300,8 +304,7 @@ struct metric_measure_data *metric_scheme_histogram_deserialize(const char *blob
{
struct hdr_histogram *hdr = NULL;
int ret = hdr_log_decode(&hdr, (char *)blob, blob_size);
- if (ret != 0 || hdr == NULL) {
- printf("ERR: hdr_log_decode failed!\n");
+ if (ret != 0 || hdr == NULL) {// todo: log
return NULL;
}
struct metric_measure_data *data = (struct metric_measure_data *)malloc(sizeof(struct metric_measure_data));
@@ -357,8 +360,7 @@ struct metric_parameter *construct_parameters(enum metric_type type, ...)
paras->hdr.highest_trackable_value = va_arg(ap, long long);
paras->hdr.significant_figures = va_arg(ap, int);
break;
- default:
- printf("ERR: construct_parameters: unknown type\n");
+ default:// todo: log
assert(0);
}
va_end(ap);
@@ -698,8 +700,7 @@ int metric_merge_or_copy_cell(struct metric *dest, const struct metric *src, int
dest_data = src->scheme->new(src->info->paras);
int ret = dest->scheme->copy(dest_data, src_data);
if (ret == -1) {
- dest->scheme->del(dest_data);
- printf("ERR: metric_merge_or_copy_cell copy failed\n");
+ dest->scheme->del(dest_data);// todo: log
return -1;
}
metric_add_one_cell(dest, dest_cell_id, dest_data);
@@ -824,8 +825,7 @@ int metric_histogram_record(struct metric *pthis, int cell_id, long long value)
struct metric_measure_data *data = metric_find_or_new_cell(pthis, cell_id);
bool ret = hdr_record_value(data->hdr, value);
- if (!ret) {
- printf("ERR: metric_histogram_record: hdr_record_value failed\n");
+ if (!ret) {// todo: log
return -1;
}
return 0;
@@ -857,7 +857,6 @@ long long metric_histogram_count_le_value(const struct metric *pthis, int cell_i
{
const struct metric_measure_data *data = metric_find_one_cell(pthis, cell_id);
if (data == NULL) {
- printf("ERR: metric_histogram_count_le_value cell id %d does not exist\n", cell_id);
return -1;
}
return hdr_count_le_value(data->hdr, value);
diff --git a/src/tags/cell_manager.c b/src/tags/cell_manager.c
index 01730bb..78155f7 100644
--- a/src/tags/cell_manager.c
+++ b/src/tags/cell_manager.c
@@ -191,7 +191,8 @@ Even though there is a small possibility of not counting certain flows due to th
The number 8 was determined through experiment, where multiple tests were conducted, randomly generating flows by which cells are determined.
The observed stable cell ID count did not exceed 3 times the value of K. Therefore, a conservative value of 8 was chosen.*/
if (pthis->next_cell_id >= pthis->max_cell_num * 8) { // max int is much larger, no risk of overflow
- printf("ERR: the number of cells exceeds the limit when topk get bad flows\n");
+ // todo: log
+ // printf("ERR: the number of cells exceeds the limit when topk get bad flows\n");
return -1;
}
@@ -255,7 +256,8 @@ int cell_manager_serialize(const struct cell_manager *pthis, char **blob, size_t
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: An error occurred in cell_manager_serialize\n");
+ // todo: log
+ // printf("ERR: An error occurred in cell_manager_serialize\n");
}
return 0;
diff --git a/src/tags/heavy_keeper.c b/src/tags/heavy_keeper.c
index dce6940..f1601ae 100644
--- a/src/tags/heavy_keeper.c
+++ b/src/tags/heavy_keeper.c
@@ -479,7 +479,8 @@ int heavy_keeper_merge_recording_id_details(struct heavy_keeper *dest, const str
if (dest->params.array_num != src->params.array_num ||
dest->params.max_bucket_num != src->params.max_bucket_num ||
dest->K != src->K) {
- printf("ERR: parameters of two merged heavy keeper must be the same\n");
+ // todo: log
+ // printf("ERR: parameters of two merged heavy keeper must be the same\n");
return -1;
}
@@ -543,7 +544,7 @@ int heavy_keeper_sorted_set_member_serialization(const struct tag_hash_key *tag,
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: An error occurred in heavy_keeper_sorted_set_member_serialization!\n");
+ // printf("ERR: An error occurred in heavy_keeper_sorted_set_member_serialization!\n");
return -1;
}
return 0;
@@ -560,7 +561,7 @@ int heavy_keeper_bucket_serialization(const struct Bucket *b, char **blob, size_
mpack_write_u32(&writer, b->finger_print);
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: An error occurred in heavy_keeper_bucket_serialization!\n");
+ // printf("ERR: An error occurred in heavy_keeper_bucket_serialization!\n");
return -1;
}
return 0;
@@ -614,7 +615,7 @@ void heavy_keeper_serialization(const struct heavy_keeper *hk, char **blob, size
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: An error occurred in heavy_keeper_serialization\n");
+ // printf("ERR: An error occurred in heavy_keeper_serialization\n");
}
}
@@ -659,7 +660,7 @@ struct heavy_keeper *heavy_keeper_deserialization(const char *blob, size_t size)
heavy_keeper_sorted_set_deserialization(&root, hk->top_K_heap);
if (mpack_tree_destroy(&tree) != mpack_ok) {
- printf("ERR: An error occurred in heavy_keeper_deserialization\n");
+ // printf("ERR: An error occurred in heavy_keeper_deserialization\n");
return NULL;
}
return hk;
diff --git a/src/tags/my_ut_hash.c b/src/tags/my_ut_hash.c
index c9a1cba..24b5e0f 100644
--- a/src/tags/my_ut_hash.c
+++ b/src/tags/my_ut_hash.c
@@ -208,7 +208,7 @@ void fieldtag_list_serialize(const struct fieldstat_tag *tag_list, size_t tag_nu
mpack_finish_array(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR mpack writer fieldtag_list_serialize destroy failed\n");
+ // printf("ERR mpack writer fieldtag_list_serialize destroy failed\n");
}
fieldtag_list_free(tag_list_sorted, tag_num);
@@ -364,7 +364,7 @@ void tag_hash_key_serialize(const struct tag_hash_key *tag, char **blob, size_t
mpack_complete_map(&writer);
if (mpack_writer_destroy(&writer) != mpack_ok) {
- printf("ERR: An error occurred in tag_hash_key_serialize!\n");
+ // printf("ERR: An error occurred in tag_hash_key_serialize!\n");
}
}
diff --git a/src/tags/sorted_set.c b/src/tags/sorted_set.c
index b8d2d46..9c90819 100644
--- a/src/tags/sorted_set.c
+++ b/src/tags/sorted_set.c
@@ -277,7 +277,7 @@ void sorted_set_incrby(struct sorted_set *ss, const struct tag_hash_key *tag, un
{
heap_entry *entry = sorted_set_find_entry(ss, tag);
if (entry == NULL) {
- printf("ERR: sorted_set_incrby: tag not found. The program will new an entry and continue, but it is not expected.\n");
+ // printf("ERR: sorted_set_incrby: tag not found. The program will new an entry and continue, but it is not expected.\n");
sorted_set_insert(ss, (struct tag_hash_key *)tag, count);
return;
}
diff --git a/test/test_exporter_json.cpp b/test/test_exporter_json.cpp
index 8fdee94..d64b913 100644
--- a/test/test_exporter_json.cpp
+++ b/test/test_exporter_json.cpp
@@ -119,7 +119,6 @@ cJSON *test_exporter_extract_results_with_standard_global(const struct fieldstat
char *json_string = fieldstat_json_exporter_export(fieldstat_json_exporter);
cJSON *root_arr = cJSON_Parse(json_string);
- printf("test, fieldstat_json_exporter_export json_string: %s\n", json_string);
free(json_string);
fieldstat_json_exporter_free(fieldstat_json_exporter);
@@ -132,7 +131,6 @@ cJSON *test_exporter_extract_results(const struct fieldstat *instance)
char *json_string = fieldstat_json_exporter_export(fieldstat_json_exporter);
cJSON *root_arr = cJSON_Parse(json_string);
- printf("test, fieldstat_json_exporter_export json_string: %s\n", json_string);
free(json_string);
fieldstat_json_exporter_free(fieldstat_json_exporter);
diff --git a/test/test_fuzz_test.cpp b/test/test_fuzz_test.cpp
index de5be99..0ed0d3c 100644
--- a/test/test_fuzz_test.cpp
+++ b/test/test_fuzz_test.cpp
@@ -136,7 +136,6 @@ TEST(Fuzz_test, both_comp_and_topk_cubes_with_merge_and_reset_expecting_correct_
delete shared_tag[i];
}
- printf("czzzz test (dest)----------------\n");
int *cubes;
int cube_num;
struct fieldstat *instance_in_focus = instance_dest;
diff --git a/test/test_merge.cpp b/test/test_merge.cpp
index 4e7a9b1..21fd02f 100644
--- a/test/test_merge.cpp
+++ b/test/test_merge.cpp
@@ -510,13 +510,6 @@ TEST(unit_test_merge, merge_accuracy_test_with_K_large_enough_topk)
flows_in_merged.push_back(new Fieldstat_tag_list_wrapper(&tag_list[i]));
}
- // // print
- // printf("flows_in_merged\n");
- // for (size_t i = 0; i < flows_in_merged.size(); i++) {
- // cout << flows_in_merged[i]->to_string() << endl;
- // }
- // cout << "---------------------------------------------" << endl;
-
flows_in_dest.insert(flows_in_dest.end(), std::make_move_iterator(flows_in_src.begin()), std::make_move_iterator(flows_in_src.end()));
double accuracy = test_cal_accuracy_given_expected_key(flows_in_dest, flows_in_merged);
EXPECT_TRUE(accuracy > 0.99); // should be 1.0
diff --git a/test/unit_test_cell_manager.cpp b/test/unit_test_cell_manager.cpp
index 0fccede..9fbe6c5 100644
--- a/test/unit_test_cell_manager.cpp
+++ b/test/unit_test_cell_manager.cpp
@@ -144,15 +144,6 @@ TEST(unit_test_cell_manager, merge_topk_given_K_large_enough)
for (size_t i = 3; i < 5; i++) {
cell_id_2[i - 3] = cell_manager_add_cell_topk(cm2, keys[i], 1, &pop_dummy, &exist_dummy);
}
- auto test_result_1 = test_query_cell_manager_content(cm1);
- for (size_t i = 0; i < test_result_1.size(); i++) {
- printf("cm1 content: %s\n", tag_hash_key_get_compound_key(test_result_1[i]));
- }
- auto test_result_2 = test_query_cell_manager_content(cm2);
- for (size_t i = 0; i < test_result_2.size(); i++) {
- printf("cm2 content: %s\n", tag_hash_key_get_compound_key(test_result_2[i]));
- }
-
int *cell_id_popped;
int n_cell_id_popped;
int *cell_id_old;