diff --git a/.chloggen/metricsgeneration_relax_type_req.yaml b/.chloggen/metricsgeneration_relax_type_req.yaml new file mode 100644 index 000000000000..cd8ba247c435 --- /dev/null +++ b/.chloggen/metricsgeneration_relax_type_req.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: metricsgenerationprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Allow metric calculations to be done on sum metrics + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [35428] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/processor/metricsgenerationprocessor/README.md b/processor/metricsgenerationprocessor/README.md index 3d81bcad46f7..42498a5ca312 100644 --- a/processor/metricsgenerationprocessor/README.md +++ b/processor/metricsgenerationprocessor/README.md @@ -16,12 +16,14 @@ ## Description -The metrics generation processor (`experimental_metricsgenerationprocessor`) can be used to create new metrics using existing metrics following a given rule. Currently it supports following two approaches for creating a new metric. +The metrics generation processor (`experimental_metricsgenerationprocessor`) can be used to create new metrics using existing metrics following a given rule. This processor currently supports the following two approaches for creating a new metric. -1. It can create a new metric from two existing metrics by applying one of the following arithmetic operations: add, subtract, multiply, divide and percent. One use case is to calculate the `pod.memory.utilization` metric like the following equation- +1. It can create a new metric from two existing metrics by applying one of the following arithmetic operations: add, subtract, multiply, divide, or percent. One use case is to calculate the `pod.memory.utilization` metric like the following equation- `pod.memory.utilization` = (`pod.memory.usage.bytes` / `node.memory.limit`) 1. It can create a new metric by scaling the value of an existing metric with a given constant number. One use case is to convert `pod.memory.usage` metric values from Megabytes to Bytes (multiply the existing metric's value by 1,048,576) +Note: The created metric's type is inherited from the metric configured as `metric1`. + ## Configuration Configuration is specified through a list of generation rules. Generation rules find the metrics which @@ -43,10 +45,10 @@ processors: # type describes how the new metric will be generated. It can be one of `calculate` or `scale`. calculate generates a metric applying the given operation on two operand metrics. scale operates only on operand1 metric to generate the new metric. type: {calculate, scale} - # This is a required field. + # This is a required field. This must be a gauge or sum metric. metric1: - # This field is required only if the type is "calculate". + # This field is required only if the type is "calculate". When required, this must be a gauge or sum metric. metric2: # Operation specifies which arithmetic operation to apply. It must be one of the five supported operations. diff --git a/processor/metricsgenerationprocessor/go.mod b/processor/metricsgenerationprocessor/go.mod index 5e7e10e33aa9..d1c2e84f8d5f 100644 --- a/processor/metricsgenerationprocessor/go.mod +++ b/processor/metricsgenerationprocessor/go.mod @@ -3,6 +3,8 @@ module github.com/open-telemetry/opentelemetry-collector-contrib/processor/metri go 1.22.0 require ( + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.110.0 + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.110.0 github.com/stretchr/testify v1.9.0 go.opentelemetry.io/collector/component v0.110.0 go.opentelemetry.io/collector/confmap v1.16.0 @@ -15,6 +17,7 @@ require ( ) require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -29,6 +32,7 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.110.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect go.opentelemetry.io/collector/component/componentstatus v0.110.0 // indirect @@ -59,3 +63,9 @@ retract ( v0.76.1 v0.65.0 ) + +replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden => ../../pkg/golden + +replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest => ../../pkg/pdatatest + +replace github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil => ../../pkg/pdatautil diff --git a/processor/metricsgenerationprocessor/go.sum b/processor/metricsgenerationprocessor/go.sum index e195251f7c4d..12d9a3eacfd4 100644 --- a/processor/metricsgenerationprocessor/go.sum +++ b/processor/metricsgenerationprocessor/go.sum @@ -1,3 +1,5 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/processor/metricsgenerationprocessor/processor_test.go b/processor/metricsgenerationprocessor/processor_test.go index 49cd25058abe..ef0e62ebfd84 100644 --- a/processor/metricsgenerationprocessor/processor_test.go +++ b/processor/metricsgenerationprocessor/processor_test.go @@ -5,15 +5,21 @@ package metricsgenerationprocessor import ( "context" + "fmt" + "path/filepath" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/consumer/consumertest" "go.opentelemetry.io/collector/pdata/pcommon" "go.opentelemetry.io/collector/pdata/pmetric" "go.opentelemetry.io/collector/processor/processortest" + + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" ) type testMetric struct { @@ -384,3 +390,107 @@ func getOutputForIntGaugeTest() pmetric.Metrics { return intGaugeOutputMetrics } + +func TestSumCalculateNewMetric(t *testing.T) { + next := new(consumertest.MetricsSink) + cfg := &Config{ + Rules: []Rule{ + { + Name: "system.filesystem.capacity", + Unit: "bytes", + Type: "calculate", + Metric1: "system.filesystem.usage", + Metric2: "system.filesystem.utilization", + Operation: "divide", + }, + }, + } + factory := NewFactory() + mgp, err := factory.CreateMetricsProcessor( + context.Background(), + processortest.NewNopSettings(), + cfg, + next, + ) + assert.NotNil(t, mgp) + assert.NoError(t, err) + + assert.True(t, mgp.Capabilities().MutatesData) + require.NoError(t, mgp.Start(context.Background(), nil)) + + inputMetrics, err := golden.ReadMetrics(filepath.Join("testdata", "filesystem_metrics_input.yaml")) + assert.NoError(t, err) + + err = mgp.ConsumeMetrics(context.Background(), inputMetrics) + assert.NoError(t, err) + + got := next.AllMetrics() + // golden.WriteMetrics(t, filepath.Join(".", "testdata", "filesystem_metrics_expected.yaml"), got[0]) + expected, err := golden.ReadMetrics(filepath.Join("testdata", "filesystem_metrics_expected.yaml")) + assert.NoError(t, err) + assert.Len(t, got, 1) + err = pmetrictest.CompareMetrics(expected, got[0], + pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreStartTimestamp(), + pmetrictest.IgnoreTimestamp()) + assert.NoError(t, err) +} + +func TestResultingMetricTypes(t *testing.T) { + testCaseNames := []string{ + "add_sum_sum", + "add_gauge_gauge", + "add_gauge_sum", + "add_sum_gauge", + "multiply_gauge_sum", + "multiply_sum_gauge", + "divide_gauge_sum", + "divide_sum_gauge", + "subtract_gauge_sum", + "subtract_sum_gauge", + "percent_sum_gauge", + "percent_gauge_sum", + } + + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "metric_types", "gauge_sum_metrics_config.yaml")) + assert.NoError(t, err) + + for _, testCase := range testCaseNames { + next := new(consumertest.MetricsSink) + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(fmt.Sprintf("%s/%s", "experimental_metricsgeneration", testCase)) + require.NoError(t, err) + require.NoError(t, sub.Unmarshal(cfg)) + + mgp, err := factory.CreateMetricsProcessor( + context.Background(), + processortest.NewNopSettings(), + cfg, + next, + ) + assert.NotNil(t, mgp) + assert.NoError(t, err) + + assert.True(t, mgp.Capabilities().MutatesData) + require.NoError(t, mgp.Start(context.Background(), nil)) + + inputMetrics, err := golden.ReadMetrics(filepath.Join("testdata", "metric_types", "gauge_sum_metrics_input.yaml")) + assert.NoError(t, err) + + err = mgp.ConsumeMetrics(context.Background(), inputMetrics) + assert.NoError(t, err) + + got := next.AllMetrics() + // golden.WriteMetrics(t, filepath.Join("testdata", "metric_types", fmt.Sprintf("%s_%s", testCase, "expected.yaml")), got[0]) + expected, err := golden.ReadMetrics(filepath.Join("testdata", "metric_types", fmt.Sprintf("%s_%s", testCase, "expected.yaml"))) + assert.NoError(t, err) + assert.Len(t, got, 1) + err = pmetrictest.CompareMetrics(expected, got[0], + pmetrictest.IgnoreMetricDataPointsOrder(), + pmetrictest.IgnoreStartTimestamp(), + pmetrictest.IgnoreTimestamp()) + assert.NoError(t, err) + } +} diff --git a/processor/metricsgenerationprocessor/testdata/filesystem_metrics_expected.yaml b/processor/metricsgenerationprocessor/testdata/filesystem_metrics_expected.yaml new file mode 100644 index 000000000000..b2ac2ec86563 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/filesystem_metrics_expected.yaml @@ -0,0 +1,1205 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: FileSystem inodes used. + name: system.filesystem.inodes.usage + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "2183953600" + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "4770142" + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "2183953600" + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "1813" + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "2183953600" + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "404475" + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "2183953600" + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "24" + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "2183953600" + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "4" + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: free + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "666" + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: used + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: free + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: used + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: '{inodes}' + - description: Filesystem bytes used. + name: system.filesystem.usage + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "223636848640" + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "276326326272" + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "223636848640" + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "276326326272" + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "223636848640" + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "276326326272" + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "223636848640" + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "276326326272" + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "223636848640" + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "276326326272" + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: free + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "197120" + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: used + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: free + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: used + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: Fraction of filesystem bytes used. + gauge: + dataPoints: + - asDouble: 0.5526933585071281 + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0.5526933585071281 + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0.5526933585071281 + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0.5526933585071281 + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0.5526933585071281 + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 1 + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: system.filesystem.utilization + unit: "1" + - name: system.filesystem.capacity + sum: + dataPoints: + - asDouble: 4.046309679639759e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.99963174912e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s1 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.046309679639759e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.99963174912e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s2 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Preboot + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.046309679639759e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.99963174912e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s4s1 + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: / + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.046309679639759e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.99963174912e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s5 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Update + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.046309679639759e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: free + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 4.99963174912e+11 + attributes: + - key: device + value: + stringValue: /dev/disk1s6 + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/VM + - key: state + value: + stringValue: used + - key: type + value: + stringValue: apfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: free + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 356653.46247770725 + attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /dev + - key: state + value: + stringValue: used + - key: type + value: + stringValue: devfs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: free + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: reserved + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asDouble: 0 + attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: /System/Volumes/Data/home + - key: state + value: + stringValue: used + - key: type + value: + stringValue: autofs + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: bytes + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: 0.110.0-dev diff --git a/processor/metricsgenerationprocessor/testdata/filesystem_metrics_input.yaml b/processor/metricsgenerationprocessor/testdata/filesystem_metrics_input.yaml new file mode 100644 index 000000000000..6e4fee3c6c5c --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/filesystem_metrics_input.yaml @@ -0,0 +1,802 @@ +resourceMetrics: + - resource: {} + scopeMetrics: + - scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: 0.110.0-dev + metrics: + - name: system.filesystem.inodes.usage + description: FileSystem inodes used. + unit: "{inodes}" + sum: + dataPoints: + - attributes: + - key: device + value: + stringValue: "/dev/disk1s4s1" + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: "/" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '404475' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s4s1" + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: "/" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '2183953600' + - attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/dev" + - key: type + value: + stringValue: devfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '666' + - attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/dev" + - key: type + value: + stringValue: devfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s2" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Preboot" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '1813' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s2" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Preboot" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '2183953600' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s6" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/VM" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '4' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s6" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/VM" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '2183953600' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s5" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Update" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '24' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s5" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Update" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '2183953600' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s1" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '4770142' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s1" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '2183953600' + - attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data/home" + - key: type + value: + stringValue: autofs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data/home" + - key: type + value: + stringValue: autofs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + aggregationTemporality: 2 + - name: system.filesystem.usage + description: Filesystem bytes used. + unit: By + sum: + dataPoints: + - attributes: + - key: device + value: + stringValue: "/dev/disk1s4s1" + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: "/" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '276326326272' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s4s1" + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: "/" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '223636848640' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s4s1" + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: "/" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/dev" + - key: type + value: + stringValue: devfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '197120' + - attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/dev" + - key: type + value: + stringValue: devfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/dev" + - key: type + value: + stringValue: devfs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s2" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Preboot" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '276326326272' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s2" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Preboot" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '223636848640' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s2" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Preboot" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s6" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/VM" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '276326326272' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s6" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/VM" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '223636848640' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s6" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/VM" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s5" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Update" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '276326326272' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s5" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Update" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '223636848640' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s5" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Update" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s1" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '276326326272' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s1" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '223636848640' + - attributes: + - key: device + value: + stringValue: "/dev/disk1s1" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data" + - key: type + value: + stringValue: apfs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data/home" + - key: type + value: + stringValue: autofs + - key: state + value: + stringValue: used + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data/home" + - key: type + value: + stringValue: autofs + - key: state + value: + stringValue: free + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + - attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data/home" + - key: type + value: + stringValue: autofs + - key: state + value: + stringValue: reserved + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asInt: '0' + aggregationTemporality: 2 + - name: system.filesystem.utilization + description: Fraction of filesystem bytes used. + unit: '1' + gauge: + dataPoints: + - attributes: + - key: device + value: + stringValue: "/dev/disk1s4s1" + - key: mode + value: + stringValue: ro + - key: mountpoint + value: + stringValue: "/" + - key: type + value: + stringValue: apfs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 0.5526933585071281 + - attributes: + - key: device + value: + stringValue: devfs + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/dev" + - key: type + value: + stringValue: devfs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 1 + - attributes: + - key: device + value: + stringValue: "/dev/disk1s2" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Preboot" + - key: type + value: + stringValue: apfs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 0.5526933585071281 + - attributes: + - key: device + value: + stringValue: "/dev/disk1s6" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/VM" + - key: type + value: + stringValue: apfs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 0.5526933585071281 + - attributes: + - key: device + value: + stringValue: "/dev/disk1s5" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Update" + - key: type + value: + stringValue: apfs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 0.5526933585071281 + - attributes: + - key: device + value: + stringValue: "/dev/disk1s1" + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data" + - key: type + value: + stringValue: apfs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 0.5526933585071281 + - attributes: + - key: device + value: + stringValue: map auto_home + - key: mode + value: + stringValue: rw + - key: mountpoint + value: + stringValue: "/System/Volumes/Data/home" + - key: type + value: + stringValue: autofs + startTimeUnixNano: '1726497870000000000' + timeUnixNano: '1727303734559741000' + asDouble: 0 + schemaUrl: https://opentelemetry.io/schemas/1.9.0 diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/add_gauge_gauge_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/add_gauge_gauge_expected.yaml new file mode 100644 index 000000000000..9bfcbb8c0c9f --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/add_gauge_gauge_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - gauge: + dataPoints: + - asDouble: 100 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: new_metric + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/add_gauge_sum_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/add_gauge_sum_expected.yaml new file mode 100644 index 000000000000..ee7c710d0414 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/add_gauge_sum_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - gauge: + dataPoints: + - asDouble: 1050 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: new_metric + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/add_sum_gauge_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/add_sum_gauge_expected.yaml new file mode 100644 index 000000000000..1769886855bb --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/add_sum_gauge_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - name: new_metric + sum: + dataPoints: + - asDouble: 1050 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/add_sum_sum_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/add_sum_sum_expected.yaml new file mode 100644 index 000000000000..a198c0c8a435 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/add_sum_sum_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - name: new_metric + sum: + dataPoints: + - asDouble: 2000 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/divide_gauge_sum_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/divide_gauge_sum_expected.yaml new file mode 100644 index 000000000000..dc7a2f34c64c --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/divide_gauge_sum_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - gauge: + dataPoints: + - asDouble: 50000 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: new_metric + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/divide_sum_gauge_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/divide_sum_gauge_expected.yaml new file mode 100644 index 000000000000..1aea52d63388 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/divide_sum_gauge_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - name: new_metric + sum: + dataPoints: + - asDouble: 20 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/gauge_sum_metrics_config.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/gauge_sum_metrics_config.yaml new file mode 100644 index 000000000000..9af299c78caa --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/gauge_sum_metrics_config.yaml @@ -0,0 +1,96 @@ +experimental_metricsgeneration/add_sum_sum: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: sum + metric2: sum + operation: add +experimental_metricsgeneration/add_gauge_gauge: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: gauge + metric2: gauge + operation: add +experimental_metricsgeneration/add_gauge_sum: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: gauge + metric2: sum + operation: add +experimental_metricsgeneration/add_sum_gauge: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: sum + metric2: gauge + operation: add +experimental_metricsgeneration/multiply_gauge_sum: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: gauge + metric2: sum + operation: multiply +experimental_metricsgeneration/multiply_sum_gauge: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: sum + metric2: gauge + operation: multiply +experimental_metricsgeneration/divide_gauge_sum: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: gauge + metric2: sum + operation: multiply +experimental_metricsgeneration/divide_sum_gauge: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: sum + metric2: gauge + operation: divide +experimental_metricsgeneration/subtract_gauge_sum: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: gauge + metric2: sum + operation: subtract +experimental_metricsgeneration/subtract_sum_gauge: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: sum + metric2: gauge + operation: subtract +experimental_metricsgeneration/percent_gauge_sum: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: gauge + metric2: sum + operation: percent +experimental_metricsgeneration/percent_sum_gauge: + rules: + - name: new_metric + unit: percent + type: calculate + metric1: sum + metric2: gauge + operation: percent \ No newline at end of file diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/gauge_sum_metrics_input.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/gauge_sum_metrics_input.yaml new file mode 100644 index 000000000000..cc63a8a46ead --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/gauge_sum_metrics_input.yaml @@ -0,0 +1,25 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: "50" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/multiply_gauge_sum_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/multiply_gauge_sum_expected.yaml new file mode 100644 index 000000000000..dc7a2f34c64c --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/multiply_gauge_sum_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - gauge: + dataPoints: + - asDouble: 50000 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: new_metric + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/multiply_sum_gauge_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/multiply_sum_gauge_expected.yaml new file mode 100644 index 000000000000..1e6a0afba6c0 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/multiply_sum_gauge_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - name: new_metric + sum: + dataPoints: + - asDouble: 50000 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/percent_gauge_sum_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/percent_gauge_sum_expected.yaml new file mode 100644 index 000000000000..345f5a96576b --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/percent_gauge_sum_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - gauge: + dataPoints: + - asDouble: 5 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: new_metric + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/percent_sum_gauge_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/percent_sum_gauge_expected.yaml new file mode 100644 index 000000000000..a198c0c8a435 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/percent_sum_gauge_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - name: new_metric + sum: + dataPoints: + - asDouble: 2000 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/subtract_gauge_sum_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/subtract_gauge_sum_expected.yaml new file mode 100644 index 000000000000..d2ab7b52109f --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/subtract_gauge_sum_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - gauge: + dataPoints: + - asDouble: -950 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: new_metric + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/testdata/metric_types/subtract_sum_gauge_expected.yaml b/processor/metricsgenerationprocessor/testdata/metric_types/subtract_sum_gauge_expected.yaml new file mode 100644 index 000000000000..190498b748f5 --- /dev/null +++ b/processor/metricsgenerationprocessor/testdata/metric_types/subtract_sum_gauge_expected.yaml @@ -0,0 +1,32 @@ +resourceMetrics: + - resource: {} + schemaUrl: https://opentelemetry.io/schemas/1.9.0 + scopeMetrics: + - metrics: + - description: foo + name: sum + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1000" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: bar + gauge: + dataPoints: + - asDouble: 50 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + name: gauge + unit: "1" + - name: new_metric + sum: + dataPoints: + - asDouble: 950 + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: percent + scope: + name: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/hostmetricsreceiver/internal/scraper/filesystemscraper + version: latest diff --git a/processor/metricsgenerationprocessor/utils.go b/processor/metricsgenerationprocessor/utils.go index af613fdb0992..beb001a383b1 100644 --- a/processor/metricsgenerationprocessor/utils.go +++ b/processor/metricsgenerationprocessor/utils.go @@ -4,6 +4,8 @@ package metricsgenerationprocessor // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/metricsgenerationprocessor" import ( + "fmt" + "go.opentelemetry.io/collector/pdata/pmetric" "go.uber.org/zap" ) @@ -25,24 +27,31 @@ func getNameToMetricMap(rm pmetric.ResourceMetrics) map[string]pmetric.Metric { // getMetricValue returns the value of the first data point from the given metric. func getMetricValue(metric pmetric.Metric) float64 { - if metric.Type() == pmetric.MetricTypeGauge { - dataPoints := metric.Gauge().DataPoints() - if dataPoints.Len() > 0 { - switch dataPoints.At(0).ValueType() { - case pmetric.NumberDataPointValueTypeDouble: - return dataPoints.At(0).DoubleValue() - case pmetric.NumberDataPointValueTypeInt: - return float64(dataPoints.At(0).IntValue()) - } - } + var dataPoints pmetric.NumberDataPointSlice + + switch metricType := metric.Type(); metricType { + case pmetric.MetricTypeGauge: + dataPoints = metric.Gauge().DataPoints() + case pmetric.MetricTypeSum: + dataPoints = metric.Sum().DataPoints() + default: return 0 } + + if dataPoints.Len() > 0 { + switch dataPoints.At(0).ValueType() { + case pmetric.NumberDataPointValueTypeDouble: + return dataPoints.At(0).DoubleValue() + case pmetric.NumberDataPointValueTypeInt: + return float64(dataPoints.At(0).IntValue()) + } + } + return 0 } // generateMetrics creates a new metric based on the given rule and add it to the Resource Metric. -// The value for newly calculated metrics is always a floting point number and the dataType is set -// as MetricTypeDoubleGauge. +// The value for newly calculated metrics is always a floating point number. func generateMetrics(rm pmetric.ResourceMetrics, operand2 float64, rule internalRule, logger *zap.Logger) { ilms := rm.ScopeMetrics() for i := 0; i < ilms.Len(); i++ { @@ -52,15 +61,27 @@ func generateMetrics(rm pmetric.ResourceMetrics, operand2 float64, rule internal metric := metricSlice.At(j) if metric.Name() == rule.metric1 { newMetric := appendMetric(ilm, rule.name, rule.unit) - newMetric.SetEmptyGauge() - addDoubleGaugeDataPoints(metric, newMetric, operand2, rule.operation, logger) + addDoubleDataPoints(metric, newMetric, operand2, rule.operation, logger) } } } } -func addDoubleGaugeDataPoints(from pmetric.Metric, to pmetric.Metric, operand2 float64, operation string, logger *zap.Logger) { - dataPoints := from.Gauge().DataPoints() +func addDoubleDataPoints(from pmetric.Metric, to pmetric.Metric, operand2 float64, operation string, logger *zap.Logger) { + var dataPoints pmetric.NumberDataPointSlice + + switch metricType := from.Type(); metricType { + case pmetric.MetricTypeGauge: + to.SetEmptyGauge() + dataPoints = from.Gauge().DataPoints() + case pmetric.MetricTypeSum: + to.SetEmptySum() + dataPoints = from.Sum().DataPoints() + default: + logger.Debug(fmt.Sprintf("Calculations are only supported on gauge or sum metric types. Given metric '%s' is of type `%s`", from.Name(), metricType.String())) + return + } + for i := 0; i < dataPoints.Len(); i++ { fromDataPoint := dataPoints.At(i) var operand1 float64 @@ -71,7 +92,14 @@ func addDoubleGaugeDataPoints(from pmetric.Metric, to pmetric.Metric, operand2 f operand1 = float64(fromDataPoint.IntValue()) } - neweDoubleDataPoint := to.Gauge().DataPoints().AppendEmpty() + var neweDoubleDataPoint pmetric.NumberDataPoint + switch to.Type() { + case pmetric.MetricTypeGauge: + neweDoubleDataPoint = to.Gauge().DataPoints().AppendEmpty() + case pmetric.MetricTypeSum: + neweDoubleDataPoint = to.Sum().DataPoints().AppendEmpty() + } + fromDataPoint.CopyTo(neweDoubleDataPoint) value := calculateValue(operand1, operand2, operation, logger, to.Name()) neweDoubleDataPoint.SetDoubleValue(value)