From fe772b6e63e3b8c4d263bdcdff50762314a6beb1 Mon Sep 17 00:00:00 2001 From: "xiang.zhou" Date: Thu, 15 Aug 2024 17:52:44 +0800 Subject: [PATCH] feat(otel):add traces --- .github/workflows/check.yml | 4 +- CMakeLists.txt | 6 +- Install-dependencies.md | 18 + codecov.yaml | 8 + include/neuron/define.h | 4 + include/neuron/utils/http.h | 2 + plugins/restful/handle.c | 10 + plugins/restful/otel_handle.c | 69 ++ plugins/restful/otel_handle.h | 27 + plugins/restful/rest.c | 28 + plugins/restful/rw_handle.c | 257 +++++++- simulator/otel_server.py | 37 ++ src/adapter/adapter.c | 164 ++++- src/adapter/driver/driver.c | 136 +++- src/adapter/driver/driver_internal.h | 8 +- src/core/manager.c | 45 ++ src/otel/common.pb-c.c | 545 ++++++++++++++++ src/otel/common.pb-c.h | 276 ++++++++ src/otel/otel_manager.c | 706 ++++++++++++++++++++ src/otel/otel_manager.h | 79 +++ src/otel/resource.pb-c.c | 107 +++ src/otel/resource.pb-c.h | 83 +++ src/otel/trace.pb-c.c | 928 +++++++++++++++++++++++++++ src/otel/trace.pb-c.h | 636 ++++++++++++++++++ src/parser/neu_json_otel.c | 103 +++ src/parser/neu_json_otel.h | 47 ++ src/utils/http.c | 89 +++ tests/ft/driver/test_modbus.py | 467 ++++++++------ tests/ft/neuron/api.py | 14 +- 29 files changed, 4651 insertions(+), 252 deletions(-) create mode 100644 codecov.yaml create mode 100644 plugins/restful/otel_handle.c create mode 100644 plugins/restful/otel_handle.h create mode 100644 simulator/otel_server.py create mode 100644 src/otel/common.pb-c.c create mode 100644 src/otel/common.pb-c.h create mode 100644 src/otel/otel_manager.c create mode 100644 src/otel/otel_manager.h create mode 100644 src/otel/resource.pb-c.c create mode 100644 src/otel/resource.pb-c.h create mode 100644 src/otel/trace.pb-c.c create mode 100644 src/otel/trace.pb-c.h create mode 100644 src/parser/neu_json_otel.c create mode 100644 src/parser/neu_json_otel.h diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 5669d3bd4..52dda5d9f 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -21,7 +21,7 @@ jobs: uses: DoozyX/clang-format-lint-action@v0.12 with: source: 'src plugins include tests' - exclude: 'include/neuron/utils/uthash.h include/neuron/utils/utarray.h include/neuron/utils/utlist.h include/neuron/utils/zlog.h' + exclude: 'include/neuron/utils/uthash.h include/neuron/utils/utarray.h include/neuron/utils/utlist.h include/neuron/utils/zlog.h src/otel/trace.pb-c.h src/otel/trace.pb-c.c src/otel/resource.pb-c.h src/otel/resource.pb-c.c src/otel/common.pb-c.c src/otel/common.pb-c.h' clangFormatVersion: 10 style: file @@ -36,7 +36,7 @@ jobs: - name: cppcheck run: | sudo apt install cppcheck - cppcheck --enable=all --error-exitcode=2 --inline-suppr --suppress=missingInclude --suppress=unusedFunction ./plugins ./src + cppcheck --enable=all --error-exitcode=2 --inline-suppr --suppress=missingInclude --suppress=unusedFunction --suppress=*:src/otel/trace.pb-c.c --suppress=*:src/otel/common.pb-c.c --suppress=*:src/otel/resource.pb-c.c ./plugins ./src cppcheck --enable=all --error-exitcode=2 --inline-suppr --suppress=missingInclude --suppress=variableScope ./simulator ut: diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b69e6d8e..9c8104634 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,6 +69,7 @@ set(PERSIST_SOURCES src/persist/sqlite.c src/persist/json/persist_json_plugin.c) aux_source_directory(src/parser NEURON_SRC_PARSE) +aux_source_directory(src/otel NEURON_SRC_OTEL) set(NEURON_BASE_SOURCES src/base/tag.c src/base/neu_plugin_common.c @@ -109,12 +110,12 @@ endif() add_library(neuron-base SHARED) -target_sources(neuron-base PRIVATE ${NEURON_BASE_SOURCES} ${NEURON_SRC_PARSE}) +target_sources(neuron-base PRIVATE ${NEURON_BASE_SOURCES} ${NEURON_SRC_PARSE} ${NEURON_SRC_OTEL}) target_include_directories(neuron-base PRIVATE include/neuron src) target_link_libraries(neuron-base libssl.a libcrypto.a) target_link_libraries(neuron-base nng libzlog.so jansson jwt - ${CMAKE_THREAD_LIBS_INIT} -lm) + ${CMAKE_THREAD_LIBS_INIT} -lm protobuf-c) add_dependencies(neuron-base neuron-version) # dependency imposed by nng @@ -148,6 +149,7 @@ set(NEURON_SOURCES plugins/restful/plugin_handle.c plugins/restful/version_handle.c plugins/restful/scan_handle.c + plugins/restful/otel_handle.c plugins/restful/rest.c plugins/restful/user.c) diff --git a/Install-dependencies.md b/Install-dependencies.md index 0486361f8..3eaae85b2 100644 --- a/Install-dependencies.md +++ b/Install-dependencies.md @@ -55,3 +55,21 @@ $ tar xzf sqlite3.tar.gz --strip-components=1 -C sqlite3 $ cd sqlite3 $ ./configure CFLAGS=-fPIC && make && sudo make install ``` + +[protobuf](https://github.com/protocolbuffers/protobuf) +```shell +$ wget --no-check-certificate --content-disposition https://github.com/protocolbuffers/protobuf/releases/download/v3.20.1/protobuf-cpp-3.20.1.tar.gz +$ tar -xzvf protobuf-cpp-3.20.1.tar.gz +$ cd protobuf-3.20.1 +$ ./configure --enable-shared=no CFLAGS=-fPIC CXXFLAGS=-fPIC +$ make && make install +``` + +[protobuf-c](https://github.com/protobuf-c/protobuf-c.git) +```shell +$ git clone -b v1.4.0 https://github.com/protobuf-c/protobuf-c.git +$ cd protobuf-c +$ ./autogen.sh +$ ./configure --disable-protoc --enable-shared=no CFLAGS=-fPIC CXXFLAGS=-fPIC +$ make && make install +``` diff --git a/codecov.yaml b/codecov.yaml new file mode 100644 index 000000000..6a83fdef2 --- /dev/null +++ b/codecov.yaml @@ -0,0 +1,8 @@ +ignore: + - "src/otel/*.pb-c.c" +coverage: + status: + project: + default: + target: auto # the required coverage value + threshold: 0.1% # the leniency in hitting the target \ No newline at end of file diff --git a/include/neuron/define.h b/include/neuron/define.h index 3de4a5df0..0345399ea 100644 --- a/include/neuron/define.h +++ b/include/neuron/define.h @@ -95,6 +95,10 @@ extern int default_log_level; extern bool disable_jwt; extern char host_port[32]; extern char g_status[32]; +extern bool otel_flag; +extern char otel_host[32]; +extern int otel_port; +extern char otel_traces_url[32]; typedef enum neu_plugin_kind { NEU_PLUGIN_KIND_STATIC = 0, diff --git a/include/neuron/utils/http.h b/include/neuron/utils/http.h index 0c1a46a25..414db033f 100644 --- a/include/neuron/utils/http.h +++ b/include/neuron/utils/http.h @@ -83,6 +83,8 @@ int neu_http_internal_error(nng_aio *aio, char *content); int neu_http_response_file(nng_aio *aio, void *data, size_t len, const char *disposition); +int neu_http_post_otel_trace(uint8_t *data, int len); + #ifdef __cplusplus } #endif diff --git a/plugins/restful/handle.c b/plugins/restful/handle.c index bf54035b3..59add016c 100644 --- a/plugins/restful/handle.c +++ b/plugins/restful/handle.c @@ -31,6 +31,7 @@ #include "log_handle.h" #include "metric_handle.h" #include "normal_handle.h" +#include "otel_handle.h" #include "plugin_handle.h" #include "rw_handle.h" #include "scan_handle.h" @@ -127,6 +128,9 @@ static struct neu_http_handler cors_handler[] = { { .url = "/api/v2/scan/tags", }, + { + .url = "/api/v2/otel", + }, }; static struct neu_http_handler rest_handlers[] = { @@ -413,6 +417,12 @@ static struct neu_http_handler rest_handlers[] = { .url = "/api/v2/status", .value.handler = handle_status, }, + { + .method = NEU_HTTP_METHOD_POST, + .type = NEU_HTTP_HANDLER_FUNCTION, + .url = "/api/v2/otel", + .value.handler = handle_otel, + }, }; void neu_rest_handler(const struct neu_http_handler **handlers, uint32_t *size) diff --git a/plugins/restful/otel_handle.c b/plugins/restful/otel_handle.c new file mode 100644 index 000000000..1e582428e --- /dev/null +++ b/plugins/restful/otel_handle.c @@ -0,0 +1,69 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "persist/persist.h" +#include "user.h" +#include "utils/asprintf.h" +#include "utils/log.h" + +#include "argparse.h" +#include "parser/neu_json_otel.h" +#include "json/neu_json_fn.h" + +#include "handle.h" +#include "utils/http.h" +#include "utils/neu_jwt.h" + +#include "otel/otel_manager.h" +#include "otel_handle.h" + +void handle_otel(nng_aio *aio) +{ + NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT( + aio, neu_json_otel_conf_req_t, neu_json_decode_otel_conf_req, { + if (strcmp(req->action, "start") == 0) { + otel_flag = true; + strcpy(otel_host, req->host); + otel_port = req->port; + strcpy(otel_traces_url, req->traces_url); + neu_http_ok(aio, "{\"error\": 0 }"); + neu_otel_start(); + } else if (strcmp(req->action, "stop") == 0) { + otel_flag = false; + neu_http_ok(aio, "{\"error\": 0 }"); + neu_otel_stop(); + } else { + NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, { + neu_http_response(aio, NEU_ERR_PARAM_IS_WRONG, + result_error); + }); + } + }) +} \ No newline at end of file diff --git a/plugins/restful/otel_handle.h b/plugins/restful/otel_handle.h new file mode 100644 index 000000000..324acc5a5 --- /dev/null +++ b/plugins/restful/otel_handle.h @@ -0,0 +1,27 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +#ifndef _NEU_OTEL_HANDLE_H_ +#define _NEU_OTEL_HANDLE_H_ + +#include + +void handle_otel(nng_aio *aio); + +#endif \ No newline at end of file diff --git a/plugins/restful/rest.c b/plugins/restful/rest.c index 9bac87e11..74c3e8f8f 100644 --- a/plugins/restful/rest.c +++ b/plugins/restful/rest.c @@ -31,6 +31,7 @@ #include "global_config_handle.h" #include "group_config_handle.h" #include "handle.h" +#include "otel/otel_manager.h" #include "plugin_handle.h" #include "rest.h" #include "rw_handle.h" @@ -38,6 +39,7 @@ #include "utils/http.h" #include "utils/log.h" #include "utils/neu_jwt.h" +#include "utils/time.h" #include "json/neu_json_fn.h" #define neu_plugin_module default_dashboard_plugin_module @@ -172,12 +174,37 @@ static int dashb_plugin_request(neu_plugin_t * plugin, return 0; } + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = neu_otel_find_trace(header->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name(scope, "rest response"); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t)(pthread_self())); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + switch (header->type) { case NEU_RESP_ERROR: { neu_resp_error_t *error = (neu_resp_error_t *) data; NEU_JSON_RESPONSE_ERROR(error->error, { neu_http_response(header->ctx, error->error, result_error); }); + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", error->error); + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + neu_otel_trace_set_final(trace); + } break; } case NEU_RESP_GET_PLUGIN: @@ -241,6 +268,7 @@ static int dashb_plugin_request(neu_plugin_t * plugin, assert(false); break; } + return 0; } diff --git a/plugins/restful/rw_handle.c b/plugins/restful/rw_handle.c index 7635e4937..488c04bb8 100644 --- a/plugins/restful/rw_handle.c +++ b/plugins/restful/rw_handle.c @@ -25,9 +25,12 @@ #include "handle.h" #include "utils/http.h" +#include "utils/time.h" #include "rw_handle.h" +#include "otel/otel_manager.h" + void handle_read(nng_aio *aio) { neu_plugin_t *plugin = neu_rest_get_plugin(); @@ -201,12 +204,76 @@ void handle_write(nng_aio *aio) neu_req_write_tag_t cmd = { 0 }; int err_type; + nng_http_req *nng_req = nng_aio_get_input(aio, 0); + nlog_notice("<%p> req %s %s", aio, nng_http_req_get_method(nng_req), + nng_http_req_get_uri(nng_req)); + + header.ctx = aio; + header.type = NEU_REQ_WRITE_TAG; + + bool trace_flag = false; + neu_otel_trace_ctx trace = NULL; + neu_otel_scope_ctx scope = NULL; + + if (otel_flag) { + const char *trace_parent = + nng_http_req_get_header(nng_req, "traceparent"); + if (trace_parent) { + char trace_id[64] = { 0 }; + char span_id[32] = { 0 }; + uint32_t flags = 0; + neu_otel_split_traceparent(trace_parent, trace_id, span_id, + &flags); + if (strlen(trace_id) == 32) { + trace_flag = true; + trace = + neu_otel_create_trace(trace_id, header.ctx, flags); + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name( + scope, nng_http_req_get_uri(nng_req)); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + if (strlen(span_id) == 16) { + neu_otel_scope_set_parent_span_id(scope, span_id); + } + neu_otel_scope_set_span_flags(scope, flags); + neu_otel_scope_set_span_start_time(scope, + neu_time_ms()); + + neu_otel_scope_add_span_attr_int( + scope, "thread id", (int64_t) pthread_self()); + + neu_otel_scope_add_span_attr_string( + scope, "HTTP method", + nng_http_req_get_method(nng_req)); + + char * req_data = NULL; + size_t req_data_size = 0; + + if (neu_http_get_body((aio), (void **) &req_data, + &req_data_size) == 0) { + neu_otel_scope_add_span_attr_string( + scope, "HTTP body", req_data); + } + + free(req_data); + } + } + } + if (req->t == NEU_JSON_STR && strlen(req->value.val_str) >= NEU_VALUE_SIZE) { NEU_JSON_RESPONSE_ERROR(NEU_ERR_STRING_TOO_LONG, { neu_http_response(aio, NEU_ERR_STRING_TOO_LONG, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", + NEU_ERR_STRING_TOO_LONG); + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + neu_otel_trace_set_final(trace); + } return; } @@ -216,16 +283,15 @@ void handle_write(nng_aio *aio) neu_http_response(aio, NEU_ERR_STRING_TOO_LONG, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", + NEU_ERR_STRING_TOO_LONG); + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + neu_otel_trace_set_final(trace); + } return; } - nng_http_req *nng_req = nng_aio_get_input(aio, 0); - nlog_notice("<%p> req %s %s", aio, nng_http_req_get_method(nng_req), - nng_http_req_get_uri(nng_req)); - - header.ctx = aio; - header.type = NEU_REQ_WRITE_TAG; - if (req->node && strlen(req->node) >= NEU_NODE_NAME_LEN) { err_type = NEU_ERR_NODE_NAME_TOO_LONG; goto error; @@ -244,6 +310,7 @@ void handle_write(nng_aio *aio) cmd.driver = req->node; cmd.group = req->group; cmd.tag = req->tag; + req->node = NULL; // ownership moved req->group = NULL; // ownership moved req->tag = NULL; // ownership moved @@ -256,6 +323,7 @@ void handle_write(nng_aio *aio) case NEU_JSON_STR: cmd.value.type = NEU_TYPE_STRING; strcpy(cmd.value.value.str, req->value.val_str); + break; case NEU_JSON_BYTES: cmd.value.type = NEU_TYPE_BYTES; @@ -266,6 +334,7 @@ void handle_write(nng_aio *aio) case NEU_JSON_DOUBLE: cmd.value.type = NEU_TYPE_DOUBLE; cmd.value.value.d64 = req->value.val_double; + break; case NEU_JSON_BOOL: cmd.value.type = NEU_TYPE_BOOL; @@ -276,18 +345,35 @@ void handle_write(nng_aio *aio) break; } - int ret = neu_plugin_op(plugin, header, &cmd); + int ret = 0; + if (otel_flag && trace_flag) { + ret = neu_plugin_op(plugin, header, &cmd); + + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + } else { + ret = neu_plugin_op(plugin, header, &cmd); + } + if (ret != 0) { neu_req_write_tag_fini(&cmd); NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, { neu_http_response(aio, NEU_ERR_IS_BUSY, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", + NEU_ERR_IS_BUSY); + neu_otel_trace_set_final(trace); + } } goto success; error: NEU_JSON_RESPONSE_ERROR( err_type, { neu_http_response(aio, err_type, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", err_type); + neu_otel_trace_set_final(trace); + } success:; }) @@ -303,6 +389,63 @@ void handle_write_tags(nng_aio *aio) neu_req_write_tags_t cmd = { 0 }; int err_type; + nng_http_req *nng_req = nng_aio_get_input(aio, 0); + nlog_notice("<%p> req %s %s", aio, nng_http_req_get_method(nng_req), + nng_http_req_get_uri(nng_req)); + header.ctx = aio; + header.type = NEU_REQ_WRITE_TAGS; + + bool trace_flag = false; + neu_otel_trace_ctx trace = NULL; + neu_otel_scope_ctx scope = NULL; + + if (otel_flag) { + const char *trace_parent = + nng_http_req_get_header(nng_req, "traceparent"); + if (trace_parent) { + char trace_id[64] = { 0 }; + char span_id[32] = { 0 }; + uint32_t flags = 0; + neu_otel_split_traceparent(trace_parent, trace_id, span_id, + &flags); + if (strlen(trace_id) == 32) { + trace_flag = true; + trace = + neu_otel_create_trace(trace_id, header.ctx, flags); + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name( + scope, nng_http_req_get_uri(nng_req)); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + if (strlen(span_id) == 16) { + neu_otel_scope_set_parent_span_id(scope, span_id); + } + neu_otel_scope_set_span_flags(scope, flags); + neu_otel_scope_set_span_start_time(scope, + neu_time_ms()); + + neu_otel_scope_add_span_attr_int( + scope, "thread id", (int64_t) pthread_self()); + + neu_otel_scope_add_span_attr_string( + scope, "HTTP method", + nng_http_req_get_method(nng_req)); + + char * req_data = NULL; + size_t req_data_size = 0; + + if (neu_http_get_body((aio), (void **) &req_data, + &req_data_size) == 0) { + neu_otel_scope_add_span_attr_string( + scope, "HTTP body", req_data); + } + + free(req_data); + } + } + } + for (int i = 0; i < req->n_tag; i++) { if (req->tags[i].t == NEU_JSON_STR) { if (strlen(req->tags[i].value.val_str) >= NEU_VALUE_SIZE) { @@ -310,17 +453,18 @@ void handle_write_tags(nng_aio *aio) neu_http_response(aio, NEU_ERR_STRING_TOO_LONG, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int( + scope, "error type", NEU_ERR_STRING_TOO_LONG); + neu_otel_scope_set_span_end_time(scope, + neu_time_ms()); + neu_otel_trace_set_final(trace); + } return; } } } - nng_http_req *nng_req = nng_aio_get_input(aio, 0); - nlog_notice("<%p> req %s %s", aio, nng_http_req_get_method(nng_req), - nng_http_req_get_uri(nng_req)); - header.ctx = aio; - header.type = NEU_REQ_WRITE_TAGS; - if (strlen(req->node) >= NEU_NODE_NAME_LEN) { err_type = NEU_ERR_NODE_NAME_TOO_LONG; goto error; @@ -373,18 +517,35 @@ void handle_write_tags(nng_aio *aio) } } - int ret = neu_plugin_op(plugin, header, &cmd); + int ret = 0; + + if (otel_flag && trace_flag) { + ret = neu_plugin_op(plugin, header, &cmd); + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + } else { + ret = neu_plugin_op(plugin, header, &cmd); + } + if (ret != 0) { neu_req_write_tags_fini(&cmd); NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, { neu_http_response(aio, NEU_ERR_IS_BUSY, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", + NEU_ERR_IS_BUSY); + neu_otel_trace_set_final(trace); + } } goto success; error: NEU_JSON_RESPONSE_ERROR( err_type, { neu_http_response(aio, err_type, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", err_type); + neu_otel_trace_set_final(trace); + } success:; }) @@ -458,14 +619,78 @@ void handle_write_gtags(nng_aio *aio) header.ctx = aio; header.type = NEU_REQ_WRITE_GTAGS; + bool trace_flag = false; + neu_otel_trace_ctx trace = NULL; + neu_otel_scope_ctx scope = NULL; + + if (otel_flag) { + const char *trace_parent = + nng_http_req_get_header(nng_req, "traceparent"); + if (trace_parent) { + char trace_id[64] = { 0 }; + char span_id[32] = { 0 }; + uint32_t flags = 0; + neu_otel_split_traceparent(trace_parent, trace_id, span_id, + &flags); + if (strlen(trace_id) == 32) { + trace_flag = true; + trace = + neu_otel_create_trace(trace_id, header.ctx, flags); + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name( + scope, nng_http_req_get_uri(nng_req)); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + if (strlen(span_id) == 16) { + neu_otel_scope_set_parent_span_id(scope, span_id); + } + neu_otel_scope_set_span_flags(scope, flags); + neu_otel_scope_set_span_start_time(scope, + neu_time_ms()); + + neu_otel_scope_add_span_attr_int( + scope, "thread id", (int64_t) pthread_self()); + + neu_otel_scope_add_span_attr_string( + scope, "HTTP method", + nng_http_req_get_method(nng_req)); + + char * req_data = NULL; + size_t req_data_size = 0; + + if (neu_http_get_body((aio), (void **) &req_data, + &req_data_size) == 0) { + neu_otel_scope_add_span_attr_string( + scope, "HTTP body", req_data); + } + + free(req_data); + } + } + } + trans(req, &cmd); - int ret = neu_plugin_op(plugin, header, &cmd); + int ret = 0; + + if (otel_flag && trace_flag) { + ret = neu_plugin_op(plugin, header, &cmd); + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + } else { + ret = neu_plugin_op(plugin, header, &cmd); + } + if (ret != 0) { neu_req_write_gtags_fini(&cmd); NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, { neu_http_response(aio, NEU_ERR_IS_BUSY, result_error); }); + if (otel_flag && trace_flag) { + neu_otel_scope_add_span_attr_int(scope, "error type", + NEU_ERR_IS_BUSY); + neu_otel_trace_set_final(trace); + } } }) } diff --git a/simulator/otel_server.py b/simulator/otel_server.py new file mode 100644 index 000000000..86acb2527 --- /dev/null +++ b/simulator/otel_server.py @@ -0,0 +1,37 @@ +from http.server import BaseHTTPRequestHandler, HTTPServer +import json +import sys + + +class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): + def do_POST(self): + if self.path == '/v1/traces': + print(f'Received request') + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.end_headers() + response = json.dumps({"status": "success"}) + self.wfile.write(response.encode('utf-8')) + else: + self.send_response(404) + self.end_headers() + self.wfile.write(b'Not Found') + + +def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler, port=4318): + server_address = ('', port) + httpd = server_class(server_address, handler_class) + print(f'Starting httpd server on port {port}...') + httpd.serve_forever() + + +if __name__ == '__main__': + if len(sys.argv) > 1: + try: + port = int(sys.argv[1]) + except ValueError: + print("Invalid port number. Using default port 8080.") + port = 4318 + else: + port = 4318 + run(port=port) diff --git a/src/adapter/adapter.c b/src/adapter/adapter.c index 984782007..f05283e6c 100644 --- a/src/adapter/adapter.c +++ b/src/adapter/adapter.c @@ -29,7 +29,11 @@ #include #include +#include "utils/http.h" #include "utils/log.h" +#include "utils/time.h" + +#include "otel/otel_manager.h" #include "adapter.h" #include "adapter_internal.h" @@ -589,6 +593,26 @@ static int adapter_responseto(neu_adapter_t * adapter, neu_reqresp_head_t *pheader = neu_msg_get_header(msg); strcpy(pheader->sender, adapter->name); + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = neu_otel_find_trace(header->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name(scope, "adapter write tag response"); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + int ret = neu_send_msg_to(adapter->control_fd, &dst, msg); if (0 != ret) { nlog_error("adapter: %s send responseto %s failed, ret: %d, errno: %d", @@ -597,6 +621,10 @@ static int adapter_responseto(neu_adapter_t * adapter, neu_msg_free(msg); } + if (otel_flag && trace) { + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + } + return ret; } @@ -770,15 +798,55 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data) case NEU_REQ_WRITE_TAG: { neu_resp_error_t error = { 0 }; + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = neu_otel_find_trace(header->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name(scope, "adapter write tag"); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + + bool re_flag = false; + if (adapter->module->type == NEU_NA_TYPE_DRIVER) { - neu_adapter_driver_write_tag((neu_adapter_driver_t *) adapter, - header); + int w_error = neu_adapter_driver_write_tag( + (neu_adapter_driver_t *) adapter, header); + if (NEU_ERR_SUCCESS == w_error) { + re_flag = true; + } else { + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", w_error); + } + } } else { neu_req_write_tag_fini((neu_req_write_tag_t *) &header[1]); error.error = NEU_ERR_GROUP_NOT_ALLOW; header->type = NEU_RESP_ERROR; neu_msg_exchange(header); reply(adapter, header, &error); + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", + NEU_ERR_GROUP_NOT_ALLOW); + } + } + + if (otel_flag && trace) { + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + if (!re_flag) { + neu_otel_trace_set_final(trace); + } } break; @@ -786,30 +854,114 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data) case NEU_REQ_WRITE_TAGS: { neu_resp_error_t error = { 0 }; + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = neu_otel_find_trace(header->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name(scope, "adapter write tags"); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + + bool re_flag = false; + if (adapter->module->type != NEU_NA_TYPE_DRIVER) { neu_req_write_tags_fini((neu_req_write_tags_t *) &header[1]); error.error = NEU_ERR_GROUP_NOT_ALLOW; header->type = NEU_RESP_ERROR; neu_msg_exchange(header); reply(adapter, header, &error); + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", + NEU_ERR_GROUP_NOT_ALLOW); + } } else { - neu_adapter_driver_write_tags((neu_adapter_driver_t *) adapter, - header); + int w_error = neu_adapter_driver_write_tags( + (neu_adapter_driver_t *) adapter, header); + + if (NEU_ERR_SUCCESS == w_error) { + re_flag = true; + } else { + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", w_error); + } + } } + + if (otel_flag && trace) { + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + if (!re_flag) { + neu_otel_trace_set_final(trace); + } + } + break; } case NEU_REQ_WRITE_GTAGS: { neu_resp_error_t error = { 0 }; + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = neu_otel_find_trace(header->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + neu_otel_scope_set_span_name(scope, "adapter write tags"); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + + bool re_flag = false; + if (adapter->module->type != NEU_NA_TYPE_DRIVER) { neu_req_write_gtags_fini((neu_req_write_gtags_t *) &header[1]); error.error = NEU_ERR_GROUP_NOT_ALLOW; header->type = NEU_RESP_ERROR; neu_msg_exchange(header); reply(adapter, header, &error); + + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", + NEU_ERR_GROUP_NOT_ALLOW); + } } else { - neu_adapter_driver_write_gtags((neu_adapter_driver_t *) adapter, - header); + int w_error = neu_adapter_driver_write_gtags( + (neu_adapter_driver_t *) adapter, header); + + if (NEU_ERR_SUCCESS == w_error) { + re_flag = true; + } else { + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", w_error); + } + } + } + + if (otel_flag && trace) { + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + if (!re_flag) { + neu_otel_trace_set_final(trace); + } } break; } diff --git a/src/adapter/driver/driver.c b/src/adapter/driver/driver.c index 4188fdcb6..0ebde7814 100644 --- a/src/adapter/driver/driver.c +++ b/src/adapter/driver/driver.c @@ -26,7 +26,9 @@ #define EPSILON 1e-9 #include "event/event.h" +#include "utils/http.h" #include "utils/log.h" +#include "utils/time.h" #include "utils/utextend.h" #include "adapter.h" @@ -38,6 +40,8 @@ #include "errcodes.h" #include "tag.h" +#include "otel/otel_manager.h" + typedef struct to_be_write_tag { bool single; neu_datatag_t *tag; @@ -157,12 +161,40 @@ static void write_response(neu_adapter_t *adapter, void *r, neu_error error) neu_reqresp_head_t *req = (neu_reqresp_head_t *) r; neu_resp_error_t nerror = { .error = error }; + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = neu_otel_find_trace(req->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + if (NEU_REQ_WRITE_TAG == req->type) { neu_req_write_tag_fini((neu_req_write_tag_t *) &req[1]); + if (otel_flag && trace) { + neu_otel_scope_set_span_name(scope, "driver write tag response"); + } } else if (NEU_REQ_WRITE_TAGS == req->type) { neu_req_write_tags_fini((neu_req_write_tags_t *) &req[1]); + if (otel_flag && trace) { + neu_otel_scope_set_span_name(scope, "driver write tags response"); + } } else if (NEU_REQ_WRITE_GTAGS == req->type) { neu_req_write_gtags_fini((neu_req_write_gtags_t *) &req[1]); + if (otel_flag && trace) { + neu_otel_scope_set_span_name(scope, "driver write gtags response"); + } } req->type = NEU_RESP_ERROR; @@ -170,6 +202,11 @@ static void write_response(neu_adapter_t *adapter, void *r, neu_error error) nlog_notice("write tag response <%p>", req->ctx); adapter->cb_funs.response(adapter, req, &nerror); + + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", error); + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + } } static void update_with_meta(neu_adapter_t *adapter, const char *group, @@ -1007,21 +1044,21 @@ int is_value_in_range(neu_type_e tag_type, int64_t value, double value_d, } } -void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, - neu_reqresp_head_t * req) +int neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, + neu_reqresp_head_t * req) { neu_req_write_tags_t *cmd = (neu_req_write_tags_t *) &req[1]; if (driver->adapter.state != NEU_NODE_RUNNING_STATE_RUNNING) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_PLUGIN_NOT_RUNNING); - return; + return NEU_ERR_PLUGIN_NOT_RUNNING; } if (driver->adapter.module->intf_funs->driver.write_tags == NULL) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_PLUGIN_NOT_SUPPORT_WRITE_TAGS); - return; + return NEU_ERR_PLUGIN_NOT_SUPPORT_WRITE_TAGS; } group_t *g = find_group(driver, cmd->group); @@ -1029,7 +1066,7 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, if (g == NULL) { driver->adapter.cb_funs.driver.write_response(&driver->adapter, req, NEU_ERR_GROUP_NOT_EXIST); - return; + return NEU_ERR_GROUP_NOT_EXIST; } UT_array *tags = NULL; @@ -1086,7 +1123,7 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, neu_tag_free(tv->tag); } utarray_free(tags); - return; + return value_err; } if (utarray_len(tags) != (unsigned int) cmd->n_tag) { @@ -1097,7 +1134,7 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, neu_tag_free(tv->tag); } utarray_free(tags); - return; + return NEU_ERR_TAG_NOT_EXIST; } to_be_write_tag_t wtag = { 0 }; @@ -1106,10 +1143,12 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, wtag.tvs = tags; store_write_tag(g, &wtag); + + return NEU_ERR_SUCCESS; } -void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, - neu_reqresp_head_t * req) +int neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, + neu_reqresp_head_t * req) { neu_req_write_gtags_t *cmd = (neu_req_write_gtags_t *) &req[1]; group_t * first_g = NULL; @@ -1117,13 +1156,13 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, if (driver->adapter.state != NEU_NODE_RUNNING_STATE_RUNNING) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_PLUGIN_NOT_RUNNING); - return; + return NEU_ERR_PLUGIN_NOT_RUNNING; } if (driver->adapter.module->intf_funs->driver.write_tags == NULL) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_PLUGIN_NOT_SUPPORT_WRITE_TAGS); - return; + return NEU_ERR_PLUGIN_NOT_SUPPORT_WRITE_TAGS; } for (int i = 0; i < cmd->n_group; i++) { @@ -1132,7 +1171,7 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, if (g == NULL) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_GROUP_NOT_EXIST); - return; + return NEU_ERR_GROUP_NOT_EXIST; } if (first_g == NULL) { @@ -1203,7 +1242,7 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, neu_tag_free(tv->tag); } utarray_free(tags); - return; + return value_err; } uint32_t n_tag = 0; @@ -1219,7 +1258,7 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, neu_tag_free(tv->tag); } utarray_free(tags); - return; + return NEU_ERR_TAG_NOT_EXIST; } to_be_write_tag_t wtag = { 0 }; @@ -1228,15 +1267,17 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, wtag.tvs = tags; store_write_tag(first_g, &wtag); + + return NEU_ERR_SUCCESS; } -void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, - neu_reqresp_head_t * req) +int neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, + neu_reqresp_head_t * req) { if (driver->adapter.state != NEU_NODE_RUNNING_STATE_RUNNING) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_PLUGIN_NOT_RUNNING); - return; + return NEU_ERR_PLUGIN_NOT_RUNNING; } neu_req_write_tag_t *cmd = (neu_req_write_tag_t *) &req[1]; @@ -1245,19 +1286,20 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, if (g == NULL) { driver->adapter.cb_funs.driver.write_response(&driver->adapter, req, NEU_ERR_GROUP_NOT_EXIST); - return; + return NEU_ERR_GROUP_NOT_EXIST; } neu_datatag_t *tag = neu_group_find_tag(g->group, cmd->tag); if (tag == NULL) { driver->adapter.cb_funs.driver.write_response(&driver->adapter, req, NEU_ERR_TAG_NOT_EXIST); + return NEU_ERR_TAG_NOT_EXIST; } else { if ((tag->attribute & NEU_ATTRIBUTE_WRITE) != NEU_ATTRIBUTE_WRITE) { driver->adapter.cb_funs.driver.write_response( &driver->adapter, req, NEU_ERR_PLUGIN_TAG_NOT_ALLOW_WRITE); neu_tag_free(tag); - return; + return NEU_ERR_PLUGIN_TAG_NOT_ALLOW_WRITE; } int value_check = is_value_in_range(tag->type, cmd->value.value.i64, @@ -1268,7 +1310,7 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, driver->adapter.cb_funs.driver.write_response(&driver->adapter, req, value_check); neu_tag_free(tag); - return; + return value_check; } if (tag->type == NEU_TYPE_FLOAT || tag->type == NEU_TYPE_DOUBLE) { @@ -1303,6 +1345,7 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, } neu_tag_free(tag); + return NEU_ERR_SUCCESS; } } @@ -2043,20 +2086,73 @@ static int write_callback(void *usr_data) pthread_mutex_lock(&group->wt_mtx); utarray_foreach(group->wt_tags, to_be_write_tag_t *, wtag) { + + int64_t s_time = 0; + int64_t e_time = 0; + + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag) { + trace = + neu_otel_find_trace(((neu_reqresp_head_t *) wtag->req)->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + if (wtag->single) { + neu_otel_scope_set_span_name(scope, + "driver timer cb write tag"); + } else { + neu_otel_scope_set_span_name(scope, + "driver timer cb write tags"); + } + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_add_span_attr_string( + scope, "plugin name", + group->driver->adapter.module->module_name); + + char version[64] = { 0 }; + sprintf(version, "%d.%d.%d", + NEU_GET_VERSION_MAJOR( + group->driver->adapter.module->version), + NEU_GET_VERSION_MINOR( + group->driver->adapter.module->version), + NEU_GET_VERSION_FIX( + group->driver->adapter.module->version)); + + neu_otel_scope_add_span_attr_string(scope, "plugin version", + version); + } + } + + s_time = neu_time_ms(); + if (wtag->single) { group->driver->adapter.module->intf_funs->driver.write_tag( group->driver->adapter.plugin, (void *) wtag->req, wtag->tag, wtag->value); + e_time = neu_time_ms(); neu_tag_free(wtag->tag); } else { group->driver->adapter.module->intf_funs->driver.write_tags( group->driver->adapter.plugin, (void *) wtag->req, wtag->tvs); + e_time = neu_time_ms(); utarray_foreach(wtag->tvs, neu_plugin_tag_value_t *, tv) { neu_tag_free(tv->tag); } utarray_free(wtag->tvs); } + if (otel_flag && trace) { + neu_otel_scope_set_span_start_time(scope, s_time); + neu_otel_scope_set_span_end_time(scope, e_time); + } } utarray_clear(group->wt_tags); pthread_mutex_unlock(&group->wt_mtx); diff --git a/src/adapter/driver/driver_internal.h b/src/adapter/driver/driver_internal.h index e1d20ca15..7eef33373 100644 --- a/src/adapter/driver/driver_internal.h +++ b/src/adapter/driver/driver_internal.h @@ -38,12 +38,12 @@ void neu_adapter_driver_read_group_paginate(neu_adapter_driver_t *driver, void neu_adapter_driver_test_read_tag(neu_adapter_driver_t *driver, neu_reqresp_head_t * req); -void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, +int neu_adapter_driver_write_tag(neu_adapter_driver_t *driver, + neu_reqresp_head_t * req); +int neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, neu_reqresp_head_t * req); -void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver, +int neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, neu_reqresp_head_t * req); -void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver, - neu_reqresp_head_t * req); int neu_adapter_driver_add_group(neu_adapter_driver_t *driver, const char *name, uint32_t interval); diff --git a/src/core/manager.c b/src/core/manager.c index 439210573..d601a7dbe 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -29,6 +29,7 @@ #include "event/event.h" #include "persist/persist.h" #include "utils/base64.h" +#include "utils/http.h" #include "utils/log.h" #include "utils/time.h" @@ -39,6 +40,7 @@ #include "argparse.h" #include "base/msg_internal.h" #include "errcodes.h" +#include "otel/otel_manager.h" #include "node_manager.h" #include "plugin_manager.h" @@ -1049,6 +1051,37 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data) case NEU_REQ_GET_TAG: case NEU_REQ_NODE_CTL: case NEU_REQ_ADD_GROUP: { + neu_otel_trace_ctx *trace = NULL; + neu_otel_scope_ctx scope = NULL; + if (otel_flag && + (NEU_REQ_WRITE_TAG == header->type || + NEU_REQ_WRITE_TAGS == header->type || + NEU_REQ_WRITE_GTAGS == header->type)) { + trace = neu_otel_find_trace(header->ctx); + if (trace) { + scope = neu_otel_add_span(trace); + if (NEU_REQ_WRITE_TAG == header->type) { + neu_otel_scope_set_span_name(scope, "manager write tag"); + } else if (NEU_REQ_WRITE_TAGS == header->type) { + neu_otel_scope_set_span_name(scope, "manager write tags"); + } else if (NEU_REQ_WRITE_GTAGS == header->type) { + neu_otel_scope_set_span_name(scope, "manager write gtags"); + } + char new_span_id[36] = { 0 }; + neu_otel_new_span_id(new_span_id); + neu_otel_scope_set_span_id(scope, new_span_id); + uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope); + if (p_sp_id) { + neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8); + } + neu_otel_scope_add_span_attr_int(scope, "thread id", + (int64_t) pthread_self()); + neu_otel_scope_set_span_start_time(scope, neu_time_ms()); + } + } + + bool re_flag = false; + if (neu_node_manager_find(manager->node_manager, header->receiver) == NULL) { if (NEU_REQ_READ_GROUP == header->type) { @@ -1067,8 +1100,20 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data) header->type = NEU_RESP_ERROR; neu_msg_exchange(header); reply(manager, header, &e); + if (otel_flag && trace) { + neu_otel_scope_add_span_attr_int(scope, "error", + NEU_ERR_NODE_NOT_EXIST); + } } else { forward_msg(manager, header, header->receiver); + re_flag = true; + } + + if (otel_flag && trace) { + neu_otel_scope_set_span_end_time(scope, neu_time_ms()); + if (!re_flag) { + neu_otel_trace_set_final(trace); + } } break; diff --git a/src/otel/common.pb-c.c b/src/otel/common.pb-c.c new file mode 100644 index 000000000..9cd8e196f --- /dev/null +++ b/src/otel/common.pb-c.c @@ -0,0 +1,545 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: opentelemetry/proto/common/v1/common.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "common.pb-c.h" +void opentelemetry__proto__common__v1__any_value__init( + Opentelemetry__Proto__Common__V1__AnyValue *message) +{ + static const Opentelemetry__Proto__Common__V1__AnyValue init_value = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__INIT; + *message = init_value; +} +size_t opentelemetry__proto__common__v1__any_value__get_packed_size( + const Opentelemetry__Proto__Common__V1__AnyValue *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__any_value__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__common__v1__any_value__pack( + const Opentelemetry__Proto__Common__V1__AnyValue *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__any_value__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__common__v1__any_value__pack_to_buffer( + const Opentelemetry__Proto__Common__V1__AnyValue *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__any_value__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Common__V1__AnyValue * +opentelemetry__proto__common__v1__any_value__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Common__V1__AnyValue *) + protobuf_c_message_unpack( + &opentelemetry__proto__common__v1__any_value__descriptor, allocator, + len, data); +} +void opentelemetry__proto__common__v1__any_value__free_unpacked( + Opentelemetry__Proto__Common__V1__AnyValue *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__any_value__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__common__v1__array_value__init( + Opentelemetry__Proto__Common__V1__ArrayValue *message) +{ + static const Opentelemetry__Proto__Common__V1__ArrayValue init_value = + OPENTELEMETRY__PROTO__COMMON__V1__ARRAY_VALUE__INIT; + *message = init_value; +} +size_t opentelemetry__proto__common__v1__array_value__get_packed_size( + const Opentelemetry__Proto__Common__V1__ArrayValue *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__array_value__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__common__v1__array_value__pack( + const Opentelemetry__Proto__Common__V1__ArrayValue *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__array_value__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__common__v1__array_value__pack_to_buffer( + const Opentelemetry__Proto__Common__V1__ArrayValue *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__array_value__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Common__V1__ArrayValue * +opentelemetry__proto__common__v1__array_value__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Common__V1__ArrayValue *) + protobuf_c_message_unpack( + &opentelemetry__proto__common__v1__array_value__descriptor, + allocator, len, data); +} +void opentelemetry__proto__common__v1__array_value__free_unpacked( + Opentelemetry__Proto__Common__V1__ArrayValue *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__array_value__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__common__v1__key_value_list__init( + Opentelemetry__Proto__Common__V1__KeyValueList *message) +{ + static const Opentelemetry__Proto__Common__V1__KeyValueList init_value = + OPENTELEMETRY__PROTO__COMMON__V1__KEY_VALUE_LIST__INIT; + *message = init_value; +} +size_t opentelemetry__proto__common__v1__key_value_list__get_packed_size( + const Opentelemetry__Proto__Common__V1__KeyValueList *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value_list__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__common__v1__key_value_list__pack( + const Opentelemetry__Proto__Common__V1__KeyValueList *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value_list__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__common__v1__key_value_list__pack_to_buffer( + const Opentelemetry__Proto__Common__V1__KeyValueList *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value_list__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Common__V1__KeyValueList * +opentelemetry__proto__common__v1__key_value_list__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Common__V1__KeyValueList *) + protobuf_c_message_unpack( + &opentelemetry__proto__common__v1__key_value_list__descriptor, + allocator, len, data); +} +void opentelemetry__proto__common__v1__key_value_list__free_unpacked( + Opentelemetry__Proto__Common__V1__KeyValueList *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value_list__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__common__v1__key_value__init( + Opentelemetry__Proto__Common__V1__KeyValue *message) +{ + static const Opentelemetry__Proto__Common__V1__KeyValue init_value = + OPENTELEMETRY__PROTO__COMMON__V1__KEY_VALUE__INIT; + *message = init_value; +} +size_t opentelemetry__proto__common__v1__key_value__get_packed_size( + const Opentelemetry__Proto__Common__V1__KeyValue *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__common__v1__key_value__pack( + const Opentelemetry__Proto__Common__V1__KeyValue *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__common__v1__key_value__pack_to_buffer( + const Opentelemetry__Proto__Common__V1__KeyValue *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Common__V1__KeyValue * +opentelemetry__proto__common__v1__key_value__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Common__V1__KeyValue *) + protobuf_c_message_unpack( + &opentelemetry__proto__common__v1__key_value__descriptor, allocator, + len, data); +} +void opentelemetry__proto__common__v1__key_value__free_unpacked( + Opentelemetry__Proto__Common__V1__KeyValue *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__common__v1__key_value__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__common__v1__instrumentation_scope__init( + Opentelemetry__Proto__Common__V1__InstrumentationScope *message) +{ + static const Opentelemetry__Proto__Common__V1__InstrumentationScope + init_value = + OPENTELEMETRY__PROTO__COMMON__V1__INSTRUMENTATION_SCOPE__INIT; + *message = init_value; +} +size_t opentelemetry__proto__common__v1__instrumentation_scope__get_packed_size( + const Opentelemetry__Proto__Common__V1__InstrumentationScope *message) +{ + assert( + message->base.descriptor == + &opentelemetry__proto__common__v1__instrumentation_scope__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__common__v1__instrumentation_scope__pack( + const Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + uint8_t * out) +{ + assert( + message->base.descriptor == + &opentelemetry__proto__common__v1__instrumentation_scope__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__common__v1__instrumentation_scope__pack_to_buffer( + const Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + ProtobufCBuffer * buffer) +{ + assert( + message->base.descriptor == + &opentelemetry__proto__common__v1__instrumentation_scope__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Common__V1__InstrumentationScope * +opentelemetry__proto__common__v1__instrumentation_scope__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Common__V1__InstrumentationScope *) + protobuf_c_message_unpack( + &opentelemetry__proto__common__v1__instrumentation_scope__descriptor, + allocator, len, data); +} +void opentelemetry__proto__common__v1__instrumentation_scope__free_unpacked( + Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert( + message->base.descriptor == + &opentelemetry__proto__common__v1__instrumentation_scope__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +static const ProtobufCFieldDescriptor + opentelemetry__proto__common__v1__any_value__field_descriptors[7] = { + { + "string_value", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, string_value), + NULL, &protobuf_c_empty_string, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "bool_value", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BOOL, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, bool_value), + NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "int_value", 3, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_INT64, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, int_value), + NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "double_value", 4, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_DOUBLE, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, double_value), + NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "array_value", 5, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, array_value), + &opentelemetry__proto__common__v1__array_value__descriptor, NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "kvlist_value", 6, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, kvlist_value), + &opentelemetry__proto__common__v1__key_value_list__descriptor, NULL, + 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "bytes_value", 7, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BYTES, + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, value_case), + offsetof(Opentelemetry__Proto__Common__V1__AnyValue, bytes_value), + NULL, NULL, 0 | PROTOBUF_C_FIELD_FLAG_ONEOF, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__common__v1__any_value__field_indices_by_name[] = { + 4, /* field[4] = array_value */ + 1, /* field[1] = bool_value */ + 6, /* field[6] = bytes_value */ + 3, /* field[3] = double_value */ + 2, /* field[2] = int_value */ + 5, /* field[5] = kvlist_value */ + 0, /* field[0] = string_value */ + }; +static const ProtobufCIntRange + opentelemetry__proto__common__v1__any_value__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 7 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__common__v1__any_value__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.common.v1.AnyValue", + "AnyValue", + "Opentelemetry__Proto__Common__V1__AnyValue", + "opentelemetry.proto.common.v1", + sizeof(Opentelemetry__Proto__Common__V1__AnyValue), + 7, + opentelemetry__proto__common__v1__any_value__field_descriptors, + opentelemetry__proto__common__v1__any_value__field_indices_by_name, + 1, + opentelemetry__proto__common__v1__any_value__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__common__v1__any_value__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__common__v1__array_value__field_descriptors[1] = { + { + "values", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Common__V1__ArrayValue, n_values), + offsetof(Opentelemetry__Proto__Common__V1__ArrayValue, values), + &opentelemetry__proto__common__v1__any_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__common__v1__array_value__field_indices_by_name[] = { + 0, /* field[0] = values */ + }; +static const ProtobufCIntRange + opentelemetry__proto__common__v1__array_value__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 1 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__common__v1__array_value__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.common.v1.ArrayValue", + "ArrayValue", + "Opentelemetry__Proto__Common__V1__ArrayValue", + "opentelemetry.proto.common.v1", + sizeof(Opentelemetry__Proto__Common__V1__ArrayValue), + 1, + opentelemetry__proto__common__v1__array_value__field_descriptors, + opentelemetry__proto__common__v1__array_value__field_indices_by_name, + 1, + opentelemetry__proto__common__v1__array_value__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__common__v1__array_value__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__common__v1__key_value_list__field_descriptors[1] = { + { + "values", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Common__V1__KeyValueList, n_values), + offsetof(Opentelemetry__Proto__Common__V1__KeyValueList, values), + &opentelemetry__proto__common__v1__key_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__common__v1__key_value_list__field_indices_by_name + [] = { + 0, /* field[0] = values */ + }; +static const ProtobufCIntRange + opentelemetry__proto__common__v1__key_value_list__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 1 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__common__v1__key_value_list__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.common.v1.KeyValueList", + "KeyValueList", + "Opentelemetry__Proto__Common__V1__KeyValueList", + "opentelemetry.proto.common.v1", + sizeof(Opentelemetry__Proto__Common__V1__KeyValueList), + 1, + opentelemetry__proto__common__v1__key_value_list__field_descriptors, + opentelemetry__proto__common__v1__key_value_list__field_indices_by_name, + 1, + opentelemetry__proto__common__v1__key_value_list__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__common__v1__key_value_list__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__common__v1__key_value__field_descriptors[2] = { + { + "key", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Common__V1__KeyValue, key), NULL, + &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "value", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Common__V1__KeyValue, value), + &opentelemetry__proto__common__v1__any_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__common__v1__key_value__field_indices_by_name[] = { + 0, /* field[0] = key */ + 1, /* field[1] = value */ + }; +static const ProtobufCIntRange + opentelemetry__proto__common__v1__key_value__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 2 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__common__v1__key_value__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.common.v1.KeyValue", + "KeyValue", + "Opentelemetry__Proto__Common__V1__KeyValue", + "opentelemetry.proto.common.v1", + sizeof(Opentelemetry__Proto__Common__V1__KeyValue), + 2, + opentelemetry__proto__common__v1__key_value__field_descriptors, + opentelemetry__proto__common__v1__key_value__field_indices_by_name, + 1, + opentelemetry__proto__common__v1__key_value__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__common__v1__key_value__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__common__v1__instrumentation_scope__field_descriptors + [4] = { + { + "name", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Common__V1__InstrumentationScope, + name), + NULL, &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "version", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Common__V1__InstrumentationScope, + version), + NULL, &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "attributes", 3, PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Common__V1__InstrumentationScope, + n_attributes), + offsetof(Opentelemetry__Proto__Common__V1__InstrumentationScope, + attributes), + &opentelemetry__proto__common__v1__key_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_attributes_count", 4, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Common__V1__InstrumentationScope, + dropped_attributes_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__common__v1__instrumentation_scope__field_indices_by_name + [] = { + 2, /* field[2] = attributes */ + 3, /* field[3] = dropped_attributes_count */ + 0, /* field[0] = name */ + 1, /* field[1] = version */ + }; +static const ProtobufCIntRange + opentelemetry__proto__common__v1__instrumentation_scope__number_ranges + [1 + 1] = { { 1, 0 }, { 0, 4 } }; +const ProtobufCMessageDescriptor + opentelemetry__proto__common__v1__instrumentation_scope__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.common.v1.InstrumentationScope", + "InstrumentationScope", + "Opentelemetry__Proto__Common__V1__InstrumentationScope", + "opentelemetry.proto.common.v1", + sizeof(Opentelemetry__Proto__Common__V1__InstrumentationScope), + 4, + opentelemetry__proto__common__v1__instrumentation_scope__field_descriptors, + opentelemetry__proto__common__v1__instrumentation_scope__field_indices_by_name, + 1, + opentelemetry__proto__common__v1__instrumentation_scope__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__common__v1__instrumentation_scope__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; diff --git a/src/otel/common.pb-c.h b/src/otel/common.pb-c.h new file mode 100644 index 000000000..6837394d9 --- /dev/null +++ b/src/otel/common.pb-c.h @@ -0,0 +1,276 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: opentelemetry/proto/common/v1/common.proto */ + +#ifndef PROTOBUF_C_opentelemetry_2fproto_2fcommon_2fv1_2fcommon_2eproto__INCLUDED +#define PROTOBUF_C_opentelemetry_2fproto_2fcommon_2fv1_2fcommon_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + + +typedef struct Opentelemetry__Proto__Common__V1__AnyValue Opentelemetry__Proto__Common__V1__AnyValue; +typedef struct Opentelemetry__Proto__Common__V1__ArrayValue Opentelemetry__Proto__Common__V1__ArrayValue; +typedef struct Opentelemetry__Proto__Common__V1__KeyValueList Opentelemetry__Proto__Common__V1__KeyValueList; +typedef struct Opentelemetry__Proto__Common__V1__KeyValue Opentelemetry__Proto__Common__V1__KeyValue; +typedef struct Opentelemetry__Proto__Common__V1__InstrumentationScope Opentelemetry__Proto__Common__V1__InstrumentationScope; + + +/* --- enums --- */ + + +/* --- messages --- */ + +typedef enum { + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE__NOT_SET = 0, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE = 1, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BOOL_VALUE = 2, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_INT_VALUE = 3, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_DOUBLE_VALUE = 4, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_ARRAY_VALUE = 5, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_KVLIST_VALUE = 6, + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BYTES_VALUE = 7 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE__CASE) +} Opentelemetry__Proto__Common__V1__AnyValue__ValueCase; + +/* + * AnyValue is used to represent any type of attribute value. AnyValue may contain a + * primitive value such as a string or integer or it may contain an arbitrary nested + * object containing arrays, key-value lists and primitives. + */ +struct Opentelemetry__Proto__Common__V1__AnyValue +{ + ProtobufCMessage base; + Opentelemetry__Proto__Common__V1__AnyValue__ValueCase value_case; + union { + char *string_value; + protobuf_c_boolean bool_value; + int64_t int_value; + double double_value; + Opentelemetry__Proto__Common__V1__ArrayValue *array_value; + Opentelemetry__Proto__Common__V1__KeyValueList *kvlist_value; + ProtobufCBinaryData bytes_value; + }; +}; +#define OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&opentelemetry__proto__common__v1__any_value__descriptor) \ + , OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE__NOT_SET, {0} } + + +/* + * ArrayValue is a list of AnyValue messages. We need ArrayValue as a message + * since oneof in AnyValue does not allow repeated fields. + */ +struct Opentelemetry__Proto__Common__V1__ArrayValue +{ + ProtobufCMessage base; + /* + * Array of values. The array may be empty (contain 0 elements). + */ + size_t n_values; + Opentelemetry__Proto__Common__V1__AnyValue **values; +}; +#define OPENTELEMETRY__PROTO__COMMON__V1__ARRAY_VALUE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&opentelemetry__proto__common__v1__array_value__descriptor) \ + , 0,NULL } + + +/* + * KeyValueList is a list of KeyValue messages. We need KeyValueList as a message + * since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need + * a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to + * avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches + * are semantically equivalent. + */ +struct Opentelemetry__Proto__Common__V1__KeyValueList +{ + ProtobufCMessage base; + /* + * A collection of key/value pairs of key-value pairs. The list may be empty (may + * contain 0 elements). + * The keys MUST be unique (it is not allowed to have more than one + * value with the same key). + */ + size_t n_values; + Opentelemetry__Proto__Common__V1__KeyValue **values; +}; +#define OPENTELEMETRY__PROTO__COMMON__V1__KEY_VALUE_LIST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&opentelemetry__proto__common__v1__key_value_list__descriptor) \ + , 0,NULL } + + +/* + * KeyValue is a key-value pair that is used to store Span attributes, Link + * attributes, etc. + */ +struct Opentelemetry__Proto__Common__V1__KeyValue +{ + ProtobufCMessage base; + char *key; + Opentelemetry__Proto__Common__V1__AnyValue *value; +}; +#define OPENTELEMETRY__PROTO__COMMON__V1__KEY_VALUE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&opentelemetry__proto__common__v1__key_value__descriptor) \ + , (char *)protobuf_c_empty_string, NULL } + + +/* + * InstrumentationScope is a message representing the instrumentation scope information + * such as the fully qualified name and version. + */ +struct Opentelemetry__Proto__Common__V1__InstrumentationScope +{ + ProtobufCMessage base; + /* + * An empty instrumentation scope name means the name is unknown. + */ + char *name; + char *version; + /* + * Additional attributes that describe the scope. [Optional]. + * Attribute keys MUST be unique (it is not allowed to have more than one + * attribute with the same key). + */ + size_t n_attributes; + Opentelemetry__Proto__Common__V1__KeyValue **attributes; + uint32_t dropped_attributes_count; +}; +#define OPENTELEMETRY__PROTO__COMMON__V1__INSTRUMENTATION_SCOPE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&opentelemetry__proto__common__v1__instrumentation_scope__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0,NULL, 0 } + + +/* Opentelemetry__Proto__Common__V1__AnyValue methods */ +void opentelemetry__proto__common__v1__any_value__init + (Opentelemetry__Proto__Common__V1__AnyValue *message); +size_t opentelemetry__proto__common__v1__any_value__get_packed_size + (const Opentelemetry__Proto__Common__V1__AnyValue *message); +size_t opentelemetry__proto__common__v1__any_value__pack + (const Opentelemetry__Proto__Common__V1__AnyValue *message, + uint8_t *out); +size_t opentelemetry__proto__common__v1__any_value__pack_to_buffer + (const Opentelemetry__Proto__Common__V1__AnyValue *message, + ProtobufCBuffer *buffer); +Opentelemetry__Proto__Common__V1__AnyValue * + opentelemetry__proto__common__v1__any_value__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void opentelemetry__proto__common__v1__any_value__free_unpacked + (Opentelemetry__Proto__Common__V1__AnyValue *message, + ProtobufCAllocator *allocator); +/* Opentelemetry__Proto__Common__V1__ArrayValue methods */ +void opentelemetry__proto__common__v1__array_value__init + (Opentelemetry__Proto__Common__V1__ArrayValue *message); +size_t opentelemetry__proto__common__v1__array_value__get_packed_size + (const Opentelemetry__Proto__Common__V1__ArrayValue *message); +size_t opentelemetry__proto__common__v1__array_value__pack + (const Opentelemetry__Proto__Common__V1__ArrayValue *message, + uint8_t *out); +size_t opentelemetry__proto__common__v1__array_value__pack_to_buffer + (const Opentelemetry__Proto__Common__V1__ArrayValue *message, + ProtobufCBuffer *buffer); +Opentelemetry__Proto__Common__V1__ArrayValue * + opentelemetry__proto__common__v1__array_value__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void opentelemetry__proto__common__v1__array_value__free_unpacked + (Opentelemetry__Proto__Common__V1__ArrayValue *message, + ProtobufCAllocator *allocator); +/* Opentelemetry__Proto__Common__V1__KeyValueList methods */ +void opentelemetry__proto__common__v1__key_value_list__init + (Opentelemetry__Proto__Common__V1__KeyValueList *message); +size_t opentelemetry__proto__common__v1__key_value_list__get_packed_size + (const Opentelemetry__Proto__Common__V1__KeyValueList *message); +size_t opentelemetry__proto__common__v1__key_value_list__pack + (const Opentelemetry__Proto__Common__V1__KeyValueList *message, + uint8_t *out); +size_t opentelemetry__proto__common__v1__key_value_list__pack_to_buffer + (const Opentelemetry__Proto__Common__V1__KeyValueList *message, + ProtobufCBuffer *buffer); +Opentelemetry__Proto__Common__V1__KeyValueList * + opentelemetry__proto__common__v1__key_value_list__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void opentelemetry__proto__common__v1__key_value_list__free_unpacked + (Opentelemetry__Proto__Common__V1__KeyValueList *message, + ProtobufCAllocator *allocator); +/* Opentelemetry__Proto__Common__V1__KeyValue methods */ +void opentelemetry__proto__common__v1__key_value__init + (Opentelemetry__Proto__Common__V1__KeyValue *message); +size_t opentelemetry__proto__common__v1__key_value__get_packed_size + (const Opentelemetry__Proto__Common__V1__KeyValue *message); +size_t opentelemetry__proto__common__v1__key_value__pack + (const Opentelemetry__Proto__Common__V1__KeyValue *message, + uint8_t *out); +size_t opentelemetry__proto__common__v1__key_value__pack_to_buffer + (const Opentelemetry__Proto__Common__V1__KeyValue *message, + ProtobufCBuffer *buffer); +Opentelemetry__Proto__Common__V1__KeyValue * + opentelemetry__proto__common__v1__key_value__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void opentelemetry__proto__common__v1__key_value__free_unpacked + (Opentelemetry__Proto__Common__V1__KeyValue *message, + ProtobufCAllocator *allocator); +/* Opentelemetry__Proto__Common__V1__InstrumentationScope methods */ +void opentelemetry__proto__common__v1__instrumentation_scope__init + (Opentelemetry__Proto__Common__V1__InstrumentationScope *message); +size_t opentelemetry__proto__common__v1__instrumentation_scope__get_packed_size + (const Opentelemetry__Proto__Common__V1__InstrumentationScope *message); +size_t opentelemetry__proto__common__v1__instrumentation_scope__pack + (const Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + uint8_t *out); +size_t opentelemetry__proto__common__v1__instrumentation_scope__pack_to_buffer + (const Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + ProtobufCBuffer *buffer); +Opentelemetry__Proto__Common__V1__InstrumentationScope * + opentelemetry__proto__common__v1__instrumentation_scope__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void opentelemetry__proto__common__v1__instrumentation_scope__free_unpacked + (Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Opentelemetry__Proto__Common__V1__AnyValue_Closure) + (const Opentelemetry__Proto__Common__V1__AnyValue *message, + void *closure_data); +typedef void (*Opentelemetry__Proto__Common__V1__ArrayValue_Closure) + (const Opentelemetry__Proto__Common__V1__ArrayValue *message, + void *closure_data); +typedef void (*Opentelemetry__Proto__Common__V1__KeyValueList_Closure) + (const Opentelemetry__Proto__Common__V1__KeyValueList *message, + void *closure_data); +typedef void (*Opentelemetry__Proto__Common__V1__KeyValue_Closure) + (const Opentelemetry__Proto__Common__V1__KeyValue *message, + void *closure_data); +typedef void (*Opentelemetry__Proto__Common__V1__InstrumentationScope_Closure) + (const Opentelemetry__Proto__Common__V1__InstrumentationScope *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor opentelemetry__proto__common__v1__any_value__descriptor; +extern const ProtobufCMessageDescriptor opentelemetry__proto__common__v1__array_value__descriptor; +extern const ProtobufCMessageDescriptor opentelemetry__proto__common__v1__key_value_list__descriptor; +extern const ProtobufCMessageDescriptor opentelemetry__proto__common__v1__key_value__descriptor; +extern const ProtobufCMessageDescriptor opentelemetry__proto__common__v1__instrumentation_scope__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_opentelemetry_2fproto_2fcommon_2fv1_2fcommon_2eproto__INCLUDED */ diff --git a/src/otel/otel_manager.c b/src/otel/otel_manager.c new file mode 100644 index 000000000..8da164733 --- /dev/null +++ b/src/otel/otel_manager.c @@ -0,0 +1,706 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +#include +#include +#include + +#include "define.h" +#include "event/event.h" +#include "plugin.h" +#include "utils/http.h" +#include "utils/utarray.h" +#include "utils/uthash.h" + +#include "otel_manager.h" +#include "trace.pb-c.h" + +#define SPAN_ID_LENGTH 16 +#define SPAN_ID_CHARSET "0123456789abcdef" + +bool otel_flag = false; +char otel_host[32] = { 0 }; +int otel_port = 0; +char otel_traces_url[32] = { 0 }; + +typedef struct { + Opentelemetry__Proto__Trace__V1__TracesData trace_data; + uint8_t trace_id[64]; + uint32_t flags; + bool final; + size_t span_num; + UT_array * scopes; + pthread_mutex_t mutex; +} trace_ctx_t; + +typedef struct { + int span_index; + Opentelemetry__Proto__Trace__V1__Span *span; + trace_ctx_t * trace_ctx; +} trace_scope_t; + +typedef struct { + void * key; + trace_ctx_t * ctx; + UT_hash_handle hh; +} trace_ctx_table_ele_t; + +trace_ctx_table_ele_t *traces_table = NULL; + +pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER; + +neu_events_t * otel_event = NULL; +neu_event_timer_t *otel_timer = NULL; + +static int hex_char_to_int(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int hex_string_to_binary(const char * hex_string, + unsigned char *binary_array, int max_length) +{ + int length = strlen(hex_string); + if (length % 2 != 0 || length <= 0) + return -1; + + int binary_length = length / 2; + if (binary_length > max_length) + return -1; + + for (int i = 0; i < binary_length; i++) { + int high_nibble = hex_char_to_int(hex_string[2 * i]); + int low_nibble = hex_char_to_int(hex_string[2 * i + 1]); + if (high_nibble == -1 || low_nibble == -1) + return -1; + + binary_array[i] = (high_nibble << 4) | low_nibble; + } + + return binary_length; +} + +void neu_otel_free_span(Opentelemetry__Proto__Trace__V1__Span *span) +{ + for (size_t i = 0; i < span->n_attributes; i++) { + if (span->attributes[i]->value->value_case == + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) { + free(span->attributes[i]->value->string_value); + } + free(span->attributes[i]->key); + free(span->attributes[i]->value); + free(span->attributes[i]); + } + + free(span->attributes); + free(span->name); + free(span->trace_id.data); + free(span->parent_span_id.data); + free(span->span_id.data); + free(span); +} + +neu_otel_trace_ctx neu_otel_create_trace(const char *trace_id, void *req_ctx, + uint32_t flags) +{ + trace_ctx_t *ctx = calloc(1, sizeof(trace_ctx_t)); + opentelemetry__proto__trace__v1__traces_data__init(&ctx->trace_data); + strncpy((char *) ctx->trace_id, trace_id, 64); + + ctx->trace_data.n_resource_spans = 1; + ctx->trace_data.resource_spans = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__ResourceSpans *)); + ctx->trace_data.resource_spans[0] = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__ResourceSpans)); + opentelemetry__proto__trace__v1__resource_spans__init( + ctx->trace_data.resource_spans[0]); + + ctx->trace_data.resource_spans[0]->resource = + calloc(1, sizeof(Opentelemetry__Proto__Resource__V1__Resource)); + opentelemetry__proto__resource__v1__resource__init( + ctx->trace_data.resource_spans[0]->resource); + + ctx->trace_data.resource_spans[0]->resource->n_attributes = 2; + ctx->trace_data.resource_spans[0]->resource->attributes = + calloc(2, sizeof(Opentelemetry__Proto__Common__V1__KeyValue *)); + + ctx->trace_data.resource_spans[0]->resource->attributes[0] = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue)); + + opentelemetry__proto__common__v1__key_value__init( + ctx->trace_data.resource_spans[0]->resource->attributes[0]); + + ctx->trace_data.resource_spans[0]->resource->attributes[0]->key = + strdup("service.name"); + + ctx->trace_data.resource_spans[0]->resource->attributes[0]->value = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue)); + opentelemetry__proto__common__v1__any_value__init( + ctx->trace_data.resource_spans[0]->resource->attributes[0]->value); + ctx->trace_data.resource_spans[0] + ->resource->attributes[0] + ->value->value_case = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE; + ctx->trace_data.resource_spans[0] + ->resource->attributes[0] + ->value->string_value = strdup("neuron"); + + ctx->trace_data.resource_spans[0]->resource->attributes[1] = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue)); + + opentelemetry__proto__common__v1__key_value__init( + ctx->trace_data.resource_spans[0]->resource->attributes[1]); + + ctx->trace_data.resource_spans[0]->resource->attributes[1]->key = + strdup("service.version"); + + ctx->trace_data.resource_spans[0]->resource->attributes[1]->value = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue)); + opentelemetry__proto__common__v1__any_value__init( + ctx->trace_data.resource_spans[0]->resource->attributes[1]->value); + char *version = calloc(1, 24); + sprintf(version, "%d.%d.%d", NEU_VERSION_MAJOR, NEU_VERSION_MINOR, + NEU_VERSION_FIX); + ctx->trace_data.resource_spans[0] + ->resource->attributes[1] + ->value->value_case = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE; + ctx->trace_data.resource_spans[0] + ->resource->attributes[1] + ->value->string_value = version; + + ctx->trace_data.resource_spans[0]->n_scope_spans = 1; + ctx->trace_data.resource_spans[0]->scope_spans = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__ScopeSpans *)); + ctx->trace_data.resource_spans[0]->scope_spans[0] = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__ScopeSpans)); + opentelemetry__proto__trace__v1__scope_spans__init( + ctx->trace_data.resource_spans[0]->scope_spans[0]); + + ctx->flags = flags; + + trace_ctx_table_ele_t *ele = calloc(1, sizeof(trace_ctx_table_ele_t)); + ele->key = req_ctx; + ele->ctx = ctx; + + utarray_new(ctx->scopes, &ut_ptr_icd); + + pthread_mutex_lock(&table_mutex); + + HASH_ADD(hh, traces_table, key, sizeof(req_ctx), ele); + + pthread_mutex_unlock(&table_mutex); + + return (neu_otel_trace_ctx) ctx; +} + +neu_otel_trace_ctx neu_otel_find_trace(void *req_ctx) +{ + trace_ctx_table_ele_t *find = NULL; + + pthread_mutex_lock(&table_mutex); + + HASH_FIND(hh, traces_table, &req_ctx, sizeof(req_ctx), find); + + pthread_mutex_unlock(&table_mutex); + + if (find) { + return (void *) find->ctx; + } else { + return NULL; + } +} + +void neu_otel_trace_set_final(neu_otel_trace_ctx ctx) +{ + trace_ctx_t *trace_ctx = (trace_ctx_t *) ctx; + trace_ctx->final = true; +} + +neu_otel_trace_ctx neu_otel_find_trace_by_id(const char *trace_id) +{ + trace_ctx_table_ele_t *el = NULL, *tmp = NULL; + + pthread_mutex_lock(&table_mutex); + + HASH_ITER(hh, traces_table, el, tmp) + { + if (strcmp((char *) el->ctx->trace_id, trace_id) == 0) { + pthread_mutex_unlock(&table_mutex); + return (void *) el->ctx; + } + } + + pthread_mutex_unlock(&table_mutex); + + return NULL; +} + +void neu_otel_free_trace(neu_otel_trace_ctx ctx) +{ + trace_ctx_t *trace_ctx = (trace_ctx_t *) ctx; + for (size_t i = 0; + i < trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans; + i++) { + neu_otel_free_span( + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[i]); + } + free(trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans); + free(trace_ctx->trace_data.resource_spans[0]->scope_spans[0]); + free(trace_ctx->trace_data.resource_spans[0]->scope_spans); + for (size_t i = 0; + i < trace_ctx->trace_data.resource_spans[0]->resource->n_attributes; + i++) { + if (trace_ctx->trace_data.resource_spans[0] + ->resource->attributes[i] + ->value->value_case == + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE) { + free(trace_ctx->trace_data.resource_spans[0] + ->resource->attributes[i] + ->value->string_value); + } + free(trace_ctx->trace_data.resource_spans[0] + ->resource->attributes[i] + ->value); + free(trace_ctx->trace_data.resource_spans[0] + ->resource->attributes[i] + ->key); + free(trace_ctx->trace_data.resource_spans[0]->resource->attributes[i]); + } + free(trace_ctx->trace_data.resource_spans[0]->resource->attributes); + free(trace_ctx->trace_data.resource_spans[0]->resource); + free(trace_ctx->trace_data.resource_spans[0]); + free(trace_ctx->trace_data.resource_spans); + utarray_foreach(trace_ctx->scopes, void **, e) { free(*e); } + utarray_free(trace_ctx->scopes); + free(ctx); +} + +neu_otel_scope_ctx neu_otel_add_span(neu_otel_trace_ctx ctx) +{ + trace_scope_t *scope = calloc(1, sizeof(trace_scope_t)); + trace_ctx_t * trace_ctx = (trace_ctx_t *) ctx; + pthread_mutex_lock(&trace_ctx->mutex); + scope->trace_ctx = ctx; + if (trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans == 0) { + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Span *)); + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[0] = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Span)); + + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans = 1; + scope->span = + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[0]; + scope->span_index = 0; + } else { + Opentelemetry__Proto__Trace__V1__Span **t_spans = + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans; + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans = + calloc(1 + + trace_ctx->trace_data.resource_spans[0] + ->scope_spans[0] + ->n_spans, + sizeof(Opentelemetry__Proto__Trace__V1__Span *)); + for (size_t i = 0; i < + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans; + i++) { + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[i] = + t_spans[i]; + } + + free(t_spans); + + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans + [trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans] = + calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Span)); + scope->span = trace_ctx->trace_data.resource_spans[0] + ->scope_spans[0] + ->spans[trace_ctx->trace_data.resource_spans[0] + ->scope_spans[0] + ->n_spans]; + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans += 1; + + scope->span_index = + trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans - + 1; + } + + opentelemetry__proto__trace__v1__span__init(scope->span); + scope->span->kind = + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_SERVER; + scope->span->flags = otel_flag; // random + uint8_t *t_id = calloc(1, 16); + hex_string_to_binary((char *) trace_ctx->trace_id, t_id, 16); + scope->span->trace_id.data = t_id; + scope->span->trace_id.len = 16; + scope->span->flags = trace_ctx->flags; + utarray_push_back(trace_ctx->scopes, &scope); + pthread_mutex_unlock(&trace_ctx->mutex); + return scope; +} + +void neu_otel_scope_set_parent_span_id(neu_otel_scope_ctx ctx, + const char * parent_span_id) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + uint8_t * p_sp_id = calloc(1, 8); + if (hex_string_to_binary(parent_span_id, p_sp_id, 8) > 0) { + scope->span->parent_span_id.len = 8; + scope->span->parent_span_id.data = p_sp_id; + } else { + scope->span->parent_span_id.len = 0; + scope->span->parent_span_id.data = NULL; + free(p_sp_id); + } +} + +void neu_otel_scope_set_parent_span_id2(neu_otel_scope_ctx ctx, + uint8_t *parent_span_id, int len) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + + uint8_t *p_sp_id = calloc(1, 8); + memcpy(p_sp_id, parent_span_id, len); + scope->span->parent_span_id.len = len; + scope->span->parent_span_id.data = p_sp_id; +} + +void neu_otel_scope_set_span_name(neu_otel_scope_ctx ctx, const char *span_name) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + scope->span->name = strdup(span_name); +} + +void neu_otel_scope_set_span_id(neu_otel_scope_ctx ctx, const char *span_id) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + uint8_t * sp_id = calloc(1, 8); + hex_string_to_binary(span_id, sp_id, 8); + scope->span->span_id.data = sp_id; + scope->span->span_id.len = 8; +} + +void neu_otel_scope_set_span_flags(neu_otel_scope_ctx ctx, uint32_t flags) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + scope->span->flags = flags; +} + +void neu_otel_scope_add_span_attr_int(neu_otel_scope_ctx ctx, const char *key, + int64_t val) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + + Opentelemetry__Proto__Common__V1__KeyValue **t_kvs = + scope->span->attributes; + + scope->span->attributes = + calloc(scope->span->n_attributes + 1, + sizeof(Opentelemetry__Proto__Common__V1__KeyValue *)); + + for (size_t i = 0; i < scope->span->n_attributes; i++) { + scope->span->attributes[i] = t_kvs[i]; + } + + Opentelemetry__Proto__Common__V1__KeyValue *kv = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue)); + opentelemetry__proto__common__v1__key_value__init(kv); + kv->key = strdup(key); + kv->value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue)); + opentelemetry__proto__common__v1__any_value__init(kv->value); + kv->value->value_case = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_INT_VALUE; + kv->value->int_value = val; + scope->span->attributes[scope->span->n_attributes] = kv; + + scope->span->n_attributes += 1; + free(t_kvs); +} +void neu_otel_scope_add_span_attr_double(neu_otel_scope_ctx ctx, + const char *key, double val) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + + Opentelemetry__Proto__Common__V1__KeyValue **t_kvs = + scope->span->attributes; + + scope->span->attributes = + calloc(scope->span->n_attributes + 1, + sizeof(Opentelemetry__Proto__Common__V1__KeyValue *)); + + for (size_t i = 0; i < scope->span->n_attributes; i++) { + scope->span->attributes[i] = t_kvs[i]; + } + + Opentelemetry__Proto__Common__V1__KeyValue *kv = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue)); + opentelemetry__proto__common__v1__key_value__init(kv); + kv->key = strdup(key); + kv->value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue)); + opentelemetry__proto__common__v1__any_value__init(kv->value); + kv->value->value_case = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_DOUBLE_VALUE; + kv->value->double_value = val; + scope->span->attributes[scope->span->n_attributes] = kv; + + scope->span->n_attributes += 1; + free(t_kvs); +} + +void neu_otel_scope_add_span_attr_string(neu_otel_scope_ctx ctx, + const char *key, const char *val) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + + Opentelemetry__Proto__Common__V1__KeyValue **t_kvs = + scope->span->attributes; + + scope->span->attributes = + calloc(scope->span->n_attributes + 1, + sizeof(Opentelemetry__Proto__Common__V1__KeyValue *)); + + for (size_t i = 0; i < scope->span->n_attributes; i++) { + scope->span->attributes[i] = t_kvs[i]; + } + + Opentelemetry__Proto__Common__V1__KeyValue *kv = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue)); + opentelemetry__proto__common__v1__key_value__init(kv); + kv->key = strdup(key); + kv->value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue)); + opentelemetry__proto__common__v1__any_value__init(kv->value); + kv->value->value_case = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_STRING_VALUE; + kv->value->string_value = strdup(val); + scope->span->attributes[scope->span->n_attributes] = kv; + + scope->span->n_attributes += 1; + free(t_kvs); +} + +void neu_otel_scope_add_span_attr_bool(neu_otel_scope_ctx ctx, const char *key, + bool val) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + + Opentelemetry__Proto__Common__V1__KeyValue **t_kvs = + scope->span->attributes; + + scope->span->attributes = + calloc(scope->span->n_attributes + 1, + sizeof(Opentelemetry__Proto__Common__V1__KeyValue *)); + + for (size_t i = 0; i < scope->span->n_attributes; i++) { + scope->span->attributes[i] = t_kvs[i]; + } + + Opentelemetry__Proto__Common__V1__KeyValue *kv = + calloc(1, sizeof(Opentelemetry__Proto__Common__V1__KeyValue)); + opentelemetry__proto__common__v1__key_value__init(kv); + kv->key = strdup(key); + kv->value = calloc(1, sizeof(Opentelemetry__Proto__Common__V1__AnyValue)); + opentelemetry__proto__common__v1__any_value__init(kv->value); + kv->value->value_case = + OPENTELEMETRY__PROTO__COMMON__V1__ANY_VALUE__VALUE_BOOL_VALUE; + kv->value->bool_value = val; + scope->span->attributes[scope->span->n_attributes] = kv; + + scope->span->n_attributes += 1; + free(t_kvs); +} + +void neu_otel_scope_set_span_start_time(neu_otel_scope_ctx ctx, int64_t ms) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + scope->span->start_time_unix_nano = ((uint64_t) ms) * 1000000; +} +void neu_otel_scope_set_span_end_time(neu_otel_scope_ctx ctx, int64_t ms) + +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + scope->span->end_time_unix_nano = ((uint64_t) ms) * 1000000; + trace_ctx_t *trace_ctx = (trace_ctx_t *) scope->trace_ctx; + trace_ctx->span_num += 1; +} + +uint8_t *neu_otel_scope_get_pre_span_id(neu_otel_scope_ctx ctx) +{ + trace_scope_t *scope = (trace_scope_t *) ctx; + trace_ctx_t * trace_ctx = (trace_ctx_t *) scope->trace_ctx; + if (scope->span_index <= 0) { + return NULL; + } + return trace_ctx->trace_data.resource_spans[0] + ->scope_spans[0] + ->spans[scope->span_index - 1] + ->span_id.data; +} + +int neu_otel_trace_pack_size(neu_otel_trace_ctx ctx) +{ + trace_ctx_t *trace_ctx = (trace_ctx_t *) ctx; + return opentelemetry__proto__trace__v1__traces_data__get_packed_size( + &trace_ctx->trace_data); +} + +int neu_otel_trace_pack(neu_otel_trace_ctx ctx, uint8_t *out) +{ + trace_ctx_t *trace_ctx = (trace_ctx_t *) ctx; + return opentelemetry__proto__trace__v1__traces_data__pack( + &trace_ctx->trace_data, out); +} + +void neu_otel_new_span_id(char *id) +{ + static uint64_t counter = 0; + uint64_t timestamp = time(NULL); + uint64_t random = rand(); + + uint64_t combined = (timestamp << 24) | (counter << 12) | random; + counter++; + + for (int i = SPAN_ID_LENGTH - 1; i >= 0; i--) { + id[i] = SPAN_ID_CHARSET[combined % 16]; + combined /= 16; + } + id[SPAN_ID_LENGTH] = '\0'; +} + +void neu_otel_split_traceparent(const char *in, char *trace_id, char *span_id, + uint32_t *flags) +{ + const char *delimiter = "-"; + char * token; + char * saveptr; + char * copy = strdup(in); + char t_flags[32] = { 0 }; + + token = strtok_r(copy, delimiter, &saveptr); + + token = strtok_r(NULL, delimiter, &saveptr); + if (token != NULL) { + strcpy(trace_id, token); + } else { + strcpy(trace_id, ""); + } + + token = strtok_r(NULL, delimiter, &saveptr); + if (token != NULL) { + strcpy(span_id, token); + } else { + strcpy(span_id, ""); + } + + token = strtok_r(NULL, delimiter, &saveptr); + if (token != NULL) { + strcpy(t_flags, token); + sscanf(t_flags, "%x", flags); + } else { + strcpy(t_flags, ""); + *flags = 0; + } + + free(copy); +} + +static int otel_timer_cb(void *data) +{ + (void) data; + + trace_ctx_table_ele_t *el = NULL, *tmp = NULL; + + pthread_mutex_lock(&table_mutex); + + HASH_ITER(hh, traces_table, el, tmp) + { + if (el->ctx->final && + el->ctx->span_num == + el->ctx->trace_data.resource_spans[0] + ->scope_spans[0] + ->n_spans) { + int data_size = neu_otel_trace_pack_size(el->ctx); + + uint8_t *data_buf = calloc(1, data_size); + neu_otel_trace_pack(el->ctx, data_buf); + int status = neu_http_post_otel_trace(data_buf, data_size); + free(data_buf); + if (status == 200 || status == 400) { + HASH_DEL(traces_table, el); + neu_otel_free_trace(el->ctx); + free(el); + } + } + } + + pthread_mutex_unlock(&table_mutex); + + return 0; +} + +void neu_otel_start() +{ + if (otel_event == NULL) { + otel_event = neu_event_new(); + } + + if (otel_timer == NULL) { + neu_event_timer_param_t param = { 0 }; + + param.usr_data = NULL; + + param.second = 0; + param.millisecond = 100; + param.cb = otel_timer_cb; + param.type = NEU_EVENT_TIMER_BLOCK; + + otel_timer = neu_event_add_timer(otel_event, param); + } +} + +void neu_otel_stop() +{ + if (otel_timer) { + neu_event_del_timer(otel_event, otel_timer); + otel_timer = NULL; + } + + if (otel_event) { + neu_event_close(otel_event); + otel_event = NULL; + } + trace_ctx_table_ele_t *el = NULL, *tmp = NULL; + + pthread_mutex_lock(&table_mutex); + + HASH_ITER(hh, traces_table, el, tmp) + { + + HASH_DEL(traces_table, el); + neu_otel_free_trace(el->ctx); + free(el); + } + + pthread_mutex_unlock(&table_mutex); +} diff --git a/src/otel/otel_manager.h b/src/otel/otel_manager.h new file mode 100644 index 000000000..7fdfbcc1b --- /dev/null +++ b/src/otel/otel_manager.h @@ -0,0 +1,79 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +#ifndef NEU_OTEL_MANAGER_H +#define NEU_OTEL_MANAGER_H + +typedef void *neu_otel_trace_ctx; +typedef void *neu_otel_scope_ctx; + +neu_otel_trace_ctx neu_otel_create_trace(const char *trace_id, void *req_ctx, + uint32_t flags); + +neu_otel_trace_ctx neu_otel_find_trace(void *req_ctx); + +void neu_otel_trace_set_final(neu_otel_trace_ctx ctx); + +neu_otel_trace_ctx neu_otel_find_trace_by_id(const char *trace_id); + +void neu_otel_free_trace(neu_otel_trace_ctx ctx); + +neu_otel_scope_ctx neu_otel_add_span(neu_otel_trace_ctx ctx); + +void neu_otel_scope_set_parent_span_id(neu_otel_scope_ctx ctx, + const char * parent_span_id); + +void neu_otel_scope_set_parent_span_id2(neu_otel_scope_ctx ctx, + uint8_t *parent_span_id, int len); + +void neu_otel_scope_set_span_name(neu_otel_scope_ctx ctx, + const char * span_name); + +void neu_otel_scope_set_span_flags(neu_otel_scope_ctx ctx, uint32_t flags); + +void neu_otel_scope_set_span_id(neu_otel_scope_ctx ctx, const char *span_id); + +void neu_otel_scope_add_span_attr_int(neu_otel_scope_ctx ctx, const char *key, + int64_t val); +void neu_otel_scope_add_span_attr_double(neu_otel_scope_ctx ctx, + const char *key, double val); +void neu_otel_scope_add_span_attr_string(neu_otel_scope_ctx ctx, + const char *key, const char *val); + +void neu_otel_scope_add_span_attr_bool(neu_otel_scope_ctx ctx, const char *key, + bool val); + +void neu_otel_scope_set_span_start_time(neu_otel_scope_ctx ctx, int64_t ms); +void neu_otel_scope_set_span_end_time(neu_otel_scope_ctx ctx, int64_t ms); + +uint8_t *neu_otel_scope_get_pre_span_id(neu_otel_scope_ctx ctx); + +int neu_otel_trace_pack_size(neu_otel_trace_ctx ctx); + +int neu_otel_trace_pack(neu_otel_trace_ctx ctx, uint8_t *out); + +void neu_otel_new_span_id(char *id); + +void neu_otel_split_traceparent(const char *in, char *trace_id, char *span_id, + uint32_t *flags); + +void neu_otel_start(); +void neu_otel_stop(); + +#endif // NEU_OTEL_MANAGER_H \ No newline at end of file diff --git a/src/otel/resource.pb-c.c b/src/otel/resource.pb-c.c new file mode 100644 index 000000000..fe5ef4170 --- /dev/null +++ b/src/otel/resource.pb-c.c @@ -0,0 +1,107 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: opentelemetry/proto/resource/v1/resource.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "resource.pb-c.h" +void opentelemetry__proto__resource__v1__resource__init( + Opentelemetry__Proto__Resource__V1__Resource *message) +{ + static const Opentelemetry__Proto__Resource__V1__Resource init_value = + OPENTELEMETRY__PROTO__RESOURCE__V1__RESOURCE__INIT; + *message = init_value; +} +size_t opentelemetry__proto__resource__v1__resource__get_packed_size( + const Opentelemetry__Proto__Resource__V1__Resource *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__resource__v1__resource__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__resource__v1__resource__pack( + const Opentelemetry__Proto__Resource__V1__Resource *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__resource__v1__resource__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__resource__v1__resource__pack_to_buffer( + const Opentelemetry__Proto__Resource__V1__Resource *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__resource__v1__resource__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Resource__V1__Resource * +opentelemetry__proto__resource__v1__resource__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Resource__V1__Resource *) + protobuf_c_message_unpack( + &opentelemetry__proto__resource__v1__resource__descriptor, + allocator, len, data); +} +void opentelemetry__proto__resource__v1__resource__free_unpacked( + Opentelemetry__Proto__Resource__V1__Resource *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__resource__v1__resource__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +static const ProtobufCFieldDescriptor + opentelemetry__proto__resource__v1__resource__field_descriptors[2] = { + { + "attributes", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Resource__V1__Resource, + n_attributes), + offsetof(Opentelemetry__Proto__Resource__V1__Resource, attributes), + &opentelemetry__proto__common__v1__key_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_attributes_count", 2, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Resource__V1__Resource, + dropped_attributes_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__resource__v1__resource__field_indices_by_name[] = { + 0, /* field[0] = attributes */ + 1, /* field[1] = dropped_attributes_count */ + }; +static const ProtobufCIntRange + opentelemetry__proto__resource__v1__resource__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 2 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__resource__v1__resource__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.resource.v1.Resource", + "Resource", + "Opentelemetry__Proto__Resource__V1__Resource", + "opentelemetry.proto.resource.v1", + sizeof(Opentelemetry__Proto__Resource__V1__Resource), + 2, + opentelemetry__proto__resource__v1__resource__field_descriptors, + opentelemetry__proto__resource__v1__resource__field_indices_by_name, + 1, + opentelemetry__proto__resource__v1__resource__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__resource__v1__resource__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; diff --git a/src/otel/resource.pb-c.h b/src/otel/resource.pb-c.h new file mode 100644 index 000000000..02c0aa60f --- /dev/null +++ b/src/otel/resource.pb-c.h @@ -0,0 +1,83 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: opentelemetry/proto/resource/v1/resource.proto */ + +#ifndef PROTOBUF_C_opentelemetry_2fproto_2fresource_2fv1_2fresource_2eproto__INCLUDED +#define PROTOBUF_C_opentelemetry_2fproto_2fresource_2fv1_2fresource_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + +#include "common.pb-c.h" + +typedef struct Opentelemetry__Proto__Resource__V1__Resource + Opentelemetry__Proto__Resource__V1__Resource; + +/* --- enums --- */ + +/* --- messages --- */ + +/* + * Resource information. + */ +struct Opentelemetry__Proto__Resource__V1__Resource { + ProtobufCMessage base; + /* + * Set of attributes that describe the resource. + * Attribute keys MUST be unique (it is not allowed to have more than one + * attribute with the same key). + */ + size_t n_attributes; + Opentelemetry__Proto__Common__V1__KeyValue **attributes; + /* + * dropped_attributes_count is the number of dropped attributes. If the + * value is 0, then no attributes were dropped. + */ + uint32_t dropped_attributes_count; +}; +#define OPENTELEMETRY__PROTO__RESOURCE__V1__RESOURCE__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__resource__v1__resource__descriptor) \ + , 0, NULL, 0 \ + } + +/* Opentelemetry__Proto__Resource__V1__Resource methods */ +void opentelemetry__proto__resource__v1__resource__init( + Opentelemetry__Proto__Resource__V1__Resource *message); +size_t opentelemetry__proto__resource__v1__resource__get_packed_size( + const Opentelemetry__Proto__Resource__V1__Resource *message); +size_t opentelemetry__proto__resource__v1__resource__pack( + const Opentelemetry__Proto__Resource__V1__Resource *message, uint8_t *out); +size_t opentelemetry__proto__resource__v1__resource__pack_to_buffer( + const Opentelemetry__Proto__Resource__V1__Resource *message, + ProtobufCBuffer * buffer); +Opentelemetry__Proto__Resource__V1__Resource * +opentelemetry__proto__resource__v1__resource__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data); +void opentelemetry__proto__resource__v1__resource__free_unpacked( + Opentelemetry__Proto__Resource__V1__Resource *message, + ProtobufCAllocator * allocator); +/* --- per-message closures --- */ + +typedef void (*Opentelemetry__Proto__Resource__V1__Resource_Closure)( + const Opentelemetry__Proto__Resource__V1__Resource *message, + void * closure_data); + +/* --- services --- */ + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor + opentelemetry__proto__resource__v1__resource__descriptor; + +PROTOBUF_C__END_DECLS + +#endif /* PROTOBUF_C_opentelemetry_2fproto_2fresource_2fv1_2fresource_2eproto__INCLUDED \ + */ diff --git a/src/otel/trace.pb-c.c b/src/otel/trace.pb-c.c new file mode 100644 index 000000000..481bee9ed --- /dev/null +++ b/src/otel/trace.pb-c.c @@ -0,0 +1,928 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: opentelemetry/proto/trace/v1/trace.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "trace.pb-c.h" +void opentelemetry__proto__trace__v1__traces_data__init( + Opentelemetry__Proto__Trace__V1__TracesData *message) +{ + static const Opentelemetry__Proto__Trace__V1__TracesData init_value = + OPENTELEMETRY__PROTO__TRACE__V1__TRACES_DATA__INIT; + *message = init_value; +} +size_t opentelemetry__proto__trace__v1__traces_data__get_packed_size( + const Opentelemetry__Proto__Trace__V1__TracesData *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__traces_data__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__trace__v1__traces_data__pack( + const Opentelemetry__Proto__Trace__V1__TracesData *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__traces_data__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__trace__v1__traces_data__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__TracesData *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__traces_data__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Trace__V1__TracesData * +opentelemetry__proto__trace__v1__traces_data__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Trace__V1__TracesData *) + protobuf_c_message_unpack( + &opentelemetry__proto__trace__v1__traces_data__descriptor, + allocator, len, data); +} +void opentelemetry__proto__trace__v1__traces_data__free_unpacked( + Opentelemetry__Proto__Trace__V1__TracesData *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__traces_data__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__trace__v1__resource_spans__init( + Opentelemetry__Proto__Trace__V1__ResourceSpans *message) +{ + static const Opentelemetry__Proto__Trace__V1__ResourceSpans init_value = + OPENTELEMETRY__PROTO__TRACE__V1__RESOURCE_SPANS__INIT; + *message = init_value; +} +size_t opentelemetry__proto__trace__v1__resource_spans__get_packed_size( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__resource_spans__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__trace__v1__resource_spans__pack( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__resource_spans__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__trace__v1__resource_spans__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__resource_spans__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Trace__V1__ResourceSpans * +opentelemetry__proto__trace__v1__resource_spans__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Trace__V1__ResourceSpans *) + protobuf_c_message_unpack( + &opentelemetry__proto__trace__v1__resource_spans__descriptor, + allocator, len, data); +} +void opentelemetry__proto__trace__v1__resource_spans__free_unpacked( + Opentelemetry__Proto__Trace__V1__ResourceSpans *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__resource_spans__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__trace__v1__scope_spans__init( + Opentelemetry__Proto__Trace__V1__ScopeSpans *message) +{ + static const Opentelemetry__Proto__Trace__V1__ScopeSpans init_value = + OPENTELEMETRY__PROTO__TRACE__V1__SCOPE_SPANS__INIT; + *message = init_value; +} +size_t opentelemetry__proto__trace__v1__scope_spans__get_packed_size( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__scope_spans__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__trace__v1__scope_spans__pack( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__scope_spans__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__trace__v1__scope_spans__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__scope_spans__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Trace__V1__ScopeSpans * +opentelemetry__proto__trace__v1__scope_spans__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Trace__V1__ScopeSpans *) + protobuf_c_message_unpack( + &opentelemetry__proto__trace__v1__scope_spans__descriptor, + allocator, len, data); +} +void opentelemetry__proto__trace__v1__scope_spans__free_unpacked( + Opentelemetry__Proto__Trace__V1__ScopeSpans *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__scope_spans__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__trace__v1__span__event__init( + Opentelemetry__Proto__Trace__V1__Span__Event *message) +{ + static const Opentelemetry__Proto__Trace__V1__Span__Event init_value = + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__EVENT__INIT; + *message = init_value; +} +void opentelemetry__proto__trace__v1__span__link__init( + Opentelemetry__Proto__Trace__V1__Span__Link *message) +{ + static const Opentelemetry__Proto__Trace__V1__Span__Link init_value = + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__LINK__INIT; + *message = init_value; +} +void opentelemetry__proto__trace__v1__span__init( + Opentelemetry__Proto__Trace__V1__Span *message) +{ + static const Opentelemetry__Proto__Trace__V1__Span init_value = + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__INIT; + *message = init_value; +} +size_t opentelemetry__proto__trace__v1__span__get_packed_size( + const Opentelemetry__Proto__Trace__V1__Span *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__span__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__trace__v1__span__pack( + const Opentelemetry__Proto__Trace__V1__Span *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__span__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__trace__v1__span__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__Span *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__span__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Trace__V1__Span * +opentelemetry__proto__trace__v1__span__unpack(ProtobufCAllocator *allocator, + size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Trace__V1__Span *) protobuf_c_message_unpack( + &opentelemetry__proto__trace__v1__span__descriptor, allocator, len, + data); +} +void opentelemetry__proto__trace__v1__span__free_unpacked( + Opentelemetry__Proto__Trace__V1__Span *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__span__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +void opentelemetry__proto__trace__v1__status__init( + Opentelemetry__Proto__Trace__V1__Status *message) +{ + static const Opentelemetry__Proto__Trace__V1__Status init_value = + OPENTELEMETRY__PROTO__TRACE__V1__STATUS__INIT; + *message = init_value; +} +size_t opentelemetry__proto__trace__v1__status__get_packed_size( + const Opentelemetry__Proto__Trace__V1__Status *message) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__status__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *) (message)); +} +size_t opentelemetry__proto__trace__v1__status__pack( + const Opentelemetry__Proto__Trace__V1__Status *message, uint8_t *out) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__status__descriptor); + return protobuf_c_message_pack((const ProtobufCMessage *) message, out); +} +size_t opentelemetry__proto__trace__v1__status__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__Status *message, + ProtobufCBuffer * buffer) +{ + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__status__descriptor); + return protobuf_c_message_pack_to_buffer((const ProtobufCMessage *) message, + buffer); +} +Opentelemetry__Proto__Trace__V1__Status * +opentelemetry__proto__trace__v1__status__unpack(ProtobufCAllocator *allocator, + size_t len, const uint8_t *data) +{ + return (Opentelemetry__Proto__Trace__V1__Status *) + protobuf_c_message_unpack( + &opentelemetry__proto__trace__v1__status__descriptor, allocator, + len, data); +} +void opentelemetry__proto__trace__v1__status__free_unpacked( + Opentelemetry__Proto__Trace__V1__Status *message, + ProtobufCAllocator * allocator) +{ + if (!message) + return; + assert(message->base.descriptor == + &opentelemetry__proto__trace__v1__status__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *) message, allocator); +} +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__traces_data__field_descriptors[1] = { + { + "resource_spans", 1, PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__TracesData, + n_resource_spans), + offsetof(Opentelemetry__Proto__Trace__V1__TracesData, + resource_spans), + &opentelemetry__proto__trace__v1__resource_spans__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__traces_data__field_indices_by_name[] = { + 0, /* field[0] = resource_spans */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__traces_data__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 1 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__traces_data__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.TracesData", + "TracesData", + "Opentelemetry__Proto__Trace__V1__TracesData", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__TracesData), + 1, + opentelemetry__proto__trace__v1__traces_data__field_descriptors, + opentelemetry__proto__trace__v1__traces_data__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__traces_data__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__trace__v1__traces_data__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__resource_spans__field_descriptors[3] = { + { + "resource", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__ResourceSpans, resource), + &opentelemetry__proto__resource__v1__resource__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "scope_spans", 2, PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__ResourceSpans, + n_scope_spans), + offsetof(Opentelemetry__Proto__Trace__V1__ResourceSpans, + scope_spans), + &opentelemetry__proto__trace__v1__scope_spans__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "schema_url", 3, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__ResourceSpans, + schema_url), + NULL, &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__resource_spans__field_indices_by_name[] = { + 0, /* field[0] = resource */ + 2, /* field[2] = schema_url */ + 1, /* field[1] = scope_spans */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__resource_spans__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 3 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__resource_spans__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.ResourceSpans", + "ResourceSpans", + "Opentelemetry__Proto__Trace__V1__ResourceSpans", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__ResourceSpans), + 3, + opentelemetry__proto__trace__v1__resource_spans__field_descriptors, + opentelemetry__proto__trace__v1__resource_spans__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__resource_spans__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__trace__v1__resource_spans__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__scope_spans__field_descriptors[3] = { + { + "scope", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__ScopeSpans, scope), + &opentelemetry__proto__common__v1__instrumentation_scope__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "spans", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__ScopeSpans, n_spans), + offsetof(Opentelemetry__Proto__Trace__V1__ScopeSpans, spans), + &opentelemetry__proto__trace__v1__span__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "schema_url", 3, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__ScopeSpans, schema_url), + NULL, &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__scope_spans__field_indices_by_name[] = { + 2, /* field[2] = schema_url */ + 0, /* field[0] = scope */ + 1, /* field[1] = spans */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__scope_spans__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 3 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__scope_spans__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.ScopeSpans", + "ScopeSpans", + "Opentelemetry__Proto__Trace__V1__ScopeSpans", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__ScopeSpans), + 3, + opentelemetry__proto__trace__v1__scope_spans__field_descriptors, + opentelemetry__proto__trace__v1__scope_spans__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__scope_spans__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__trace__v1__scope_spans__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__span__event__field_descriptors[4] = { + { + "time_unix_nano", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_FIXED64, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Event, + time_unix_nano), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "name", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Event, name), NULL, + &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "attributes", 3, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__Span__Event, + n_attributes), + offsetof(Opentelemetry__Proto__Trace__V1__Span__Event, attributes), + &opentelemetry__proto__common__v1__key_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_attributes_count", 4, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Event, + dropped_attributes_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__span__event__field_indices_by_name[] = { + 2, /* field[2] = attributes */ + 3, /* field[3] = dropped_attributes_count */ + 1, /* field[1] = name */ + 0, /* field[0] = time_unix_nano */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__span__event__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 4 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__span__event__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.Span.Event", + "Event", + "Opentelemetry__Proto__Trace__V1__Span__Event", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__Span__Event), + 4, + opentelemetry__proto__trace__v1__span__event__field_descriptors, + opentelemetry__proto__trace__v1__span__event__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__span__event__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__trace__v1__span__event__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__span__link__field_descriptors[6] = { + { + "trace_id", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, trace_id), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "span_id", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, span_id), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "trace_state", 3, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, trace_state), + NULL, &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "attributes", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, n_attributes), + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, attributes), + &opentelemetry__proto__common__v1__key_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_attributes_count", 5, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, + dropped_attributes_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "flags", 6, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_FIXED32, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span__Link, flags), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__span__link__field_indices_by_name[] = { + 3, /* field[3] = attributes */ + 4, /* field[4] = dropped_attributes_count */ + 5, /* field[5] = flags */ + 1, /* field[1] = span_id */ + 0, /* field[0] = trace_id */ + 2, /* field[2] = trace_state */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__span__link__number_ranges[1 + 1] = { + { 1, 0 }, { 0, 6 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__span__link__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.Span.Link", + "Link", + "Opentelemetry__Proto__Trace__V1__Span__Link", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__Span__Link), + 6, + opentelemetry__proto__trace__v1__span__link__field_descriptors, + opentelemetry__proto__trace__v1__span__link__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__span__link__number_ranges, + (ProtobufCMessageInit) + opentelemetry__proto__trace__v1__span__link__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCEnumValue + opentelemetry__proto__trace__v1__span__span_kind__enum_values_by_number + [6] = { + { "SPAN_KIND_UNSPECIFIED", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_" + "UNSPECIFIED", + 0 }, + { "SPAN_KIND_INTERNAL", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_" + "INTERNAL", + 1 }, + { "SPAN_KIND_SERVER", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_" + "SERVER", + 2 }, + { "SPAN_KIND_CLIENT", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_" + "CLIENT", + 3 }, + { "SPAN_KIND_PRODUCER", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_" + "PRODUCER", + 4 }, + { "SPAN_KIND_CONSUMER", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_" + "CONSUMER", + 5 }, + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__span__span_kind__value_ranges[] = { + { 0, 0 }, { 0, 6 } + }; +static const ProtobufCEnumValueIndex + opentelemetry__proto__trace__v1__span__span_kind__enum_values_by_name[6] = { + { "SPAN_KIND_CLIENT", 3 }, { "SPAN_KIND_CONSUMER", 5 }, + { "SPAN_KIND_INTERNAL", 1 }, { "SPAN_KIND_PRODUCER", 4 }, + { "SPAN_KIND_SERVER", 2 }, { "SPAN_KIND_UNSPECIFIED", 0 }, + }; +const ProtobufCEnumDescriptor + opentelemetry__proto__trace__v1__span__span_kind__descriptor = { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.Span.SpanKind", + "SpanKind", + "Opentelemetry__Proto__Trace__V1__Span__SpanKind", + "opentelemetry.proto.trace.v1", + 6, + opentelemetry__proto__trace__v1__span__span_kind__enum_values_by_number, + 6, + opentelemetry__proto__trace__v1__span__span_kind__enum_values_by_name, + 1, + opentelemetry__proto__trace__v1__span__span_kind__value_ranges, + NULL, + NULL, + NULL, + NULL /* reserved[1234] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__span__field_descriptors[16] = { + { + "trace_id", 1, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, trace_id), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "span_id", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, span_id), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "trace_state", 3, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, trace_state), NULL, + &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "parent_span_id", 4, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, parent_span_id), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "name", 5, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, name), NULL, + &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "kind", 6, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, kind), + &opentelemetry__proto__trace__v1__span__span_kind__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "start_time_unix_nano", 7, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_FIXED64, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, + start_time_unix_nano), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "end_time_unix_nano", 8, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_FIXED64, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, end_time_unix_nano), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "attributes", 9, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__Span, n_attributes), + offsetof(Opentelemetry__Proto__Trace__V1__Span, attributes), + &opentelemetry__proto__common__v1__key_value__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_attributes_count", 10, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, + dropped_attributes_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "events", 11, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__Span, n_events), + offsetof(Opentelemetry__Proto__Trace__V1__Span, events), + &opentelemetry__proto__trace__v1__span__event__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_events_count", 12, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, + dropped_events_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "links", 13, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(Opentelemetry__Proto__Trace__V1__Span, n_links), + offsetof(Opentelemetry__Proto__Trace__V1__Span, links), + &opentelemetry__proto__trace__v1__span__link__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dropped_links_count", 14, PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_UINT32, 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, + dropped_links_count), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "status", 15, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, status), + &opentelemetry__proto__trace__v1__status__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "flags", 16, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_FIXED32, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Span, flags), NULL, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__span__field_indices_by_name[] = { + 8, /* field[8] = attributes */ + 9, /* field[9] = dropped_attributes_count */ + 11, /* field[11] = dropped_events_count */ + 13, /* field[13] = dropped_links_count */ + 7, /* field[7] = end_time_unix_nano */ + 10, /* field[10] = events */ + 15, /* field[15] = flags */ + 5, /* field[5] = kind */ + 12, /* field[12] = links */ + 4, /* field[4] = name */ + 3, /* field[3] = parent_span_id */ + 1, /* field[1] = span_id */ + 6, /* field[6] = start_time_unix_nano */ + 14, /* field[14] = status */ + 0, /* field[0] = trace_id */ + 2, /* field[2] = trace_state */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__span__number_ranges[1 + 1] = { { 1, 0 }, + { 0, 16 } }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__span__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.Span", + "Span", + "Opentelemetry__Proto__Trace__V1__Span", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__Span), + 16, + opentelemetry__proto__trace__v1__span__field_descriptors, + opentelemetry__proto__trace__v1__span__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__span__number_ranges, + (ProtobufCMessageInit) opentelemetry__proto__trace__v1__span__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCEnumValue + opentelemetry__proto__trace__v1__status__status_code__enum_values_by_number + [3] = { + { "STATUS_CODE_UNSET", + "OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_" + "CODE_UNSET", + 0 }, + { "STATUS_CODE_OK", + "OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_" + "CODE_OK", + 1 }, + { "STATUS_CODE_ERROR", + "OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_" + "CODE_ERROR", + 2 }, + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__status__status_code__value_ranges[] = { + { 0, 0 }, { 0, 3 } + }; +static const ProtobufCEnumValueIndex + opentelemetry__proto__trace__v1__status__status_code__enum_values_by_name + [3] = { + { "STATUS_CODE_ERROR", 2 }, + { "STATUS_CODE_OK", 1 }, + { "STATUS_CODE_UNSET", 0 }, + }; +const ProtobufCEnumDescriptor + opentelemetry__proto__trace__v1__status__status_code__descriptor = { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.Status.StatusCode", + "StatusCode", + "Opentelemetry__Proto__Trace__V1__Status__StatusCode", + "opentelemetry.proto.trace.v1", + 3, + opentelemetry__proto__trace__v1__status__status_code__enum_values_by_number, + 3, + opentelemetry__proto__trace__v1__status__status_code__enum_values_by_name, + 1, + opentelemetry__proto__trace__v1__status__status_code__value_ranges, + NULL, + NULL, + NULL, + NULL /* reserved[1234] */ + }; +static const ProtobufCFieldDescriptor + opentelemetry__proto__trace__v1__status__field_descriptors[2] = { + { + "message", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Status, message), NULL, + &protobuf_c_empty_string, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "code", 3, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Opentelemetry__Proto__Trace__V1__Status, code), + &opentelemetry__proto__trace__v1__status__status_code__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + }; +static const unsigned + opentelemetry__proto__trace__v1__status__field_indices_by_name[] = { + 1, /* field[1] = code */ + 0, /* field[0] = message */ + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__status__number_ranges[1 + 1] = { + { 2, 0 }, { 0, 2 } + }; +const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__status__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.Status", + "Status", + "Opentelemetry__Proto__Trace__V1__Status", + "opentelemetry.proto.trace.v1", + sizeof(Opentelemetry__Proto__Trace__V1__Status), + 2, + opentelemetry__proto__trace__v1__status__field_descriptors, + opentelemetry__proto__trace__v1__status__field_indices_by_name, + 1, + opentelemetry__proto__trace__v1__status__number_ranges, + (ProtobufCMessageInit) opentelemetry__proto__trace__v1__status__init, + NULL, + NULL, + NULL /* reserved[123] */ + }; +static const ProtobufCEnumValue + opentelemetry__proto__trace__v1__span_flags__enum_values_by_number[4] = { + { "SPAN_FLAGS_DO_NOT_USE", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_DO_NOT_USE", + 0 }, + { "SPAN_FLAGS_TRACE_FLAGS_MASK", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_TRACE_FLAGS_" + "MASK", + 255 }, + { "SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_CONTEXT_HAS_" + "IS_REMOTE_MASK", + 256 }, + { "SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK", + "OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_CONTEXT_IS_" + "REMOTE_MASK", + 512 }, + }; +static const ProtobufCIntRange + opentelemetry__proto__trace__v1__span_flags__value_ranges[] = { + { 0, 0 }, { 255, 1 }, { 512, 3 }, { 0, 4 } + }; +static const ProtobufCEnumValueIndex + opentelemetry__proto__trace__v1__span_flags__enum_values_by_name[4] = { + { "SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK", 2 }, + { "SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK", 3 }, + { "SPAN_FLAGS_DO_NOT_USE", 0 }, + { "SPAN_FLAGS_TRACE_FLAGS_MASK", 1 }, + }; +const ProtobufCEnumDescriptor + opentelemetry__proto__trace__v1__span_flags__descriptor = { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "opentelemetry.proto.trace.v1.SpanFlags", + "SpanFlags", + "Opentelemetry__Proto__Trace__V1__SpanFlags", + "opentelemetry.proto.trace.v1", + 4, + opentelemetry__proto__trace__v1__span_flags__enum_values_by_number, + 4, + opentelemetry__proto__trace__v1__span_flags__enum_values_by_name, + 3, + opentelemetry__proto__trace__v1__span_flags__value_ranges, + NULL, + NULL, + NULL, + NULL /* reserved[1234] */ + }; diff --git a/src/otel/trace.pb-c.h b/src/otel/trace.pb-c.h new file mode 100644 index 000000000..40b8f53db --- /dev/null +++ b/src/otel/trace.pb-c.h @@ -0,0 +1,636 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: opentelemetry/proto/trace/v1/trace.proto */ + +#ifndef PROTOBUF_C_opentelemetry_2fproto_2ftrace_2fv1_2ftrace_2eproto__INCLUDED +#define PROTOBUF_C_opentelemetry_2fproto_2ftrace_2fv1_2ftrace_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + +#include "common.pb-c.h" +#include "resource.pb-c.h" + +typedef struct Opentelemetry__Proto__Trace__V1__TracesData + Opentelemetry__Proto__Trace__V1__TracesData; +typedef struct Opentelemetry__Proto__Trace__V1__ResourceSpans + Opentelemetry__Proto__Trace__V1__ResourceSpans; +typedef struct Opentelemetry__Proto__Trace__V1__ScopeSpans + Opentelemetry__Proto__Trace__V1__ScopeSpans; +typedef struct Opentelemetry__Proto__Trace__V1__Span + Opentelemetry__Proto__Trace__V1__Span; +typedef struct Opentelemetry__Proto__Trace__V1__Span__Event + Opentelemetry__Proto__Trace__V1__Span__Event; +typedef struct Opentelemetry__Proto__Trace__V1__Span__Link + Opentelemetry__Proto__Trace__V1__Span__Link; +typedef struct Opentelemetry__Proto__Trace__V1__Status + Opentelemetry__Proto__Trace__V1__Status; + +/* --- enums --- */ + +/* + * SpanKind is the type of span. Can be used to specify additional relationships + * between spans in addition to a parent/child relationship. + */ +typedef enum _Opentelemetry__Proto__Trace__V1__Span__SpanKind { + /* + * Unspecified. Do NOT use as default. + * Implementations MAY assume SpanKind to be INTERNAL when receiving + * UNSPECIFIED. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_UNSPECIFIED = 0, + /* + * Indicates that the span represents an internal operation within an + * application, as opposed to an operation happening at the boundaries. + * Default value. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_INTERNAL = 1, + /* + * Indicates that the span covers server-side handling of an RPC or other + * remote network request. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_SERVER = 2, + /* + * Indicates that the span describes a request to some remote service. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_CLIENT = 3, + /* + * Indicates that the span describes a producer sending a message to a + * broker. Unlike CLIENT and SERVER, there is often no direct critical path + * latency relationship between producer and consumer spans. A PRODUCER span + * ends when the message was accepted by the broker while the logical + * processing of the message might span a much longer time. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_PRODUCER = 4, + /* + * Indicates that the span describes consumer receiving a message from a + * broker. Like the PRODUCER kind, there is often no direct critical path + * latency relationship between producer and consumer spans. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_CONSUMER = + 5 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE( + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND) +} Opentelemetry__Proto__Trace__V1__Span__SpanKind; +/* + * For the semantics of status codes see + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#set-status + */ +typedef enum _Opentelemetry__Proto__Trace__V1__Status__StatusCode { + /* + * The default status. + */ + OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_CODE_UNSET = 0, + /* + * The Span has been validated by an Application developer or Operator to + * have completed successfully. + */ + OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_CODE_OK = 1, + /* + * The Span contains an error. + */ + OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_CODE_ERROR = + 2 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE( + OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE) +} Opentelemetry__Proto__Trace__V1__Status__StatusCode; +/* + * SpanFlags represents constants used to interpret the + * Span.flags field, which is protobuf 'fixed32' type and is to + * be used as bit-fields. Each non-zero value defined in this enum is + * a bit-mask. To extract the bit-field, for example, use an + * expression like: + * (span.flags & SPAN_FLAGS_TRACE_FLAGS_MASK) + * See https://www.w3.org/TR/trace-context-2/#trace-flags for the flag + * definitions. Note that Span flags were introduced in version 1.1 of the + * OpenTelemetry protocol. Older Span producers do not set this + * field, consequently consumers should not rely on the absence of a + * particular flag bit to indicate the presence of a particular feature. + */ +typedef enum _Opentelemetry__Proto__Trace__V1__SpanFlags { + /* + * The zero value for the enum. Should not be used for comparisons. + * Instead use bitwise "and" with the appropriate mask as shown above. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_DO_NOT_USE = 0, + /* + * Bits 0-7 are used for trace flags. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_TRACE_FLAGS_MASK = + 255, + /* + * Bits 8 and 9 are used to indicate that the parent span or link span is + * remote. Bit 8 (`HAS_IS_REMOTE`) indicates whether the value is known. Bit + * 9 (`IS_REMOTE`) indicates whether the span or link is remote. + */ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK = + 256, + OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS__SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK = + 512 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE( + OPENTELEMETRY__PROTO__TRACE__V1__SPAN_FLAGS) +} Opentelemetry__Proto__Trace__V1__SpanFlags; + +/* --- messages --- */ + +/* + * TracesData represents the traces data that can be stored in a persistent + * storage, OR can be embedded by other protocols that transfer OTLP traces data + * but do not implement the OTLP protocol. The main difference between this + * message and collector protocol is that in this message there will not be any + * "control" or "metadata" specific to OTLP protocol. When new fields are added + * into this message, the OTLP request MUST be updated as well. + */ +struct Opentelemetry__Proto__Trace__V1__TracesData { + ProtobufCMessage base; + /* + * An array of ResourceSpans. + * For data coming from a single resource this array will typically contain + * one element. Intermediary nodes that receive data from multiple origins + * typically batch the data before forwarding further and in that case this + * array will contain multiple elements. + */ + size_t n_resource_spans; + Opentelemetry__Proto__Trace__V1__ResourceSpans **resource_spans; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__TRACES_DATA__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__traces_data__descriptor) \ + , 0, NULL \ + } + +/* + * A collection of ScopeSpans from a Resource. + */ +struct Opentelemetry__Proto__Trace__V1__ResourceSpans { + ProtobufCMessage base; + /* + * The resource for the spans in this message. + * If this field is not set then no resource info is known. + */ + Opentelemetry__Proto__Resource__V1__Resource *resource; + /* + * A list of ScopeSpans that originate from a resource. + */ + size_t n_scope_spans; + Opentelemetry__Proto__Trace__V1__ScopeSpans **scope_spans; + /* + * The Schema URL, if known. This is the identifier of the Schema that the + * resource data is recorded in. To learn more about Schema URL see + * https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + * This schema_url applies to the data in the "resource" field. It does not + * apply to the data in the "scope_spans" field which have their own + * schema_url field. + */ + char *schema_url; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__RESOURCE_SPANS__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__resource_spans__descriptor) \ + , NULL, 0, NULL, (char *) protobuf_c_empty_string \ + } + +/* + * A collection of Spans produced by an InstrumentationScope. + */ +struct Opentelemetry__Proto__Trace__V1__ScopeSpans { + ProtobufCMessage base; + /* + * The instrumentation scope information for the spans in this message. + * Semantically when InstrumentationScope isn't set, it is equivalent with + * an empty instrumentation scope name (unknown). + */ + Opentelemetry__Proto__Common__V1__InstrumentationScope *scope; + /* + * A list of Spans that originate from an instrumentation scope. + */ + size_t n_spans; + Opentelemetry__Proto__Trace__V1__Span **spans; + /* + * The Schema URL, if known. This is the identifier of the Schema that the + * span data is recorded in. To learn more about Schema URL see + * https://opentelemetry.io/docs/specs/otel/schemas/#schema-url + * This schema_url applies to all spans and span events in the "spans" + * field. + */ + char *schema_url; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__SCOPE_SPANS__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__scope_spans__descriptor) \ + , NULL, 0, NULL, (char *) protobuf_c_empty_string \ + } + +/* + * Event is a time-stamped annotation of the span, consisting of user-supplied + * text description and key-value pairs. + */ +struct Opentelemetry__Proto__Trace__V1__Span__Event { + ProtobufCMessage base; + /* + * time_unix_nano is the time the event occurred. + */ + uint64_t time_unix_nano; + /* + * name of the event. + * This field is semantically required to be set to non-empty string. + */ + char *name; + /* + * attributes is a collection of attribute key/value pairs on the event. + * Attribute keys MUST be unique (it is not allowed to have more than one + * attribute with the same key). + */ + size_t n_attributes; + Opentelemetry__Proto__Common__V1__KeyValue **attributes; + /* + * dropped_attributes_count is the number of dropped attributes. If the + * value is 0, then no attributes were dropped. + */ + uint32_t dropped_attributes_count; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__SPAN__EVENT__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__span__event__descriptor) \ + , 0, (char *) protobuf_c_empty_string, 0, NULL, 0 \ + } + +/* + * A pointer from the current span to another span in the same trace or in a + * different trace. For example, this can be used in batching operations, + * where a single batch handler processes multiple requests from different + * traces or when the handler receives a request from a different project. + */ +struct Opentelemetry__Proto__Trace__V1__Span__Link { + ProtobufCMessage base; + /* + * A unique identifier of a trace that this linked span is part of. The ID + * is a 16-byte array. + */ + ProtobufCBinaryData trace_id; + /* + * A unique identifier for the linked span. The ID is an 8-byte array. + */ + ProtobufCBinaryData span_id; + /* + * The trace_state associated with the link. + */ + char *trace_state; + /* + * attributes is a collection of attribute key/value pairs on the link. + * Attribute keys MUST be unique (it is not allowed to have more than one + * attribute with the same key). + */ + size_t n_attributes; + Opentelemetry__Proto__Common__V1__KeyValue **attributes; + /* + * dropped_attributes_count is the number of dropped attributes. If the + * value is 0, then no attributes were dropped. + */ + uint32_t dropped_attributes_count; + /* + * Flags, a bit field. + * Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C + * Trace Context specification. To read the 8-bit W3C trace flag, use `flags + * & SPAN_FLAGS_TRACE_FLAGS_MASK`. See + * https://www.w3.org/TR/trace-context-2/#trace-flags for the flag + * definitions. Bits 8 and 9 represent the 3 states of whether the link is + * remote. The states are (unknown, is not remote, is remote). To read + * whether the value is known, use `(flags & + * SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. To read whether the link is + * remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. Readers + * MUST NOT assume that bits 10-31 (22 most significant bits) will be zero. + * When creating new spans, bits 10-31 (most-significant 22-bits) MUST be + * zero. [Optional]. + */ + uint32_t flags; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__SPAN__LINK__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__span__link__descriptor) \ + , { 0, NULL }, { 0, NULL }, (char *) protobuf_c_empty_string, 0, NULL, \ + 0, 0 \ + } + +/* + * A Span represents a single operation performed by a single component of the + * system. The next available field id is 17. + */ +struct Opentelemetry__Proto__Trace__V1__Span { + ProtobufCMessage base; + /* + * A unique identifier for a trace. All spans from the same trace share + * the same `trace_id`. The ID is a 16-byte array. An ID with all zeroes OR + * of length other than 16 bytes is considered invalid (empty string in + * OTLP/JSON is zero-length and thus is also invalid). This field is + * required. + */ + ProtobufCBinaryData trace_id; + /* + * A unique identifier for a span within a trace, assigned when the span + * is created. The ID is an 8-byte array. An ID with all zeroes OR of length + * other than 8 bytes is considered invalid (empty string in OTLP/JSON + * is zero-length and thus is also invalid). + * This field is required. + */ + ProtobufCBinaryData span_id; + /* + * trace_state conveys information about request position in multiple + * distributed tracing graphs. It is a trace_state in w3c-trace-context + * format: https://www.w3.org/TR/trace-context/#tracestate-header See also + * https://github.com/w3c/distributed-tracing for more details about this + * field. + */ + char *trace_state; + /* + * The `span_id` of this span's parent span. If this is a root span, then + * this field must be empty. The ID is an 8-byte array. + */ + ProtobufCBinaryData parent_span_id; + /* + * Flags, a bit field. + * Bits 0-7 (8 least significant bits) are the trace flags as defined in W3C + * Trace Context specification. To read the 8-bit W3C trace flag, use `flags + * & SPAN_FLAGS_TRACE_FLAGS_MASK`. See + * https://www.w3.org/TR/trace-context-2/#trace-flags for the flag + * definitions. Bits 8 and 9 represent the 3 states of whether a span's + * parent is remote. The states are (unknown, is not remote, is remote). To + * read whether the value is known, use `(flags & + * SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK) != 0`. To read whether the span is + * remote, use `(flags & SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK) != 0`. When + * creating span messages, if the message is logically forwarded from + * another source with an equivalent flags fields (i.e., usually another + * OTLP span message), the field SHOULD be copied as-is. If creating from a + * source that does not have an equivalent flags field (such as a runtime + * representation of an OpenTelemetry span), the high 22 bits MUST be set to + * zero. Readers MUST NOT assume that bits 10-31 (22 most significant bits) + * will be zero. [Optional]. + */ + uint32_t flags; + /* + * A description of the span's operation. + * For example, the name can be a qualified method name or a file name + * and a line number where the operation is called. A best practice is to + * use the same display name at the same call point in an application. This + * makes it easier to correlate spans in different traces. This field is + * semantically required to be set to non-empty string. Empty value is + * equivalent to an unknown span name. This field is required. + */ + char *name; + /* + * Distinguishes between spans generated in a particular context. For + * example, two spans with the same name may be distinguished using `CLIENT` + * (caller) and `SERVER` (callee) to identify queueing latency associated + * with the span. + */ + Opentelemetry__Proto__Trace__V1__Span__SpanKind kind; + /* + * start_time_unix_nano is the start time of the span. On the client side, + * this is the time kept by the local machine where the span execution + * starts. On the server side, this is the time when the server's + * application handler starts running. Value is UNIX Epoch time in + * nanoseconds since 00:00:00 UTC on 1 January 1970. This field is + * semantically required and it is expected that end_time >= start_time. + */ + uint64_t start_time_unix_nano; + /* + * end_time_unix_nano is the end time of the span. On the client side, this + * is the time kept by the local machine where the span execution ends. On + * the server side, this is the time when the server application handler + * stops running. Value is UNIX Epoch time in nanoseconds since 00:00:00 UTC + * on 1 January 1970. This field is semantically required and it is expected + * that end_time >= start_time. + */ + uint64_t end_time_unix_nano; + /* + * attributes is a collection of key/value pairs. Note, global attributes + * like server name can be set using the resource API. Examples of + * attributes: + * "/http/user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) + * AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" + * "/http/server_latency": 300 + * "example.com/myattribute": true + * "example.com/score": 10.239 + * The OpenTelemetry API specification further restricts the allowed value + * types: + * https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/common/README.md#attribute + * Attribute keys MUST be unique (it is not allowed to have more than one + * attribute with the same key). + */ + size_t n_attributes; + Opentelemetry__Proto__Common__V1__KeyValue **attributes; + /* + * dropped_attributes_count is the number of attributes that were discarded. + * Attributes can be discarded because their keys are too long or because + * there are too many attributes. If this value is 0, then no attributes + * were dropped. + */ + uint32_t dropped_attributes_count; + /* + * events is a collection of Event items. + */ + size_t n_events; + Opentelemetry__Proto__Trace__V1__Span__Event **events; + /* + * dropped_events_count is the number of dropped events. If the value is 0, + * then no events were dropped. + */ + uint32_t dropped_events_count; + /* + * links is a collection of Links, which are references from this span to a + * span in the same or different trace. + */ + size_t n_links; + Opentelemetry__Proto__Trace__V1__Span__Link **links; + /* + * dropped_links_count is the number of dropped links after the maximum size + * was enforced. If this value is 0, then no links were dropped. + */ + uint32_t dropped_links_count; + /* + * An optional final status for this span. Semantically when Status isn't + * set, it means span's status code is unset, i.e. assume STATUS_CODE_UNSET + * (code = 0). + */ + Opentelemetry__Proto__Trace__V1__Status *status; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__SPAN__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__span__descriptor) \ + , { 0, NULL }, { 0, NULL }, (char *) protobuf_c_empty_string, \ + { 0, NULL }, 0, (char *) protobuf_c_empty_string, \ + OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_UNSPECIFIED, \ + 0, 0, 0, NULL, 0, 0, NULL, 0, 0, NULL, 0, NULL \ + } + +/* + * The Status type defines a logical error model that is suitable for different + * programming environments, including REST APIs and RPC APIs. + */ +struct Opentelemetry__Proto__Trace__V1__Status { + ProtobufCMessage base; + /* + * A developer-facing human readable error message. + */ + char *message; + /* + * The status code. + */ + Opentelemetry__Proto__Trace__V1__Status__StatusCode code; +}; +#define OPENTELEMETRY__PROTO__TRACE__V1__STATUS__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &opentelemetry__proto__trace__v1__status__descriptor) \ + , (char *) protobuf_c_empty_string, \ + OPENTELEMETRY__PROTO__TRACE__V1__STATUS__STATUS_CODE__STATUS_CODE_UNSET \ + } + +/* Opentelemetry__Proto__Trace__V1__TracesData methods */ +void opentelemetry__proto__trace__v1__traces_data__init( + Opentelemetry__Proto__Trace__V1__TracesData *message); +size_t opentelemetry__proto__trace__v1__traces_data__get_packed_size( + const Opentelemetry__Proto__Trace__V1__TracesData *message); +size_t opentelemetry__proto__trace__v1__traces_data__pack( + const Opentelemetry__Proto__Trace__V1__TracesData *message, uint8_t *out); +size_t opentelemetry__proto__trace__v1__traces_data__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__TracesData *message, + ProtobufCBuffer * buffer); +Opentelemetry__Proto__Trace__V1__TracesData * +opentelemetry__proto__trace__v1__traces_data__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data); +void opentelemetry__proto__trace__v1__traces_data__free_unpacked( + Opentelemetry__Proto__Trace__V1__TracesData *message, + ProtobufCAllocator * allocator); +/* Opentelemetry__Proto__Trace__V1__ResourceSpans methods */ +void opentelemetry__proto__trace__v1__resource_spans__init( + Opentelemetry__Proto__Trace__V1__ResourceSpans *message); +size_t opentelemetry__proto__trace__v1__resource_spans__get_packed_size( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message); +size_t opentelemetry__proto__trace__v1__resource_spans__pack( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message, + uint8_t * out); +size_t opentelemetry__proto__trace__v1__resource_spans__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message, + ProtobufCBuffer * buffer); +Opentelemetry__Proto__Trace__V1__ResourceSpans * +opentelemetry__proto__trace__v1__resource_spans__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data); +void opentelemetry__proto__trace__v1__resource_spans__free_unpacked( + Opentelemetry__Proto__Trace__V1__ResourceSpans *message, + ProtobufCAllocator * allocator); +/* Opentelemetry__Proto__Trace__V1__ScopeSpans methods */ +void opentelemetry__proto__trace__v1__scope_spans__init( + Opentelemetry__Proto__Trace__V1__ScopeSpans *message); +size_t opentelemetry__proto__trace__v1__scope_spans__get_packed_size( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message); +size_t opentelemetry__proto__trace__v1__scope_spans__pack( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message, uint8_t *out); +size_t opentelemetry__proto__trace__v1__scope_spans__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message, + ProtobufCBuffer * buffer); +Opentelemetry__Proto__Trace__V1__ScopeSpans * +opentelemetry__proto__trace__v1__scope_spans__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data); +void opentelemetry__proto__trace__v1__scope_spans__free_unpacked( + Opentelemetry__Proto__Trace__V1__ScopeSpans *message, + ProtobufCAllocator * allocator); +/* Opentelemetry__Proto__Trace__V1__Span__Event methods */ +void opentelemetry__proto__trace__v1__span__event__init( + Opentelemetry__Proto__Trace__V1__Span__Event *message); +/* Opentelemetry__Proto__Trace__V1__Span__Link methods */ +void opentelemetry__proto__trace__v1__span__link__init( + Opentelemetry__Proto__Trace__V1__Span__Link *message); +/* Opentelemetry__Proto__Trace__V1__Span methods */ +void opentelemetry__proto__trace__v1__span__init( + Opentelemetry__Proto__Trace__V1__Span *message); +size_t opentelemetry__proto__trace__v1__span__get_packed_size( + const Opentelemetry__Proto__Trace__V1__Span *message); +size_t opentelemetry__proto__trace__v1__span__pack( + const Opentelemetry__Proto__Trace__V1__Span *message, uint8_t *out); +size_t opentelemetry__proto__trace__v1__span__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__Span *message, + ProtobufCBuffer * buffer); +Opentelemetry__Proto__Trace__V1__Span * +opentelemetry__proto__trace__v1__span__unpack(ProtobufCAllocator *allocator, + size_t len, const uint8_t *data); +void opentelemetry__proto__trace__v1__span__free_unpacked( + Opentelemetry__Proto__Trace__V1__Span *message, + ProtobufCAllocator * allocator); +/* Opentelemetry__Proto__Trace__V1__Status methods */ +void opentelemetry__proto__trace__v1__status__init( + Opentelemetry__Proto__Trace__V1__Status *message); +size_t opentelemetry__proto__trace__v1__status__get_packed_size( + const Opentelemetry__Proto__Trace__V1__Status *message); +size_t opentelemetry__proto__trace__v1__status__pack( + const Opentelemetry__Proto__Trace__V1__Status *message, uint8_t *out); +size_t opentelemetry__proto__trace__v1__status__pack_to_buffer( + const Opentelemetry__Proto__Trace__V1__Status *message, + ProtobufCBuffer * buffer); +Opentelemetry__Proto__Trace__V1__Status * +opentelemetry__proto__trace__v1__status__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t * data); +void opentelemetry__proto__trace__v1__status__free_unpacked( + Opentelemetry__Proto__Trace__V1__Status *message, + ProtobufCAllocator * allocator); +/* --- per-message closures --- */ + +typedef void (*Opentelemetry__Proto__Trace__V1__TracesData_Closure)( + const Opentelemetry__Proto__Trace__V1__TracesData *message, + void * closure_data); +typedef void (*Opentelemetry__Proto__Trace__V1__ResourceSpans_Closure)( + const Opentelemetry__Proto__Trace__V1__ResourceSpans *message, + void * closure_data); +typedef void (*Opentelemetry__Proto__Trace__V1__ScopeSpans_Closure)( + const Opentelemetry__Proto__Trace__V1__ScopeSpans *message, + void * closure_data); +typedef void (*Opentelemetry__Proto__Trace__V1__Span__Event_Closure)( + const Opentelemetry__Proto__Trace__V1__Span__Event *message, + void * closure_data); +typedef void (*Opentelemetry__Proto__Trace__V1__Span__Link_Closure)( + const Opentelemetry__Proto__Trace__V1__Span__Link *message, + void * closure_data); +typedef void (*Opentelemetry__Proto__Trace__V1__Span_Closure)( + const Opentelemetry__Proto__Trace__V1__Span *message, void *closure_data); +typedef void (*Opentelemetry__Proto__Trace__V1__Status_Closure)( + const Opentelemetry__Proto__Trace__V1__Status *message, void *closure_data); + +/* --- services --- */ + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor + opentelemetry__proto__trace__v1__span_flags__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__traces_data__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__resource_spans__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__scope_spans__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__span__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__span__event__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__span__link__descriptor; +extern const ProtobufCEnumDescriptor + opentelemetry__proto__trace__v1__span__span_kind__descriptor; +extern const ProtobufCMessageDescriptor + opentelemetry__proto__trace__v1__status__descriptor; +extern const ProtobufCEnumDescriptor + opentelemetry__proto__trace__v1__status__status_code__descriptor; + +PROTOBUF_C__END_DECLS + +#endif /* PROTOBUF_C_opentelemetry_2fproto_2ftrace_2fv1_2ftrace_2eproto__INCLUDED \ + */ diff --git a/src/parser/neu_json_otel.c b/src/parser/neu_json_otel.c new file mode 100644 index 000000000..e982dcfc9 --- /dev/null +++ b/src/parser/neu_json_otel.c @@ -0,0 +1,103 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +/* + * DO NOT EDIT THIS FILE MANUALLY! + * It was automatically generated by `json-autotype`. + */ + +#include +#include + +#include "json/json.h" + +#include "utils/log.h" + +#include "neu_json_otel.h" + +void neu_json_decode_otel_conf_req_free(neu_json_otel_conf_req_t *req) +{ + if (req->action != NULL) { + free(req->action); + } + if (req->host != NULL) { + free(req->host); + } + if (req->traces_url != NULL) { + free(req->traces_url); + } + if (req != NULL) { + free(req); + } +} +int neu_json_decode_otel_conf_req(char *buf, neu_json_otel_conf_req_t **result) +{ + int ret = 0; + void *json_obj = neu_json_decode_new(buf); + + neu_json_otel_conf_req_t *req = calloc(1, sizeof(neu_json_otel_conf_req_t)); + if (req == NULL) { + return -1; + } + + neu_json_elem_t req_elems[] = { + { + .name = "action", + .t = NEU_JSON_STR, + }, + { + .name = "host", + .t = NEU_JSON_STR, + .attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, + }, + { + .name = "port", + .t = NEU_JSON_INT, + .attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, + }, + { + .name = "traces_url", + .t = NEU_JSON_STR, + .attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, + } + }; + + ret = neu_json_decode_by_json(json_obj, NEU_JSON_ELEM_SIZE(req_elems), + req_elems); + if (ret != 0) { + free(req); + if (json_obj != NULL) { + neu_json_decode_free(json_obj); + } + return -1; + } + + if (req_elems[0].v.val_str != NULL) { + req->action = req_elems[0].v.val_str; + } + req->host = req_elems[1].v.val_str; + req->port = req_elems[2].v.val_int; + req->traces_url = req_elems[3].v.val_str; + *result = req; + + if (json_obj != NULL) { + neu_json_decode_free(json_obj); + } + return ret; +} \ No newline at end of file diff --git a/src/parser/neu_json_otel.h b/src/parser/neu_json_otel.h new file mode 100644 index 000000000..2a5c9fbf4 --- /dev/null +++ b/src/parser/neu_json_otel.h @@ -0,0 +1,47 @@ +/** + * NEURON IIoT System for Industry 4.0 + * Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + **/ + +/* + * DO NOT EDIT THIS FILE MANUALLY! + * It was automatically generated by `json-autotype`. + */ + +#ifndef _NEU_JSON_API_NEU_JSON_OTEL_H_ +#define _NEU_JSON_API_NEU_JSON_OTEL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *action; + char *host; + int port; + char *traces_url; + +} neu_json_otel_conf_req_t; + +void neu_json_decode_otel_conf_req_free(neu_json_otel_conf_req_t *req); +int neu_json_decode_otel_conf_req(char *buf, neu_json_otel_conf_req_t **result); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/utils/http.c b/src/utils/http.c index 13e5b6cd2..460ebcda6 100644 --- a/src/utils/http.c +++ b/src/utils/http.c @@ -28,6 +28,7 @@ #include #include +#include "define.h" #include "errcodes.h" #include "utils/http.h" #include "utils/log.h" @@ -414,3 +415,91 @@ int neu_http_internal_error(nng_aio *aio, char *content) { return response(aio, content, NNG_HTTP_STATUS_INTERNAL_SERVER_ERROR); } + +int neu_http_post_otel_trace(uint8_t *data, int len) +{ + nng_url * url = NULL; + nng_http_client *client = NULL; + nng_aio * aio = NULL; + + nng_aio_alloc(&aio, NULL, NULL); + nng_aio_set_timeout(aio, 1000); + + char url_s[128] = { 0 }; + snprintf(url_s, sizeof(url_s), "http://%s:%d%s", otel_host, otel_port, + otel_traces_url); + if (nng_url_parse(&url, url_s) != 0) { + nng_aio_free(aio); + return -1; + } + nng_http_client_alloc(&client, url); + + nng_http_client_connect(client, aio); + + nng_aio_wait(aio); + + int rv = -1; + if ((rv = nng_aio_result(aio)) != 0) { + nlog_error("(%s)nng error: %s", url_s, nng_strerror(rv)); + nng_url_free(url); + nng_http_client_free(client); + nng_aio_free(aio); + return -1; + } + + nng_http_conn *conn = nng_aio_get_output(aio, 0); + nng_http_req * req = NULL; + nng_http_res * res = NULL; + nng_http_req_alloc(&req, url); + nng_http_req_set_method(req, "POST"); + nng_http_req_add_header(req, "Content-Type", "application/x-protobuf"); + char buf_len[32] = { 0 }; + sprintf(buf_len, "%d", len); + nng_http_req_add_header(req, "Content-Length", buf_len); + nng_http_req_set_data(req, data, len); + nng_http_conn_write_req(conn, req, aio); + nng_aio_wait(aio); + if ((rv = nng_aio_result(aio)) != 0) { + nlog_error("nng error: %s", nng_strerror(rv)); + nng_url_free(url); + nng_http_client_free(client); + nng_http_req_free(req); + nng_http_conn_close(conn); + nng_aio_free(aio); + return -1; + } + + nng_http_res_alloc(&res); + nng_http_conn_read_res(conn, res, aio); + nng_aio_wait(aio); + + if ((rv = nng_aio_result(aio)) != 0) { + nlog_error("nng error: %s", nng_strerror(rv)); + nng_url_free(url); + nng_http_client_free(client); + nng_http_req_free(req); + nng_http_res_free(res); + nng_http_conn_close(conn); + nng_aio_free(aio); + return -1; + } + + uint16_t status = nng_http_res_get_status(res); + + if (status != NNG_HTTP_STATUS_OK) { + nng_url_free(url); + nng_http_client_free(client); + nng_http_req_free(req); + nng_http_res_free(res); + nng_http_conn_close(conn); + nng_aio_free(aio); + return status; + } + nng_url_free(url); + nng_http_client_free(client); + nng_http_req_free(req); + nng_http_res_free(res); + nng_http_conn_close(conn); + nng_aio_free(aio); + return status; +} \ No newline at end of file diff --git a/tests/ft/driver/test_modbus.py b/tests/ft/driver/test_modbus.py index 1730578ac..2f143e5aa 100644 --- a/tests/ft/driver/test_modbus.py +++ b/tests/ft/driver/test_modbus.py @@ -10,6 +10,7 @@ tcp_port = random_port() rtu_port = random_port() +otel_port = random_port() def start_socat(): @@ -17,7 +18,7 @@ def start_socat(): socat_proc = subprocess.Popen( socat_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - + fl = fcntl.fcntl(socat_proc.stderr.fileno(), fcntl.F_GETFL) fcntl.fcntl(socat_proc.stderr.fileno(), fcntl.F_SETFL, fl | os.O_NONBLOCK) @@ -47,6 +48,10 @@ def param(request): @pytest.fixture(autouse=True, scope='class') def simulator_setup_teardown(param): + + otel_p = subprocess.Popen( + ["python3", "otel_server.py", f'{otel_port}'], stderr=subprocess.PIPE, cwd="simulator") + if param[0] == 'modbus-tcp': p = process.start_simulator( ['./modbus_simulator', 'tcp', f'{tcp_port}', 'ip_v4']) @@ -77,8 +82,13 @@ def simulator_setup_teardown(param): response = api.modbus_rtu_node_setting( node=param[0], interval=1, device=modbus_neuron_dev, link=0) + api.otel_start("127.0.0.1", otel_port, "/v1/traces") + yield + api.otel_stop() process.stop_simulator(p) + otel_p.terminate() + otel_p.wait() if param[0] == 'modbus-rtu-tty': socat_proc.terminate() time.sleep(2) @@ -109,35 +119,35 @@ def simulator_setup_teardown(param): "attribute": config.NEU_TAG_ATTRIBUTE_RW_SUBSCRIBE, "type": config.NEU_TYPE_DOUBLE}] hold_bit_0 = [{"name": "hold_bit_0", "address": "1!400001.0", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_1 = [{"name": "hold_bit_1", "address": "1!400001.1", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_2 = [{"name": "hold_bit_2", "address": "1!400001.2", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_3 = [{"name": "hold_bit_3", "address": "1!400001.3", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_4 = [{"name": "hold_bit_4", "address": "1!400001.4", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_5 = [{"name": "hold_bit_5", "address": "1!400001.5", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_6 = [{"name": "hold_bit_6", "address": "1!400001.6", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_7 = [{"name": "hold_bit_7", "address": "1!400001.7", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_8 = [{"name": "hold_bit_8", "address": "1!400001.8", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_9 = [{"name": "hold_bit_9", "address": "1!400001.9", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_10 = [{"name": "hold_bit_10", "address": "1!400001.10", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_11 = [{"name": "hold_bit_11", "address": "1!400001.11", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_12 = [{"name": "hold_bit_12", "address": "1!400001.12", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_13 = [{"name": "hold_bit_13", "address": "1!400001.13", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] hold_bit_14 = [{"name": "hold_bit_14", "address": "1!400001.14", - "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_READ_SUBSCRIBE, "type": config.NEU_TYPE_BIT}] coil_bit_1 = [{"name": "coil_bit_1", "address": "1!000001", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] @@ -200,9 +210,9 @@ def simulator_setup_teardown(param): hold_int16_decimal = [{"name": "hold_int16_decimal", "address": "1!40103", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "decimal": 0.1}] hold_int16_decimal_w = [{"name": "hold_int16_decimal_w", "address": "1!40103", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "decimal": 0.1}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "decimal": 0.1}] hold_int16_decimal_neg = [{"name": "int16_decimal_neg", "address": "1!40140", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "decimal": -1}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "decimal": -1}] hold_uint16_decimal = [{"name": "hold_uint16_decimal", "address": "1!400105", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16, "decimal": 0.2}] hold_int32_decimal = [{"name": "hold_int32_decimal", "address": "1!400199", @@ -222,35 +232,35 @@ def simulator_setup_teardown(param): "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_DOUBLE, "precision": 3}] hold_int16_m1 = [{"name": "hold_int16_m1", "address": "1!400301", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m2 = [{"name": "hold_int16_m2", "address": "1!400302", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m3 = [{"name": "hold_int16_m3", "address": "1!400303", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m4 = [{"name": "hold_int16_m4", "address": "1!400304", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m5 = [{"name": "hold_int16_m5", "address": "1!400305", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m6 = [{"name": "hold_int16_m6", "address": "1!400307", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m7 = [{"name": "hold_int16_m7", "address": "1!400309", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m8 = [{"name": "hold_int16_m8", "address": "1!400311", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m9 = [{"name": "hold_int16_m9", "address": "1!400313", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m10 = [{"name": "hold_int16_m10", "address": "1!400315", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m11 = [{"name": "hold_int16_m11", "address": "1!400317", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m12 = [{"name": "hold_int16_m12", "address": "1!400319", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m13 = [{"name": "hold_int16_m13", "address": "1!400321", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m14 = [{"name": "hold_int16_m14", "address": "1!400323", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_m15 = [{"name": "hold_int16_m15", "address": "1!400325", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] coil_bit_m1 = [{"name": "coil_bit_m1", "address": "1!000101", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] @@ -271,55 +281,55 @@ def simulator_setup_teardown(param): coil_bit_m9 = [{"name": "coil_bit_m9", "address": "1!000113", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] coil_bit_m10 = [{"name": "coil_bit_m10", "address": "1!000115", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] coil_bit_m11 = [{"name": "coil_bit_m11", "address": "1!000117", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] coil_bit_m12 = [{"name": "coil_bit_m12", "address": "1!000119", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] coil_bit_m13 = [{"name": "coil_bit_m13", "address": "1!000121", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] coil_bit_m14 = [{"name": "coil_bit_m14", "address": "1!000123", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] coil_bit_m15 = [{"name": "coil_bit_m15", "address": "1!000125", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT}] hold_int16_retry_1 = [{"name": "hold_int16_retry_1", "address": "1!408000", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_retry_2 = [{"name": "hold_int16_retry_2", "address": "1!408005", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_B = [{"name": "hold_int16_B", "address": "1!400401#B", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int16_L = [{"name": "hold_int16_L", "address": "1!400402#L", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_int32_LL = [{"name": "hold_int32_LL", "address": "1!400403#LL", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] hold_int32_LB = [{"name": "hold_int32_LB", "address": "1!400405#LB", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] hold_int32_BL = [{"name": "hold_int32_BL", "address": "1!400407#BL", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] hold_int32_BB = [{"name": "hold_int32_BB", "address": "1!400409#BB", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32}] hold_uint16_B = [{"name": "hold_uint16_B", "address": "1!400411#B", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] hold_uint16_L = [{"name": "hold_uint16_L", "address": "1!400412#L", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] hold_uint32_LL = [{"name": "hold_uint32_LL", "address": "1!400413#LL", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] hold_uint32_LB = [{"name": "hold_uint32_LB", "address": "1!400415#LB", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] hold_uint32_BL = [{"name": "hold_uint32_BL", "address": "1!400417#BL", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] hold_uint32_BB = [{"name": "hold_uint32_BB", "address": "1!400419#BB", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32}] hold_float_LL = [{"name": "hold_float_LL", "address": "1!400421#LL", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] hold_float_LB = [{"name": "hold_float_LB", "address": "1!400423#LB", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] hold_float_BL = [{"name": "hold_float_BL", "address": "1!400425#BL", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] hold_float_BB = [{"name": "hold_float_BB", "address": "1!400427#BB", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT}] hold_int64_B = [{"name": "hold_int64_B", "address": "1!400429#B", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT64}] hold_int64_L = [{"name": "hold_int64_L", "address": "1!400433#L", @@ -333,44 +343,45 @@ def simulator_setup_teardown(param): hold_double_L = [{"name": "hold_double_L", "address": "1!400449#L", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_DOUBLE}] hold_string_H = [{"name": "hold_string_H", "address": "1!400710.4H", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] hold_string_L = [{"name": "hold_string_L", "address": "1!400710.4L", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] hold_string_l1 = [{"name": "hold_string_l1", "address": "1!400501.127", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] hold_string_l2 = [{"name": "hold_string_l2", "address": "1!400628.127", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] hold_int16_device_err = [{"name": "hold_int16_device_err", "address": "1!409000", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16}] hold_uint16_utf8 = [{"name": "hold_uint16_utf8", "address": "1!401100", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16}] hold_string_utf8 = [{"name": "hold_string_utf8", "address": "1!401100.4", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] - -test_hold_int16 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400001", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "precision": 0, "decimal": 0, "bias": 0.0} -test_hold_uint16 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400002", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16, "precision": 0, "decimal": 0, "bias": 0.0} -test_hold_int32 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400003", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32, "precision": 0, "decimal": 0, "bias": 0.0} -test_hold_uint32 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400015", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32, "precision": 0, "decimal": 0, "bias": 0.0} -test_hold_float = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400017", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT, "precision": 0, "decimal": 0, "bias": 0.0} -test_hold_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400001.15", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING}] + +test_hold_int16 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400001", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT16, "precision": 0, "decimal": 0, "bias": 0.0} +test_hold_uint16 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400002", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT16, "precision": 0, "decimal": 0, "bias": 0.0} +test_hold_int32 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400003", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_INT32, "precision": 0, "decimal": 0, "bias": 0.0} +test_hold_uint32 = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400015", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_UINT32, "precision": 0, "decimal": 0, "bias": 0.0} +test_hold_float = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400017", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_FLOAT, "precision": 0, "decimal": 0, "bias": 0.0} +test_hold_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400001.15", "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT, "precision": 0, "decimal": 0, "bias": 0.0} -test_hold_string = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400020.10", - "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING, "precision": 0, "decimal": 0, "bias": 0.0} -test_coil_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!000001", +test_hold_string = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!400020.10", + "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_STRING, "precision": 0, "decimal": 0, "bias": 0.0} +test_coil_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!000001", "attribute": config.NEU_TAG_ATTRIBUTE_RW, "type": config.NEU_TYPE_BIT, "precision": 0, "decimal": 0, "bias": 0.0} -test_input_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!100001", - "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT, "precision": 0, "decimal": 0, "bias": 0.0} +test_input_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!100001", + "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT, "precision": 0, "decimal": 0, "bias": 0.0} test_input_register_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!30010.0", "attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT, "precision": 0, "decimal": 0, "bias": 0.0} + class TestModbus: @description(given="created modbus node", when="add multiple tags", then="add success") @@ -500,15 +511,24 @@ def test_add_read_static_tags(self, param): response = api.get_tags(node=param[0], group="group") assert 200 == response.status_code - assert 1 == api.read_tag(node=param[0], group='group', tag=hold_int16_s[0]['name']) - assert 1 == api.read_tag(node=param[0], group='group', tag=hold_uint16_s[0]['name']) - assert 1 == api.read_tag(node=param[0], group='group', tag=hold_int32_s[0]['name']) - assert 1 == api.read_tag(node=param[0], group='group', tag=hold_uint32_s[0]['name']) - assert 1 == api.read_tag(node=param[0], group='group', tag=hold_int64_s[0]['name']) - assert 1 == api.read_tag(node=param[0], group='group', tag=hold_uint64_s[0]['name']) - assert 1.0 == api.read_tag(node=param[0], group='group', tag=hold_float_s[0]['name']) - assert 1.0 == api.read_tag(node=param[0], group='group', tag=hold_double_s[0]['name']) - assert 'a' == api.read_tag(node=param[0], group='group', tag=hold_string_s[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=hold_int16_s[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=hold_uint16_s[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=hold_int32_s[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=hold_uint32_s[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=hold_int64_s[0]['name']) + assert 1 == api.read_tag( + node=param[0], group='group', tag=hold_uint64_s[0]['name']) + assert 1.0 == api.read_tag( + node=param[0], group='group', tag=hold_float_s[0]['name']) + assert 1.0 == api.read_tag( + node=param[0], group='group', tag=hold_double_s[0]['name']) + assert 'a' == api.read_tag( + node=param[0], group='group', tag=hold_string_s[0]['name']) @description(given="created modbus node", when="add wrong tags", then="add failed") def test_add_wrong_tags(self, param): @@ -547,46 +567,65 @@ def test_add_wrong_tags(self, param): assert 400 == response.status_code assert error.NEU_ERR_TAG_ADDRESS_FORMAT_INVALID == response.json()[ 'error'] - + @description(given="created modbus node and tags", when="write tags with invalid value", then="write failed") def test_write_tags_invalid_value(self, param): - response = api.write_tag(node=param[0], group='group', tag=hold_int16[0]['name'], value=32768) + response = api.write_tag( + node=param[0], group='group', tag=hold_int16[0]['name'], value=32768) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=hold_uint16[0]['name'], value=-1) + response = api.write_tag( + node=param[0], group='group', tag=hold_uint16[0]['name'], value=-1) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=hold_int32[0]['name'], value=2147483648) + response = api.write_tag( + node=param[0], group='group', tag=hold_int32[0]['name'], value=2147483648) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=hold_uint32[0]['name'], value=-1) + response = api.write_tag( + node=param[0], group='group', tag=hold_uint32[0]['name'], value=-1) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=hold_string[0]['name'], value=1) + response = api.write_tag( + node=param[0], group='group', tag=hold_string[0]['name'], value=1) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=coil_bit_1[0]['name'], value=2) + response = api.write_tag( + node=param[0], group='group', tag=coil_bit_1[0]['name'], value=2) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=coil_bit_1[0]['name'], value=True) + response = api.write_tag( + node=param[0], group='group', tag=coil_bit_1[0]['name'], value=True) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()[ + 'error'] - api.add_tags_check(node=param[0], group='group', tags=hold_int16_decimal_w) + api.add_tags_check( + node=param[0], group='group', tags=hold_int16_decimal_w) - response = api.write_tag(node=param[0], group='group', tag=hold_int16_decimal_w[0]['name'], value=1.11) + response = api.write_tag( + node=param[0], group='group', tag=hold_int16_decimal_w[0]['name'], value=1.11) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()[ + 'error'] - response = api.write_tag(node=param[0], group='group', tag=hold_float[0]['name'], value=1) + response = api.write_tag( + node=param[0], group='group', tag=hold_float[0]['name'], value=1) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH == response.json()[ + 'error'] response = api.write_tags(node=param[0], group='group', tag_values=[ {"tag": hold_int16[0]['name'], "value": 32768}, @@ -594,7 +633,8 @@ def test_write_tags_invalid_value(self, param): {"tag": hold_int32[0]['name'], "value": 3}, {"tag": hold_uint32[0]['name'], "value": 4}]) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] response = api.write_tags(node=param[0], group='group', tag_values=[ {"tag": hold_int16[0]['name'], "value": 1}, @@ -602,7 +642,8 @@ def test_write_tags_invalid_value(self, param): {"tag": hold_int32[0]['name'], "value": 3}, {"tag": hold_uint32[0]['name'], "value": 4}]) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] response = api.write_tags(node=param[0], group='group', tag_values=[ {"tag": hold_int16[0]['name'], "value": 1}, @@ -610,7 +651,8 @@ def test_write_tags_invalid_value(self, param): {"tag": hold_int32[0]['name'], "value": 2147483648}, {"tag": hold_uint32[0]['name'], "value": 4}]) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] response = api.write_tags(node=param[0], group='group', tag_values=[ {"tag": hold_int16[0]['name'], "value": 1}, @@ -618,31 +660,36 @@ def test_write_tags_invalid_value(self, param): {"tag": hold_int32[0]['name'], "value": 3}, {"tag": hold_uint32[0]['name'], "value": -1}]) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags" : [{"tag": "hold_int16", "value": 32768}, - {"tag": "hold_uint16", "value": 2}, {"tag": "hold_int32", "value": 3}, {"tag": "hold_uint32", "value": 4}]}]} + modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags": [{"tag": "hold_int16", "value": 32768}, + {"tag": "hold_uint16", "value": 2}, {"tag": "hold_int32", "value": 3}, {"tag": "hold_uint32", "value": 4}]}]} response = api.write_gtags(json=modbus_write_gtags) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags" : [{"tag": "hold_int16", "value": 1}, - {"tag": "hold_uint16", "value": -1}, {"tag": "hold_int32", "value": 3}, {"tag": "hold_uint32", "value": 4}]}]} + modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags": [{"tag": "hold_int16", "value": 1}, + {"tag": "hold_uint16", "value": -1}, {"tag": "hold_int32", "value": 3}, {"tag": "hold_uint32", "value": 4}]}]} response = api.write_gtags(json=modbus_write_gtags) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags" : [{"tag": "hold_int16", "value": 1}, - {"tag": "hold_uint16", "value": 2}, {"tag": "hold_int32", "value": 2147483648}, {"tag": "hold_uint32", "value": 4}]}]} + modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags": [{"tag": "hold_int16", "value": 1}, + {"tag": "hold_uint16", "value": 2}, {"tag": "hold_int32", "value": 2147483648}, {"tag": "hold_uint32", "value": 4}]}]} response = api.write_gtags(json=modbus_write_gtags) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] - modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags" : [{"tag": "hold_int16", "value": 1}, - {"tag": "hold_uint16", "value": 2}, {"tag": "hold_int32", "value": 3}, {"tag": "hold_uint32", "value": -1}]}]} + modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags": [{"tag": "hold_int16", "value": 1}, + {"tag": "hold_uint16", "value": 2}, {"tag": "hold_int32", "value": 3}, {"tag": "hold_uint32", "value": -1}]}]} response = api.write_gtags(json=modbus_write_gtags) assert 400 == response.status_code - assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()['error'] + assert error.NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE == response.json()[ + 'error'] @description(given="created modbus node and tags", when="write/read tags", then="write/read success") def test_write_read_tags(self, param): @@ -768,31 +815,42 @@ def test_modbus_test_read_tag(self, param): "precision": 0, "decimal": 0, "bias": 0.0 - } + } response = api.test_read_tag(json=body) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_NOT_SUPPORT_TEST_READ_TAG + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_NOT_SUPPORT_TEST_READ_TAG """ simulator of modbus tcp stopped """ response = api.test_read_tag(json=test_hold_bit) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_hold_int16) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_hold_uint16) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_hold_int32) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_hold_uint32) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_hold_float) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_hold_string) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_coil_bit) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_input_bit) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE response = api.test_read_tag(json=test_input_register_bit) - assert response.json()["error"] == error.NEU_ERR_PLUGIN_READ_FAILURE + assert response.json()[ + "error"] == error.NEU_ERR_PLUGIN_READ_FAILURE @description(given="created modbus node and tags", when="read tags", then="read success") def test_read_tags(self, param): @@ -983,12 +1041,14 @@ def test_read_write_tag_stopped_node(self, param): @description(given="created modbus node", when="create group with invalid configuration", then="create failed") def test_config_group_with_invalid_configuration(self, param): - response = api.add_group(node=param[0], group='group_config_test', interval = 0) + response = api.add_group( + node=param[0], group='group_config_test', interval=0) assert 400 == response.status_code assert error.NEU_ERR_GROUP_PARAMETER_INVALID == response.json()[ 'error'] - - response = api.add_group(node=param[0], group='group_config_test', interval = -1) + + response = api.add_group( + node=param[0], group='group_config_test', interval=-1) assert 400 == response.status_code assert error.NEU_ERR_GROUP_PARAMETER_INVALID == response.json()[ 'error'] @@ -1120,11 +1180,13 @@ def test_read_decimal_bias_tag_i(self, param): grp = "group-bias" api.add_group_check(node=param[0], group=grp, interval=100) api.add_tags_check(node=param[0], group=grp, tags=tags) - api.write_tags_check(node=param[0], group=grp, tag_values=tag_values) + api.write_tags_check( + node=param[0], group=grp, tag_values=tag_values) # 2. read value + bias api.update_tags_check(node=param[0], group=grp, tags=tags_bias) time.sleep(0.3) - resp_values = api.read_tags(node=param[0], group=grp).json()['tags'] + resp_values = api.read_tags( + node=param[0], group=grp).json()['tags'] assert len(tag_values) == len(resp_values) for tag, value, resp in zip(tags_bias, tag_values, resp_values): expected = value['value'] + tag['bias'] @@ -1133,7 +1195,8 @@ def test_read_decimal_bias_tag_i(self, param): api.update_tags_check( node=param[0], group=grp, tags=tags_decimal_bias) time.sleep(0.3) - resp_values = api.read_tags(node=param[0], group=grp).json()['tags'] + resp_values = api.read_tags( + node=param[0], group=grp).json()['tags'] assert len(tag_values) == len(resp_values) for tag, value, resp in zip(tags_decimal_bias, tag_values, resp_values): expected = value['value'] * tag['decimal'] + tag['bias'] @@ -1184,11 +1247,13 @@ def test_read_decimal_bias_tag_f(self, param): grp = "group-bias" api.add_group_check(node=param[0], group=grp, interval=100) api.add_tags_check(node=param[0], group=grp, tags=tags) - api.write_tags_check(node=param[0], group=grp, tag_values=tag_values) + api.write_tags_check( + node=param[0], group=grp, tag_values=tag_values) # 2. read value + bias api.update_tags_check(node=param[0], group=grp, tags=tags_bias) time.sleep(0.3) - resp_values = api.read_tags(node=param[0], group=grp).json()['tags'] + resp_values = api.read_tags( + node=param[0], group=grp).json()['tags'] assert len(tag_values) == len(resp_values) for tag, value, resp in zip(tags_bias, tag_values, resp_values): expected = value['value'] + tag['bias'] @@ -1197,7 +1262,8 @@ def test_read_decimal_bias_tag_f(self, param): api.update_tags_check( node=param[0], group=grp, tags=tags_decimal_bias) time.sleep(0.3) - resp_values = api.read_tags(node=param[0], group=grp).json()['tags'] + resp_values = api.read_tags( + node=param[0], group=grp).json()['tags'] assert len(tag_values) == len(resp_values) for tag, value, resp in zip(tags_decimal_bias, tag_values, resp_values): expected = value['value'] * tag['decimal'] + tag['bias'] @@ -1229,16 +1295,16 @@ def test_read_write_precision_tag(self, param): def test_write_multiple_hold_tags_partially_continuous(self, param): api.write_tags_check( node=param[0], group='group', tag_values=[ - {"tag": hold_int16_m1[0]['name'], "value": 1}, - {"tag": hold_int16_m2[0]['name'], "value": 2}, - {"tag": hold_int16_m3[0]['name'], "value": 3}, - {"tag": hold_int16_m4[0]['name'], "value": 4}, - {"tag": hold_int16_m5[0]['name'], "value": 5}, - {"tag": hold_int16_m6[0]['name'], "value": 6}, - {"tag": hold_int16_m7[0]['name'], "value": 7}, - {"tag": hold_int16_m8[0]['name'], "value": 8}, - {"tag": hold_int16_m9[0]['name'], "value": 9}, - {"tag": hold_int16_m10[0]['name'], "value": 10}]) + {"tag": hold_int16_m1[0]['name'], "value": 1}, + {"tag": hold_int16_m2[0]['name'], "value": 2}, + {"tag": hold_int16_m3[0]['name'], "value": 3}, + {"tag": hold_int16_m4[0]['name'], "value": 4}, + {"tag": hold_int16_m5[0]['name'], "value": 5}, + {"tag": hold_int16_m6[0]['name'], "value": 6}, + {"tag": hold_int16_m7[0]['name'], "value": 7}, + {"tag": hold_int16_m8[0]['name'], "value": 8}, + {"tag": hold_int16_m9[0]['name'], "value": 9}, + {"tag": hold_int16_m10[0]['name'], "value": 10}]) time.sleep(0.3) assert 1 == api.read_tag( node=param[0], group='group', tag=hold_int16_m1[0]['name']) @@ -1265,16 +1331,16 @@ def test_write_multiple_hold_tags_partially_continuous(self, param): def test_write_multiple_hold_tags_discontinuous(self, param): api.write_tags_check( node=param[0], group='group', tag_values=[ - {"tag": hold_int16_m6[0]['name'], "value": 11}, - {"tag": hold_int16_m7[0]['name'], "value": 12}, - {"tag": hold_int16_m8[0]['name'], "value": 13}, - {"tag": hold_int16_m9[0]['name'], "value": 14}, - {"tag": hold_int16_m10[0]['name'], "value": 15}, - {"tag": hold_int16_m11[0]['name'], "value": 16}, - {"tag": hold_int16_m12[0]['name'], "value": 17}, - {"tag": hold_int16_m13[0]['name'], "value": 18}, - {"tag": hold_int16_m14[0]['name'], "value": 19}, - {"tag": hold_int16_m15[0]['name'], "value": 20}]) + {"tag": hold_int16_m6[0]['name'], "value": 11}, + {"tag": hold_int16_m7[0]['name'], "value": 12}, + {"tag": hold_int16_m8[0]['name'], "value": 13}, + {"tag": hold_int16_m9[0]['name'], "value": 14}, + {"tag": hold_int16_m10[0]['name'], "value": 15}, + {"tag": hold_int16_m11[0]['name'], "value": 16}, + {"tag": hold_int16_m12[0]['name'], "value": 17}, + {"tag": hold_int16_m13[0]['name'], "value": 18}, + {"tag": hold_int16_m14[0]['name'], "value": 19}, + {"tag": hold_int16_m15[0]['name'], "value": 20}]) time.sleep(0.3) assert 11 == api.read_tag( node=param[0], group='group', tag=hold_int16_m6[0]['name']) @@ -1301,16 +1367,16 @@ def test_write_multiple_hold_tags_discontinuous(self, param): def test_write_multiple_coil_tags_partially_continuous(self, param): api.write_tags_check( node=param[0], group='group', tag_values=[ - {"tag": coil_bit_m1[0]['name'], "value": 0}, - {"tag": coil_bit_m2[0]['name'], "value": 1}, - {"tag": coil_bit_m3[0]['name'], "value": 0}, - {"tag": coil_bit_m4[0]['name'], "value": 1}, - {"tag": coil_bit_m5[0]['name'], "value": 0}, - {"tag": coil_bit_m6[0]['name'], "value": 1}, - {"tag": coil_bit_m7[0]['name'], "value": 0}, - {"tag": coil_bit_m8[0]['name'], "value": 1}, - {"tag": coil_bit_m9[0]['name'], "value": 0}, - {"tag": coil_bit_m10[0]['name'], "value": 1}]) + {"tag": coil_bit_m1[0]['name'], "value": 0}, + {"tag": coil_bit_m2[0]['name'], "value": 1}, + {"tag": coil_bit_m3[0]['name'], "value": 0}, + {"tag": coil_bit_m4[0]['name'], "value": 1}, + {"tag": coil_bit_m5[0]['name'], "value": 0}, + {"tag": coil_bit_m6[0]['name'], "value": 1}, + {"tag": coil_bit_m7[0]['name'], "value": 0}, + {"tag": coil_bit_m8[0]['name'], "value": 1}, + {"tag": coil_bit_m9[0]['name'], "value": 0}, + {"tag": coil_bit_m10[0]['name'], "value": 1}]) time.sleep(0.3) assert 0 == api.read_tag( node=param[0], group='group', tag=coil_bit_m1[0]['name']) @@ -1337,16 +1403,16 @@ def test_write_multiple_coil_tags_partially_continuous(self, param): def test_write_multiple_coil_tags_discontinuous(self, param): api.write_tags_check( node=param[0], group='group', tag_values=[ - {"tag": coil_bit_m6[0]['name'], "value": 0}, - {"tag": coil_bit_m7[0]['name'], "value": 1}, - {"tag": coil_bit_m8[0]['name'], "value": 0}, - {"tag": coil_bit_m9[0]['name'], "value": 1}, - {"tag": coil_bit_m10[0]['name'], "value": 0}, - {"tag": coil_bit_m11[0]['name'], "value": 1}, - {"tag": coil_bit_m12[0]['name'], "value": 0}, - {"tag": coil_bit_m13[0]['name'], "value": 1}, - {"tag": coil_bit_m14[0]['name'], "value": 0}, - {"tag": coil_bit_m15[0]['name'], "value": 1}]) + {"tag": coil_bit_m6[0]['name'], "value": 0}, + {"tag": coil_bit_m7[0]['name'], "value": 1}, + {"tag": coil_bit_m8[0]['name'], "value": 0}, + {"tag": coil_bit_m9[0]['name'], "value": 1}, + {"tag": coil_bit_m10[0]['name'], "value": 0}, + {"tag": coil_bit_m11[0]['name'], "value": 1}, + {"tag": coil_bit_m12[0]['name'], "value": 0}, + {"tag": coil_bit_m13[0]['name'], "value": 1}, + {"tag": coil_bit_m14[0]['name'], "value": 0}, + {"tag": coil_bit_m15[0]['name'], "value": 1}]) time.sleep(0.3) assert 0 == api.read_tag( node=param[0], group='group', tag=coil_bit_m6[0]['name']) @@ -1405,12 +1471,12 @@ def test_read_write_tag_order(self, param): node=param[0], group='group', tag=hold_float_BL[0]['name'], value=123.4) api.write_tag_check( node=param[0], group='group', tag=hold_float_BB[0]['name'], value=123.4) - + api.write_tag_check( node=param[0], group='group', tag=hold_string_H[0]['name'], value='abcd') time.sleep(0.3) - assert 1234== api.read_tag( + assert 1234 == api.read_tag( node=param[0], group='group', tag=hold_int16_B[0]['name']) assert 1234 == api.read_tag( node=param[0], group='group', tag=hold_int16_L[0]['name']) @@ -1423,7 +1489,7 @@ def test_read_write_tag_order(self, param): assert 12345678 == api.read_tag( node=param[0], group='group', tag=hold_int32_BB[0]['name']) - assert 1234== api.read_tag( + assert 1234 == api.read_tag( node=param[0], group='group', tag=hold_uint16_B[0]['name']) assert 1234 == api.read_tag( node=param[0], group='group', tag=hold_uint16_L[0]['name']) @@ -1444,7 +1510,7 @@ def test_read_write_tag_order(self, param): node=param[0], group='group', tag=hold_float_BL[0]['name'])) assert compare_float(123.4, api.read_tag( node=param[0], group='group', tag=hold_float_BB[0]['name'])) - + assert "abcd" == api.read_tag( node=param[0], group='group', tag=hold_string_H[0]['name']) assert "badc" == api.read_tag( @@ -1464,12 +1530,12 @@ def test_read_tag_length_exceeds_250(self, param): node=param[0], group='group', tag=hold_string_l1[0]['name']) assert 'b' == api.read_tag( node=param[0], group='group', tag=hold_string_l2[0]['name']) - + @description(given="created modbus node ,groups and tags", when="write/read gtags", then="write/read success") def test_write_read_gtags(self, param): - modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags" : [{"tag": "hold_uint16", "value": 1}, {"tag": "hold_string", "value": 'hello'}, - {"tag": "coil_bit_1", "value": 1}, {"tag": "hold_double_decimal", "value": 513.11}, {"tag": "hold_bytes", "value": [0x1, 0x2, 0x3, 0x4]}]}, - {"group": "group1", "tags" : [{"tag": "hold_int16", "value": 1}]}]} + modbus_write_gtags = {"node": param[0], "groups": [{"group": "group", "tags": [{"tag": "hold_uint16", "value": 1}, {"tag": "hold_string", "value": 'hello'}, + {"tag": "coil_bit_1", "value": 1}, {"tag": "hold_double_decimal", "value": 513.11}, {"tag": "hold_bytes", "value": [0x1, 0x2, 0x3, 0x4]}]}, + {"group": "group1", "tags": [{"tag": "hold_int16", "value": 1}]}]} response = api.write_gtags(json=modbus_write_gtags) assert 200 == response.status_code assert error.NEU_ERR_SUCCESS == response.json()['error'] @@ -1483,7 +1549,8 @@ def test_write_read_gtags(self, param): def test_read_modbus_device_err(self, param): if param[0] == 'modbus-rtu-tty': pytest.skip("modbus rtu tty pass") - api.add_tags_check(node=param[0], group='group', tags=hold_int16_device_err) + api.add_tags_check( + node=param[0], group='group', tags=hold_int16_device_err) time.sleep(4.0) assert error.NEU_ERR_PLUGIN_READ_FAILURE == api.read_tag_err( node=param[0], group='group', tag=hold_int16_device_err[0]['name']) @@ -1492,7 +1559,8 @@ def test_read_modbus_device_err(self, param): def test_read_tag_retry(self, param): if param[0] == 'modbus-rtu-tty': pytest.skip("modbus rtu tty pass") - api.add_tags_check(node=param[0], group='group', tags=hold_int16_retry_2) + api.add_tags_check( + node=param[0], group='group', tags=hold_int16_retry_2) api.write_tag_check( node=param[0], group='group', tag=hold_int16_retry_2[0]['name'], value=222) time.sleep(0.5) @@ -1515,7 +1583,8 @@ def test_write_read_modbus_disconnected(self, param): response = api.add_group(node=param[0]+"_3002", group='group') assert 200 == response.status_code - api.add_tags_check(node=param[0]+"_3002", group='group', tags=hold_int16) + api.add_tags_check(node=param[0]+"_3002", + group='group', tags=hold_int16) time.sleep(0.3) assert error.NEU_ERR_PLUGIN_DISCONNECTED == api.read_tag_err( node=param[0]+"_3002", group='group', tag=hold_int16[0]['name']) @@ -1532,4 +1601,4 @@ def test_set_modbus_tcp_server_mode(self, param): pytest.skip("modbus rtu tty pass") assert 200 == response.status_code - assert error.NEU_ERR_SUCCESS == response.json()['error'] \ No newline at end of file + assert error.NEU_ERR_SUCCESS == response.json()['error'] diff --git a/tests/ft/neuron/api.py b/tests/ft/neuron/api.py index 27f6847e1..1ce8237c0 100644 --- a/tests/ft/neuron/api.py +++ b/tests/ft/neuron/api.py @@ -228,16 +228,16 @@ def read_tag_err(node, group, tag, sync=False): @gen_check def write_tag(node, group, tag, value): - return requests.post(url=config.BASE_URL + "/api/v2/write", headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "tag": tag, "value": value}) + return requests.post(url=config.BASE_URL + "/api/v2/write", headers={"Authorization": config.default_jwt, "traceparent": "00-6fb7651916cd43dd8448eb211c80319c-c7ad6b7169203331-01"}, json={"node": node, "group": group, "tag": tag, "value": value}) @gen_check def write_tags(node, group, tag_values): - return requests.post(url=config.BASE_URL + "/api/v2/write/tags", headers={"Authorization": config.default_jwt}, json={"node": node, "group": group, "tags": tag_values}) + return requests.post(url=config.BASE_URL + "/api/v2/write/tags", headers={"Authorization": config.default_jwt, "traceparent": "00-6fb7651916cd43dd8448eb211c80319c-c7ad6b7169203331-01"}, json={"node": node, "group": group, "tags": tag_values}) def write_gtags(json): - return requests.post(url=config.BASE_URL + "/api/v2/write/gtags", headers={"Authorization": config.default_jwt}, json=json) + return requests.post(url=config.BASE_URL + "/api/v2/write/gtags", headers={"Authorization": config.default_jwt, "traceparent": "00-6fb7651916cd43dd8448eb211c80319c-c7ad6b7169203331-01"}, json=json) def add_plugin(library_name, so_file, schema_file): @@ -388,3 +388,11 @@ def get_nodes_disable_auth(type): @gen_check def scan_tags(node, id, ctx=""): return requests.post(url=config.BASE_URL + "/api/v2/scan/tags", headers={"Authorization": config.default_jwt}, json={"node": node, "id": id, "ctx": ctx}) + + +def otel_start(host, port, traces_url): + return requests.post(url=config.BASE_URL + "/api/v2/otel", headers={"Authorization": config.default_jwt}, json={"action": "start", "host": host, "port": port, "traces_url": traces_url}) + + +def otel_stop(): + return requests.post(url=config.BASE_URL + "/api/v2/otel", headers={"Authorization": config.default_jwt}, json={"action": "stop"})