From 5d042526fe06a6613316a81e671b450c87268732 Mon Sep 17 00:00:00 2001 From: Aleksandr Razumov Date: Sat, 25 Nov 2023 14:36:47 +0300 Subject: [PATCH] feat(otelschema): add golden test --- .../otelschema/_golden/all_attributes.yaml | 716 ++++++++++++++++++ internal/otelschema/gold_test.go | 15 + internal/otelschema/group.go | 141 +++- internal/otelschema/list_test.go | 65 ++ internal/otelschema/schema.yml | 6 + 5 files changed, 934 insertions(+), 9 deletions(-) create mode 100644 internal/otelschema/_golden/all_attributes.yaml create mode 100644 internal/otelschema/gold_test.go create mode 100644 internal/otelschema/list_test.go diff --git a/internal/otelschema/_golden/all_attributes.yaml b/internal/otelschema/_golden/all_attributes.yaml new file mode 100644 index 00000000..82b9f002 --- /dev/null +++ b/internal/otelschema/_golden/all_attributes.yaml @@ -0,0 +1,716 @@ +- Name: exception.type + Type: string +- Name: exception.message + Type: string +- Name: exception.stacktrace + Type: string +- Name: faas.trigger + Type: enum +- Name: faas.invoked_name + Type: string +- Name: faas.invoked_provider + Type: enum +- Name: faas.invoked_region + Type: string +- Name: peer.service + Type: string +- Name: enduser.id + Type: string +- Name: enduser.role + Type: string +- Name: enduser.scope + Type: string +- Name: event.name + Type: string +- Name: log.record.uid + Type: string +- Name: log.iostream + Type: enum +- Name: log.file.name + Type: string +- Name: log.file.path + Type: string +- Name: log.file.name_resolved + Type: string +- Name: log.file.path_resolved + Type: string +- Name: ios.state + Type: enum +- Name: android.state + Type: enum +- Name: state + Type: enum +- Name: pool.name + Type: string +- Name: jvm.buffer.pool.name + Type: string +- Name: jvm.memory.type + Type: enum +- Name: jvm.memory.pool.name + Type: string +- Name: jvm.gc.name + Type: string +- Name: jvm.gc.action + Type: string +- Name: jvm.thread.daemon + Type: boolean +- Name: jvm.thread.state + Type: enum +- Name: system.device + Type: string +- Name: system.cpu.state + Type: enum +- Name: system.cpu.logical_number + Type: int +- Name: system.memory.state + Type: enum +- Name: system.paging.state + Type: enum +- Name: system.paging.type + Type: enum +- Name: system.paging.direction + Type: enum +- Name: system.filesystem.state + Type: enum +- Name: system.filesystem.type + Type: enum +- Name: system.filesystem.mode + Type: string +- Name: system.filesystem.mountpoint + Type: string +- Name: system.network.state + Type: enum +- Name: system.processes.status + Type: enum +- Name: client.address + Type: string +- Name: client.port + Type: int +- Name: cloud.provider + Type: enum +- Name: cloud.account.id + Type: string +- Name: cloud.region + Type: string +- Name: cloud.resource_id + Type: string +- Name: cloud.availability_zone + Type: string +- Name: cloud.platform + Type: enum +- Name: code.function + Type: string +- Name: code.namespace + Type: string +- Name: code.filepath + Type: string +- Name: code.lineno + Type: int +- Name: code.column + Type: int +- Name: code.stacktrace + Type: string +- Name: container.name + Type: string +- Name: container.id + Type: string +- Name: container.runtime + Type: string +- Name: container.image.name + Type: string +- Name: container.image.tags + Type: string[] +- Name: container.image.id + Type: string +- Name: container.image.repo_digests + Type: string[] +- Name: container.command + Type: string +- Name: container.command_line + Type: string +- Name: container.command_args + Type: string[] +- Name: container.labels + Type: template[string] +- Name: db.cassandra.coordinator.dc + Type: string +- Name: db.cassandra.coordinator.id + Type: string +- Name: db.cassandra.consistency_level + Type: enum +- Name: db.cassandra.idempotence + Type: boolean +- Name: db.cassandra.page_size + Type: int +- Name: db.cassandra.speculative_execution_count + Type: int +- Name: db.cassandra.table + Type: string +- Name: db.connection_string + Type: string +- Name: db.cosmosdb.client_id + Type: string +- Name: db.cosmosdb.connection_mode + Type: enum +- Name: db.cosmosdb.container + Type: string +- Name: db.cosmosdb.operation_type + Type: enum +- Name: db.cosmosdb.request_charge + Type: double +- Name: db.cosmosdb.request_content_length + Type: int +- Name: db.cosmosdb.status_code + Type: int +- Name: db.cosmosdb.sub_status_code + Type: int +- Name: db.elasticsearch.cluster.name + Type: string +- Name: db.elasticsearch.node.name + Type: string +- Name: db.elasticsearch.path_parts + Type: template[string] +- Name: db.jdbc.driver_classname + Type: string +- Name: db.mongodb.collection + Type: string +- Name: db.mssql.instance_name + Type: string +- Name: db.name + Type: string +- Name: db.operation + Type: string +- Name: db.redis.database_index + Type: int +- Name: db.sql.table + Type: string +- Name: db.statement + Type: string +- Name: db.system + Type: enum +- Name: db.user + Type: string +- Name: http.method + Type: string +- Name: http.status_code + Type: int +- Name: http.scheme + Type: string +- Name: http.url + Type: string +- Name: http.target + Type: string +- Name: http.request_content_length + Type: int +- Name: http.response_content_length + Type: int +- Name: http.flavor + Type: enum +- Name: http.user_agent + Type: string +- Name: net.sock.peer.name + Type: string +- Name: net.sock.peer.addr + Type: string +- Name: net.sock.peer.port + Type: int +- Name: net.peer.name + Type: string +- Name: net.peer.port + Type: int +- Name: net.host.name + Type: string +- Name: net.host.port + Type: int +- Name: net.sock.host.addr + Type: string +- Name: net.sock.host.port + Type: int +- Name: net.transport + Type: enum +- Name: net.protocol.name + Type: string +- Name: net.protocol.version + Type: string +- Name: net.sock.family + Type: enum +- Name: destination.address + Type: string +- Name: destination.port + Type: int +- Name: device.id + Type: string +- Name: device.manufacturer + Type: string +- Name: device.model.identifier + Type: string +- Name: device.model.name + Type: string +- Name: disk.io.direction + Type: enum +- Name: error.type + Type: enum +- Name: host.id + Type: string +- Name: host.name + Type: string +- Name: host.type + Type: string +- Name: host.arch + Type: enum +- Name: host.image.name + Type: string +- Name: host.image.id + Type: string +- Name: host.image.version + Type: string +- Name: host.ip + Type: string[] +- Name: host.mac + Type: string[] +- Name: host.cpu.vendor.id + Type: string +- Name: host.cpu.family + Type: string +- Name: host.cpu.model.id + Type: string +- Name: host.cpu.model.name + Type: string +- Name: host.cpu.stepping + Type: int +- Name: host.cpu.cache.l2.size + Type: int +- Name: http.request.body.size + Type: int +- Name: http.request.header + Type: template[string[]] +- Name: http.request.method + Type: enum +- Name: http.request.method_original + Type: string +- Name: http.request.resend_count + Type: int +- Name: http.response.body.size + Type: int +- Name: http.response.header + Type: template[string[]] +- Name: http.response.status_code + Type: int +- Name: http.route + Type: string +- Name: k8s.cluster.name + Type: string +- Name: k8s.cluster.uid + Type: string +- Name: k8s.node.name + Type: string +- Name: k8s.node.uid + Type: string +- Name: k8s.namespace.name + Type: string +- Name: k8s.pod.uid + Type: string +- Name: k8s.pod.name + Type: string +- Name: k8s.container.name + Type: string +- Name: k8s.container.restart_count + Type: int +- Name: k8s.replicaset.uid + Type: string +- Name: k8s.replicaset.name + Type: string +- Name: k8s.deployment.uid + Type: string +- Name: k8s.deployment.name + Type: string +- Name: k8s.statefulset.uid + Type: string +- Name: k8s.statefulset.name + Type: string +- Name: k8s.daemonset.uid + Type: string +- Name: k8s.daemonset.name + Type: string +- Name: k8s.job.uid + Type: string +- Name: k8s.job.name + Type: string +- Name: k8s.cronjob.uid + Type: string +- Name: k8s.cronjob.name + Type: string +- Name: messaging.batch.message_count + Type: int +- Name: messaging.client_id + Type: string +- Name: messaging.destination.name + Type: string +- Name: messaging.destination.template + Type: string +- Name: messaging.destination.anonymous + Type: boolean +- Name: messaging.destination.temporary + Type: boolean +- Name: messaging.destination_publish.anonymous + Type: boolean +- Name: messaging.destination_publish.name + Type: string +- Name: messaging.kafka.consumer.group + Type: string +- Name: messaging.kafka.destination.partition + Type: int +- Name: messaging.kafka.message.key + Type: string +- Name: messaging.kafka.message.offset + Type: int +- Name: messaging.kafka.message.tombstone + Type: boolean +- Name: messaging.message.conversation_id + Type: string +- Name: messaging.message.envelope.size + Type: int +- Name: messaging.message.id + Type: string +- Name: messaging.message.body.size + Type: int +- Name: messaging.operation + Type: enum +- Name: messaging.rabbitmq.destination.routing_key + Type: string +- Name: messaging.rocketmq.client_group + Type: string +- Name: messaging.rocketmq.consumption_model + Type: enum +- Name: messaging.rocketmq.message.delay_time_level + Type: int +- Name: messaging.rocketmq.message.delivery_timestamp + Type: int +- Name: messaging.rocketmq.message.group + Type: string +- Name: messaging.rocketmq.message.keys + Type: string[] +- Name: messaging.rocketmq.message.tag + Type: string +- Name: messaging.rocketmq.message.type + Type: enum +- Name: messaging.rocketmq.namespace + Type: string +- Name: messaging.gcp_pubsub.message.ordering_key + Type: string +- Name: messaging.system + Type: enum +- Name: network.carrier.icc + Type: string +- Name: network.carrier.mcc + Type: string +- Name: network.carrier.mnc + Type: string +- Name: network.carrier.name + Type: string +- Name: network.connection.subtype + Type: enum +- Name: network.connection.type + Type: enum +- Name: network.local.address + Type: string +- Name: network.local.port + Type: int +- Name: network.peer.address + Type: string +- Name: network.peer.port + Type: int +- Name: network.protocol.name + Type: string +- Name: network.protocol.version + Type: string +- Name: network.transport + Type: enum +- Name: network.type + Type: enum +- Name: network.io.direction + Type: enum +- Name: oci.manifest.digest + Type: string +- Name: os.type + Type: enum +- Name: os.description + Type: string +- Name: os.name + Type: string +- Name: os.version + Type: string +- Name: os.build_id + Type: string +- Name: process.pid + Type: int +- Name: process.parent_pid + Type: int +- Name: process.executable.name + Type: string +- Name: process.executable.path + Type: string +- Name: process.command + Type: string +- Name: process.command_line + Type: string +- Name: process.command_args + Type: string[] +- Name: process.owner + Type: string +- Name: process.runtime.name + Type: string +- Name: process.runtime.version + Type: string +- Name: process.runtime.description + Type: string +- Name: rpc.connect_rpc.error_code + Type: enum +- Name: rpc.connect_rpc.request.metadata + Type: template[string[]] +- Name: rpc.connect_rpc.response.metadata + Type: template[string[]] +- Name: rpc.grpc.status_code + Type: enum +- Name: rpc.grpc.request.metadata + Type: template[string[]] +- Name: rpc.grpc.response.metadata + Type: template[string[]] +- Name: rpc.jsonrpc.error_code + Type: int +- Name: rpc.jsonrpc.error_message + Type: string +- Name: rpc.jsonrpc.request_id + Type: string +- Name: rpc.jsonrpc.version + Type: string +- Name: rpc.method + Type: string +- Name: rpc.service + Type: string +- Name: rpc.system + Type: enum +- Name: server.address + Type: string +- Name: server.port + Type: int +- Name: source.address + Type: string +- Name: source.port + Type: int +- Name: thread.id + Type: int +- Name: thread.name + Type: string +- Name: tls.cipher + Type: string +- Name: tls.client.certificate + Type: string +- Name: tls.client.certificate_chain + Type: string[] +- Name: tls.client.hash.md5 + Type: string +- Name: tls.client.hash.sha1 + Type: string +- Name: tls.client.hash.sha256 + Type: string +- Name: tls.client.issuer + Type: string +- Name: tls.client.ja3 + Type: string +- Name: tls.client.not_after + Type: string +- Name: tls.client.not_before + Type: string +- Name: tls.client.server_name + Type: string +- Name: tls.client.subject + Type: string +- Name: tls.client.supported_ciphers + Type: string[] +- Name: tls.curve + Type: string +- Name: tls.established + Type: boolean +- Name: tls.next_protocol + Type: string +- Name: tls.protocol.name + Type: enum +- Name: tls.protocol.version + Type: string +- Name: tls.resumed + Type: boolean +- Name: tls.server.certificate + Type: string +- Name: tls.server.certificate_chain + Type: string[] +- Name: tls.server.hash.md5 + Type: string +- Name: tls.server.hash.sha1 + Type: string +- Name: tls.server.hash.sha256 + Type: string +- Name: tls.server.issuer + Type: string +- Name: tls.server.ja3s + Type: string +- Name: tls.server.not_after + Type: string +- Name: tls.server.not_before + Type: string +- Name: tls.server.subject + Type: string +- Name: url.scheme + Type: string +- Name: url.full + Type: string +- Name: url.path + Type: string +- Name: url.query + Type: string +- Name: url.fragment + Type: string +- Name: user_agent.original + Type: string +- Name: android.os.api_level + Type: string +- Name: browser.brands + Type: string[] +- Name: browser.platform + Type: string +- Name: browser.mobile + Type: boolean +- Name: browser.language + Type: string +- Name: aws.ecs.container.arn + Type: string +- Name: aws.ecs.cluster.arn + Type: string +- Name: aws.ecs.launchtype + Type: enum +- Name: aws.ecs.task.arn + Type: string +- Name: aws.ecs.task.family + Type: string +- Name: aws.ecs.task.revision + Type: string +- Name: aws.eks.cluster.arn + Type: string +- Name: aws.log.group.names + Type: string[] +- Name: aws.log.group.arns + Type: string[] +- Name: aws.log.stream.names + Type: string[] +- Name: aws.log.stream.arns + Type: string[] +- Name: gcp.cloud_run.job.execution + Type: string +- Name: gcp.cloud_run.job.task_index + Type: int +- Name: gcp.gce.instance.name + Type: string +- Name: gcp.gce.instance.hostname + Type: string +- Name: heroku.release.creation_timestamp + Type: string +- Name: heroku.release.commit + Type: string +- Name: heroku.app.id + Type: string +- Name: deployment.environment + Type: string +- Name: faas.name + Type: string +- Name: faas.version + Type: string +- Name: faas.instance + Type: string +- Name: faas.max_memory + Type: int +- Name: service.name + Type: string +- Name: service.version + Type: string +- Name: service.namespace + Type: string +- Name: service.instance.id + Type: string +- Name: telemetry.sdk.name + Type: string +- Name: telemetry.sdk.language + Type: enum +- Name: telemetry.sdk.version + Type: string +- Name: telemetry.distro.name + Type: string +- Name: telemetry.distro.version + Type: string +- Name: webengine.name + Type: string +- Name: webengine.version + Type: string +- Name: webengine.description + Type: string +- Name: otel.scope.name + Type: string +- Name: otel.scope.version + Type: string +- Name: otel.library.name + Type: string +- Name: otel.library.version + Type: string +- Name: session.id + Type: string +- Name: session.previous_id + Type: string +- Name: aws.lambda.invoked_arn + Type: string +- Name: cloudevents.event_id + Type: string +- Name: cloudevents.event_source + Type: string +- Name: cloudevents.event_spec_version + Type: string +- Name: cloudevents.event_type + Type: string +- Name: cloudevents.event_subject + Type: string +- Name: opentracing.ref_type + Type: enum +- Name: otel.status_code + Type: enum +- Name: otel.status_description + Type: string +- Name: faas.invocation_id + Type: string +- Name: faas.document.collection + Type: string +- Name: faas.document.operation + Type: enum +- Name: faas.document.time + Type: string +- Name: faas.document.name + Type: string +- Name: faas.time + Type: string +- Name: faas.cron + Type: string +- Name: faas.coldstart + Type: boolean +- Name: feature_flag.key + Type: string +- Name: feature_flag.provider_name + Type: string +- Name: feature_flag.variant + Type: string +- Name: message.type + Type: enum +- Name: message.id + Type: int +- Name: message.compressed_size + Type: int +- Name: message.uncompressed_size + Type: int +- Name: exception.escaped + Type: boolean diff --git a/internal/otelschema/gold_test.go b/internal/otelschema/gold_test.go new file mode 100644 index 00000000..3250a2e0 --- /dev/null +++ b/internal/otelschema/gold_test.go @@ -0,0 +1,15 @@ +package otelschema + +import ( + "os" + "testing" + + "github.com/go-faster/sdk/gold" +) + +func TestMain(m *testing.M) { + // Explicitly registering flags for golden files. + gold.Init() + + os.Exit(m.Run()) +} diff --git a/internal/otelschema/group.go b/internal/otelschema/group.go index d7aac38a..d00237d8 100644 --- a/internal/otelschema/group.go +++ b/internal/otelschema/group.go @@ -631,7 +631,7 @@ func (s *Type) SetGroups(val []TypeGroupsItem) { type TypeGroupsItem struct { ID string `json:"id"` Prefix OptString `json:"prefix"` - Type OptString `json:"type"` + Type TypeGroupsItemType `json:"type"` Brief OptString `json:"brief"` Note OptString `json:"note"` Attributes []TypeGroupsItemAttributesItem `json:"attributes"` @@ -648,7 +648,7 @@ func (s *TypeGroupsItem) GetPrefix() OptString { } // GetType returns the value of Type. -func (s *TypeGroupsItem) GetType() OptString { +func (s *TypeGroupsItem) GetType() TypeGroupsItemType { return s.Type } @@ -678,7 +678,7 @@ func (s *TypeGroupsItem) SetPrefix(val OptString) { } // SetType sets the value of Type. -func (s *TypeGroupsItem) SetType(val OptString) { +func (s *TypeGroupsItem) SetType(val TypeGroupsItemType) { s.Type = val } @@ -765,6 +765,61 @@ func NewAttributeTypeGroupsItemAttributesItem(v Attribute) TypeGroupsItemAttribu return s } +type TypeGroupsItemType string + +const ( + TypeGroupsItemTypeMetric TypeGroupsItemType = "metric" + TypeGroupsItemTypeSpan TypeGroupsItemType = "span" + TypeGroupsItemTypeResource TypeGroupsItemType = "resource" + TypeGroupsItemTypeAttributeGroup TypeGroupsItemType = "attribute_group" +) + +// AllValues returns all TypeGroupsItemType values. +func (TypeGroupsItemType) AllValues() []TypeGroupsItemType { + return []TypeGroupsItemType{ + TypeGroupsItemTypeMetric, + TypeGroupsItemTypeSpan, + TypeGroupsItemTypeResource, + TypeGroupsItemTypeAttributeGroup, + } +} + +// MarshalText implements encoding.TextMarshaler. +func (s TypeGroupsItemType) MarshalText() ([]byte, error) { + switch s { + case TypeGroupsItemTypeMetric: + return []byte(s), nil + case TypeGroupsItemTypeSpan: + return []byte(s), nil + case TypeGroupsItemTypeResource: + return []byte(s), nil + case TypeGroupsItemTypeAttributeGroup: + return []byte(s), nil + default: + return nil, errors.Errorf("invalid value: %q", s) + } +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (s *TypeGroupsItemType) UnmarshalText(data []byte) error { + switch TypeGroupsItemType(data) { + case TypeGroupsItemTypeMetric: + *s = TypeGroupsItemTypeMetric + return nil + case TypeGroupsItemTypeSpan: + *s = TypeGroupsItemTypeSpan + return nil + case TypeGroupsItemTypeResource: + *s = TypeGroupsItemTypeResource + return nil + case TypeGroupsItemTypeAttributeGroup: + *s = TypeGroupsItemTypeAttributeGroup + return nil + default: + return errors.Errorf("invalid value: %q", data) + } +} + // Encode implements json.Marshaler. func (s *Attribute) Encode(e *jx.Encoder) { e.ObjStart() @@ -1909,10 +1964,8 @@ func (s *TypeGroupsItem) encodeFields(e *jx.Encoder) { } } { - if s.Type.Set { - e.FieldStart("type") - s.Type.Encode(e) - } + e.FieldStart("type") + s.Type.Encode(e) } { if s.Brief.Set { @@ -1979,8 +2032,8 @@ func (s *TypeGroupsItem) Decode(d *jx.Decoder) error { return errors.Wrap(err, "decode field \"prefix\"") } case "type": + requiredBitSet[0] |= 1 << 2 if err := func() error { - s.Type.Reset() if err := s.Type.Decode(d); err != nil { return err } @@ -2035,7 +2088,7 @@ func (s *TypeGroupsItem) Decode(d *jx.Decoder) error { // Validate required fields. var failures []validate.FieldError for i, mask := range [1]uint8{ - 0b00000001, + 0b00000101, } { if result := (requiredBitSet[i] & mask) ^ mask; result != 0 { // Mask only required fields and check equality to mask using XOR. @@ -2183,6 +2236,50 @@ func (s *TypeGroupsItemAttributesItem) UnmarshalJSON(data []byte) error { return s.Decode(d) } +// Encode encodes TypeGroupsItemType as json. +func (s TypeGroupsItemType) Encode(e *jx.Encoder) { + e.Str(string(s)) +} + +// Decode decodes TypeGroupsItemType from json. +func (s *TypeGroupsItemType) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode TypeGroupsItemType to nil") + } + v, err := d.StrBytes() + if err != nil { + return err + } + // Try to use constant string. + switch TypeGroupsItemType(v) { + case TypeGroupsItemTypeMetric: + *s = TypeGroupsItemTypeMetric + case TypeGroupsItemTypeSpan: + *s = TypeGroupsItemTypeSpan + case TypeGroupsItemTypeResource: + *s = TypeGroupsItemTypeResource + case TypeGroupsItemTypeAttributeGroup: + *s = TypeGroupsItemTypeAttributeGroup + default: + *s = TypeGroupsItemType(v) + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s TypeGroupsItemType) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *TypeGroupsItemType) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + func (s *Attribute) Validate() error { if s == nil { return validate.ErrNilPointer @@ -2343,6 +2440,17 @@ func (s *TypeGroupsItem) Validate() error { } var failures []validate.FieldError + if err := func() error { + if err := s.Type.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "type", + Error: err, + }) + } if err := func() error { var failures []validate.FieldError for i, elem := range s.Attributes { @@ -2387,3 +2495,18 @@ func (s TypeGroupsItemAttributesItem) Validate() error { return errors.Errorf("invalid type %q", s.Type) } } + +func (s TypeGroupsItemType) Validate() error { + switch s { + case "metric": + return nil + case "span": + return nil + case "resource": + return nil + case "attribute_group": + return nil + default: + return errors.Errorf("invalid value: %v", s) + } +} diff --git a/internal/otelschema/list_test.go b/internal/otelschema/list_test.go new file mode 100644 index 00000000..f04dad62 --- /dev/null +++ b/internal/otelschema/list_test.go @@ -0,0 +1,65 @@ +package otelschema + +import ( + "io/fs" + "os" + "path/filepath" + "testing" + + "github.com/go-faster/sdk/gold" + "github.com/stretchr/testify/require" + "sigs.k8s.io/yaml" +) + +func TestParseAllAttributes(t *testing.T) { + var parsed []TypeGroupsItem + require.NoError(t, filepath.Walk(filepath.Join("_testdata", "model"), func(path string, info fs.FileInfo, err error) error { + require.NoError(t, err) + if info.IsDir() { + return nil + } + if filepath.Ext(path) != ".yaml" { + return nil + } + data, err := os.ReadFile(path) + require.NoError(t, err) + + var schema Type + jsonData, err := yaml.YAMLToJSON(data) + require.NoError(t, err) + require.NoError(t, schema.UnmarshalJSON(jsonData)) + parsed = append(parsed, schema.Groups...) + return nil + })) + type entry struct { + Name string + Type string + } + var entries []entry + for _, group := range parsed { + for _, attr := range group.Attributes { + v, ok := attr.GetAttribute() + if !ok { + continue + } + name := v.ID + if prefix, ok := group.Prefix.Get(); ok { + name = prefix + "." + name + } + typ := "enum" + if s, ok := v.Type.GetString(); ok { + typ = s + } + t.Logf("%s (%s)", name, typ) + entries = append(entries, entry{ + Name: name, + Type: typ, + }) + } + } + t.Logf("total: %d", len(entries)) + data, err := yaml.Marshal(entries) + require.NoError(t, err) + + gold.Str(t, string(data), "all_attributes.yaml") +} diff --git a/internal/otelschema/schema.yml b/internal/otelschema/schema.yml index 342c31d7..3c5c217f 100644 --- a/internal/otelschema/schema.yml +++ b/internal/otelschema/schema.yml @@ -96,6 +96,11 @@ properties: type: string type: type: string + enum: + - metric + - span + - resource + - attribute_group brief: type: string note: @@ -108,5 +113,6 @@ properties: - $ref: "#/$defs/attribute" required: - id + - type required: - groups