diff --git a/neuron.json b/neuron.json index 51b70c27..79621cb7 100644 --- a/neuron.json +++ b/neuron.json @@ -3,5 +3,6 @@ "port": 7000, "disable_auth": 0, "syslog_host": "", - "syslog_port": 541 + "syslog_port": 541, + "sub_filter_error": 0 } diff --git a/src/adapter/driver/cache.c b/src/adapter/driver/cache.c index 1c209044..2c4db5f3 100644 --- a/src/adapter/driver/cache.c +++ b/src/adapter/driver/cache.c @@ -29,6 +29,8 @@ #include "cache.h" +extern bool sub_filter_err; + typedef struct { char group[NEU_GROUP_NAME_LEN]; char tag[NEU_TAG_NAME_LEN]; @@ -39,6 +41,7 @@ struct elem { bool changed; neu_dvalue_t value; + neu_dvalue_t value_old; neu_tag_meta_t metas[NEU_TAG_META_SIZE]; @@ -142,8 +145,91 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache, HASH_FIND(hh, cache->table, &key, sizeof(tkey_t), elem); if (elem != NULL) { elem->timestamp = timestamp; - if (elem->value.type != value.type) { + + if (sub_filter_err && value.type == NEU_TYPE_ERROR) { + goto error_not_report; + } + + if ((!sub_filter_err && elem->value.type != value.type) || + (sub_filter_err && elem->value.type != value.type && + elem->value.type != NEU_TYPE_ERROR)) { elem->changed = true; + } else if (sub_filter_err && elem->value.type != value.type && + elem->value.type == NEU_TYPE_ERROR) { + switch (value.type) { + case NEU_TYPE_INT8: + case NEU_TYPE_UINT8: + case NEU_TYPE_INT16: + case NEU_TYPE_UINT16: + case NEU_TYPE_INT32: + case NEU_TYPE_UINT32: + case NEU_TYPE_INT64: + case NEU_TYPE_UINT64: + case NEU_TYPE_BIT: + case NEU_TYPE_BOOL: + case NEU_TYPE_STRING: + case NEU_TYPE_TIME: + case NEU_TYPE_DATA_AND_TIME: + case NEU_TYPE_WORD: + case NEU_TYPE_DWORD: + case NEU_TYPE_LWORD: + if (memcmp(&elem->value_old.value, &value.value, + sizeof(value.value)) != 0) { + elem->changed = true; + } + break; + case NEU_TYPE_BYTES: + if (elem->value_old.value.bytes.length != + value.value.bytes.length) { + elem->changed = true; + } else { + if (memcpy(elem->value_old.value.bytes.bytes, + value.value.bytes.bytes, + value.value.bytes.length) != 0) { + elem->changed = true; + } + } + break; + case NEU_TYPE_PTR: { + if (elem->value_old.value.ptr.length != + value.value.ptr.length) { + elem->changed = true; + } else { + if (memcmp(elem->value_old.value.ptr.ptr, + value.value.ptr.ptr, + value.value.ptr.length) != 0) { + elem->changed = true; + } + } + + break; + } + case NEU_TYPE_FLOAT: + if (elem->value_old.precision == 0) { + elem->changed = + elem->value_old.value.f32 != value.value.f32; + } else { + if (fabs(elem->value_old.value.f32 - value.value.f32) > + pow(0.1, elem->value_old.precision)) { + elem->changed = true; + } + } + break; + case NEU_TYPE_DOUBLE: + if (elem->value_old.precision == 0) { + elem->changed = + elem->value_old.value.d64 != value.value.d64; + } else { + if (fabs(elem->value_old.value.d64 - value.value.d64) > + pow(0.1, elem->value_old.precision)) { + elem->changed = true; + } + } + + break; + case NEU_TYPE_ERROR: + break; + } } else { switch (value.type) { case NEU_TYPE_INT8: @@ -218,6 +304,14 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache, } } + if (sub_filter_err && value.type != NEU_TYPE_ERROR) { + elem->value_old.type = value.type; + elem->value_old.value = value.value; + elem->value_old.precision = value.precision; + } + + error_not_report: + if (change) { elem->changed = true; } diff --git a/src/argparse.c b/src/argparse.c index 25be4d13..2cfc91e6 100644 --- a/src/argparse.c +++ b/src/argparse.c @@ -80,6 +80,7 @@ const char *usage_text = " --plugin_dir directory from which neuron loads plugin lib files\n" " --syslog_host syslog server host to which neuron will send logs\n" " --syslog_port syslog server port (default 541 if not provided)\n" +" --sub_filter_error The subscribe attribute only detects the last read value and does not report any error tags\n" "\n"; // clang-format on @@ -181,6 +182,19 @@ static inline int load_env(neu_cli_args_t *args, char **log_level_out, } } + char *sub_filter_e = getenv(NEU_ENV_SUB_FILTER_ERROR); + if (sub_filter_e != NULL) { + if (strcmp(sub_filter_e, "1") == 0) { + args->sub_filter_err = true; + } else if (strcmp(sub_filter_e, "0") == 0) { + args->sub_filter_err = false; + } else { + printf("neuron NEURON_SUB_FILTER_ERROR setting error!\n"); + ret = -1; + break; + } + } + char *log_level = getenv(NEU_ENV_LOG_LEVEL); if (log_level != NULL) { if (*log_level_out != NULL) { @@ -289,6 +303,7 @@ static inline int load_config_file(int argc, char *argv[], { .name = "port", .t = NEU_JSON_INT }, { .name = "syslog_host", .t = NEU_JSON_STR }, { .name = "syslog_port", .t = NEU_JSON_INT }, + { .name = "sub_filter_error", .t = NEU_JSON_INT }, }; resolve_config_file_path(argc, argv, long_options, opts, &config_file); @@ -369,6 +384,16 @@ static inline int load_config_file(int argc, char *argv[], break; } + if (elems[5].v.val_int == 1) { + args->sub_filter_err = true; + } else if (elems[5].v.val_int == 0) { + args->sub_filter_err = false; + } else { + printf("config file %s sub_filter_error setting error!\n", + config_file); + break; + } + ret = 0; } else { printf("config file %s elems error! must had ip, port and " @@ -424,6 +449,7 @@ void neu_cli_args_init(neu_cli_args_t *args, int argc, char *argv[]) { "stop", no_argument, NULL, 's' }, { "syslog_host", required_argument, NULL, 'S' }, { "syslog_port", required_argument, NULL, 'P' }, + { "sub_filter_error", no_argument, NULL, 'f' }, { NULL, 0, NULL, 0 }, }; @@ -517,6 +543,9 @@ void neu_cli_args_init(neu_cli_args_t *args, int argc, char *argv[]) } args->syslog_host = strdup(optarg); break; + case 'f': + args->sub_filter_err = true; + break; case '?': default: usage(); diff --git a/src/argparse.h b/src/argparse.h index 8c0ab506..e844c164 100644 --- a/src/argparse.h +++ b/src/argparse.h @@ -35,6 +35,7 @@ #define NEU_ENV_PLUGIN_DIR "NEURON_PLUGIN_DIR" #define NEU_ENV_SYSLOG_HOST "NEURON_SYSLOG_HOST" #define NEU_ENV_SYSLOG_PORT "NEURON_SYSLOG_PORT" +#define NEU_ENV_SUB_FILTER_ERROR "NEURON_SUB_FILTER_ERROR" #define NEURON_CONFIG_FNAME "./config/neuron.json" @@ -64,6 +65,7 @@ typedef struct { int port; char * syslog_host; uint16_t syslog_port; + bool sub_filter_err; } neu_cli_args_t; /** Parse command line arguments. diff --git a/src/main.c b/src/main.c index c16a4512..d5a4bf34 100644 --- a/src/main.c +++ b/src/main.c @@ -39,6 +39,7 @@ static bool exit_flag = false; static neu_manager_t *g_manager = NULL; zlog_category_t * neuron = NULL; bool disable_jwt = false; +bool sub_filter_err = false; int default_log_level = ZLOG_LEVEL_NOTICE; char host_port[32] = { 0 }; char g_status[32] = { 0 }; @@ -165,7 +166,8 @@ int main(int argc, char *argv[]) global_timestamp = neu_time_ms(); neu_cli_args_init(&args, argc, argv); - disable_jwt = args.disable_auth; + disable_jwt = args.disable_auth; + sub_filter_err = args.sub_filter_err; snprintf(host_port, sizeof(host_port), "http://%s:%d", args.ip, args.port); if (args.daemonized) {