-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add schema transformation functionality to resource creation and merge #4503
Conversation
Codecov Report
@@ Coverage Diff @@
## main #4503 +/- ##
=======================================
- Coverage 81.3% 81.3% -0.1%
=======================================
Files 220 222 +2
Lines 17678 17825 +147
=======================================
+ Hits 14386 14499 +113
- Misses 2992 3020 +28
- Partials 300 306 +6
|
There is only one schema needed now. Keep it in code.
Add suggested tests from review.
2088cee
to
f70951d
Compare
github.com/go-logr/logr v1.2.4 | ||
github.com/google/go-cmp v0.5.9 | ||
github.com/stretchr/testify v1.8.4 | ||
go.opentelemetry.io/otel v1.19.0-rc.1 | ||
go.opentelemetry.io/otel/schema v0.0.6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are introducing on a new unstable Go module.
If I am not mistaken I have found that this module is currently used by:
- https://github.com/open-telemetry/build-tools/tree/main/schemas
- https://github.com/MrAlias/otel-schema-utils
Still somebody else can potentially use go.opentelemetry.io/otel/schema
and then we can have a problem in case there would be some incompatible changes in go.opentelemetry.io/otel/schema
.
Currently, I have two ideas how we could resolve the issue:
A) Stabilize go.opentelemetry.io/otel/schema
.
B) Use gotmpl
to copy (vendor) ./schema
content.
Are there any reasons why not going with option A? Any other ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tracking stability here: https://github.com/orgs/open-telemetry/projects/64/views/1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Private project @MrAlias ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC you need to be an OTel member to see the project.
package cmd | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"os" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
sUtil "go.opentelemetry.io/otel/schema/v1.1" | ||
) | ||
|
||
func TestRender(t *testing.T) { | ||
schemaF, err := os.Open("./testdata/schema.yaml") | ||
require.NoError(t, err) | ||
defer schemaF.Close() | ||
|
||
s, err := sUtil.Parse(schemaF) | ||
require.NoError(t, err) | ||
|
||
wantF, err := os.Open("./testdata/transforms.go") | ||
require.NoError(t, err) | ||
|
||
var want bytes.Buffer | ||
_, err = io.Copy(&want, wantF) | ||
require.NoError(t, err) | ||
|
||
e, err := entries(s) | ||
require.NoError(t, err) | ||
|
||
var got bytes.Buffer | ||
require.NoError(t, render(&got, e)) | ||
|
||
assert.Equal(t, want.String(), got.String()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
schema "go.opentelemetry.io/otel/schema/v1.1"
instead ofsUtil "go.opentelemetry.io/otel/schema/v1.1"
(it is even suggested in https://pkg.go.dev/go.opentelemetry.io/otel/schema- Use
os.ReadFile
- Move
want
preparation on the top.
package cmd | |
import ( | |
"bytes" | |
"io" | |
"os" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
"github.com/stretchr/testify/require" | |
sUtil "go.opentelemetry.io/otel/schema/v1.1" | |
) | |
func TestRender(t *testing.T) { | |
schemaF, err := os.Open("./testdata/schema.yaml") | |
require.NoError(t, err) | |
defer schemaF.Close() | |
s, err := sUtil.Parse(schemaF) | |
require.NoError(t, err) | |
wantF, err := os.Open("./testdata/transforms.go") | |
require.NoError(t, err) | |
var want bytes.Buffer | |
_, err = io.Copy(&want, wantF) | |
require.NoError(t, err) | |
e, err := entries(s) | |
require.NoError(t, err) | |
var got bytes.Buffer | |
require.NoError(t, render(&got, e)) | |
assert.Equal(t, want.String(), got.String()) | |
} | |
package cmd | |
import ( | |
"bytes" | |
"os" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
"github.com/stretchr/testify/require" | |
schema "go.opentelemetry.io/otel/schema/v1.1" | |
) | |
func TestRender(t *testing.T) { | |
want, err := os.ReadFile("./testdata/transforms.go") | |
require.NoError(t, err) | |
schemaF, err := os.Open("./testdata/schema.yaml") | |
require.NoError(t, err) | |
defer schemaF.Close() | |
s, err := schema.Parse(schemaF) | |
require.NoError(t, err) | |
e, err := entries(s) | |
require.NoError(t, err) | |
var got bytes.Buffer | |
require.NoError(t, render(&got, e)) | |
assert.Equal(t, string(want), got.String()) | |
} |
"flag" | ||
"log" | ||
|
||
sUtil "go.opentelemetry.io/otel/schema/v1.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change the alias to schema
as suggested https://pkg.go.dev/go.opentelemetry.io/otel/schema
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add some package documentation that would describe what this tool is doing and why it was created.
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add some package documentation that would describe what this tool is doing and why it was created.
Also am I correct the usage of it is not currently implemented? Shouldn't it be invoked as part of make semconv-generate
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll update RELEASING.md to include it as a manual step for now.
return err | ||
} | ||
|
||
src, err := format.Source(out.Bytes()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are shadowing const src = "transforms.go.tmpl"
here. Maybe we should rename the const?
// prior to the merge using the OpenTelemetry schema resource section | ||
// (https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/schemas/file_format_v1.1.0.md#resources-section) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update the tag
- Make it an URL
// prior to the merge using the OpenTelemetry schema resource section | |
// (https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/schemas/file_format_v1.1.0.md#resources-section) | |
// prior to the merge using | |
// [the OpenTelemetry schema resource section](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.25.0/specification/schemas/file_format_v1.1.0.md#resources-section) |
// (https://github.com/open-telemetry/opentelemetry-specification/blob/v1.20.0/specification/schemas/file_format_v1.1.0.md#resources-section) | ||
// for the translation. | ||
// | ||
// If either of the resources have an invalid SchemaURL (non-OpenTelemetry or |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be good to call out that "newer" versions of SchemaURL are also not supported. E.g. this will not magically support https://opentelemetry.io/schemas/1.22.0
once https://github.com/open-telemetry/semantic-conventions is released. I am not sure how to describe it in a readable way...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't we upgrade and release support for v1.22.0 when it is released?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will. My point is that somebody may not understand that the support is "compiled"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like
If either of the resources have an unknown SchemaURL (only specific versions of OpenTelemetry schemas are supported), [...]
name: "BothUnknownSchemas", | ||
a: resource.NewWithAttributes("https://localhost/1", kv41), | ||
b: resource.NewWithAttributes("https://localhost/2", kv42), | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding this scenario
}, | |
}, | |
{ | |
name: "NotSupportedOTelSchema", | |
a: resource.NewWithAttributes("https://opentelemetry.io/schemas/1.999.0", kv41), | |
b: resource.NewWithAttributes("https://opentelemetry.io/schemas/1.0.0", kv42), | |
}, |
Also I think in such scenario we should either:
a) simply return error that this semconv version is not supported and that the user can try using a new version of the OTel Go SDK
b) prefer all "known" translations (current implementation) and additionally return the error - it should be possible for the user to determine this error type so he could ignore the error returned in this scenario
👀 |
Based on the resource merge specification:
Doing anything other than preserving all the keys provided to merge will be non-compliant. |
I agree. I think that we can consider enhancing the specification so that (examples, brainstorming):
|
Currently, the
resource
package fails for conflicting schema URL merges in the following way:New
is used with multiple detectors that detect resources at with different schema URLsDetect
is used with multiple detectors that detect resources at with different schema URLsMerge
is provided two resources with different schema URLsAll of these errors can be reduced to the last one: the
New
function will call the underlyingdetect
which itself callsMerge
for multiple resources.This fixes all of these failures by upgrading the older resources prior to merging using schema transformations.
There are no API changes added at this time. The translation is limited to only upgrading and only in the
Merge
function. It is possible to add more customizable translations that support more schema (other than just OpenTelemetry ones), but that is left for another PR once there is deemed enough user support.Fixes #2341
Fixes #3769
Fixes #4476
Fixes open-telemetry/opentelemetry-go-contrib#3657
Design
Based on https://github.com/MrAlias/otel-schema-utils/tree/main with the following notable differences:
Merge
function insdk/resource
to upgrade the less of the two passed resourcesDetect
callsdetect
which usesMerge
to resolve resources from multiple detectorsNew
usesdetect
to create new resources withDetector
ssdk/resource/internal/schema
packageVersion
function parses and converts schema URL tosemconv.Version
types.Upgrade
function allows the upgrade of a resources attributes using a statically defined transform from an OTel schemageneration
schema
directoryfetch.go
script is included to fetch a schema and can be used for upgraderender
package is included that will render and format Go to generate thetemplate.go
file with the static transforms