You've already forked opentelemetry-go
							
							
				mirror of
				https://github.com/open-telemetry/opentelemetry-go.git
				synced 2025-10-31 00:07:40 +02:00 
			
		
		
		
	Introduce "split" metric schema transformation (#2999)
This is a new transformation type that allows to describe a change where a metric is converted to several other metrics by eliminating an attribute. An example of such change that happened recently is this: https://github.com/open-telemetry/opentelemetry-specification/pull/2617 This PR implements specification change https://github.com/open-telemetry/opentelemetry-specification/pull/2653 This PR creates package v1.1 for the new functionality. The old package v1.0 remains unchanged.
This commit is contained in:
		| @@ -26,6 +26,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm | ||||
|  | ||||
| - Add support for `opentracing.TextMap` format in the `Inject` and `Extract` methods | ||||
| of the `"go.opentelemetry.io/otel/bridge/opentracing".BridgeTracer` type. (#2911) | ||||
| - Add support for Schema Files format 1.1.x (metric "split" transform). (#2999) | ||||
|  | ||||
| ### Changed | ||||
|  | ||||
|   | ||||
| @@ -11,9 +11,9 @@ then import the corresponding package and use the `Parse` or `ParseFile` functio | ||||
| like this: | ||||
|  | ||||
| ```go | ||||
| import schema "go.opentelemetry.io/otel/schema/v1.0" | ||||
| import schema "go.opentelemetry.io/otel/schema/v1.1" | ||||
|  | ||||
| // Load the schema from a file in v1.0.x file format. | ||||
| // Load the schema from a file in v1.1.x file format. | ||||
| func loadSchemaFromFile() error { | ||||
| 	telSchema, err := schema.ParseFile("schema-file.yaml") | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										74
									
								
								schema/internal/parser_checks.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								schema/internal/parser_checks.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package internal // import "go.opentelemetry.io/otel/schema/internal" | ||||
|  | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/Masterminds/semver/v3" | ||||
| ) | ||||
|  | ||||
| // CheckFileFormatField validates the file format field according to the rules here: | ||||
| // https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md#schema-file-format-number | ||||
| func CheckFileFormatField(fileFormat string, supportedFormatMajor, supportedFormatMinor int) error { | ||||
| 	// Verify that the version number in the file is a semver. | ||||
| 	fileFormatParsed, err := semver.StrictNewVersion(fileFormat) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf( | ||||
| 			"invalid schema file format version number %q (expected semver): %w", | ||||
| 			fileFormat, err, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	// Check that the major version number in the file is the same as what we expect. | ||||
| 	if fileFormatParsed.Major() != uint64(supportedFormatMajor) { | ||||
| 		return fmt.Errorf( | ||||
| 			"this library cannot parse file formats with major version other than %v", | ||||
| 			supportedFormatMajor, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	// Check that the file minor version number is not greater than | ||||
| 	// what is requested supports. | ||||
| 	if fileFormatParsed.Minor() > uint64(supportedFormatMinor) { | ||||
| 		supportedFormatMajorMinor := strconv.Itoa(supportedFormatMajor) + "." + | ||||
| 			strconv.Itoa(supportedFormatMinor) // 1.0 | ||||
|  | ||||
| 		return fmt.Errorf( | ||||
| 			"unsupported schema file format minor version number, expected no newer than %v, got %v", | ||||
| 			supportedFormatMajorMinor+".x", fileFormat, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	// Patch, prerelease and metadata version number does not matter, so we don't check it. | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // CheckSchemaURL verifies that schemaURL is valid. | ||||
| func CheckSchemaURL(schemaURL string) error { | ||||
| 	if strings.TrimSpace(schemaURL) == "" { | ||||
| 		return errors.New("schema_url field is missing") | ||||
| 	} | ||||
|  | ||||
| 	if _, err := url.Parse(schemaURL); err != nil { | ||||
| 		return fmt.Errorf("invalid URL specified in schema_url field: %w", err) | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										41
									
								
								schema/internal/parser_checks_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								schema/internal/parser_checks_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package internal // import "go.opentelemetry.io/otel/schema/internal" | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestCheckFileFormatField(t *testing.T) { | ||||
| 	// Invalid file format version numbers. | ||||
| 	assert.Error(t, CheckFileFormatField("not a semver", 1, 0)) | ||||
| 	assert.Error(t, CheckFileFormatField("2.0.0", 1, 0)) | ||||
| 	assert.Error(t, CheckFileFormatField("1.1.0", 1, 0)) | ||||
|  | ||||
| 	assert.Error(t, CheckFileFormatField("1.2.0", 1, 1)) | ||||
|  | ||||
| 	// Valid cases. | ||||
| 	assert.NoError(t, CheckFileFormatField("1.0.0", 1, 0)) | ||||
| 	assert.NoError(t, CheckFileFormatField("1.0.1", 1, 0)) | ||||
| 	assert.NoError(t, CheckFileFormatField("1.0.10000-alpha+4857", 1, 0)) | ||||
|  | ||||
| 	assert.NoError(t, CheckFileFormatField("1.0.0", 1, 1)) | ||||
| 	assert.NoError(t, CheckFileFormatField("1.0.1", 1, 1)) | ||||
| 	assert.NoError(t, CheckFileFormatField("1.0.10000-alpha+4857", 1, 1)) | ||||
| 	assert.NoError(t, CheckFileFormatField("1.1.0", 1, 1)) | ||||
| 	assert.NoError(t, CheckFileFormatField("1.1.1", 1, 1)) | ||||
| } | ||||
| @@ -15,16 +15,12 @@ | ||||
| package schema // import "go.opentelemetry.io/otel/schema/v1.0" | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net/url" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/Masterminds/semver/v3" | ||||
| 	"gopkg.in/yaml.v2" | ||||
|  | ||||
| 	"go.opentelemetry.io/otel/schema/internal" | ||||
| 	"go.opentelemetry.io/otel/schema/v1.0/ast" | ||||
| ) | ||||
|  | ||||
| @@ -34,10 +30,6 @@ const supportedFormatMajor = 1 | ||||
| // Maximum minor version number that this library supports. | ||||
| const supportedFormatMinor = 0 | ||||
|  | ||||
| // Maximum major+minor version number that this library supports, as a string. | ||||
| var supportedFormatMajorMinor = strconv.Itoa(supportedFormatMajor) + "." + | ||||
| 	strconv.Itoa(supportedFormatMinor) // 1.0 | ||||
|  | ||||
| // ParseFile a schema file. schemaFilePath is the file path. | ||||
| func ParseFile(schemaFilePath string) (*ast.Schema, error) { | ||||
| 	file, err := os.Open(schemaFilePath) | ||||
| @@ -56,51 +48,15 @@ func Parse(schemaFileContent io.Reader) (*ast.Schema, error) { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if err := checkFileFormatField(ts.FileFormat); err != nil { | ||||
| 	err = internal.CheckFileFormatField(ts.FileFormat, supportedFormatMajor, supportedFormatMinor) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	if strings.TrimSpace(ts.SchemaURL) == "" { | ||||
| 		return nil, fmt.Errorf("schema_url field is missing") | ||||
| 	} | ||||
|  | ||||
| 	if _, err := url.Parse(ts.SchemaURL); err != nil { | ||||
| 		return nil, fmt.Errorf("invalid URL specified in schema_url field: %w", err) | ||||
| 	err = internal.CheckSchemaURL(ts.SchemaURL) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &ts, nil | ||||
| } | ||||
|  | ||||
| // checkFileFormatField validates the file format field according to the rules here: | ||||
| // https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md#schema-file-format-number | ||||
| func checkFileFormatField(fileFormat string) error { | ||||
| 	// Verify that the version number in the file is a semver. | ||||
| 	fileFormatParsed, err := semver.StrictNewVersion(fileFormat) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf( | ||||
| 			"invalid schema file format version number %q (expected semver): %w", | ||||
| 			fileFormat, err, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	// Check that the major version number in the file is the same as what we expect. | ||||
| 	if fileFormatParsed.Major() != supportedFormatMajor { | ||||
| 		return fmt.Errorf( | ||||
| 			"this library cannot parse file formats with major version other than %v", | ||||
| 			supportedFormatMajor, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	// Check that the file minor version number is not greater than | ||||
| 	// what is requested supports. | ||||
| 	if fileFormatParsed.Minor() > supportedFormatMinor { | ||||
| 		return fmt.Errorf( | ||||
| 			"unsupported schema file format minor version number, expected no newer than %v, got %v", | ||||
| 			supportedFormatMajorMinor+".x", fileFormat, | ||||
| 		) | ||||
| 	} | ||||
|  | ||||
| 	// Patch, prerelease and metadata version number does not matter, so we don't check it. | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -28,123 +28,132 @@ func TestParseSchemaFile(t *testing.T) { | ||||
| 	ts, err := ParseFile("testdata/valid-example.yaml") | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.NotNil(t, ts) | ||||
| 	assert.EqualValues(t, &ast.Schema{ | ||||
| 		FileFormat: "1.0.0", | ||||
| 		SchemaURL:  "https://opentelemetry.io/schemas/1.1.0", | ||||
| 		Versions: map[types.TelemetryVersion]ast.VersionDef{ | ||||
| 			"1.0.0": {}, | ||||
| 	assert.EqualValues( | ||||
| 		t, &ast.Schema{ | ||||
| 			FileFormat: "1.0.0", | ||||
| 			SchemaURL:  "https://opentelemetry.io/schemas/1.1.0", | ||||
| 			Versions: map[types.TelemetryVersion]ast.VersionDef{ | ||||
| 				"1.0.0": {}, | ||||
|  | ||||
| 			"1.1.0": { | ||||
| 				All: ast.Attributes{ | ||||
| 					Changes: []ast.AttributeChange{ | ||||
| 						{RenameAttributes: &ast.AttributeMap{ | ||||
| 							"k8s.cluster.name":     "kubernetes.cluster.name", | ||||
| 							"k8s.namespace.name":   "kubernetes.namespace.name", | ||||
| 							"k8s.node.name":        "kubernetes.node.name", | ||||
| 							"k8s.node.uid":         "kubernetes.node.uid", | ||||
| 							"k8s.pod.name":         "kubernetes.pod.name", | ||||
| 							"k8s.pod.uid":          "kubernetes.pod.uid", | ||||
| 							"k8s.container.name":   "kubernetes.container.name", | ||||
| 							"k8s.replicaset.name":  "kubernetes.replicaset.name", | ||||
| 							"k8s.replicaset.uid":   "kubernetes.replicaset.uid", | ||||
| 							"k8s.cronjob.name":     "kubernetes.cronjob.name", | ||||
| 							"k8s.cronjob.uid":      "kubernetes.cronjob.uid", | ||||
| 							"k8s.job.name":         "kubernetes.job.name", | ||||
| 							"k8s.job.uid":          "kubernetes.job.uid", | ||||
| 							"k8s.statefulset.name": "kubernetes.statefulset.name", | ||||
| 							"k8s.statefulset.uid":  "kubernetes.statefulset.uid", | ||||
| 							"k8s.daemonset.name":   "kubernetes.daemonset.name", | ||||
| 							"k8s.daemonset.uid":    "kubernetes.daemonset.uid", | ||||
| 							"k8s.deployment.name":  "kubernetes.deployment.name", | ||||
| 							"k8s.deployment.uid":   "kubernetes.deployment.uid", | ||||
| 							"service.namespace":    "service.namespace.name", | ||||
| 						}}, | ||||
| 					}, | ||||
| 				}, | ||||
|  | ||||
| 				Resources: ast.Attributes{ | ||||
| 					Changes: []ast.AttributeChange{ | ||||
| 						{ | ||||
| 							RenameAttributes: &ast.AttributeMap{ | ||||
| 								"telemetry.auto.version": "telemetry.auto_instr.version", | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
|  | ||||
| 				Spans: ast.Spans{ | ||||
| 					Changes: []ast.SpansChange{ | ||||
| 						{ | ||||
| 							RenameAttributes: &ast.AttributeMapForSpans{ | ||||
| 								AttributeMap: ast.AttributeMap{ | ||||
| 									"peer.service": "peer.service.name", | ||||
| 								}, | ||||
| 								ApplyToSpans: []types.SpanName{"HTTP GET"}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
|  | ||||
| 				SpanEvents: ast.SpanEvents{ | ||||
| 					Changes: []ast.SpanEventsChange{ | ||||
| 						{ | ||||
| 							RenameEvents: &ast.RenameSpanEvents{ | ||||
| 								EventNameMap: map[string]string{ | ||||
| 									"exception.stacktrace": "exception.stack_trace", | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 						{ | ||||
| 							RenameAttributes: &ast.RenameSpanEventAttributes{ | ||||
| 								ApplyToEvents: []types.EventName{"exception.stack_trace"}, | ||||
| 								AttributeMap: ast.AttributeMap{ | ||||
| 									"peer.service": "peer.service.name", | ||||
| 				"1.1.0": { | ||||
| 					All: ast.Attributes{ | ||||
| 						Changes: []ast.AttributeChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.AttributeMap{ | ||||
| 									"k8s.cluster.name":     "kubernetes.cluster.name", | ||||
| 									"k8s.namespace.name":   "kubernetes.namespace.name", | ||||
| 									"k8s.node.name":        "kubernetes.node.name", | ||||
| 									"k8s.node.uid":         "kubernetes.node.uid", | ||||
| 									"k8s.pod.name":         "kubernetes.pod.name", | ||||
| 									"k8s.pod.uid":          "kubernetes.pod.uid", | ||||
| 									"k8s.container.name":   "kubernetes.container.name", | ||||
| 									"k8s.replicaset.name":  "kubernetes.replicaset.name", | ||||
| 									"k8s.replicaset.uid":   "kubernetes.replicaset.uid", | ||||
| 									"k8s.cronjob.name":     "kubernetes.cronjob.name", | ||||
| 									"k8s.cronjob.uid":      "kubernetes.cronjob.uid", | ||||
| 									"k8s.job.name":         "kubernetes.job.name", | ||||
| 									"k8s.job.uid":          "kubernetes.job.uid", | ||||
| 									"k8s.statefulset.name": "kubernetes.statefulset.name", | ||||
| 									"k8s.statefulset.uid":  "kubernetes.statefulset.uid", | ||||
| 									"k8s.daemonset.name":   "kubernetes.daemonset.name", | ||||
| 									"k8s.daemonset.uid":    "kubernetes.daemonset.uid", | ||||
| 									"k8s.deployment.name":  "kubernetes.deployment.name", | ||||
| 									"k8s.deployment.uid":   "kubernetes.deployment.uid", | ||||
| 									"service.namespace":    "service.namespace.name", | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
|  | ||||
| 				Logs: ast.Logs{Changes: []ast.LogsChange{ | ||||
| 					{RenameAttributes: &ast.RenameAttributes{ | ||||
| 						AttributeMap: map[string]string{ | ||||
| 							"process.executable_name": "process.executable.name", | ||||
| 						}, | ||||
| 					}}, | ||||
| 				}}, | ||||
|  | ||||
| 				Metrics: ast.Metrics{ | ||||
| 					Changes: []ast.MetricsChange{ | ||||
| 						{ | ||||
| 							RenameAttributes: &ast.AttributeMapForMetrics{ | ||||
| 								AttributeMap: map[string]string{ | ||||
| 									"http.status_code": "http.response_status_code", | ||||
| 					Resources: ast.Attributes{ | ||||
| 						Changes: []ast.AttributeChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.AttributeMap{ | ||||
| 									"telemetry.auto.version": "telemetry.auto_instr.version", | ||||
| 								}, | ||||
| 							}}, | ||||
| 						{ | ||||
| 							RenameMetrics: map[types.MetricName]types.MetricName{ | ||||
| 								"container.cpu.usage.total":  "cpu.usage.total", | ||||
| 								"container.memory.usage.max": "memory.usage.max", | ||||
| 							}, | ||||
| 						}, | ||||
| 						{ | ||||
| 							RenameAttributes: &ast.AttributeMapForMetrics{ | ||||
| 								ApplyToMetrics: []types.MetricName{ | ||||
| 									"system.cpu.utilization", | ||||
| 									"system.memory.usage", | ||||
| 									"system.memory.utilization", | ||||
| 									"system.paging.usage", | ||||
| 					}, | ||||
|  | ||||
| 					Spans: ast.Spans{ | ||||
| 						Changes: []ast.SpansChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.AttributeMapForSpans{ | ||||
| 									AttributeMap: ast.AttributeMap{ | ||||
| 										"peer.service": "peer.service.name", | ||||
| 									}, | ||||
| 									ApplyToSpans: []types.SpanName{"HTTP GET"}, | ||||
| 								}, | ||||
| 								AttributeMap: map[string]string{ | ||||
| 									"status": "state", | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					SpanEvents: ast.SpanEvents{ | ||||
| 						Changes: []ast.SpanEventsChange{ | ||||
| 							{ | ||||
| 								RenameEvents: &ast.RenameSpanEvents{ | ||||
| 									EventNameMap: map[string]string{ | ||||
| 										"exception.stacktrace": "exception.stack_trace", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.RenameSpanEventAttributes{ | ||||
| 									ApplyToEvents: []types.EventName{"exception.stack_trace"}, | ||||
| 									AttributeMap: ast.AttributeMap{ | ||||
| 										"peer.service": "peer.service.name", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					Logs: ast.Logs{ | ||||
| 						Changes: []ast.LogsChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.RenameAttributes{ | ||||
| 									AttributeMap: map[string]string{ | ||||
| 										"process.executable_name": "process.executable.name", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					Metrics: ast.Metrics{ | ||||
| 						Changes: []ast.MetricsChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.AttributeMapForMetrics{ | ||||
| 									AttributeMap: map[string]string{ | ||||
| 										"http.status_code": "http.response_status_code", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								RenameMetrics: map[types.MetricName]types.MetricName{ | ||||
| 									"container.cpu.usage.total":  "cpu.usage.total", | ||||
| 									"container.memory.usage.max": "memory.usage.max", | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								RenameAttributes: &ast.AttributeMapForMetrics{ | ||||
| 									ApplyToMetrics: []types.MetricName{ | ||||
| 										"system.cpu.utilization", | ||||
| 										"system.memory.usage", | ||||
| 										"system.memory.utilization", | ||||
| 										"system.paging.usage", | ||||
| 									}, | ||||
| 									AttributeMap: map[string]string{ | ||||
| 										"status": "state", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	}, ts) | ||||
| 		}, ts, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func TestFailParseSchemaFile(t *testing.T) { | ||||
| @@ -167,15 +176,3 @@ func TestFailParseSchema(t *testing.T) { | ||||
| 	_, err = Parse(bytes.NewReader([]byte("file_format: 1.0.0"))) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  | ||||
| func TestCheckFileFormatField(t *testing.T) { | ||||
| 	// Invalid file format version numbers. | ||||
| 	assert.Error(t, checkFileFormatField("not a semver")) | ||||
| 	assert.Error(t, checkFileFormatField("2.0.0")) | ||||
| 	assert.Error(t, checkFileFormatField("1.1.0")) | ||||
|  | ||||
| 	// Valid cases. | ||||
| 	assert.NoError(t, checkFileFormatField("1.0.0")) | ||||
| 	assert.NoError(t, checkFileFormatField("1.0.1")) | ||||
| 	assert.NoError(t, checkFileFormatField("1.0.10000-alpha+4857")) | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| file_format: 1.1.0 | ||||
| schema_url: https://opentelemetry.io/schemas/1.1.0 | ||||
|  | ||||
| versions: | ||||
|   1.1.0: | ||||
|   | ||||
							
								
								
									
										50
									
								
								schema/v1.1/ast/ast_schema.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								schema/v1.1/ast/ast_schema.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package ast // import "go.opentelemetry.io/otel/schema/v1.1/ast" | ||||
|  | ||||
| import ( | ||||
| 	ast10 "go.opentelemetry.io/otel/schema/v1.0/ast" | ||||
| 	"go.opentelemetry.io/otel/schema/v1.1/types" | ||||
| ) | ||||
|  | ||||
| // Schema represents a Schema file in FileFormat 1.1.0 as defined in | ||||
| // https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md | ||||
| type Schema struct { | ||||
| 	// Schema file format. SHOULD be 1.1.0 for the current specification version. | ||||
| 	// See https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md#schema-file-format-number | ||||
| 	FileFormat string `yaml:"file_format"` | ||||
|  | ||||
| 	// Schema URL is an identifier of a Schema. The URL specifies a location of this | ||||
| 	// Schema File that can be retrieved (so it is a URL and not just a URI) using HTTP | ||||
| 	// or HTTPS protocol. | ||||
| 	// See https://github.com/open-telemetry/oteps/blob/main/text/0152-telemetry-schemas.md#schema-url | ||||
| 	SchemaURL string `yaml:"schema_url"` | ||||
|  | ||||
| 	// Versions section that lists changes that happened in each particular version. | ||||
| 	Versions map[types.TelemetryVersion]VersionDef | ||||
| } | ||||
|  | ||||
| // VersionDef corresponds to a section representing one version under the "versions" | ||||
| // top-level key. | ||||
| // Note that most of the fields are the same as in ast 1.0 package, only Metrics are defined | ||||
| // differently, since only that field has changed from 1.0 to 1.1 of schema file format. | ||||
| type VersionDef struct { | ||||
| 	All        ast10.Attributes | ||||
| 	Resources  ast10.Attributes | ||||
| 	Spans      ast10.Spans | ||||
| 	SpanEvents ast10.SpanEvents `yaml:"span_events"` | ||||
| 	Logs       ast10.Logs | ||||
| 	Metrics    Metrics | ||||
| } | ||||
							
								
								
									
										52
									
								
								schema/v1.1/ast/metrics.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								schema/v1.1/ast/metrics.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package ast // import "go.opentelemetry.io/otel/schema/v1.1/ast" | ||||
|  | ||||
| import ( | ||||
| 	ast10 "go.opentelemetry.io/otel/schema/v1.0/ast" | ||||
| 	types10 "go.opentelemetry.io/otel/schema/v1.0/types" | ||||
| 	types11 "go.opentelemetry.io/otel/schema/v1.1/types" | ||||
| ) | ||||
|  | ||||
| // Metrics corresponds to a section representing a list of changes that happened | ||||
| // to metrics schema in a particular version. | ||||
| type Metrics struct { | ||||
| 	Changes []MetricsChange | ||||
| } | ||||
|  | ||||
| // MetricsChange corresponds to a section representing metrics change. | ||||
| type MetricsChange struct { | ||||
| 	RenameMetrics    map[types10.MetricName]types10.MetricName `yaml:"rename_metrics"` | ||||
| 	RenameAttributes *ast10.AttributeMapForMetrics             `yaml:"rename_attributes"` | ||||
| 	Split            *SplitMetric                              `yaml:"split"` | ||||
| } | ||||
|  | ||||
| // SplitMetric  corresponds to a section representing a splitting of a metric | ||||
| // into multiple metrics by eliminating an attribute. | ||||
| // SplitMetrics is introduced in schema file format 1.1, | ||||
| // see https://github.com/open-telemetry/opentelemetry-specification/pull/2653 | ||||
| type SplitMetric struct { | ||||
| 	// Name of the old metric to split. | ||||
| 	ApplyToMetric types10.MetricName `yaml:"apply_to_metric"` | ||||
|  | ||||
| 	// Name of attribute in the old metric to use for splitting. The attribute will be | ||||
| 	// eliminated, the new metric will not have it. | ||||
| 	ByAttribute types11.AttributeName `yaml:"by_attribute"` | ||||
|  | ||||
| 	// Names of new metrics to create, one for each possible value of attribute. | ||||
| 	// map of key/values. The keys are the new metric name starting from this version, | ||||
| 	// the values are old attribute value used in the previous version. | ||||
| 	MetricsFromAttributes map[types10.MetricName]types11.AttributeValue `yaml:"metrics_from_attributes"` | ||||
| } | ||||
							
								
								
									
										62
									
								
								schema/v1.1/parser.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								schema/v1.1/parser.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package schema // import "go.opentelemetry.io/otel/schema/v1.1" | ||||
|  | ||||
| import ( | ||||
| 	"io" | ||||
| 	"os" | ||||
|  | ||||
| 	"gopkg.in/yaml.v2" | ||||
|  | ||||
| 	"go.opentelemetry.io/otel/schema/internal" | ||||
| 	"go.opentelemetry.io/otel/schema/v1.1/ast" | ||||
| ) | ||||
|  | ||||
| // Major file version number that this library supports. | ||||
| const supportedFormatMajor = 1 | ||||
|  | ||||
| // Maximum minor version number that this library supports. | ||||
| const supportedFormatMinor = 1 | ||||
|  | ||||
| // ParseFile a schema file. schemaFilePath is the file path. | ||||
| func ParseFile(schemaFilePath string) (*ast.Schema, error) { | ||||
| 	file, err := os.Open(schemaFilePath) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return Parse(file) | ||||
| } | ||||
|  | ||||
| // Parse a schema file. schemaFileContent is the readable content of the schema file. | ||||
| func Parse(schemaFileContent io.Reader) (*ast.Schema, error) { | ||||
| 	var ts ast.Schema | ||||
| 	d := yaml.NewDecoder(schemaFileContent) | ||||
| 	err := d.Decode(&ts) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = internal.CheckFileFormatField(ts.FileFormat, supportedFormatMajor, supportedFormatMinor) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	err = internal.CheckSchemaURL(ts.SchemaURL) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &ts, nil | ||||
| } | ||||
							
								
								
									
										174
									
								
								schema/v1.1/parser_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										174
									
								
								schema/v1.1/parser_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,174 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package schema | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | ||||
| 	ast10 "go.opentelemetry.io/otel/schema/v1.0/ast" | ||||
| 	types10 "go.opentelemetry.io/otel/schema/v1.0/types" | ||||
| 	ast11 "go.opentelemetry.io/otel/schema/v1.1/ast" | ||||
| 	types11 "go.opentelemetry.io/otel/schema/v1.1/types" | ||||
| ) | ||||
|  | ||||
| func TestParseSchemaFile(t *testing.T) { | ||||
| 	ts, err := ParseFile("testdata/valid-example.yaml") | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.NotNil(t, ts) | ||||
| 	assert.EqualValues( | ||||
| 		t, &ast11.Schema{ | ||||
| 			FileFormat: "1.1.0", | ||||
| 			SchemaURL:  "https://opentelemetry.io/schemas/1.1.0", | ||||
| 			Versions: map[types11.TelemetryVersion]ast11.VersionDef{ | ||||
| 				"1.0.0": {}, | ||||
|  | ||||
| 				"1.1.0": { | ||||
| 					All: ast10.Attributes{ | ||||
| 						Changes: []ast10.AttributeChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.AttributeMap{ | ||||
| 									"k8s.cluster.name":     "kubernetes.cluster.name", | ||||
| 									"k8s.namespace.name":   "kubernetes.namespace.name", | ||||
| 									"k8s.node.name":        "kubernetes.node.name", | ||||
| 									"k8s.node.uid":         "kubernetes.node.uid", | ||||
| 									"k8s.pod.name":         "kubernetes.pod.name", | ||||
| 									"k8s.pod.uid":          "kubernetes.pod.uid", | ||||
| 									"k8s.container.name":   "kubernetes.container.name", | ||||
| 									"k8s.replicaset.name":  "kubernetes.replicaset.name", | ||||
| 									"k8s.replicaset.uid":   "kubernetes.replicaset.uid", | ||||
| 									"k8s.cronjob.name":     "kubernetes.cronjob.name", | ||||
| 									"k8s.cronjob.uid":      "kubernetes.cronjob.uid", | ||||
| 									"k8s.job.name":         "kubernetes.job.name", | ||||
| 									"k8s.job.uid":          "kubernetes.job.uid", | ||||
| 									"k8s.statefulset.name": "kubernetes.statefulset.name", | ||||
| 									"k8s.statefulset.uid":  "kubernetes.statefulset.uid", | ||||
| 									"k8s.daemonset.name":   "kubernetes.daemonset.name", | ||||
| 									"k8s.daemonset.uid":    "kubernetes.daemonset.uid", | ||||
| 									"k8s.deployment.name":  "kubernetes.deployment.name", | ||||
| 									"k8s.deployment.uid":   "kubernetes.deployment.uid", | ||||
| 									"service.namespace":    "service.namespace.name", | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					Resources: ast10.Attributes{ | ||||
| 						Changes: []ast10.AttributeChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.AttributeMap{ | ||||
| 									"telemetry.auto.version": "telemetry.auto_instr.version", | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					Spans: ast10.Spans{ | ||||
| 						Changes: []ast10.SpansChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.AttributeMapForSpans{ | ||||
| 									AttributeMap: ast10.AttributeMap{ | ||||
| 										"peer.service": "peer.service.name", | ||||
| 									}, | ||||
| 									ApplyToSpans: []types10.SpanName{"HTTP GET"}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					SpanEvents: ast10.SpanEvents{ | ||||
| 						Changes: []ast10.SpanEventsChange{ | ||||
| 							{ | ||||
| 								RenameEvents: &ast10.RenameSpanEvents{ | ||||
| 									EventNameMap: map[string]string{ | ||||
| 										"exception.stacktrace": "exception.stack_trace", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.RenameSpanEventAttributes{ | ||||
| 									ApplyToEvents: []types10.EventName{"exception.stack_trace"}, | ||||
| 									AttributeMap: ast10.AttributeMap{ | ||||
| 										"peer.service": "peer.service.name", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					Logs: ast10.Logs{ | ||||
| 						Changes: []ast10.LogsChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.RenameAttributes{ | ||||
| 									AttributeMap: map[string]string{ | ||||
| 										"process.executable_name": "process.executable.name", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
|  | ||||
| 					Metrics: ast11.Metrics{ | ||||
| 						Changes: []ast11.MetricsChange{ | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.AttributeMapForMetrics{ | ||||
| 									AttributeMap: map[string]string{ | ||||
| 										"http.status_code": "http.response_status_code", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								RenameMetrics: map[types10.MetricName]types10.MetricName{ | ||||
| 									"container.cpu.usage.total":  "cpu.usage.total", | ||||
| 									"container.memory.usage.max": "memory.usage.max", | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								RenameAttributes: &ast10.AttributeMapForMetrics{ | ||||
| 									ApplyToMetrics: []types10.MetricName{ | ||||
| 										"system.cpu.utilization", | ||||
| 										"system.memory.usage", | ||||
| 										"system.memory.utilization", | ||||
| 										"system.paging.usage", | ||||
| 									}, | ||||
| 									AttributeMap: map[string]string{ | ||||
| 										"status": "state", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 							{ | ||||
| 								Split: &ast11.SplitMetric{ | ||||
| 									ApplyToMetric: "system.paging.operations", | ||||
| 									ByAttribute:   "direction", | ||||
| 									MetricsFromAttributes: map[types10.MetricName]types11.AttributeValue{ | ||||
| 										"system.paging.operations.in":  "in", | ||||
| 										"system.paging.operations.out": "out", | ||||
| 									}, | ||||
| 								}, | ||||
| 							}, | ||||
| 						}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, ts, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func TestFailParseSchemaFile(t *testing.T) { | ||||
| 	ts, err := ParseFile("testdata/unsupported-file-format.yaml") | ||||
| 	assert.Error(t, err) | ||||
| 	assert.Nil(t, ts) | ||||
| } | ||||
							
								
								
									
										10
									
								
								schema/v1.1/testdata/unsupported-file-format.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								schema/v1.1/testdata/unsupported-file-format.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| file_format: 1.2.0 | ||||
| schema_url: https://opentelemetry.io/schemas/1.1.0 | ||||
|  | ||||
| versions: | ||||
|   1.1.0: | ||||
|     all: | ||||
|       changes: | ||||
|         - rename_attributes: | ||||
|             k8s.cluster.name: kubernetes.cluster.name | ||||
|   1.0.0: | ||||
							
								
								
									
										144
									
								
								schema/v1.1/testdata/valid-example.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								schema/v1.1/testdata/valid-example.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,144 @@ | ||||
| file_format: 1.1.0 | ||||
|  | ||||
| schema_url: https://opentelemetry.io/schemas/1.1.0 | ||||
|  | ||||
| versions: | ||||
|   1.1.0: | ||||
|     # Section "all" applies to attribute names for all data types: resources, spans, logs, | ||||
|     # span events, metric labels. | ||||
|     # | ||||
|     # The translations in "all" section are performed first (for each particular version). | ||||
|     # Only after that the translations in the specific section ("resources", "traces", | ||||
|     # "metrics" or "logs") that corresponds to the data type are applied. | ||||
|     # | ||||
|     # The only translation possible in section "all" is renaming of attributes in | ||||
|     # versions. For human readability versions are listed in reverse chronological | ||||
|     # order, however note that the translations are applied in the order defined by | ||||
|     # semver ordering. | ||||
|     all: | ||||
|       changes: | ||||
|         - rename_attributes: | ||||
|             # Mapping of attribute names (label names for metrics). The key is the old name | ||||
|             # used prior to this version, the value is the new name starting from this version. | ||||
|  | ||||
|             # Rename k8s.* to kubernetes.* | ||||
|             k8s.cluster.name: kubernetes.cluster.name | ||||
|             k8s.namespace.name: kubernetes.namespace.name | ||||
|             k8s.node.name: kubernetes.node.name | ||||
|             k8s.node.uid: kubernetes.node.uid | ||||
|             k8s.pod.name: kubernetes.pod.name | ||||
|             k8s.pod.uid: kubernetes.pod.uid | ||||
|             k8s.container.name: kubernetes.container.name | ||||
|             k8s.replicaset.name: kubernetes.replicaset.name | ||||
|             k8s.replicaset.uid: kubernetes.replicaset.uid | ||||
|             k8s.cronjob.name: kubernetes.cronjob.name | ||||
|             k8s.cronjob.uid: kubernetes.cronjob.uid | ||||
|             k8s.job.name: kubernetes.job.name | ||||
|             k8s.job.uid: kubernetes.job.uid | ||||
|             k8s.statefulset.name: kubernetes.statefulset.name | ||||
|             k8s.statefulset.uid: kubernetes.statefulset.uid | ||||
|             k8s.daemonset.name: kubernetes.daemonset.name | ||||
|             k8s.daemonset.uid: kubernetes.daemonset.uid | ||||
|             k8s.deployment.name: kubernetes.deployment.name | ||||
|             k8s.deployment.uid: kubernetes.deployment.uid | ||||
|  | ||||
|             service.namespace: service.namespace.name | ||||
|  | ||||
|     # Like "all" the "resources" section may contain only attribute renaming translations. | ||||
|     # The only translation possible in this section is renaming of attributes in | ||||
|     # versions. | ||||
|     resources: | ||||
|       changes: | ||||
|         - rename_attributes: | ||||
|             # Mapping of attribute names. The key is the old name | ||||
|             # used prior to this version, the value is the new name starting from this version. | ||||
|             telemetry.auto.version: telemetry.auto_instr.version | ||||
|  | ||||
|     spans: | ||||
|       changes: | ||||
|         # Sequence of translations to apply to convert the schema from a prior version | ||||
|         # to this version. The order in this sequence is important. Translations are | ||||
|         # applied from top to bottom in the listed order. | ||||
|         - rename_attributes: | ||||
|             # Rename attributes of all spans, regardless of span name. | ||||
|             # The keys are the old attribute name used prior to this version, the values are | ||||
|             # the new attribute name starting from this version. | ||||
|             attribute_map: | ||||
|               peer.service: peer.service.name | ||||
|             apply_to_spans: | ||||
|               # apply only to spans named "HTTP GET" | ||||
|               - "HTTP GET" | ||||
|     span_events: | ||||
|       changes: | ||||
|         # Sequence of translations to apply to convert the schema from a prior version | ||||
|         # to this version. The order in this sequence is important. Translations are | ||||
|         # applied from top to bottom in the listed order. | ||||
|         - rename_events: | ||||
|             # Rename events. The keys are old event names, the values are the new event names. | ||||
|             name_map: {exception.stacktrace: exception.stack_trace} | ||||
|  | ||||
|         - rename_attributes: | ||||
|             # Rename attributes of events. | ||||
|             # The keys are the old attribute name used prior to this version, the values are | ||||
|             # the new attribute name starting from this version. | ||||
|             attribute_map: | ||||
|               peer.service: peer.service.name | ||||
|  | ||||
|             apply_to_events: | ||||
|               # Optional event names to apply to. If empty applies to all events. | ||||
|               # Conditions in apply_to_spans and apply_to_events are logical AND-ed, | ||||
|               # both should match for transformation to be applied. | ||||
|               - exception.stack_trace | ||||
|  | ||||
|     metrics: | ||||
|       changes: | ||||
|         # Sequence of translations to apply to convert the schema from a prior version | ||||
|         # to this version. The order in this sequence is important. Translations are | ||||
|         # applied from top to bottom in the listed order. | ||||
|  | ||||
|         - rename_attributes: | ||||
|             # Rename attributes of all metrics, regardless of metric name. | ||||
|             # The keys are the old attribute name used prior to this version, the values are | ||||
|             # the new attribute name starting from this version. | ||||
|             attribute_map: | ||||
|               http.status_code: http.response_status_code | ||||
|  | ||||
|         - rename_metrics: | ||||
|             # Rename metrics. The keys are old metric names, the values are the new metric names. | ||||
|             container.cpu.usage.total: cpu.usage.total | ||||
|             container.memory.usage.max: memory.usage.max | ||||
|  | ||||
|         - rename_attributes: | ||||
|             apply_to_metrics: | ||||
|               # Name of the metric to apply this rule to. If empty the rule applies to all metrics. | ||||
|               - system.cpu.utilization | ||||
|               - system.memory.usage | ||||
|               - system.memory.utilization | ||||
|               - system.paging.usage | ||||
|             attribute_map: | ||||
|               # The keys are the old attribute name used prior to this version, the values are | ||||
|               # the new attribute name starting from this version. | ||||
|               status: state | ||||
|  | ||||
|         - split: | ||||
|             # Rules to split a metric into several metrics using an attribute for split. | ||||
|             # This example rule implements the change done by | ||||
|             # https://github.com/open-telemetry/opentelemetry-specification/pull/2617 | ||||
|             # Name of old metric to split. | ||||
|             apply_to_metric: system.paging.operations | ||||
|             # Name of attribute in the old metric to use for splitting. The attribute will be | ||||
|             # eliminated, the new metric will not have it. | ||||
|             by_attribute: direction | ||||
|             # Names of new metrics to create, one for each possible value of the attribute. | ||||
|             metrics_from_attributes: | ||||
|               # If "direction" attribute equals "in" create a new metric called "system.paging.operations.in". | ||||
|               system.paging.operations.in: in | ||||
|               system.paging.operations.out: out | ||||
|  | ||||
|     logs: | ||||
|       changes: | ||||
|         - rename_attributes: | ||||
|             attribute_map: | ||||
|               process.executable_name: process.executable.name | ||||
|  | ||||
|   1.0.0: | ||||
							
								
								
									
										26
									
								
								schema/v1.1/types/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								schema/v1.1/types/types.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // Copyright The OpenTelemetry Authors | ||||
| // | ||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| // you may not use this file except in compliance with the License. | ||||
| // You may obtain a copy of the License at | ||||
| // | ||||
| //     http://www.apache.org/licenses/LICENSE-2.0 | ||||
| // | ||||
| // Unless required by applicable law or agreed to in writing, software | ||||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| // See the License for the specific language governing permissions and | ||||
| // limitations under the License. | ||||
|  | ||||
| package types // import "go.opentelemetry.io/otel/schema/v1.1/types" | ||||
|  | ||||
| import types10 "go.opentelemetry.io/otel/schema/v1.0/types" | ||||
|  | ||||
| // TelemetryVersion is a version number key in the schema file (e.g. "1.7.0"). | ||||
| type TelemetryVersion types10.TelemetryVersion | ||||
|  | ||||
| // AttributeName is an attribute name string. | ||||
| type AttributeName string | ||||
|  | ||||
| // AttributeValue is an attribute value. | ||||
| type AttributeValue interface{} | ||||
		Reference in New Issue
	
	Block a user