Skip to content
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

[DO NOT MERGE] PoC: Sharing code across multiple Go modules #3841

Closed
wants to merge 6 commits into from

Conversation

pellared
Copy link
Member

@pellared pellared commented Mar 6, 2023

Towards #3548

This PR is a proposal on how we can deal with sharing common code across multiple Go modules.

@pellared pellared added the Skip Changelog PRs that do not require a CHANGELOG.md entry label Mar 6, 2023
@codecov
Copy link

codecov bot commented Mar 6, 2023

Codecov Report

Merging #3841 (93dc9e5) into main (3015c86) will decrease coverage by 0.3%.
The diff coverage is 55.1%.

❗ Current head 93dc9e5 differs from pull request most recent head 435be78. Consider uploading reports for the commit 435be78 to get more accurate results

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #3841     +/-   ##
=======================================
- Coverage   81.7%   81.4%   -0.3%     
=======================================
  Files        170     172      +2     
  Lines      12474   12571     +97     
=======================================
+ Hits       10192   10237     +45     
- Misses      2067    2113     +46     
- Partials     215     221      +6     
Impacted Files Coverage Δ
exporters/jaeger/env_shared.go 21.8% <21.8%> (ø)
internal/shared/gocpy/gocpy.go 39.4% <39.4%> (ø)
exporters/jaeger/uploader.go 47.5% <100.0%> (ø)
internal/shared/env.go 100.0% <100.0%> (ø)
sdk/trace/batch_span_processor.go 81.1% <0.0%> (-0.9%) ⬇️
exporters/jaeger/jaeger.go 90.3% <0.0%> (-0.9%) ⬇️
bridge/opentracing/migration/defer.go 100.0% <0.0%> (ø)

internal/shared/gen.go Outdated Show resolved Hide resolved

**Note**.
We might consier moving [`gocpy`](gocpy/gocpy.go)
to [`opentelemetry-go-build-tools`](https://github.com/open-telemetry/opentelemetry-go-build-tools).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd think we should do this from the beginning. The collector may find itself in this situation as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If everyone agrees and accepts the current proposal then I can go for it.

CC @open-telemetry/build-tools-approvers @open-telemetry/collector-approvers

@@ -498,6 +498,16 @@ functionality should be added, each one will need their own super-set
interfaces and will duplicate the pattern. For this reason, the simple targeted
interface that defines the specific functionality should be preferred.

### Shared code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we plan to address the internal otel logging functionality?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will take a look tomorrow. Can you send a hyperlink with an example code that you are mentioning?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

func Debug(msg string, keysAndValues ...interface{}) {

Copy link
Member Author

@pellared pellared Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR;
I think that it would make sense to extract the internal logging to a public Go module with package name e.g. loginternal.

Using code generation (gocpy)
Initially I was thinking about adding func Logger() to the go.opentelemetry.io/otel package and making the Debug Info and Error as shared. But then I realized that this would introduce a cyclic dependency, becasue logging is used internally e.g. in internal/global/state.go....

Creating new module/package
Then I realized that probably exposing loginternal may be good as it would also allow others (e.g. instrumentation library authors) to use the same internal logging infrastructure. Right now the instrumentation library authors would have to create their own logging abstractions as getting the globalLogger is not possible using the OTel Go functions. Take notice that OTel Go users have access to their own logger if they set it. Therefore, I think it would be useful to make the internal logging functions publicly available.

(Possibly) Motivating example. In Splunk distribution of OTel Go we set a different default logger: https://github.com/signalfx/splunk-otel-go/blob/8cef1ed33297c9e8f348346b6b0b2da0225ab89e/distro/otel.go#LL86

And then if we want to use the same logger we need to pass it everywhere (or we could introduce our own global):

I think that it would be more maintainable and consistent if we could use the same Debug, Info, Error functions as OTel Go uses internally.

I find the internal logging as good use case for @Aneurysm9 alternatice proposal (source) on how we can share code between modules:

Alternately, we can extract this into a separate module with a stable public API. It might limit our flexibility going forward, but should be the least surprising in all use cases.

Of course, this approach should be used in moderation as it increases the exported API surface.

PS. I hope that my comment is "understandable". Feel free to ask question and let me know what is not clear.

PS2. Great question.

txt := scanner.Text()

if strings.HasPrefix(txt, "package ") {
if _, err := w.WriteString("package " + pkg + "\n"); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about using text/template and making the input files templates? That would allow replacing the package name and canonical import comment and eliminate the prefix check on each line.

Copy link
Member Author

@pellared pellared Mar 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same idea initially 😉

However, I found it easier to use actual code than writing Go source code templates. We get IDE, linting support when writing the shared code what we could not say about templates. We only need to replace the package name which is not anything complex.

eliminate the prefix check on each line.

If the performance is the concern, this could be easily improved by making sure that after the package name is replaced then we are not longer checking the line prefix. So the prefix check would be done only for the first couple of lines.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the performance is the concern, this could be easily improved by making sure that after the package name is replaced then we are not longer checking the line prefix. So the prefix check would be done only for the first couple of lines.

I did it in open-telemetry/opentelemetry-go-build-tools#275

@pellared pellared changed the title [DO NOT MERGE] PoC: Sharing code across multiple Go modules. [DO NOT MERGE] PoC: Sharing code across multiple Go modules Mar 7, 2023
@pellared pellared requested a review from Aneurysm9 March 7, 2023 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Skip Changelog PRs that do not require a CHANGELOG.md entry
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants