From 4c6e09f4d959a874c8c8f01d13949ca639fc39c3 Mon Sep 17 00:00:00 2001 From: duncanpo Date: Wed, 25 Oct 2023 10:06:48 -0400 Subject: [PATCH 1/5] Revert "Merge branch 'metrics' into changes_after_v_1_3_0" This reverts commit 083ee564ffc9c07ee4e0fbda4131753eaa0aec34, reversing changes made to 99894413e8034fb825f8ea91f60e6ddd46f2cda1. --- CMakeLists.txt | 18 +- OtelMatlabProxyFactory.cpp | 4 - api/metrics/+opentelemetry/+metrics/Counter.m | 59 --- .../+opentelemetry/+metrics/Histogram.m | 55 --- api/metrics/+opentelemetry/+metrics/Meter.m | 89 ----- .../+opentelemetry/+metrics/UpDownCounter.m | 58 --- .../metrics/CounterProxy.h | 33 -- .../metrics/HistogramProxy.h | 36 -- .../opentelemetry-matlab/metrics/MeterProxy.h | 36 -- .../metrics/UpDownCounterProxy.h | 33 -- api/metrics/src/CounterProxy.cpp | 41 -- api/metrics/src/HistogramProxy.cpp | 44 --- api/metrics/src/MeterProxy.cpp | 88 ----- api/metrics/src/UpDownCounterProxy.cpp | 41 -- .../+sdk/+metrics/MeterProvider.m | 56 --- .../sdk/metrics/MeterProviderProxy.h | 48 --- sdk/metrics/src/MeterProviderProxy.cpp | 54 --- test/tmetrics.m | 364 ------------------ 18 files changed, 1 insertion(+), 1156 deletions(-) delete mode 100644 api/metrics/+opentelemetry/+metrics/Counter.m delete mode 100644 api/metrics/+opentelemetry/+metrics/Histogram.m delete mode 100644 api/metrics/+opentelemetry/+metrics/Meter.m delete mode 100644 api/metrics/+opentelemetry/+metrics/UpDownCounter.m delete mode 100644 api/metrics/include/opentelemetry-matlab/metrics/CounterProxy.h delete mode 100644 api/metrics/include/opentelemetry-matlab/metrics/HistogramProxy.h delete mode 100644 api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h delete mode 100644 api/metrics/include/opentelemetry-matlab/metrics/UpDownCounterProxy.h delete mode 100644 api/metrics/src/CounterProxy.cpp delete mode 100644 api/metrics/src/HistogramProxy.cpp delete mode 100644 api/metrics/src/MeterProxy.cpp delete mode 100644 api/metrics/src/UpDownCounterProxy.cpp delete mode 100644 sdk/metrics/+opentelemetry/+sdk/+metrics/MeterProvider.m delete mode 100644 sdk/metrics/include/opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h delete mode 100644 sdk/metrics/src/MeterProviderProxy.cpp delete mode 100644 test/tmetrics.m diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ee427c..1b9f509 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,25 +188,21 @@ if(WITH_OTLP_GRPC) endif() set(TRACE_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/include) -set(METRICS_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/metrics/include) set(CONTEXT_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/context/include) set(BAGGAGE_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/baggage/include) set(COMMON_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/common/include) set(TRACE_SDK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/trace/include) -set(METRICS_SDK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/metrics/include) set(COMMON_SDK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/common/include) set(OTLP_EXPORTER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/include) -set(OPENTELEMETRY_PROXY_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${TRACE_API_INCLUDE_DIR} ${METRICS_API_INCLUDE_DIR} ${CONTEXT_API_INCLUDE_DIR} ${BAGGAGE_API_INCLUDE_DIR} ${COMMON_API_INCLUDE_DIR} ${TRACE_SDK_INCLUDE_DIR} ${METRICS_SDK_INCLUDE_DIR} ${COMMON_SDK_INCLUDE_DIR} ${OTLP_EXPORTER_INCLUDE_DIR} ${OTEL_CPP_PREFIX}/include) +set(OPENTELEMETRY_PROXY_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${TRACE_API_INCLUDE_DIR} ${CONTEXT_API_INCLUDE_DIR} ${BAGGAGE_API_INCLUDE_DIR} ${COMMON_API_INCLUDE_DIR} ${TRACE_SDK_INCLUDE_DIR} ${COMMON_SDK_INCLUDE_DIR} ${OTLP_EXPORTER_INCLUDE_DIR} ${OTEL_CPP_PREFIX}/include) set(OPENTELEMETRY_PROXY_FACTORY_CLASS_NAME OtelMatlabProxyFactory) set(OPENTELEMETRY_PROXY_FACTORY_SOURCES_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(TRACE_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/src) -set(METRICS_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/metrics/src) set(CONTEXT_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/context/src) set(BAGGAGE_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/baggage/src) set(COMMON_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/common/src) set(TRACE_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/trace/src) -set(METRICS_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/metrics/src) set(COMMON_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/common/src) set(OTLP_EXPORTER_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/src) set(OPENTELEMETRY_PROXY_SOURCES @@ -216,10 +212,6 @@ set(OPENTELEMETRY_PROXY_SOURCES ${TRACE_API_SOURCE_DIR}/SpanProxy.cpp ${TRACE_API_SOURCE_DIR}/SpanContextProxy.cpp ${COMMON_API_SOURCE_DIR}/attribute.cpp - ${METRICS_API_SOURCE_DIR}/MeterProxy.cpp - ${METRICS_API_SOURCE_DIR}/CounterProxy.cpp - ${METRICS_API_SOURCE_DIR}/UpDownCounterProxy.cpp - ${METRICS_API_SOURCE_DIR}/HistogramProxy.cpp ${CONTEXT_API_SOURCE_DIR}/TextMapPropagatorProxy.cpp ${CONTEXT_API_SOURCE_DIR}/CompositePropagatorProxy.cpp ${CONTEXT_API_SOURCE_DIR}/TextMapCarrierProxy.cpp @@ -229,7 +221,6 @@ set(OPENTELEMETRY_PROXY_SOURCES ${TRACE_SDK_SOURCE_DIR}/SimpleSpanProcessorProxy.cpp ${TRACE_SDK_SOURCE_DIR}/BatchSpanProcessorProxy.cpp ${TRACE_SDK_SOURCE_DIR}/ParentBasedSamplerProxy.cpp - ${METRICS_SDK_SOURCE_DIR}/MeterProviderProxy.cpp ${COMMON_SDK_SOURCE_DIR}/resource.cpp) if(WITH_OTLP_HTTP) set(OPENTELEMETRY_PROXY_SOURCES ${OPENTELEMETRY_PROXY_SOURCES} @@ -286,19 +277,16 @@ set(OTEL_CPP_LINK_LIBRARIES ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_trace${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_version${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_logs${CMAKE_STATIC_LIBRARY_SUFFIX} - ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_metrics${CMAKE_STATIC_LIBRARY_SUFFIX} ${Protobuf_LIBRARIES}) if(WITH_OTLP_HTTP) set(OTEL_CPP_LINK_LIBRARIES ${OTEL_CPP_LINK_LIBRARIES} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_http${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_http_client${CMAKE_STATIC_LIBRARY_SUFFIX} - ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_http_metric${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_http_client_curl${CMAKE_STATIC_LIBRARY_SUFFIX} ${CURL_LIBRARIES}) endif() if(WITH_OTLP_GRPC) set(OTEL_CPP_LINK_LIBRARIES ${OTEL_CPP_LINK_LIBRARIES} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_grpc${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_grpc_client${CMAKE_STATIC_LIBRARY_SUFFIX} - ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_grpc_metrics${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}opentelemetry_proto_grpc${OTEL_PROTO_LIBRARY_SUFFIX} gRPC::grpc++ absl::synchronization) @@ -385,12 +373,10 @@ libmexclass_client_install( # Install M files set(TRACE_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/+opentelemetry) -set(METRICS_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/metrics/+opentelemetry) set(CONTEXT_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/context/+opentelemetry) set(BAGGAGE_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/baggage/+opentelemetry) set(COMMON_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/common/+opentelemetry) set(TRACE_SDK_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sdk/trace/+opentelemetry) -set(METRICS_SDK_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/sdk/metrics/+opentelemetry) set(DEFAULT_EXPORTER_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/defaultSpanExporter.m) set(OTLP_HTTP_EXPORTER_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpSpanExporter.m) set(OTLP_GRPC_EXPORTER_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcSpanExporter.m) @@ -398,12 +384,10 @@ set(OTLP_GRPC_EXPORTER_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp set(OTLP_EXPORTERS_DIR +opentelemetry/+exporters/+otlp) install(DIRECTORY ${TRACE_API_MATLAB_SOURCES} DESTINATION .) -install(DIRECTORY ${METRICS_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${CONTEXT_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${BAGGAGE_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${COMMON_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${TRACE_SDK_MATLAB_SOURCES} DESTINATION .) -install(DIRECTORY ${METRICS_SDK_MATLAB_SOURCES} DESTINATION .) install(FILES ${DEFAULT_EXPORTER_MATLAB_SOURCES} DESTINATION ${OTLP_EXPORTERS_DIR}) if(WITH_OTLP_HTTP) install(FILES ${OTLP_HTTP_EXPORTER_MATLAB_SOURCES} DESTINATION ${OTLP_EXPORTERS_DIR}) diff --git a/OtelMatlabProxyFactory.cpp b/OtelMatlabProxyFactory.cpp index 925094d..a2f1315 100644 --- a/OtelMatlabProxyFactory.cpp +++ b/OtelMatlabProxyFactory.cpp @@ -22,7 +22,6 @@ #include "opentelemetry-matlab/sdk/trace/AlwaysOffSamplerProxy.h" #include "opentelemetry-matlab/sdk/trace/TraceIdRatioBasedSamplerProxy.h" #include "opentelemetry-matlab/sdk/trace/ParentBasedSamplerProxy.h" -#include "opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h" #ifdef WITH_OTLP_HTTP #include "opentelemetry-matlab/exporters/otlp/OtlpHttpSpanExporterProxy.h" #endif @@ -55,9 +54,6 @@ OtelMatlabProxyFactory::make_proxy(const libmexclass::proxy::ClassName& class_na REGISTER_PROXY(libmexclass.opentelemetry.sdk.AlwaysOffSamplerProxy, libmexclass::opentelemetry::sdk::AlwaysOffSamplerProxy); REGISTER_PROXY(libmexclass.opentelemetry.sdk.TraceIdRatioBasedSamplerProxy, libmexclass::opentelemetry::sdk::TraceIdRatioBasedSamplerProxy); REGISTER_PROXY(libmexclass.opentelemetry.sdk.ParentBasedSamplerProxy, libmexclass::opentelemetry::sdk::ParentBasedSamplerProxy); - - REGISTER_PROXY(libmexclass.opentelemetry.sdk.MeterProviderProxy, libmexclass::opentelemetry::sdk::MeterProviderProxy); - #ifdef WITH_OTLP_HTTP REGISTER_PROXY(libmexclass.opentelemetry.exporters.OtlpHttpSpanExporterProxy, libmexclass::opentelemetry::exporters::OtlpHttpSpanExporterProxy); #endif diff --git a/api/metrics/+opentelemetry/+metrics/Counter.m b/api/metrics/+opentelemetry/+metrics/Counter.m deleted file mode 100644 index f416f41..0000000 --- a/api/metrics/+opentelemetry/+metrics/Counter.m +++ /dev/null @@ -1,59 +0,0 @@ -classdef Counter < handle - % Counter is a value that accumulates over time, - % you can think of this like an odometer on a car; it only ever goes up. - - % Copyright 2023 The MathWorks, Inc. - - properties (SetAccess=immutable) - Name (1,1) string - Description (1,1) string - Unit (1,1) string - end - - properties (Access=private) - Proxy % Proxy object to interface C++ code - end - - methods (Access={?opentelemetry.metrics.Meter}) - - function obj = Counter(proxy, ctname, ctdescription, ctunit) - % Private constructor. Use createCounter method of Meter - % to create Counters. - obj.Proxy = proxy; - obj.Name = ctname; - obj.Description = ctdescription; - obj.Unit = ctunit; - end - - end - - methods - - function add(obj, value, varargin) - % input value must be a numerical scalar - if isnumeric(value) && isscalar(value) - - if nargin == 2 - obj.Proxy.add(value); - - elseif isa(varargin{1}, "dictionary") - attrkeys = keys(varargin{1}); - attrvals = values(varargin{1},"cell"); - if all(cellfun(@iscell, attrvals)) - attrvals = [attrvals{:}]; - end - obj.Proxy.add(value,attrkeys,attrvals); - - else - attrkeys = [varargin{1:2:length(varargin)}]'; - attrvals = [varargin(2:2:length(varargin))]'; - obj.Proxy.add(value,attrkeys,attrvals); - end - end - - end - - end - - -end diff --git a/api/metrics/+opentelemetry/+metrics/Histogram.m b/api/metrics/+opentelemetry/+metrics/Histogram.m deleted file mode 100644 index 8abc9ee..0000000 --- a/api/metrics/+opentelemetry/+metrics/Histogram.m +++ /dev/null @@ -1,55 +0,0 @@ -classdef Histogram < handle - % Histogram is an instrument that adds or reduce values. - - % Copyright 2023 The MathWorks, Inc. - - properties (SetAccess=immutable) - Name (1,1) string - Description (1,1) string - Unit (1,1) string - end - - properties (Access=public) - Proxy % Proxy object to interface C++ code - end - - methods (Access={?opentelemetry.metrics.Meter}) - - function obj = Histogram(proxy, hiname, hidescription, hiunit) - % Private constructor. Use createHistogram method of Meter - % to create Histograms. - obj.Proxy = proxy; - obj.Name = hiname; - obj.Description = hidescription; - obj.Unit = hiunit; - end - - end - - methods - - function record(obj, value, varargin) - % input value must be a numerical scalar - if isnumeric(value) && isscalar(value) - if nargin == 2 - obj.Proxy.record(value); - elseif isa(varargin{1}, "dictionary") - attrkeys = keys(varargin{1}); - attrvals = values(varargin{1},"cell"); - if all(cellfun(@iscell, attrvals)) - attrvals = [attrvals{:}]; - end - obj.Proxy.record(value,attrkeys,attrvals); - else - attrkeys = [varargin{1:2:length(varargin)}]'; - attrvals = [varargin(2:2:length(varargin))]'; - obj.Proxy.record(value,attrkeys,attrvals); - end - end - - end - - end - - -end diff --git a/api/metrics/+opentelemetry/+metrics/Meter.m b/api/metrics/+opentelemetry/+metrics/Meter.m deleted file mode 100644 index 250a5b9..0000000 --- a/api/metrics/+opentelemetry/+metrics/Meter.m +++ /dev/null @@ -1,89 +0,0 @@ -classdef Meter < handle - % A Meter creates metric instruments, capturing measurements about a service at runtime. - % Meters are created from Meter Providers. - - % Copyright 2023 The MathWorks, Inc. - - properties (SetAccess=immutable) - Name (1,1) string % Meter name - Version (1,1) string % Meter version - Schema (1,1) string % URL that documents the schema of the generated spans - end - - properties (Access=private) - Proxy % Proxy object to interface C++ code - end - - methods (Access={?opentelemetry.sdk.metrics.MeterProvider}) - - function obj = Meter(proxy, mtname, mtversion, mtschema) - % Private constructor. Use getMeter method of MeterProvider - % to create Meters. - obj.Proxy = proxy; - obj.Name = mtname; - obj.Version = mtversion; - obj.Schema = mtschema; - end - - end - - methods - - function counter = createCounter(obj, ctname, ctdescription, ctunit) - arguments - obj - ctname - ctdescription = "" - ctunit = "" - end - import opentelemetry.common.mustBeScalarString - ctname = mustBeScalarString(ctname); - ctdescription = mustBeScalarString(ctdescription); - ctunit = mustBeScalarString(ctunit); - id = obj.Proxy.createCounter(ctname, ctdescription, ctunit); - CounterProxy = libmexclass.proxy.Proxy("Name", ... - "libmexclass.opentelemetry.CounterProxy", "ID", id); - counter = opentelemetry.metrics.Counter(CounterProxy, ctname, ctdescription, ctunit); - end - - - function updowncounter = createUpDownCounter(obj, ctname, ctdescription, ctunit) - arguments - obj - ctname - ctdescription = "" - ctunit = "" - end - - import opentelemetry.common.mustBeScalarString - ctname = mustBeScalarString(ctname); - ctdescription = mustBeScalarString(ctdescription); - ctunit = mustBeScalarString(ctunit); - id = obj.Proxy.createUpDownCounter(ctname, ctdescription, ctunit); - UpDownCounterProxy = libmexclass.proxy.Proxy("Name", ... - "libmexclass.opentelemetry.UpDownCounterProxy", "ID", id); - updowncounter = opentelemetry.metrics.UpDownCounter(UpDownCounterProxy, ctname, ctdescription, ctunit); - end - - - function histogram = createHistogram(obj, hiname, hidescription, hiunit) - arguments - obj - hiname - hidescription = "" - hiunit = "" - end - - import opentelemetry.common.mustBeScalarString - hiname = mustBeScalarString(hiname); - hidescription = mustBeScalarString(hidescription); - hiunit = mustBeScalarString(hiunit); - id = obj.Proxy.createHistogram(hiname, hidescription, hiunit); - HistogramProxy = libmexclass.proxy.Proxy("Name", ... - "libmexclass.opentelemetry.HistogramProxy", "ID", id); - histogram = opentelemetry.metrics.Histogram(HistogramProxy, hiname, hidescription, hiunit); - end - - end - -end diff --git a/api/metrics/+opentelemetry/+metrics/UpDownCounter.m b/api/metrics/+opentelemetry/+metrics/UpDownCounter.m deleted file mode 100644 index b008dc5..0000000 --- a/api/metrics/+opentelemetry/+metrics/UpDownCounter.m +++ /dev/null @@ -1,58 +0,0 @@ -classdef UpDownCounter < handle - % UpDownCounter is an instrument that adds or reduce values. - - % Copyright 2023 The MathWorks, Inc. - - properties (SetAccess=immutable) - Name (1,1) string - Description (1,1) string - Unit (1,1) string - end - - properties (Access=public) - Proxy % Proxy object to interface C++ code - end - - methods (Access={?opentelemetry.metrics.Meter}) - - function obj = UpDownCounter(proxy, ctname, ctdescription, ctunit) - % Private constructor. Use createUpDownCounter method of Meter - % to create UpDownCounters. - obj.Proxy = proxy; - obj.Name = ctname; - obj.Description = ctdescription; - obj.Unit = ctunit; - end - - end - - methods - - function add(obj, value, varargin) - % input value must be a numerical scalar - if isnumeric(value) && isscalar(value) - - if nargin == 2 - obj.Proxy.add(value); - - elseif isa(varargin{1}, "dictionary") - attrkeys = keys(varargin{1}); - attrvals = values(varargin{1},"cell"); - if all(cellfun(@iscell, attrvals)) - attrvals = [attrvals{:}]; - end - obj.Proxy.add(value,attrkeys,attrvals); - - else - attrkeys = [varargin{1:2:length(varargin)}]'; - attrvals = [varargin(2:2:length(varargin))]'; - obj.Proxy.add(value,attrkeys,attrvals); - end - end - - end - - end - - -end diff --git a/api/metrics/include/opentelemetry-matlab/metrics/CounterProxy.h b/api/metrics/include/opentelemetry-matlab/metrics/CounterProxy.h deleted file mode 100644 index 6271d60..0000000 --- a/api/metrics/include/opentelemetry-matlab/metrics/CounterProxy.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#pragma once - -#include "libmexclass/proxy/Proxy.h" -#include "libmexclass/proxy/method/Context.h" - -#include "opentelemetry/metrics/meter.h" -#include "opentelemetry/metrics/sync_instruments.h" - -#include "opentelemetry-matlab/common/attribute.h" -#include "opentelemetry-matlab/common/ProcessedAttributes.h" - -namespace metrics_api = opentelemetry::metrics; -namespace nostd = opentelemetry::nostd; - -namespace libmexclass::opentelemetry { -class CounterProxy : public libmexclass::proxy::Proxy { - public: - CounterProxy(nostd::shared_ptr > ct) : CppCounter(ct) { - REGISTER_METHOD(CounterProxy, add); - } - - void add(libmexclass::proxy::method::Context& context); - - private: - - nostd::shared_ptr > CppCounter; - -}; -} // namespace libmexclass::opentelemetry - - diff --git a/api/metrics/include/opentelemetry-matlab/metrics/HistogramProxy.h b/api/metrics/include/opentelemetry-matlab/metrics/HistogramProxy.h deleted file mode 100644 index 248c628..0000000 --- a/api/metrics/include/opentelemetry-matlab/metrics/HistogramProxy.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#pragma once - -#include "libmexclass/proxy/Proxy.h" -#include "libmexclass/proxy/method/Context.h" - -#include "opentelemetry/context/context.h" -#include "opentelemetry/metrics/meter.h" -#include "opentelemetry/metrics/sync_instruments.h" - -#include "opentelemetry-matlab/common/attribute.h" -#include "opentelemetry-matlab/common/ProcessedAttributes.h" -#include "opentelemetry-matlab/context/ContextProxy.h" - -namespace metrics_api = opentelemetry::metrics; -namespace context = opentelemetry::context; -namespace nostd = opentelemetry::nostd; - -namespace libmexclass::opentelemetry { -class HistogramProxy : public libmexclass::proxy::Proxy { - public: - HistogramProxy(nostd::shared_ptr > hist) : CppHistogram(hist) { - REGISTER_METHOD(HistogramProxy, record); - } - - void record(libmexclass::proxy::method::Context& context); - - private: - - nostd::shared_ptr > CppHistogram; - -}; -} // namespace libmexclass::opentelemetry - - diff --git a/api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h b/api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h deleted file mode 100644 index ab45e48..0000000 --- a/api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#pragma once - -#include "libmexclass/proxy/Proxy.h" -#include "libmexclass/proxy/method/Context.h" - -#include "opentelemetry-matlab/metrics/CounterProxy.h" -#include "opentelemetry-matlab/metrics/HistogramProxy.h" -#include "opentelemetry-matlab/metrics/UpDownCounterProxy.h" - -#include "opentelemetry/metrics/meter.h" - -namespace metrics_api = opentelemetry::metrics; -namespace nostd = opentelemetry::nostd; - -namespace libmexclass::opentelemetry { -class MeterProxy : public libmexclass::proxy::Proxy { - public: - MeterProxy(nostd::shared_ptr mt) : CppMeter(mt) { - REGISTER_METHOD(MeterProxy, createCounter); - REGISTER_METHOD(MeterProxy, createUpDownCounter); - REGISTER_METHOD(MeterProxy, createHistogram); - } - - void createCounter(libmexclass::proxy::method::Context& context); - - void createUpDownCounter(libmexclass::proxy::method::Context& context); - - void createHistogram(libmexclass::proxy::method::Context& context); - - private: - - nostd::shared_ptr CppMeter; -}; -} // namespace libmexclass::opentelemetry diff --git a/api/metrics/include/opentelemetry-matlab/metrics/UpDownCounterProxy.h b/api/metrics/include/opentelemetry-matlab/metrics/UpDownCounterProxy.h deleted file mode 100644 index 6a41c75..0000000 --- a/api/metrics/include/opentelemetry-matlab/metrics/UpDownCounterProxy.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#pragma once - -#include "libmexclass/proxy/Proxy.h" -#include "libmexclass/proxy/method/Context.h" - -#include "opentelemetry/metrics/meter.h" -#include "opentelemetry/metrics/sync_instruments.h" - -#include "opentelemetry-matlab/common/attribute.h" -#include "opentelemetry-matlab/common/ProcessedAttributes.h" - -namespace metrics_api = opentelemetry::metrics; -namespace nostd = opentelemetry::nostd; - -namespace libmexclass::opentelemetry { -class UpDownCounterProxy : public libmexclass::proxy::Proxy { - public: - UpDownCounterProxy(nostd::shared_ptr > ct) : CppUpDownCounter(ct) { - REGISTER_METHOD(UpDownCounterProxy, add); - } - - void add(libmexclass::proxy::method::Context& context); - - private: - - nostd::shared_ptr > CppUpDownCounter; - -}; -} // namespace libmexclass::opentelemetry - - diff --git a/api/metrics/src/CounterProxy.cpp b/api/metrics/src/CounterProxy.cpp deleted file mode 100644 index 77e498f..0000000 --- a/api/metrics/src/CounterProxy.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#include "opentelemetry-matlab/metrics/CounterProxy.h" - -#include "libmexclass/proxy/ProxyManager.h" - - -#include "MatlabDataArray.hpp" - -#include - -namespace libmexclass::opentelemetry { - - -void CounterProxy::add(libmexclass::proxy::method::Context& context){ - - matlab::data::Array value_mda = context.inputs[0]; - double value = static_cast(value_mda[0]); - size_t nin = context.inputs.getNumberOfElements(); - if (nin == 1){ - CppCounter->Add(value); - } - // add attributes - else { - ProcessedAttributes attrs; - matlab::data::StringArray attrnames_mda = context.inputs[1]; - matlab::data::Array attrvalues_mda = context.inputs[2]; - size_t nattrs = attrnames_mda.getNumberOfElements(); - for (size_t i = 0; i < nattrs; i ++){ - std::string attrname = static_cast(attrnames_mda[i]); - matlab::data::Array attrvalue = attrvalues_mda[i]; - processAttribute(attrname, attrvalue, attrs); - } - CppCounter->Add(value, attrs.Attributes); - } - -} - - - -} // namespace libmexclass::opentelemetry diff --git a/api/metrics/src/HistogramProxy.cpp b/api/metrics/src/HistogramProxy.cpp deleted file mode 100644 index 3d3ea5f..0000000 --- a/api/metrics/src/HistogramProxy.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#include "opentelemetry-matlab/metrics/HistogramProxy.h" - -#include "libmexclass/proxy/ProxyManager.h" - - -#include "MatlabDataArray.hpp" - -#include - -namespace libmexclass::opentelemetry { - - -void HistogramProxy::record(libmexclass::proxy::method::Context& context){ - // Get value - matlab::data::Array value_mda = context.inputs[0]; - double value = static_cast(value_mda[0]); - // Create empty context - auto ctxt = context_api::Context(); - // If no attributes input, record value and context - size_t nin = context.inputs.getNumberOfElements(); - if (nin == 1){ - CppHistogram->Record(value, ctxt); - } - // Otherwise, get attributes, record value, attributes and context - else { - ProcessedAttributes attrs; - matlab::data::StringArray attrnames_mda = context.inputs[1]; - matlab::data::Array attrvalues_mda = context.inputs[2]; - size_t nattrs = attrnames_mda.getNumberOfElements(); - for (size_t i = 0; i < nattrs; i ++){ - std::string attrname = static_cast(attrnames_mda[i]); - matlab::data::Array attrvalue = attrvalues_mda[i]; - processAttribute(attrname, attrvalue, attrs); - } - CppHistogram->Record(value, attrs.Attributes, ctxt); - } - -} - - - -} // namespace libmexclass::opentelemetry diff --git a/api/metrics/src/MeterProxy.cpp b/api/metrics/src/MeterProxy.cpp deleted file mode 100644 index 3d0d399..0000000 --- a/api/metrics/src/MeterProxy.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#include "opentelemetry-matlab/metrics/MeterProxy.h" - -#include "libmexclass/proxy/ProxyManager.h" - -#include "MatlabDataArray.hpp" - -#include - -namespace libmexclass::opentelemetry { -void MeterProxy::createCounter(libmexclass::proxy::method::Context& context) { - // Always assumes 3 inputs - matlab::data::StringArray name_mda = context.inputs[0]; - std::string name = static_cast(name_mda[0]); - matlab::data::StringArray description_mda = context.inputs[1]; - std::string description= static_cast(description_mda[0]); - matlab::data::StringArray unit_mda = context.inputs[2]; - std::string unit = static_cast(unit_mda[0]); - - nostd::shared_ptr > ct = std::move(CppMeter->CreateDoubleCounter(name, description, unit)); - - // instantiate a CounterProxy instance - CounterProxy* newproxy = new CounterProxy(ct); - auto proxy = std::shared_ptr(newproxy); - - // obtain a proxy ID - libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(proxy); - - // return the ID - matlab::data::ArrayFactory factory; - auto proxyid_mda = factory.createScalar(proxyid); - context.outputs[0] = proxyid_mda; -} - - -void MeterProxy::createUpDownCounter(libmexclass::proxy::method::Context& context) { - // Always assumes 3 inputs - matlab::data::StringArray name_mda = context.inputs[0]; - std::string name = static_cast(name_mda[0]); - matlab::data::StringArray description_mda = context.inputs[1]; - std::string description= static_cast(description_mda[0]); - matlab::data::StringArray unit_mda = context.inputs[2]; - std::string unit = static_cast(unit_mda[0]); - - nostd::shared_ptr > ct = std::move(CppMeter->CreateDoubleUpDownCounter -(name, description, unit)); - - // instantiate a UpDownCounterProxy instance - UpDownCounterProxy* newproxy = new UpDownCounterProxy(ct); - auto proxy = std::shared_ptr(newproxy); - - // obtain a proxy ID - libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(proxy); - - // return the ID - matlab::data::ArrayFactory factory; - auto proxyid_mda = factory.createScalar(proxyid); - context.outputs[0] = proxyid_mda; -} - - -void MeterProxy::createHistogram(libmexclass::proxy::method::Context& context) { - // Always assumes 3 inputs - matlab::data::StringArray name_mda = context.inputs[0]; - std::string name = static_cast(name_mda[0]); - matlab::data::StringArray description_mda = context.inputs[1]; - std::string description= static_cast(description_mda[0]); - matlab::data::StringArray unit_mda = context.inputs[2]; - std::string unit = static_cast(unit_mda[0]); - - nostd::shared_ptr > hist = std::move(CppMeter->CreateDoubleHistogram(name, description, unit)); - - // instantiate a HistogramProxy instance - HistogramProxy* newproxy = new HistogramProxy(hist); - auto proxy = std::shared_ptr(newproxy); - - // obtain a proxy ID - libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(proxy); - - // return the ID - matlab::data::ArrayFactory factory; - auto proxyid_mda = factory.createScalar(proxyid); - context.outputs[0] = proxyid_mda; -} - - -} // namespace libmexclass::opentelemetry diff --git a/api/metrics/src/UpDownCounterProxy.cpp b/api/metrics/src/UpDownCounterProxy.cpp deleted file mode 100644 index f4d35ef..0000000 --- a/api/metrics/src/UpDownCounterProxy.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#include "opentelemetry-matlab/metrics/UpDownCounterProxy.h" - -#include "libmexclass/proxy/ProxyManager.h" - - -#include "MatlabDataArray.hpp" - -#include - -namespace libmexclass::opentelemetry { - - -void UpDownCounterProxy::add(libmexclass::proxy::method::Context& context){ - - matlab::data::Array value_mda = context.inputs[0]; - double value = static_cast(value_mda[0]); - size_t nin = context.inputs.getNumberOfElements(); - if (nin == 1){ - CppUpDownCounter->Add(value); - } - // add attributes - else { - ProcessedAttributes attrs; - matlab::data::StringArray attrnames_mda = context.inputs[1]; - matlab::data::Array attrvalues_mda = context.inputs[2]; - size_t nattrs = attrnames_mda.getNumberOfElements(); - for (size_t i = 0; i < nattrs; i ++){ - std::string attrname = static_cast(attrnames_mda[i]); - matlab::data::Array attrvalue = attrvalues_mda[i]; - processAttribute(attrname, attrvalue, attrs); - } - CppUpDownCounter->Add(value, attrs.Attributes); - } - -} - - - -} // namespace libmexclass::opentelemetry diff --git a/sdk/metrics/+opentelemetry/+sdk/+metrics/MeterProvider.m b/sdk/metrics/+opentelemetry/+sdk/+metrics/MeterProvider.m deleted file mode 100644 index ec019eb..0000000 --- a/sdk/metrics/+opentelemetry/+sdk/+metrics/MeterProvider.m +++ /dev/null @@ -1,56 +0,0 @@ -classdef MeterProvider < handle - % An SDK implementation of meter provider, which stores a set of configurations used - % in a metrics system. - - % Copyright 2023 The MathWorks, Inc. - - properties (Access=private) - Proxy - end - - methods - function obj = MeterProvider() - % SDK implementation of tracer provider - % MP = OPENTELEMETRY.SDK.METRICS.METERPROVIDER creates a meter - % provider that uses a periodic exporting metric reader and default configurations. - % - % MP = OPENTELEMETRY.SDK.METRICS.METERPROVIDER(R) uses metric - % reader R. Currently, the only supported metric reader is the periodic - % exporting metric reader. - % - % TP = OPENTELEMETRY.SDK.METRICS.METERPROVIDER(R, PARAM1, VALUE1, - % PARAM2, VALUE2, ...) specifies optional parameter name/value pairs. - % Parameters are: - % "View" - View object used to customize collected metrics. - % "Resource" - Additional resource attributes. - % Specified as a dictionary. - % - % See also OPENTELEMETRY.SDK.METRICS.PERIODICEXPORTINGMETRICREADER - % OPENTELEMETRY.SDK.METRICS.VIEW - - obj.Proxy = libmexclass.proxy.Proxy("Name", ... - "libmexclass.opentelemetry.sdk.MeterProviderProxy", ... - "ConstructorArguments", {}); - end - - function meter = getMeter(obj, mtname, mtversion, mtschema) - arguments - obj - mtname - mtversion = "" - mtschema = "" - end - % name, version, schema accepts any types that can convert to a - % string - import opentelemetry.common.mustBeScalarString - mtname = mustBeScalarString(mtname); - mtversion = mustBeScalarString(mtversion); - mtschema = mustBeScalarString(mtschema); - id = obj.Proxy.getMeter(mtname, mtversion, mtschema); - Meterproxy = libmexclass.proxy.Proxy("Name", ... - "libmexclass.opentelemetry.MeterProxy", "ID", id); - meter = opentelemetry.metrics.Meter(Meterproxy, mtname, mtversion, mtschema); - end - - end -end diff --git a/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h b/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h deleted file mode 100644 index 3526822..0000000 --- a/sdk/metrics/include/opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#pragma once - -#include "libmexclass/proxy/Proxy.h" -#include "libmexclass/proxy/method/Context.h" - - -#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h" -#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter.h" -#include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h" -#include "opentelemetry/exporters/otlp/otlp_http_exporter.h" - -#include "opentelemetry/metrics/provider.h" -#include "opentelemetry/metrics/meter_provider.h" -#include "opentelemetry/sdk/common/global_log_handler.h" -#include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" -#include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" -#include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader_factory.h" -#include "opentelemetry/sdk/metrics/meter.h" -#include "opentelemetry/sdk/metrics/meter_provider.h" -#include "opentelemetry/sdk/metrics/meter_provider_factory.h" -#include "opentelemetry/sdk/metrics/push_metric_exporter.h" - -#include "opentelemetry-matlab/metrics/MeterProxy.h" - -namespace metrics_api = opentelemetry::metrics; -namespace nostd = opentelemetry::nostd; -namespace metrics_sdk = opentelemetry::sdk::metrics; -namespace common = opentelemetry::common; -namespace otlpexporter = opentelemetry::exporter::otlp; - - -namespace libmexclass::opentelemetry::sdk { -class MeterProviderProxy : public libmexclass::proxy::Proxy { - public: - MeterProviderProxy(nostd::shared_ptr mp) : CppMeterProvider(mp) { - REGISTER_METHOD(MeterProviderProxy, getMeter); - } - - static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); - - void getMeter(libmexclass::proxy::method::Context& context); - - protected: - nostd::shared_ptr CppMeterProvider; -}; -} // namespace libmexclass::opentelemetry diff --git a/sdk/metrics/src/MeterProviderProxy.cpp b/sdk/metrics/src/MeterProviderProxy.cpp deleted file mode 100644 index e0eb3c3..0000000 --- a/sdk/metrics/src/MeterProviderProxy.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2023 The MathWorks, Inc. - -#include "opentelemetry-matlab/sdk/metrics/MeterProviderProxy.h" - -#include "libmexclass/proxy/ProxyManager.h" - -#include - -namespace libmexclass::opentelemetry::sdk { -libmexclass::proxy::MakeResult MeterProviderProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - - libmexclass::proxy::MakeResult out; - - auto exporter = otlpexporter::OtlpHttpMetricExporterFactory::Create(); - // Initialize and set the periodic metrics reader - metrics_sdk::PeriodicExportingMetricReaderOptions options; - auto reader = metrics_sdk::PeriodicExportingMetricReaderFactory::Create(std::move(exporter), options); - - auto p = metrics_sdk::MeterProviderFactory::Create(); - auto *p_sdk = static_cast(p.get()); - p_sdk->AddMetricReader(std::move(reader)); - - auto p_out = nostd::shared_ptr(std::move(p)); - out = std::make_shared(p_out); - - return out; -} - -void MeterProviderProxy::getMeter(libmexclass::proxy::method::Context& context) { - // Always assumes 3 inputs - matlab::data::StringArray name_mda = context.inputs[0]; - std::string name = static_cast(name_mda[0]); - matlab::data::StringArray version_mda = context.inputs[1]; - std::string version = static_cast(version_mda[0]); - matlab::data::StringArray schema_mda = context.inputs[2]; - std::string schema = static_cast(schema_mda[0]); - - auto mt = CppMeterProvider->GetMeter(name, version, schema); - - // instantiate a MeterProxy instance - MeterProxy* newproxy = new MeterProxy(mt); - auto mtproxy = std::shared_ptr(newproxy); - - // obtain a proxy ID - libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(mtproxy); - - // return the ID - matlab::data::ArrayFactory factory; - auto proxyid_mda = factory.createScalar(proxyid); - context.outputs[0] = proxyid_mda; -} - - -} // namespace libmexclass::opentelemetry diff --git a/test/tmetrics.m b/test/tmetrics.m deleted file mode 100644 index c452504..0000000 --- a/test/tmetrics.m +++ /dev/null @@ -1,364 +0,0 @@ -classdef tmetrics < matlab.unittest.TestCase - % tests for traces and spans - - % Copyright 2023 The MathWorks, Inc. - - properties - OtelConfigFile - OtelRoot - JsonFile - PidFile - OtelcolName - Otelcol - ListPid - ReadPidList - ExtractPid - Sigint - Sigterm - end - - methods (TestClassSetup) - function setupOnce(testCase) - commonSetupOnce(testCase); - end - end - - methods (TestMethodSetup) - function setup(testCase) - commonSetup(testCase); - end - end - - methods (TestMethodTeardown) - function teardown(testCase) - commonTeardown(testCase); - end - end - - methods (Test) - - function testCounterBasic(testCase) - % test names and added value in Counter - - metername = "foo"; - countername = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - ct = mt.createCounter(countername); - - % verify MATLAB object properties - verifyEqual(testCase, mt.Name, metername); - verifyEqual(testCase, mt.Version, ""); - verifyEqual(testCase, mt.Schema, ""); - verifyEqual(testCase, ct.Name, countername); - - % create testing value - val = 10; - - % add value and attributes - ct.add(val); - - % wait for default collector response time (60s) - pause(70); - - % fetch result - results = readJsonResults(testCase); - results = results{1}; - - % verify meter and counter names - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.metrics.name), countername); - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.scope.name), metername); - - % fetch datapoint - dp = results.resourceMetrics.scopeMetrics.metrics.sum.dataPoints; - - % verify counter value - verifyEqual(testCase, dp.asDouble, val); - - end - - - function testCounterAddAttributes(testCase) - % test names, added value and attributes in Counter - - metername = "foo"; - countername = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - ct = mt.createCounter(countername); - - % create testing value and dictionary - dict = dictionary("k1","v1","k2",5); - vals = [1,2.4,3]; - dict_keys = keys(dict); - dict_vals = values(dict); - - % add value and attributes - ct.add(vals(1),dict); - ct.add(vals(2),dict); - ct.add(vals(3),dict_keys(1),dict_vals(1),dict_keys(2),dict_vals(2)); - - % wait for default collector response time (60s) - pause(70); - - % fetch result - results = readJsonResults(testCase); - results = results{1}; - - % verify meter and counter names - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.metrics.name), countername); - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.scope.name), metername); - - % fetch datapoint - dp = results.resourceMetrics.scopeMetrics.metrics.sum.dataPoints; - - % verify counter value - verifyEqual(testCase, dp.asDouble, sum(vals)); - - % verify counter attributes - resourcekeys = string({dp.attributes.key}); - idx1 = find(resourcekeys == dict_keys(1)); - idx2 = find(resourcekeys == dict_keys(2)); - verifyEqual(testCase, string(dp.attributes(idx1).key), dict_keys(1)); - verifyEqual(testCase, string(dp.attributes(idx1).value.stringValue), dict_vals(1)); - verifyEqual(testCase, string(dp.attributes(idx2).key), dict_keys(2)); - verifyEqual(testCase, string(dp.attributes(idx2).value.stringValue), dict_vals(2)); - - end - - - function testCounterAddNegative(testCase) - % test if counter value remain 0 when added negative value - - metername = "foo"; - countername = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - ct = mt.createCounter(countername); - - % add negative value to counter - ct.add(-1); - pause(70); - - % fetch results - results = readJsonResults(testCase); - results = results{1}; - dp = results.resourceMetrics.scopeMetrics.metrics.sum.dataPoints; - - % verify that the counter value is still 0 - verifyEqual(testCase, dp.asDouble, 0); - - end - - - function testUpDownCounterBasic(testCase) - % test names and added value in UpDownCounter - - metername = "foo"; - countername = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - ct = mt.createUpDownCounter(countername); - - % verify MATLAB object properties - verifyEqual(testCase, mt.Name, metername); - verifyEqual(testCase, mt.Version, ""); - verifyEqual(testCase, mt.Schema, ""); - verifyEqual(testCase, ct.Name, countername); - - % create testing value - val = -10; - - % add value and attributes - ct.add(val); - - % wait for default collector response time (60s) - pause(70); - - % fetch result - results = readJsonResults(testCase); - results = results{1}; - - % verify meter and counter names - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.metrics.name), countername); - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.scope.name), metername); - - % fetch datapoint - dp = results.resourceMetrics.scopeMetrics.metrics.sum.dataPoints; - - % verify counter value - verifyEqual(testCase, dp.asDouble, val); - - end - - - function testUpDownCounterAddAttributes(testCase) - % test names, added value and attributes in UpDownCounter - - metername = "foo"; - countername = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - ct = mt.createUpDownCounter(countername); - - % create testing value and dictionary - dict = dictionary("k1","v1","k2",5); - vals = [2,-1.9,3]; - dict_keys = keys(dict); - dict_vals = values(dict); - - % add value and attributes - ct.add(vals(1),dict); - ct.add(vals(2),dict); - ct.add(vals(3),dict_keys(1),dict_vals(1),dict_keys(2),dict_vals(2)); - - % wait for default collector response time (60s) - pause(70); - - % fetch result - results = readJsonResults(testCase); - results = results{1}; - - % verify meter and counter names - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.metrics.name), countername); - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.scope.name), metername); - - % fetch datapoint - dp = results.resourceMetrics.scopeMetrics.metrics.sum.dataPoints; - - % verify counter value - verifyEqual(testCase, dp.asDouble, sum(vals)); - - % verify counter attributes - resourcekeys = string({dp.attributes.key}); - idx1 = find(resourcekeys == dict_keys(1)); - idx2 = find(resourcekeys == dict_keys(2)); - verifyEqual(testCase, string(dp.attributes(idx1).key), dict_keys(1)); - verifyEqual(testCase, string(dp.attributes(idx1).value.stringValue), dict_vals(1)); - verifyEqual(testCase, string(dp.attributes(idx2).key), dict_keys(2)); - verifyEqual(testCase, string(dp.attributes(idx2).value.stringValue), dict_vals(2)); - - end - - - function testHistogramBasic(testCase) - % test recorded values in histogram - - metername = "foo"; - histname = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - hist = mt.createHistogram(histname); - - % verify MATLAB object properties - verifyEqual(testCase, mt.Name, metername); - verifyEqual(testCase, mt.Version, ""); - verifyEqual(testCase, mt.Schema, ""); - verifyEqual(testCase, hist.Name, histname); - - % create value for histogram - val = 1; - - % record value - hist.record(val); - - % wait for collector response - pause(75); - - % fetch results - results = readJsonResults(testCase); - results = results{1}; - dp = results.resourceMetrics.scopeMetrics.metrics.histogram.dataPoints; - bounds = dp.explicitBounds; - counts = dp.bucketCounts; - - % verify meter and histogram names - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.metrics.name), histname); - verifyEqual(testCase, string(results.resourceMetrics.scopeMetrics.scope.name), metername); - - % verify statistics - verifyEqual(testCase, dp.min, val); - verifyEqual(testCase, dp.max, val); - verifyEqual(testCase, dp.sum, val); - - % verify count in bucket - len = length(counts); - verifyEqual(testCase, str2double(counts{1}), sum(val<=bounds(1))); - for i = 2:(len-1) - lower = bounds(i-1); - upper = bounds(i); - expect_count = sum(val>lower & val<=upper); - verifyEqual(testCase, str2double(counts{i}), expect_count); - end - verifyEqual(testCase, str2double(counts{len}), sum(val>bounds(len-1))); - - end - - - function testHistogramRecordAttributes(testCase) - % test recorded values and attributes in histogram - - metername = "foo"; - histname = "bar"; - - p = opentelemetry.sdk.metrics.MeterProvider(); - mt = p.getMeter(metername); - hist = mt.createHistogram(histname); - - % create value and attributes for histogram - dict = dictionary("k1","v1","k2","v2"); - vals = [1,5,8.1]; - dict_keys = keys(dict); - dict_vals = values(dict); - - % record value and attributes - hist.record(vals(1),dict); - hist.record(vals(2),dict); - hist.record(vals(3),dict_keys(1),dict_vals(1),dict_keys(2),dict_vals(2)); - - % wait for collector response - pause(75); - - % fetch results - results = readJsonResults(testCase); - results = results{1}; - dp = results.resourceMetrics.scopeMetrics.metrics.histogram.dataPoints; - bounds = dp.explicitBounds; - counts = dp.bucketCounts; - - % verify statistics - verifyEqual(testCase, dp.min, min(vals)); - verifyEqual(testCase, dp.max, max(vals)); - verifyEqual(testCase, dp.sum, sum(vals)); - - % verify attributes - resourcekeys = string({dp.attributes.key}); - idx1 = find(resourcekeys == dict_keys(1)); - idx2 = find(resourcekeys == dict_keys(2)); - verifyEqual(testCase, string(dp.attributes(idx1).key), dict_keys(1)); - verifyEqual(testCase, string(dp.attributes(idx1).value.stringValue), dict_vals(1)); - verifyEqual(testCase, string(dp.attributes(idx2).key), dict_keys(2)); - verifyEqual(testCase, string(dp.attributes(idx2).value.stringValue), dict_vals(2)); - - % verify count in bucket - len = length(counts); - verifyEqual(testCase, str2double(counts{1}), sum(vals<=bounds(1))); - for i = 2:(len-1) - lower = bounds(i-1); - upper = bounds(i); - expect_count = sum(vals>lower & vals<=upper); - verifyEqual(testCase, str2double(counts{i}), expect_count); - end - verifyEqual(testCase, str2double(counts{len}), sum(vals>bounds(len-1))); - - end - - end - -end From b55ffdfc42e5ecc8de8c62ae32bf9c41e26a381c Mon Sep 17 00:00:00 2001 From: duncanpo Date: Wed, 25 Oct 2023 12:23:37 -0400 Subject: [PATCH 2/5] Fix a bug in span/setStatus #20 --- api/trace/+opentelemetry/+trace/Span.m | 10 +++++++--- test/ttrace.m | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/api/trace/+opentelemetry/+trace/Span.m b/api/trace/+opentelemetry/+trace/Span.m index 5698920..3ac71b7 100644 --- a/api/trace/+opentelemetry/+trace/Span.m +++ b/api/trace/+opentelemetry/+trace/Span.m @@ -132,7 +132,11 @@ function setStatus(obj, status, description) % new status is not valid, ignore return end - description = opentelemetry.common.mustBeScalarString(description); + if nargin < 3 + description = ""; + else + description = opentelemetry.common.mustBeScalarString(description); + end obj.Proxy.setStatus(status, description); end @@ -181,8 +185,7 @@ function setStatus(obj, status, description) function attrs = processAttributes(attrsin) import opentelemetry.trace.Span.processAttribute - nin = length(attrsin); - if nin == 1 && isa(attrsin{1}, "dictionary") + if isscalar(attrsin) && isa(attrsin{1}, "dictionary") % dictionary case attrtbl = entries(attrsin{1}); nattr = height(attrtbl); @@ -203,6 +206,7 @@ function setStatus(obj, status, description) attrs = attrs(:); else % NV pairs + nin = length(attrsin); if rem(nin,2) ~= 0 % Mismatched name-value pairs. Ignore all attributes. attrs = cell(1,0); diff --git a/test/ttrace.m b/test/ttrace.m index 8b01773..02d2eb7 100644 --- a/test/ttrace.m +++ b/test/ttrace.m @@ -262,6 +262,28 @@ function testTime(testCase) "convertFrom", "posixtime") - endtime), seconds(2)); end + function testStatus(testCase) + % testStatus: setting status + tp = opentelemetry.sdk.trace.TracerProvider(); + tr = getTracer(tp, "foo"); + sp = startSpan(tr, "bar"); + setStatus(sp, "ok"); + endSpan(sp); + + sp1 = startSpan(tr, "quz"); + setStatus(sp1, "Error", "Something went wrong.") % with description + endSpan(sp1); + + % perform test comparisons + results = readJsonResults(testCase); + % status codes + % Unset: 0 + % Ok: 1 + % Error: 2 + verifyEqual(testCase, results{1}.resourceSpans.scopeSpans.spans.status.code, 1); + verifyEqual(testCase, results{2}.resourceSpans.scopeSpans.spans.status.code, 2); + end + function testAttributes(testCase) % testAttributes: specifying attributes when starting spans From ac78aacdf500dd6fd9fb14e424419e66c16f0175 Mon Sep 17 00:00:00 2001 From: duncanpo Date: Wed, 1 Nov 2023 10:37:06 -0400 Subject: [PATCH 3/5] Make properties of exporters, span processors, and samplers no longer read-only #36 --- .../+exporters/+otlp/OtlpGrpcSpanExporter.m | 146 ++++++------ .../+exporters/+otlp/OtlpHttpSpanExporter.m | 134 +++++------ .../otlp/OtlpGrpcSpanExporterProxy.h | 14 +- .../otlp/OtlpHttpSpanExporterProxy.h | 19 +- .../otlp/src/OtlpGrpcSpanExporterProxy.cpp | 93 ++++---- .../otlp/src/OtlpHttpSpanExporterProxy.cpp | 108 ++++----- .../+sdk/+trace/BatchSpanProcessor.m | 85 +++---- .../+opentelemetry/+sdk/+trace/Sampler.m | 9 +- .../+opentelemetry/+sdk/+trace/SpanExporter.m | 4 +- .../+sdk/+trace/TraceIdRatioBasedSampler.m | 18 +- .../sdk/trace/BatchSpanProcessorProxy.h | 9 +- sdk/trace/src/BatchSpanProcessorProxy.cpp | 62 +++-- test/commonSetup.m | 8 +- test/commonTeardown.m | 6 +- test/nondefault_endpoint.yml | 33 +++ test/ttrace_sdk.m | 213 ++++++++++++++++++ 16 files changed, 589 insertions(+), 372 deletions(-) create mode 100644 test/nondefault_endpoint.yml create mode 100644 test/ttrace_sdk.m diff --git a/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcSpanExporter.m b/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcSpanExporter.m index 068755a..bcf2bb6 100644 --- a/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcSpanExporter.m +++ b/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpGrpcSpanExporter.m @@ -5,13 +5,13 @@ % Copyright 2023 The MathWorks, Inc. - properties (SetAccess=immutable) - Endpoint (1,1) string % Export destination - UseCredentials (1,1) logical % Whether to use SSL credentials - CertificatePath (1,1) string % Path to .pem file for SSL encryption - CertificateString (1,1) string % In-memory string representation of .pem file for SSL encryption - Timeout (1,1) duration % Maximum time above which exports will abort - HttpHeaders (1,1) dictionary % Additional HTTP headers + properties + Endpoint (1,1) string = "http://localhost:4317" % Export destination + UseCredentials (1,1) logical = false % Whether to use SSL credentials + CertificatePath (1,1) string = "" % Path to .pem file for SSL encryption + CertificateString (1,1) string = "" % In-memory string representation of .pem file for SSL encryption + Timeout (1,1) duration = seconds(10) % Maximum time above which exports will abort + HttpHeaders (1,1) dictionary = dictionary(string.empty, string.empty) % Additional HTTP headers end methods @@ -43,93 +43,73 @@ optionvalues end + obj = obj@opentelemetry.sdk.trace.SpanExporter(... + "libmexclass.opentelemetry.exporters.OtlpGrpcSpanExporterProxy"); + validnames = ["Endpoint", "UseCredentials ", "CertificatePath", ... "CertificateString", "Timeout", "HttpHeaders"]; - % set default values to empty or negative - endpoint = ""; - usessl = false; - certificatepath = ""; - certificatestring = ""; - timeout_millis = -1; - headerkeys = string.empty(); - headervalues = string.empty(); for i = 1:length(optionnames) namei = validatestring(optionnames{i}, validnames); valuei = optionvalues{i}; - if strcmp(namei, "Endpoint") - if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei))) - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:EndpointNotScalarText", "Endpoint must be a scalar string."); - end - endpoint = string(valuei); - elseif strcmp(namei, "UseCredentials ") - if ~((islogical(valuei) || isnumeric(valuei)) && isscalar(valuei)) - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:UseCredentialsNotScalarLogical", "UseCredentials must be a scalar logical.") - end - usessl = logical(valuei); - elseif strcmp(namei, "CertificatePath") - if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei))) - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:CertificatePathNotScalarText", "CertificatePath must be a scalar string."); - end - certificatepath = string(valuei); - elseif strcmp(namei, "CertificateString") - if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei))) - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:CertificateStringNotScalarText", "CertificateString must be a scalar string."); - end - certificatestring = string(valuei); - elseif strcmp(namei, "Timeout") - if ~(isduration(valuei) && isscalar(valuei)) - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration."); - end - timeout = valuei; - timeout_millis = milliseconds(timeout); - else % HttpHeaders - if ~isa(valuei, "dictionary") - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary."); - end - httpheaders = valuei; - headerkeys = keys(valuei); - headervalues = values(valuei); - if ~isstring(headervalues) - error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.") - end - end + obj.(namei) = valuei; end - - obj = obj@opentelemetry.sdk.trace.SpanExporter(... - "libmexclass.opentelemetry.exporters.OtlpGrpcSpanExporterProxy", ... - endpoint, usessl, certificatepath, certificatestring, ... - timeout_millis, headerkeys, headervalues); + end - % populate immutable properties - [defaultendpoint, defaultcertpath, defaultcertstring, defaultmillis] = ... - getDefaultOptionValues(obj); - if endpoint == "" % not specified, use default value - obj.Endpoint = defaultendpoint; - else - obj.Endpoint = endpoint; - end - obj.UseCredentials = usessl; - if certificatepath == "" % not specified, use default value - obj.CertificatePath = defaultcertpath; - else - obj.CertificatePath = certificatepath; + function obj = set.Endpoint(obj, ep) + if ~(isStringScalar(ep) || (ischar(ep) && isrow(ep))) + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:EndpointNotScalarText", "Endpoint must be a scalar string."); end - if certificatestring == "" % not specified, use default value - obj.CertificateString = defaultcertstring; - else - obj.CertificateString = certificatestring; + ep = string(ep); + obj.Proxy.setEndpoint(ep); + obj.Endpoint = ep; + end + + function obj = set.UseCredentials(obj, uc) + if ~((islogical(uc) || isnumeric(uc)) && isscalar(uc)) + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:UseCredentialsNotScalarLogical", "UseCredentials must be a scalar logical.") + end + uc = logical(uc); + obj.Proxy.setUseCredentials(uc); + obj.UseCredentials = uc; + end + + function obj = set.CertificatePath(obj, certpath) + if ~(isStringScalar(certpath) || (ischar(certpath) && isrow(certpath))) + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:CertificatePathNotScalarText", "CertificatePath must be a scalar string."); end - if timeout_millis < 0 % not specified, use default value - obj.Timeout = milliseconds(defaultmillis); - else - obj.Timeout = timeout; + certpath = string(certpath); + obj.Proxy.setCertificatePath(certpath); + obj.CertificatePath = certpath; + end + + function obj = set.CertificateString(obj, certstr) + if ~(isStringScalar(certstr) || (ischar(certstr) && isrow(certstr))) + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:CertificateStringNotScalarText", "CertificateString must be a scalar string."); + end + certstr = string(certstr); + obj.Proxy.setCertificateString(certstr); + obj.CertificateString = certstr; + end + + function obj = set.Timeout(obj, timeout) + if ~(isduration(timeout) && isscalar(timeout)) + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration."); + end + obj.Proxy.setTimeout(milliseconds(timeout)); + obj.Timeout = timeout; + end + + function obj = set.HttpHeaders(obj, httpheaders) + if ~isa(httpheaders, "dictionary") + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary."); end - if isempty(headerkeys) % not specified, return empty dictionary - obj.HttpHeaders = dictionary(headerkeys, headervalues); - else - obj.HttpHeaders = httpheaders; + headerkeys = keys(httpheaders); + headervalues = values(httpheaders); + if ~isstring(headervalues) + error("opentelemetry:exporters:otlp:OtlpGrpcSpanExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.") end - + obj.Proxy.setHttpHeaders(headerkeys, headervalues); + obj.HttpHeaders = httpheaders; end end end diff --git a/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpSpanExporter.m b/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpSpanExporter.m index 8bed109..cf79565 100644 --- a/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpSpanExporter.m +++ b/exporters/otlp/+opentelemetry/+exporters/+otlp/OtlpHttpSpanExporter.m @@ -5,13 +5,13 @@ % Copyright 2023 The MathWorks, Inc. - properties (SetAccess=immutable) - Endpoint (1,1) string % Export destination - Format (1,1) string % Data format, JSON or binary - JsonBytesMapping (1,1) string % What to convert JSON bytes to - UseJsonName (1,1) logical % Whether to use JSON name of protobuf field to set the key of JSON - Timeout (1,1) duration % Maximum time above which exports will abort - HttpHeaders (1,1) dictionary % Additional HTTP headers + properties + Endpoint (1,1) string = "http://localhost:4318/v1/traces" % Export destination + Format (1,1) string = "JSON" % Data format, JSON or binary + JsonBytesMapping (1,1) string = "hexId" % What to convert JSON bytes to + UseJsonName (1,1) logical = false % Whether to use JSON name of protobuf field to set the key of JSON + Timeout (1,1) duration = seconds(10) % Maximum time above which exports will abort + HttpHeaders (1,1) dictionary = dictionary(string.empty, string.empty) % Additional HTTP headers end methods @@ -43,89 +43,67 @@ optionvalues end + obj = obj@opentelemetry.sdk.trace.SpanExporter(... + "libmexclass.opentelemetry.exporters.OtlpHttpSpanExporterProxy"); + validnames = ["Endpoint", "Format", "JsonBytesMapping", ... "UseJsonName", "Timeout", "HttpHeaders"]; - % set default values to empty or negative - endpoint = ""; - dataformat = ""; - jsonbytesmapping = ""; - usejsonname = false; - timeout_millis = -1; - headerkeys = string.empty(); - headervalues = string.empty(); for i = 1:length(optionnames) namei = validatestring(optionnames{i}, validnames); valuei = optionvalues{i}; - if strcmp(namei, "Endpoint") - if ~(isStringScalar(valuei) || (ischar(valuei) && isrow(valuei))) - error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:EndpointNotScalarText", "Endpoint must be a scalar string."); - end - endpoint = string(valuei); - elseif strcmp(namei, "Format") - dataformat = validatestring(valuei, ["JSON", "binary"]); - elseif strcmp(namei, "JsonBytesMapping") - jsonbytesmapping = validatestring(valuei, ["hex", "hexId", "base64"]); - elseif strcmp(namei, "UseJsonName") - if ~((islogical(valuei) || isnumeric(valuei)) && isscalar(valuei)) - error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:UseJsonNameNotScalarLogical", "UseJsonName must be a scalar logical.") - end - usejsonname = logical(valuei); - elseif strcmp(namei, "Timeout") - if ~(isduration(valuei) && isscalar(valuei)) - error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration."); - end - timeout = valuei; - timeout_millis = milliseconds(timeout); - else % HttpHeaders - if ~isa(valuei, "dictionary") - error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary."); - end - httpheaders = valuei; - headerkeys = keys(valuei); - headervalues = values(valuei); - if ~isstring(headervalues) - error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.") - end - end + obj.(namei) = valuei; end - - obj = obj@opentelemetry.sdk.trace.SpanExporter(... - "libmexclass.opentelemetry.exporters.OtlpHttpSpanExporterProxy", ... - endpoint, dataformat, jsonbytesmapping, usejsonname, ... - timeout_millis, headerkeys, headervalues); + end - % populate immutable properties - if endpoint == "" || dataformat == "" || jsonbytesmapping == "" || ... - timeout_millis < 0 - [defaultendpoint, defaultformat, defaultmapping, defaultmillis] = ... - getDefaultOptionValues(obj); + function obj = set.Endpoint(obj, ep) + if ~(isStringScalar(ep) || (ischar(ep) && isrow(ep))) + error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:EndpointNotScalarText", "Endpoint must be a scalar string."); end - if endpoint == "" % not specified, use default value - obj.Endpoint = defaultendpoint; - else - obj.Endpoint = endpoint; - end - if dataformat == "" % not specified, use default value - obj.Format = defaultformat; - else - obj.Format = dataformat; + ep = string(ep); + obj.Proxy.setEndpoint(ep); + obj.Endpoint = ep; + end + + function obj = set.Format(obj, newformat) + newformat = validatestring(newformat, ["JSON", "binary"]); + obj.Proxy.setFormat(newformat); + obj.Format = newformat; + end + + function obj = set.JsonBytesMapping(obj, jbm) + jbm = validatestring(jbm, ["hex", "hexId", "base64"]); + obj.Proxy.setJsonBytesMapping(jbm); + obj.JsonBytesMapping = jbm; + end + + function obj = set.UseJsonName(obj, ujn) + if ~((islogical(ujn) || isnumeric(ujn)) && isscalar(ujn)) + error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:UseJsonNameNotScalarLogical", "UseJsonName must be a scalar logical.") end - if jsonbytesmapping == "" % not specified, use default value - obj.JsonBytesMapping = defaultmapping; - else - obj.JsonBytesMapping = jsonbytesmapping; + ujn = logical(ujn); + obj.Proxy.setUseJsonName(ujn); + obj.UseJsonName = ujn; + end + + function obj = set.Timeout(obj, timeout) + if ~(isduration(timeout) && isscalar(timeout)) + error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:TimeoutNotScalarDuration", "Timeout must be a scalar duration."); end - obj.UseJsonName = usejsonname; - if timeout_millis < 0 % not specified, use default value - obj.Timeout = milliseconds(defaultmillis); - else - obj.Timeout = timeout; + obj.Proxy.setTimeout(milliseconds(timeout)); + obj.Timeout = timeout; + end + + function obj = set.HttpHeaders(obj, httpheaders) + if ~isa(httpheaders, "dictionary") + error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:HttpHeadersNotDictionary", "HttpHeaders input must be a dictionary."); end - if isempty(headerkeys) % not specified, return empty dictionary - obj.HttpHeaders = dictionary(headerkeys, headervalues); - else - obj.HttpHeaders = httpheaders; + headerkeys = keys(httpheaders); + headervalues = values(httpheaders); + if ~isstring(headervalues) + error("opentelemetry:exporters:otlp:OtlpHttpSpanExporter:HttpHeadersNonStringValues", "HttpHeaders dictionary values must be strings.") end + obj.Proxy.setHttpHeaders(headerkeys, headervalues); + obj.HttpHeaders = httpheaders; end end end diff --git a/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpGrpcSpanExporterProxy.h b/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpGrpcSpanExporterProxy.h index 716c941..bcc4879 100644 --- a/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpGrpcSpanExporterProxy.h +++ b/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpGrpcSpanExporterProxy.h @@ -17,14 +17,24 @@ namespace libmexclass::opentelemetry::exporters { class OtlpGrpcSpanExporterProxy: public libmexclass::opentelemetry::sdk::SpanExporterProxy { public: OtlpGrpcSpanExporterProxy(otlp_exporter::OtlpGrpcExporterOptions options) : CppOptions(options) { - REGISTER_METHOD(OtlpGrpcSpanExporterProxy, getDefaultOptionValues); + REGISTER_METHOD(OtlpGrpcSpanExporterProxy, setEndpoint); + REGISTER_METHOD(OtlpGrpcSpanExporterProxy, setUseCredentials); + REGISTER_METHOD(OtlpGrpcSpanExporterProxy, setCertificatePath); + REGISTER_METHOD(OtlpGrpcSpanExporterProxy, setCertificateString); + REGISTER_METHOD(OtlpGrpcSpanExporterProxy, setTimeout); + REGISTER_METHOD(OtlpGrpcSpanExporterProxy, setHttpHeaders); } static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); std::unique_ptr getInstance() override; - void getDefaultOptionValues(libmexclass::proxy::method::Context& context); + void setEndpoint(libmexclass::proxy::method::Context& context); + void setUseCredentials(libmexclass::proxy::method::Context& context); + void setCertificatePath(libmexclass::proxy::method::Context& context); + void setCertificateString(libmexclass::proxy::method::Context& context); + void setTimeout(libmexclass::proxy::method::Context& context); + void setHttpHeaders(libmexclass::proxy::method::Context& context); private: otlp_exporter::OtlpGrpcExporterOptions CppOptions; diff --git a/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpHttpSpanExporterProxy.h b/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpHttpSpanExporterProxy.h index f843303..f735635 100644 --- a/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpHttpSpanExporterProxy.h +++ b/exporters/otlp/include/opentelemetry-matlab/exporters/otlp/OtlpHttpSpanExporterProxy.h @@ -17,7 +17,12 @@ namespace libmexclass::opentelemetry::exporters { class OtlpHttpSpanExporterProxy: public libmexclass::opentelemetry::sdk::SpanExporterProxy { public: OtlpHttpSpanExporterProxy(otlp_exporter::OtlpHttpExporterOptions options) : CppOptions(options) { - REGISTER_METHOD(OtlpHttpSpanExporterProxy, getDefaultOptionValues); + REGISTER_METHOD(OtlpHttpSpanExporterProxy, setEndpoint); + REGISTER_METHOD(OtlpHttpSpanExporterProxy, setFormat); + REGISTER_METHOD(OtlpHttpSpanExporterProxy, setJsonBytesMapping); + REGISTER_METHOD(OtlpHttpSpanExporterProxy, setUseJsonName); + REGISTER_METHOD(OtlpHttpSpanExporterProxy, setTimeout); + REGISTER_METHOD(OtlpHttpSpanExporterProxy, setHttpHeaders); } static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); @@ -26,6 +31,18 @@ class OtlpHttpSpanExporterProxy: public libmexclass::opentelemetry::sdk::SpanExp void getDefaultOptionValues(libmexclass::proxy::method::Context& context); + void setEndpoint(libmexclass::proxy::method::Context& context); + + void setFormat(libmexclass::proxy::method::Context& context); + + void setJsonBytesMapping(libmexclass::proxy::method::Context& context); + + void setUseJsonName(libmexclass::proxy::method::Context& context); + + void setTimeout(libmexclass::proxy::method::Context& context); + + void setHttpHeaders(libmexclass::proxy::method::Context& context); + private: otlp_exporter::OtlpHttpExporterOptions CppOptions; }; diff --git a/exporters/otlp/src/OtlpGrpcSpanExporterProxy.cpp b/exporters/otlp/src/OtlpGrpcSpanExporterProxy.cpp index 1ae66a0..c4e4770 100644 --- a/exporters/otlp/src/OtlpGrpcSpanExporterProxy.cpp +++ b/exporters/otlp/src/OtlpGrpcSpanExporterProxy.cpp @@ -10,60 +10,63 @@ namespace otlp_exporter = opentelemetry::exporter::otlp; namespace libmexclass::opentelemetry::exporters { libmexclass::proxy::MakeResult OtlpGrpcSpanExporterProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - matlab::data::StringArray endpoint_mda = constructor_arguments[0]; + otlp_exporter::OtlpGrpcExporterOptions options; + return std::make_shared(options); +} + +std::unique_ptr OtlpGrpcSpanExporterProxy::getInstance() { + return otlp_exporter::OtlpGrpcExporterFactory::Create(CppOptions); +} + +void OtlpGrpcSpanExporterProxy::setEndpoint(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray endpoint_mda = context.inputs[0]; std::string endpoint = static_cast(endpoint_mda[0]); - matlab::data::TypedArray use_ssl_mda = constructor_arguments[1]; - bool use_ssl = use_ssl_mda[0]; - matlab::data::StringArray certpath_mda = constructor_arguments[2]; - std::string certpath = static_cast(certpath_mda[0]); - matlab::data::StringArray certstring_mda = constructor_arguments[3]; - std::string certstring = static_cast(certstring_mda[0]); - matlab::data::TypedArray timeout_mda = constructor_arguments[4]; - double timeout = timeout_mda[0]; - matlab::data::Array header_mda = constructor_arguments[5]; - size_t nheaders = header_mda.getNumberOfElements(); - matlab::data::StringArray headernames_mda = constructor_arguments[5]; - matlab::data::StringArray headervalues_mda = constructor_arguments[6]; - otlp_exporter::OtlpGrpcExporterOptions options; if (!endpoint.empty()) { - options.endpoint = endpoint; - } - // use_ssl - options.use_ssl_credentials = use_ssl; + CppOptions.endpoint = endpoint; + } +} + + +void OtlpGrpcSpanExporterProxy::setUseCredentials(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray use_credentials_mda = context.inputs[0]; + CppOptions.use_ssl_credentials = use_credentials_mda[0]; +} + +void OtlpGrpcSpanExporterProxy::setCertificatePath(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray certpath_mda = context.inputs[0]; + std::string certpath = static_cast(certpath_mda[0]); + if (!certpath.empty()) { - options.ssl_credentials_cacert_path = certpath; - } - if (!certstring.empty()) { - options.ssl_credentials_cacert_as_string = certstring; - } - // timeout - if (timeout >= 0) { - options.timeout = std::chrono::milliseconds(static_cast(timeout)); + CppOptions.ssl_credentials_cacert_path = certpath; } - // http headers - for (size_t i = 0; i < nheaders; ++i) { - options.metadata.insert(std::pair{static_cast(headernames_mda[i]), - static_cast(headervalues_mda[i])}); +} + +void OtlpGrpcSpanExporterProxy::setCertificateString(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray certstr_mda = context.inputs[0]; + std::string certstr = static_cast(certstr_mda[0]); + + if (!certstr.empty()) { + CppOptions.ssl_credentials_cacert_as_string = certstr; } - return std::make_shared(options); } -std::unique_ptr OtlpGrpcSpanExporterProxy::getInstance() { - return otlp_exporter::OtlpGrpcExporterFactory::Create(CppOptions); +void OtlpGrpcSpanExporterProxy::setTimeout(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray timeout_mda = context.inputs[0]; + double timeout = timeout_mda[0]; + + if (timeout >= 0) { + CppOptions.timeout = std::chrono::milliseconds(static_cast(timeout)); + } } -void OtlpGrpcSpanExporterProxy::getDefaultOptionValues(libmexclass::proxy::method::Context& context) { - otlp_exporter::OtlpGrpcExporterOptions options; - matlab::data::ArrayFactory factory; - auto endpoint_mda = factory.createScalar(options.endpoint); - auto certpath_mda = factory.createScalar(options.ssl_credentials_cacert_path); - auto certstring_mda = factory.createScalar(options.ssl_credentials_cacert_as_string); - auto timeout_millis = std::chrono::duration_cast(options.timeout); - auto timeout_mda = factory.createScalar(static_cast(timeout_millis.count())); - context.outputs[0] = endpoint_mda; - context.outputs[1] = certpath_mda; - context.outputs[2] = certstring_mda; - context.outputs[3] = timeout_mda; +void OtlpGrpcSpanExporterProxy::setHttpHeaders(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray headernames_mda = context.inputs[0]; + matlab::data::StringArray headervalues_mda = context.inputs[1]; + size_t nheaders = headernames_mda.getNumberOfElements(); + for (size_t i = 0; i < nheaders; ++i) { + CppOptions.metadata.insert(std::pair{static_cast(headernames_mda[i]), + static_cast(headervalues_mda[i])}); + } } } // namespace libmexclass::opentelemetry diff --git a/exporters/otlp/src/OtlpHttpSpanExporterProxy.cpp b/exporters/otlp/src/OtlpHttpSpanExporterProxy.cpp index f8c42ce..ebcdaa5 100644 --- a/exporters/otlp/src/OtlpHttpSpanExporterProxy.cpp +++ b/exporters/otlp/src/OtlpHttpSpanExporterProxy.cpp @@ -10,84 +10,68 @@ namespace otlp_exporter = opentelemetry::exporter::otlp; namespace libmexclass::opentelemetry::exporters { libmexclass::proxy::MakeResult OtlpHttpSpanExporterProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { - matlab::data::StringArray endpoint_mda = constructor_arguments[0]; + otlp_exporter::OtlpHttpExporterOptions options; + return std::make_shared(options); +} + +std::unique_ptr OtlpHttpSpanExporterProxy::getInstance() { + return otlp_exporter::OtlpHttpExporterFactory::Create(CppOptions); +} + +void OtlpHttpSpanExporterProxy::setEndpoint(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray endpoint_mda = context.inputs[0]; std::string endpoint = static_cast(endpoint_mda[0]); - matlab::data::StringArray dataformat_mda = constructor_arguments[1]; - std::string dataformat = static_cast(dataformat_mda[0]); - matlab::data::StringArray json_bytes_mapping_mda = constructor_arguments[2]; - std::string json_bytes_mapping = static_cast(json_bytes_mapping_mda[0]); - matlab::data::TypedArray use_json_name_mda = constructor_arguments[3]; - bool use_json_name = use_json_name_mda[0]; - matlab::data::TypedArray timeout_mda = constructor_arguments[4]; - double timeout = timeout_mda[0]; - matlab::data::Array header_mda = constructor_arguments[5]; - size_t nheaders = header_mda.getNumberOfElements(); - matlab::data::StringArray headernames_mda = constructor_arguments[5]; - matlab::data::StringArray headervalues_mda = constructor_arguments[6]; - otlp_exporter::OtlpHttpExporterOptions options; if (!endpoint.empty()) { - options.url = endpoint; + CppOptions.url = endpoint; } - // TODO: store the relationship between strings and enums in an associative container - // dataformat +} + +void OtlpHttpSpanExporterProxy::setFormat(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray dataformat_mda = context.inputs[0]; + std::string dataformat = static_cast(dataformat_mda[0]); + if (dataformat.compare("JSON") == 0) { - options.content_type = otlp_exporter::HttpRequestContentType::kJson; + CppOptions.content_type = otlp_exporter::HttpRequestContentType::kJson; } else if (dataformat.compare("binary") == 0) { - options.content_type = otlp_exporter::HttpRequestContentType::kBinary; + CppOptions.content_type = otlp_exporter::HttpRequestContentType::kBinary; } - // json_bytes_mapping +} + +void OtlpHttpSpanExporterProxy::setJsonBytesMapping(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray json_bytes_mapping_mda = context.inputs[0]; + std::string json_bytes_mapping = static_cast(json_bytes_mapping_mda[0]); + if (json_bytes_mapping.compare("hex") == 0) { - options.json_bytes_mapping = otlp_exporter::JsonBytesMappingKind::kHex; + CppOptions.json_bytes_mapping = otlp_exporter::JsonBytesMappingKind::kHex; } else if (json_bytes_mapping.compare("hexId") == 0) { - options.json_bytes_mapping = otlp_exporter::JsonBytesMappingKind::kHexId; + CppOptions.json_bytes_mapping = otlp_exporter::JsonBytesMappingKind::kHexId; } else if (json_bytes_mapping.compare("base64") == 0) { - options.json_bytes_mapping = otlp_exporter::JsonBytesMappingKind::kBase64; + CppOptions.json_bytes_mapping = otlp_exporter::JsonBytesMappingKind::kBase64; } - // use_json_name - options.use_json_name = use_json_name; - // timeout - if (timeout >= 0) { - options.timeout = std::chrono::milliseconds(static_cast(timeout)); - } - // http headers - for (size_t i = 0; i < nheaders; ++i) { - options.http_headers.insert(std::pair{static_cast(headernames_mda[i]), - static_cast(headervalues_mda[i])}); - } - return std::make_shared(options); } -std::unique_ptr OtlpHttpSpanExporterProxy::getInstance() { - return otlp_exporter::OtlpHttpExporterFactory::Create(CppOptions); +void OtlpHttpSpanExporterProxy::setUseJsonName(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray use_json_name_mda = context.inputs[0]; + CppOptions.use_json_name = use_json_name_mda[0]; } -void OtlpHttpSpanExporterProxy::getDefaultOptionValues(libmexclass::proxy::method::Context& context) { - otlp_exporter::OtlpHttpExporterOptions options; - matlab::data::ArrayFactory factory; - auto endpoint_mda = factory.createScalar(options.url); - std::string dataformat, json_bytes_mapping; - // dataformat - if (options.content_type == otlp_exporter::HttpRequestContentType::kJson) { - dataformat = "JSON"; - } else { - dataformat = "binary"; +void OtlpHttpSpanExporterProxy::setTimeout(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray timeout_mda = context.inputs[0]; + double timeout = timeout_mda[0]; + + if (timeout >= 0) { + CppOptions.timeout = std::chrono::milliseconds(static_cast(timeout)); } - // json_bytes_mapping - if (options.json_bytes_mapping == otlp_exporter::JsonBytesMappingKind::kHex) { - json_bytes_mapping = "hex"; - } else if (options.json_bytes_mapping == otlp_exporter::JsonBytesMappingKind::kHexId) { - json_bytes_mapping = "hexId"; - } else { // kBase64 - json_bytes_mapping = "base64"; +} + +void OtlpHttpSpanExporterProxy::setHttpHeaders(libmexclass::proxy::method::Context& context) { + matlab::data::StringArray headernames_mda = context.inputs[0]; + matlab::data::StringArray headervalues_mda = context.inputs[1]; + size_t nheaders = headernames_mda.getNumberOfElements(); + for (size_t i = 0; i < nheaders; ++i) { + CppOptions.http_headers.insert(std::pair{static_cast(headernames_mda[i]), + static_cast(headervalues_mda[i])}); } - auto dataformat_mda = factory.createScalar(dataformat); - auto json_bytes_mapping_mda = factory.createScalar(json_bytes_mapping); - auto timeout_millis = std::chrono::duration_cast(options.timeout); - auto timeout_mda = factory.createScalar(static_cast(timeout_millis.count())); - context.outputs[0] = endpoint_mda; - context.outputs[1] = dataformat_mda; - context.outputs[2] = json_bytes_mapping_mda; - context.outputs[3] = timeout_mda; } } // namespace libmexclass::opentelemetry diff --git a/sdk/trace/+opentelemetry/+sdk/+trace/BatchSpanProcessor.m b/sdk/trace/+opentelemetry/+sdk/+trace/BatchSpanProcessor.m index 84b05bc..3101dd3 100644 --- a/sdk/trace/+opentelemetry/+sdk/+trace/BatchSpanProcessor.m +++ b/sdk/trace/+opentelemetry/+sdk/+trace/BatchSpanProcessor.m @@ -3,10 +3,10 @@ % Copyright 2023 The MathWorks, Inc. - properties (SetAccess=immutable) - MaximumQueueSize (1,1) double % Maximum queue size. After queue size is reached, spans are dropped. - ScheduledDelay (1,1) duration % Time interval between span exports - MaximumExportBatchSize (1,1) double % Maximum batch size to export. + properties + MaximumQueueSize (1,1) double = 2048 % Maximum queue size. After queue size is reached, spans are dropped. + ScheduledDelay (1,1) duration = seconds(5) % Time interval between span exports + MaximumExportBatchSize (1,1) double = 512 % Maximum batch size to export. end methods @@ -44,61 +44,46 @@ optionvalues end + obj = obj@opentelemetry.sdk.trace.SpanProcessor(spanexporter, ... + "libmexclass.opentelemetry.sdk.BatchSpanProcessorProxy"); + validnames = ["MaximumQueueSize", "ScheduledDelay", "MaximumExportBatchSize"]; - % set default values to negative - qsize = -1; - delaymillis = -1; - batchsize = -1; for i = 1:length(optionnames) namei = validatestring(optionnames{i}, validnames); valuei = optionvalues{i}; - if strcmp(namei, "MaximumQueueSize") - if ~isnumeric(valuei) || ~isscalar(valuei) || valuei <= 0 || ... - round(valuei) ~= valuei - error("opentelemetry:sdk:trace:BatchSpanProcessor:InvalidMaxQueueSize", ... - "MaximumQueueSize must be a scalar positive integer."); - end - qsize = double(valuei); - elseif strcmp(namei, "ScheduledDelay") - if ~isduration(valuei) || ~isscalar(valuei) || valuei <= 0 - error("opentelemetry:sdk:trace:BatchSpanProcessor:InvalidScheduledDelay", ... - "ScheduledDelay must be a positive duration scalar."); - end - delay = valuei; - delaymillis = milliseconds(valuei); - else % "MaximumExportBatchSize" - if ~isnumeric(valuei) || ~isscalar(valuei) || valuei <= 0 || ... - round(valuei) ~= valuei - error("opentelemetry:sdk:trace:BatchSpanProcessor:InvalidMaxExportBatchSize", ... - "MaximumExportBatchSize must be a scalar positive integer."); - end - batchsize = double(valuei); - end + obj.(namei) = valuei; end - - obj = obj@opentelemetry.sdk.trace.SpanProcessor(spanexporter, ... - "libmexclass.opentelemetry.sdk.BatchSpanProcessorProxy", ... - qsize, delaymillis, batchsize); + end - % populate immutable properties - if qsize < 0 || delaymillis < 0 || batchsize < 0 - [defaultqsize, defaultmillis, defaultbatchsize] = obj.Proxy.getDefaultOptionValues(); - end - if qsize < 0 % not specified, use default value - obj.MaximumQueueSize = defaultqsize; - else - obj.MaximumQueueSize = qsize; + function obj = set.MaximumQueueSize(obj, maxqsz) + if ~isnumeric(maxqsz) || ~isscalar(maxqsz) || maxqsz <= 0 || ... + round(maxqsz) ~= maxqsz + error("opentelemetry:sdk:trace:BatchSpanProcessor:InvalidMaxQueueSize", ... + "MaximumQueueSize must be a scalar positive integer."); end - if delaymillis < 0 % not specified, use default value - obj.ScheduledDelay = milliseconds(defaultmillis); - else - obj.ScheduledDelay = delay; + maxqsz = double(maxqsz); + obj.Proxy.setMaximumQueueSize(maxqsz); + obj.MaximumQueueSize = maxqsz; + end + + function obj = set.ScheduledDelay(obj, delay) + if ~isduration(delay) || ~isscalar(delay) || delay <= 0 + error("opentelemetry:sdk:trace:BatchSpanProcessor:InvalidScheduledDelay", ... + "ScheduledDelay must be a positive duration scalar."); end - if batchsize < 0 % not specified, use default value - obj.MaximumExportBatchSize = defaultbatchsize; - else - obj.MaximumExportBatchSize = batchsize; + obj.Proxy.setScheduledDelay(milliseconds(delay)); + obj.ScheduledDelay = delay; + end + + function obj = set.MaximumExportBatchSize(obj, maxbatch) + if ~isnumeric(maxbatch) || ~isscalar(maxbatch) || maxbatch <= 0 || ... + round(maxbatch) ~= maxbatch + error("opentelemetry:sdk:trace:BatchSpanProcessor:InvalidMaxExportBatchSize", ... + "MaximumExportBatchSize must be a scalar positive integer."); end + maxbatch = double(maxbatch); + obj.Proxy.setMaximumExportBatchSize(maxbatch); + obj.MaximumExportBatchSize = maxbatch; end end end diff --git a/sdk/trace/+opentelemetry/+sdk/+trace/Sampler.m b/sdk/trace/+opentelemetry/+sdk/+trace/Sampler.m index ccaee21..397f310 100644 --- a/sdk/trace/+opentelemetry/+sdk/+trace/Sampler.m +++ b/sdk/trace/+opentelemetry/+sdk/+trace/Sampler.m @@ -4,15 +4,18 @@ % Copyright 2023 The MathWorks, Inc. properties (GetAccess={?opentelemetry.sdk.trace.TracerProvider,... - ?opentelemetry.sdk.trace.ParentBasedSampler}) + ?opentelemetry.sdk.trace.ParentBasedSampler, ... + ?opentelemetry.sdk.trace.TraceIdRatioBasedSampler}) Proxy % Proxy object to interface C++ code end methods (Access=protected) function obj = Sampler(proxyname, varargin) % Base class constructor - obj.Proxy = libmexclass.proxy.Proxy("Name", proxyname, ... - "ConstructorArguments", varargin); + if nargin > 0 + obj.Proxy = libmexclass.proxy.Proxy("Name", proxyname, ... + "ConstructorArguments", varargin); + end end end end diff --git a/sdk/trace/+opentelemetry/+sdk/+trace/SpanExporter.m b/sdk/trace/+opentelemetry/+sdk/+trace/SpanExporter.m index b2bcf4b..846e518 100644 --- a/sdk/trace/+opentelemetry/+sdk/+trace/SpanExporter.m +++ b/sdk/trace/+opentelemetry/+sdk/+trace/SpanExporter.m @@ -3,7 +3,9 @@ % Copyright 2023 The MathWorks, Inc. - properties (GetAccess=?opentelemetry.sdk.trace.SpanProcessor) + properties (GetAccess={?opentelemetry.sdk.trace.SpanProcessor, ... + ?opentelemetry.exporters.otlp.OtlpHttpSpanExporter, ... + ?opentelemetry.exporters.otlp.OtlpGrpcSpanExporter}) Proxy % Proxy object to interface C++ code end diff --git a/sdk/trace/+opentelemetry/+sdk/+trace/TraceIdRatioBasedSampler.m b/sdk/trace/+opentelemetry/+sdk/+trace/TraceIdRatioBasedSampler.m index 3b1f2ca..ab7310c 100644 --- a/sdk/trace/+opentelemetry/+sdk/+trace/TraceIdRatioBasedSampler.m +++ b/sdk/trace/+opentelemetry/+sdk/+trace/TraceIdRatioBasedSampler.m @@ -3,7 +3,7 @@ % Copyright 2023 The MathWorks, Inc. - properties (SetAccess=immutable) + properties Ratio (1,1) double % Sampling ratio between 0 and 1 end @@ -16,12 +16,18 @@ % See also OPENTELEMETRY.SDK.TRACE.ALWAYSONSAMPLER, % OPENTELEMETRY.SDK.TRACE.ALWAYSOFFSAMPLER, % OPENTELEMETRY.SDK.TRACE.PARENTBASEDSAMPLER - arguments - ratio (1,1) {mustBeNumeric, mustBeNonnegative, mustBeLessThanOrEqual(ratio,1)} + + obj.Ratio = ratio; + end + + function obj = set.Ratio(obj, ratio) + if ~(ratio >= 0 && ratio <= 1) + error("opentelemetry:sdk:trace:TraceIdRatioBasedSampler:InvalidRatio", ... + "Ratio must be a numeric scalar between 0 and 1."); end - ratio = double(ratio); - obj = obj@opentelemetry.sdk.trace.Sampler(... - "libmexclass.opentelemetry.sdk.TraceIdRatioBasedSamplerProxy", ratio); + obj.Proxy = libmexclass.proxy.Proxy("Name", ... + "libmexclass.opentelemetry.sdk.TraceIdRatioBasedSamplerProxy", ... + "ConstructorArguments", {ratio}); obj.Ratio = ratio; end end diff --git a/sdk/trace/include/opentelemetry-matlab/sdk/trace/BatchSpanProcessorProxy.h b/sdk/trace/include/opentelemetry-matlab/sdk/trace/BatchSpanProcessorProxy.h index 1afc8a0..00ecd21 100644 --- a/sdk/trace/include/opentelemetry-matlab/sdk/trace/BatchSpanProcessorProxy.h +++ b/sdk/trace/include/opentelemetry-matlab/sdk/trace/BatchSpanProcessorProxy.h @@ -15,14 +15,17 @@ namespace trace_sdk = opentelemetry::sdk::trace; namespace libmexclass::opentelemetry::sdk { class BatchSpanProcessorProxy : public SpanProcessorProxy { public: - BatchSpanProcessorProxy(std::shared_ptr exporter, double qsize, - double delay, double batchsize); + BatchSpanProcessorProxy(std::shared_ptr exporter); static libmexclass::proxy::MakeResult make(const libmexclass::proxy::FunctionArguments& constructor_arguments); std::unique_ptr getInstance() override; - void getDefaultOptionValues(libmexclass::proxy::method::Context& context); + void setMaximumQueueSize(libmexclass::proxy::method::Context& context); + + void setScheduledDelay(libmexclass::proxy::method::Context& context); + + void setMaximumExportBatchSize(libmexclass::proxy::method::Context& context); private: trace_sdk::BatchSpanProcessorOptions CppOptions; diff --git a/sdk/trace/src/BatchSpanProcessorProxy.cpp b/sdk/trace/src/BatchSpanProcessorProxy.cpp index 4e369b6..75b0cb5 100644 --- a/sdk/trace/src/BatchSpanProcessorProxy.cpp +++ b/sdk/trace/src/BatchSpanProcessorProxy.cpp @@ -8,52 +8,46 @@ #include "opentelemetry/sdk/trace/batch_span_processor_factory.h" namespace libmexclass::opentelemetry::sdk { -BatchSpanProcessorProxy::BatchSpanProcessorProxy(std::shared_ptr exporter, - double qsize, double delay, double batchsize) +BatchSpanProcessorProxy::BatchSpanProcessorProxy(std::shared_ptr exporter) : SpanProcessorProxy(exporter) { - - if (qsize > 0) { - CppOptions.max_queue_size = static_cast(qsize); - } - if (delay > 0) { - CppOptions.schedule_delay_millis = std::chrono::milliseconds(static_cast(delay)); - } - if (batchsize > 0) { - CppOptions.max_export_batch_size = static_cast(batchsize); - } - REGISTER_METHOD(BatchSpanProcessorProxy, getDefaultOptionValues); + REGISTER_METHOD(BatchSpanProcessorProxy, setMaximumQueueSize); + REGISTER_METHOD(BatchSpanProcessorProxy, setScheduledDelay); + REGISTER_METHOD(BatchSpanProcessorProxy, setMaximumExportBatchSize); } libmexclass::proxy::MakeResult BatchSpanProcessorProxy::make(const libmexclass::proxy::FunctionArguments& constructor_arguments) { matlab::data::TypedArray exporterid_mda = constructor_arguments[0]; - libmexclass::proxy::ID exporterid = exporterid_mda[0]; + libmexclass::proxy::ID exporterid = exporterid_mda[0]; std::shared_ptr exporter = std::static_pointer_cast( libmexclass::proxy::ProxyManager::getProxy(exporterid)); - matlab::data::TypedArray qsize_mda = constructor_arguments[1]; - double qsize = qsize_mda[0]; - matlab::data::TypedArray delay_mda = constructor_arguments[2]; - double delay = delay_mda[0]; - matlab::data::TypedArray batchsize_mda = constructor_arguments[3]; - double batchsize = batchsize_mda[0]; - - return std::make_shared(exporter, qsize, delay, batchsize); + return std::make_shared(exporter); } std::unique_ptr BatchSpanProcessorProxy::getInstance() { return trace_sdk::BatchSpanProcessorFactory::Create(std::move(SpanExporter->getInstance()), CppOptions); } -void BatchSpanProcessorProxy::getDefaultOptionValues(libmexclass::proxy::method::Context& context) { - trace_sdk::BatchSpanProcessorOptions options; - matlab::data::ArrayFactory factory; - auto qsize_mda = factory.createScalar(static_cast( - options.max_queue_size)); - auto delay_mda = factory.createScalar(static_cast( - options.schedule_delay_millis.count())); - auto batchsize_mda = factory.createScalar(static_cast( - options.max_export_batch_size)); - context.outputs[0] = qsize_mda; - context.outputs[1] = delay_mda; - context.outputs[2] = batchsize_mda; +void BatchSpanProcessorProxy::setMaximumQueueSize(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray qsize_mda = context.inputs[0]; + double qsize = qsize_mda[0]; + if (qsize > 0) { + CppOptions.max_queue_size = static_cast(qsize); + } +} + +void BatchSpanProcessorProxy::setScheduledDelay(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray delay_mda = context.inputs[0]; + double delay = delay_mda[0]; + if (delay > 0) { + CppOptions.schedule_delay_millis = std::chrono::milliseconds(static_cast(delay)); + } +} + +void BatchSpanProcessorProxy::setMaximumExportBatchSize(libmexclass::proxy::method::Context& context) { + matlab::data::TypedArray batchsize_mda = context.inputs[0]; + double batchsize = batchsize_mda[0]; + if (batchsize > 0) { + CppOptions.max_export_batch_size = static_cast(batchsize); + } } } // namespace libmexclass::opentelemetry diff --git a/test/commonSetup.m b/test/commonSetup.m index 98d1fa8..6ac5190 100644 --- a/test/commonSetup.m +++ b/test/commonSetup.m @@ -1,8 +1,12 @@ -function commonSetup(testCase) +function commonSetup(testCase, configfile) % Setup function for tests % % Copyright 2023 The MathWorks, Inc. +if nargin < 2 + configfile = testCase.OtelConfigFile; +end + % start collector -system(testCase.Otelcol + " --config " + testCase.OtelConfigFile + '&'); +system(testCase.Otelcol + " --config " + configfile + '&'); pause(1); % give a little time for Collector to start up \ No newline at end of file diff --git a/test/commonTeardown.m b/test/commonTeardown.m index 0f037a2..e484629 100644 --- a/test/commonTeardown.m +++ b/test/commonTeardown.m @@ -10,8 +10,10 @@ function commonTeardown(testCase) if ispc system(testCase.ListPid("cmd") + " > " + testCase.PidFile); tbl = testCase.ReadPidList(testCase.PidFile); - pid = tbl.Var2(end-1); - system(testCase.Sigterm(pid)); + if height(tbl) > 1 + pid = tbl.Var2(end-1); + system(testCase.Sigterm(pid)); + end end if exist(testCase.JsonFile, "file") diff --git a/test/nondefault_endpoint.yml b/test/nondefault_endpoint.yml new file mode 100644 index 0000000..c3ec1d7 --- /dev/null +++ b/test/nondefault_endpoint.yml @@ -0,0 +1,33 @@ +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:9922 + http: + endpoint: 0.0.0.0:9921 + +processors: + +exporters: + file: + path: ./myoutput.json + +service: + + pipelines: + + logs: + receivers: [otlp] + processors: + exporters: [file] + + traces: + receivers: [otlp] + processors: + exporters: [file] + + metrics: + receivers: [otlp] + processors: + exporters: [file] + diff --git a/test/ttrace_sdk.m b/test/ttrace_sdk.m new file mode 100644 index 0000000..2040c55 --- /dev/null +++ b/test/ttrace_sdk.m @@ -0,0 +1,213 @@ +classdef ttrace_sdk < matlab.unittest.TestCase + % tests for tracing SDK (span processors, exporters, samplers, resource) + + % Copyright 2023 The MathWorks, Inc. + + properties + OtelConfigFile + JsonFile + PidFile + OtelcolName + Otelcol + ListPid + ReadPidList + ExtractPid + Sigint + Sigterm + end + + methods (TestClassSetup) + function setupOnce(testCase) + commonSetupOnce(testCase); + end + end + + methods (TestMethodTeardown) + function teardown(testCase) + commonTeardown(testCase); + end + end + + methods (Test) + function testNondefaultEndpoint(testCase) + % testNondefaultEndpoint: using an alternative endpoint + + testCase.assumeTrue(logical(exist("opentelemetry.exporters.otlp.OtlpHttpSpanExporter", "class")), ... + "Otlp HTTP exporter must be installed."); + + commonSetup(testCase, "nondefault_endpoint.yml") + + tracername = "foo"; + spanname = "bar"; + + exp = opentelemetry.exporters.otlp.OtlpHttpSpanExporter(... + "Endpoint", "http://localhost:9921/v1/traces"); + processor = opentelemetry.sdk.trace.SimpleSpanProcessor(exp); + tp = opentelemetry.sdk.trace.TracerProvider(processor); + tr = getTracer(tp, tracername); + sp = startSpan(tr, spanname); + pause(1); + endSpan(sp); + + % perform test comparisons + results = readJsonResults(testCase); + results = results{1}; + + % check span and tracer names + verifyEqual(testCase, string(results.resourceSpans.scopeSpans.spans.name), spanname); + verifyEqual(testCase, string(results.resourceSpans.scopeSpans.scope.name), tracername); + end + + function testNondefaultGrpcEndpoint(testCase) + % testNondefaultEndpoint: using an alternative endpoint + + testCase.assumeTrue(logical(exist("opentelemetry.exporters.otlp.OtlpGrpcSpanExporter", "class")), ... + "Otlp gRPC exporter must be installed."); + + commonSetup(testCase, "nondefault_endpoint.yml") + + tracername = "foo"; + spanname = "bar"; + + exp = opentelemetry.exporters.otlp.OtlpGrpcSpanExporter(... + "Endpoint", "http://localhost:9922"); + processor = opentelemetry.sdk.trace.SimpleSpanProcessor(exp); + tp = opentelemetry.sdk.trace.TracerProvider(processor); + tr = getTracer(tp, tracername); + sp = startSpan(tr, spanname); + pause(1); + endSpan(sp); + + % perform test comparisons + results = readJsonResults(testCase); + results = results{1}; + + % check span and tracer names + verifyEqual(testCase, string(results.resourceSpans.scopeSpans.spans.name), spanname); + verifyEqual(testCase, string(results.resourceSpans.scopeSpans.scope.name), tracername); + end + + function testAlwaysOffSampler(testCase) + % testAlwaysOffSampler: should not produce any spans + commonSetup(testCase) + + tp = opentelemetry.sdk.trace.TracerProvider( ... + opentelemetry.sdk.trace.SimpleSpanProcessor, ... + "Sampler", opentelemetry.sdk.trace.AlwaysOffSampler); + tr = getTracer(tp, "mytracer"); + sp = startSpan(tr, "myspan"); + pause(1); + endSpan(sp); + + % verify no spans are generated + results = readJsonResults(testCase); + verifyEmpty(testCase, results); + end + + function testAlwaysOnSampler(testCase) + % testAlwaysOnSampler: should produce all spans + commonSetup(testCase) + + tracername = "foo"; + spanname = "bar"; + + tp = opentelemetry.sdk.trace.TracerProvider( ... + opentelemetry.sdk.trace.SimpleSpanProcessor, ... + "Sampler", opentelemetry.sdk.trace.AlwaysOnSampler); + tr = getTracer(tp, tracername); + sp = startSpan(tr, spanname); + pause(1); + endSpan(sp); + + % perform test comparisons + results = readJsonResults(testCase); + results = results{1}; + + % check span and tracer names + verifyEqual(testCase, string(results.resourceSpans.scopeSpans.spans.name), spanname); + verifyEqual(testCase, string(results.resourceSpans.scopeSpans.scope.name), tracername); + end + + function testTraceIdRatioBasedSampler(testCase) + % testTraceIdRatioBasedSampler: filter spans based on a ratio + commonSetup(testCase) + + s = opentelemetry.sdk.trace.TraceIdRatioBasedSampler(0); % equivalent to always off + + tracername = "mytracer"; + offspan = "offspan"; + tp = opentelemetry.sdk.trace.TracerProvider( ... + opentelemetry.sdk.trace.SimpleSpanProcessor, "Sampler", s); + tr = getTracer(tp, tracername); + sp = startSpan(tr, offspan); + pause(1); + endSpan(sp); + + s.Ratio = 1; % equivalent to always on + onspan = "onspan"; + tp = opentelemetry.sdk.trace.TracerProvider( ... + opentelemetry.sdk.trace.SimpleSpanProcessor, "Sampler", s); + tr = getTracer(tp, tracername); + sp = startSpan(tr, onspan); + pause(1); + endSpan(sp); + + s.Ratio = 0.5; % filter half of the spans + sampledspan = "sampledspan"; + numspans = 10; + tp = opentelemetry.sdk.trace.TracerProvider( ... + opentelemetry.sdk.trace.SimpleSpanProcessor, "Sampler", s); + tr = getTracer(tp, tracername); + for i = 1:numspans + sp = startSpan(tr, sampledspan + i); + pause(1); + endSpan(sp); + end + + % perform test comparisons + results = readJsonResults(testCase); + n = length(results); + % total spans should be 1 span when ratio == 1, plus a number of + % spans between 0 and numspans when ratio == 0.5 + % Verifying 1 < total_spans < numspans+1. If this fails, there + % is still a chance nothing went wrong, because number of spans + % are non-deterministic when ratio == 0.5. When ratio == 0.5, + % it is still possible to get 0 or numspans spans. But that + % probability is small, so we fail the test to flag something + % may have gone wrong. + verifyGreaterThan(testCase, n, 1); + verifyLessThan(testCase, n, 1 + numspans); + verifyEqual(testCase, string(results{1}.resourceSpans.scopeSpans.spans.name), onspan); + for i = 2:n + verifySubstring(testCase, string(results{i}.resourceSpans.scopeSpans.spans.name), ... + sampledspan); + end + end + + function testCustomResource(testCase) + % testCustomResource: check custom resources are included in + % emitted spans + commonSetup(testCase) + + customkeys = ["foo" "bar"]; + customvalues = [1 5]; + tp = opentelemetry.sdk.trace.TracerProvider(opentelemetry.sdk.trace.SimpleSpanProcessor, ... + "Resource", dictionary(customkeys, customvalues)); + tr = getTracer(tp, "mytracer"); + sp = startSpan(tr, "myspan"); + pause(1); + endSpan(sp); + + % perform test comparisons + results = readJsonResults(testCase); + results = results{1}; + + resourcekeys = string({results.resourceSpans.resource.attributes.key}); + for i = length(customkeys) + idx = find(resourcekeys == customkeys(i)); + verifyNotEmpty(testCase, idx); + verifyEqual(testCase, results.resourceSpans.resource.attributes(idx).value.doubleValue, customvalues(i)); + end + end + end +end \ No newline at end of file From 613e99e6d1fca6bd930b60e901265d87665bd129 Mon Sep 17 00:00:00 2001 From: duncanpo Date: Mon, 13 Nov 2023 13:55:46 -0500 Subject: [PATCH 4/5] fix merge issues --- CMakeLists.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a06e4b9..4ad886b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -187,22 +187,26 @@ if(WITH_OTLP_GRPC) endif() endif() -set(TRACE_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/include) +set(TRACE_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/include) +set(METRICS_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/metrics/include) set(CONTEXT_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/context/include) set(BAGGAGE_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/baggage/include) set(COMMON_API_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/common/include) set(TRACE_SDK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/trace/include) +set(METRICS_SDK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/metrics/include) set(COMMON_SDK_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/common/include) set(OTLP_EXPORTER_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/include) -set(OPENTELEMETRY_PROXY_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${TRACE_API_INCLUDE_DIR} ${CONTEXT_API_INCLUDE_DIR} ${BAGGAGE_API_INCLUDE_DIR} ${COMMON_API_INCLUDE_DIR} ${TRACE_SDK_INCLUDE_DIR} ${COMMON_SDK_INCLUDE_DIR} ${OTLP_EXPORTER_INCLUDE_DIR} ${OTEL_CPP_PREFIX}/include) +set(OPENTELEMETRY_PROXY_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} ${TRACE_API_INCLUDE_DIR} ${METRICS_API_INCLUDE_DIR} ${CONTEXT_API_INCLUDE_DIR} ${BAGGAGE_API_INCLUDE_DIR} ${COMMON_API_INCLUDE_DIR} ${TRACE_SDK_INCLUDE_DIR} ${METRICS_SDK_INCLUDE_DIR} ${COMMON_SDK_INCLUDE_DIR} ${OTLP_EXPORTER_INCLUDE_DIR} ${OTEL_CPP_PREFIX}/include) set(OPENTELEMETRY_PROXY_FACTORY_CLASS_NAME OtelMatlabProxyFactory) set(OPENTELEMETRY_PROXY_FACTORY_SOURCES_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(TRACE_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/src) +set(METRICS_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/metrics/src) set(CONTEXT_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/context/src) set(BAGGAGE_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/baggage/src) set(COMMON_API_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/api/common/src) set(TRACE_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/trace/src) +set(METRICS_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/metrics/src) set(COMMON_SDK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/sdk/common/src) set(OTLP_EXPORTER_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/exporters/otlp/src) set(OPENTELEMETRY_PROXY_SOURCES @@ -289,16 +293,19 @@ set(OTEL_CPP_LINK_LIBRARIES ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_trace${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_version${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_logs${CMAKE_STATIC_LIBRARY_SUFFIX} + ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_metrics${CMAKE_STATIC_LIBRARY_SUFFIX} ${Protobuf_LIBRARIES}) if(WITH_OTLP_HTTP) set(OTEL_CPP_LINK_LIBRARIES ${OTEL_CPP_LINK_LIBRARIES} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_http${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_http_client${CMAKE_STATIC_LIBRARY_SUFFIX} + ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_http_metric${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_http_client_curl${CMAKE_STATIC_LIBRARY_SUFFIX} ${CURL_LIBRARIES}) endif() if(WITH_OTLP_GRPC) set(OTEL_CPP_LINK_LIBRARIES ${OTEL_CPP_LINK_LIBRARIES} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_grpc${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_grpc_client${CMAKE_STATIC_LIBRARY_SUFFIX} + ${OTEL_CPP_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}opentelemetry_exporter_otlp_grpc_metrics${CMAKE_STATIC_LIBRARY_SUFFIX} ${OTEL_CPP_PREFIX}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}opentelemetry_proto_grpc${OTEL_PROTO_LIBRARY_SUFFIX} gRPC::grpc++ absl::synchronization) @@ -385,6 +392,7 @@ libmexclass_client_install( # Install M files set(TRACE_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/trace/+opentelemetry) +set(METRICS_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/metrics/+opentelemetry) set(CONTEXT_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/context/+opentelemetry) set(BAGGAGE_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/baggage/+opentelemetry) set(COMMON_API_MATLAB_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/api/common/+opentelemetry) @@ -404,6 +412,7 @@ set(OTLP_GRPC_EXPORTER_MATLAB_SOURCES set(OTLP_EXPORTERS_DIR +opentelemetry/+exporters/+otlp) install(DIRECTORY ${TRACE_API_MATLAB_SOURCES} DESTINATION .) +install(DIRECTORY ${METRICS_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${CONTEXT_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${BAGGAGE_API_MATLAB_SOURCES} DESTINATION .) install(DIRECTORY ${COMMON_API_MATLAB_SOURCES} DESTINATION .) From dd0d28afca8071bba0389e1025fd3e1b74b490f4 Mon Sep 17 00:00:00 2001 From: duncanpo Date: Mon, 13 Nov 2023 14:24:23 -0500 Subject: [PATCH 5/5] fix merge issues --- .../opentelemetry-matlab/metrics/MeterProxy.h | 36 ++++++++ api/metrics/src/MeterProxy.cpp | 88 +++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h create mode 100644 api/metrics/src/MeterProxy.cpp diff --git a/api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h b/api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h new file mode 100644 index 0000000..ab45e48 --- /dev/null +++ b/api/metrics/include/opentelemetry-matlab/metrics/MeterProxy.h @@ -0,0 +1,36 @@ +// Copyright 2023 The MathWorks, Inc. + +#pragma once + +#include "libmexclass/proxy/Proxy.h" +#include "libmexclass/proxy/method/Context.h" + +#include "opentelemetry-matlab/metrics/CounterProxy.h" +#include "opentelemetry-matlab/metrics/HistogramProxy.h" +#include "opentelemetry-matlab/metrics/UpDownCounterProxy.h" + +#include "opentelemetry/metrics/meter.h" + +namespace metrics_api = opentelemetry::metrics; +namespace nostd = opentelemetry::nostd; + +namespace libmexclass::opentelemetry { +class MeterProxy : public libmexclass::proxy::Proxy { + public: + MeterProxy(nostd::shared_ptr mt) : CppMeter(mt) { + REGISTER_METHOD(MeterProxy, createCounter); + REGISTER_METHOD(MeterProxy, createUpDownCounter); + REGISTER_METHOD(MeterProxy, createHistogram); + } + + void createCounter(libmexclass::proxy::method::Context& context); + + void createUpDownCounter(libmexclass::proxy::method::Context& context); + + void createHistogram(libmexclass::proxy::method::Context& context); + + private: + + nostd::shared_ptr CppMeter; +}; +} // namespace libmexclass::opentelemetry diff --git a/api/metrics/src/MeterProxy.cpp b/api/metrics/src/MeterProxy.cpp new file mode 100644 index 0000000..3d0d399 --- /dev/null +++ b/api/metrics/src/MeterProxy.cpp @@ -0,0 +1,88 @@ +// Copyright 2023 The MathWorks, Inc. + +#include "opentelemetry-matlab/metrics/MeterProxy.h" + +#include "libmexclass/proxy/ProxyManager.h" + +#include "MatlabDataArray.hpp" + +#include + +namespace libmexclass::opentelemetry { +void MeterProxy::createCounter(libmexclass::proxy::method::Context& context) { + // Always assumes 3 inputs + matlab::data::StringArray name_mda = context.inputs[0]; + std::string name = static_cast(name_mda[0]); + matlab::data::StringArray description_mda = context.inputs[1]; + std::string description= static_cast(description_mda[0]); + matlab::data::StringArray unit_mda = context.inputs[2]; + std::string unit = static_cast(unit_mda[0]); + + nostd::shared_ptr > ct = std::move(CppMeter->CreateDoubleCounter(name, description, unit)); + + // instantiate a CounterProxy instance + CounterProxy* newproxy = new CounterProxy(ct); + auto proxy = std::shared_ptr(newproxy); + + // obtain a proxy ID + libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(proxy); + + // return the ID + matlab::data::ArrayFactory factory; + auto proxyid_mda = factory.createScalar(proxyid); + context.outputs[0] = proxyid_mda; +} + + +void MeterProxy::createUpDownCounter(libmexclass::proxy::method::Context& context) { + // Always assumes 3 inputs + matlab::data::StringArray name_mda = context.inputs[0]; + std::string name = static_cast(name_mda[0]); + matlab::data::StringArray description_mda = context.inputs[1]; + std::string description= static_cast(description_mda[0]); + matlab::data::StringArray unit_mda = context.inputs[2]; + std::string unit = static_cast(unit_mda[0]); + + nostd::shared_ptr > ct = std::move(CppMeter->CreateDoubleUpDownCounter +(name, description, unit)); + + // instantiate a UpDownCounterProxy instance + UpDownCounterProxy* newproxy = new UpDownCounterProxy(ct); + auto proxy = std::shared_ptr(newproxy); + + // obtain a proxy ID + libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(proxy); + + // return the ID + matlab::data::ArrayFactory factory; + auto proxyid_mda = factory.createScalar(proxyid); + context.outputs[0] = proxyid_mda; +} + + +void MeterProxy::createHistogram(libmexclass::proxy::method::Context& context) { + // Always assumes 3 inputs + matlab::data::StringArray name_mda = context.inputs[0]; + std::string name = static_cast(name_mda[0]); + matlab::data::StringArray description_mda = context.inputs[1]; + std::string description= static_cast(description_mda[0]); + matlab::data::StringArray unit_mda = context.inputs[2]; + std::string unit = static_cast(unit_mda[0]); + + nostd::shared_ptr > hist = std::move(CppMeter->CreateDoubleHistogram(name, description, unit)); + + // instantiate a HistogramProxy instance + HistogramProxy* newproxy = new HistogramProxy(hist); + auto proxy = std::shared_ptr(newproxy); + + // obtain a proxy ID + libmexclass::proxy::ID proxyid = libmexclass::proxy::ProxyManager::manageProxy(proxy); + + // return the ID + matlab::data::ArrayFactory factory; + auto proxyid_mda = factory.createScalar(proxyid); + context.outputs[0] = proxyid_mda; +} + + +} // namespace libmexclass::opentelemetry