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

Introduce component logger with appropriate attributes #12259

Merged
merged 6 commits into from
Feb 6, 2025

Conversation

djaglowski
Copy link
Member

@djaglowski djaglowski commented Feb 3, 2025

Implements the logger described in #12217

Alternative to #12057

Resolves #11814

component/componentattribute:

  • Initializes new module
  • Defines constants for component telemetry attribute keys
  • Defines a zapcore.Core which can remove attributes from the root logger

service:

  • Rebases component instantiation on attribute sets
  • Internal constructors for attribute sets for each component type
  • Constructs loggers from componentattribute

otlpreceiver:

  • Uses componentattribute to remove otelcol.signal attribute from logger

memorylimiter:

  • Uses componentattribute to remove otelcol.signal, otelcol.pipeline.id and otelcol.component.id attributes from logger

@djaglowski djaglowski force-pushed the component-logger branch 8 times, most recently from 8845f3e to e8565de Compare February 4, 2025 16:32
@djaglowski djaglowski force-pushed the component-logger branch 4 times, most recently from 8ebe64f to 0cdc5de Compare February 4, 2025 17:05
Copy link

codecov bot commented Feb 4, 2025

Codecov Report

Attention: Patch coverage is 86.90476% with 11 lines in your changes missing coverage. Please review.

Project coverage is 91.31%. Comparing base (fb06c99) to head (662c1db).
Report is 12 commits behind head on main.

Files with missing lines Patch % Lines
component/telemetry.go 0.00% 11 Missing ⚠️

❌ Your patch status has failed because the patch coverage (86.90%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12259      +/-   ##
==========================================
- Coverage   91.35%   91.31%   -0.04%     
==========================================
  Files         467      467              
  Lines       25761    25811      +50     
==========================================
+ Hits        23533    23570      +37     
- Misses       1810     1823      +13     
  Partials      418      418              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@djaglowski djaglowski force-pushed the component-logger branch 2 times, most recently from ddc480f to 39415d7 Compare February 4, 2025 17:59
@djaglowski djaglowski marked this pull request as ready for review February 4, 2025 18:42
@djaglowski djaglowski requested a review from a team as a code owner February 4, 2025 18:42
@djaglowski djaglowski requested a review from dmitryax February 4, 2025 18:42
Comment on lines 14 to 18
type Core struct {
zapcore.Core
from *zap.Logger
attrs attribute.Set
}
Copy link
Member

@bogdandrutu bogdandrutu Feb 5, 2025

Choose a reason for hiding this comment

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

Looking at usages (outside the service) the only think needed is Without(keys ...string) *zap.Logger

Can we do some golang magic, and actually public expose only an interface (rest of the implementation is in otelcol/service)?

The ideal scenario may be something that extend Logger, not sure if that works because Logger is a struct.

Copy link
Member

Choose a reason for hiding this comment

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

Here is where I got #12289

I don't have to expose public any interface. We will still need to expose the fields keys not sure where though.

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 don't have to expose public any interface

I'm trying to incorporate your solution to simplify mine, but one consideration overlooked is that in practice we pass different kinds of loggers into tests, so we must make a type assertion to check for the Without method. If we're doing this, I think we need to at least give a name the interface so that components do not need to assert against an anonymous interface. The alternative would be to enforce somehow that tests use the same logger, but this is impractical IMO.

Copy link
Member Author

Choose a reason for hiding this comment

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

Similarly, for tests that do want to validate the functionality of the shared logger, they need to be able to instantiate a logger, so at least then you need to expose a testing logger which is very similar to the actual logger.

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 was able to reduce the surface area of componentattribute but still think we need a constructor for the logger

attrs attribute.Set
}

func NewLogger(from *zap.Logger, attrs *attribute.Set) *zap.Logger {
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'm not sure how to avoid exposing this. It's used in component tests, and also in the graph when instantiating the loggers for components.

Comment on lines +7 to +11
ComponentKindKey = "otelcol.component.kind"
ComponentIDKey = "otelcol.component.id"
PipelineIDKey = "otelcol.pipeline.id"
SignalKey = "otelcol.signal"
SignalOutputKey = "otelcol.signal.output"
Copy link
Member

Choose a reason for hiding this comment

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

I would not couple this change with breaking the keys.

	zapKindKey            = "kind"
	zapNameKey            = "name"
	zapDataTypeKey        = "data_type"
	zapStabilityKey       = "stability"
	zapPipelineKey        = "pipeline"
	zapExporterInPipeline = "exporter_in_pipeline"
	zapReceiverInPipeline = "receiver_in_pipeline"

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'm not sure what you're suggesting

Copy link
Member

@bogdandrutu bogdandrutu left a comment

Choose a reason for hiding this comment

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

LGTM, few comments:

  1. Need good comments when to use LoggerWithout, no comments at all now.
  2. I think the attributes keys should be "semconv", maybe someone can start that effort before we change them. Also, I would not change them in this PR.
  3. I think we can have the "NewLogger" in otelcol as private, for testing we can use a mock/fake core.

@djaglowski
Copy link
Member Author

I think the attributes keys should be "semconv", maybe someone can start that effort before we change them. Also, I would not change them in this PR.

We went through a months long RFC process just to decide on these keys. Why wouldn't we switch to them immediately? That's the entire point of this PR. I can see the value of moving them to a xsemconv package instead but beyond that needs an explanation why your feeling about it overrides the RFC.

I think we can have the "NewLogger" in otelcol as private, for testing we can use a mock/fake core.

If it's going to be private and not available in tests, I think it can be in service/internal.

For testing, we should make it easy to validate certain things happen expected number of times. e.g. Logger is created once instead of once-per-signal, or log is logged once with correct attributes. Setting aside that a fake/mock core would implement mostly the same functionality as the actual, which package would expose this functionality so that each component does not need to write their own? componenttest?

@mx-psi
Copy link
Member

mx-psi commented Feb 6, 2025

  1. I think the attributes keys should be "semconv", maybe someone can start that effort before we change them. Also, I would not change them in this PR.

This was discussed during the RFC #11406 (comment) resulting in open-telemetry/semantic-conventions/issues/1555. Quoting from the thread, this is the plan we are following:

Decide which prefix you want to use: "otelcol." or "otel.collector." appear to be your top choices.
Submit a request to get this added to semconv. We should be able to convince semconv group to accept it and I do not anticipate difficulties here.
You don't need to be blocked or wait until acceptance by semconv group, there is a ton of work that needs to happen anyway and replacing metric names should be trivial anytime before you declare them stable.

Therefore, I agree with @djaglowski that we should change them here and not wait for any semconv work.

@bogdandrutu
Copy link
Member

Therefore, I agree with @djaglowski that we should change them here and not wait for any semconv work.

Sorry, maybe I was not clear. I am not suggesting to wait for that. Just that I was hoping to have a simple PR after this that only does the breaking changes/bug fixes: rename and use of the new API in otelreceiver and memorylimiter.

The main reason for that is to have clean changelog for that, and a simple enough change so that user can go to that PR and easily see what changed.

Happy to move forward with this way as well.

# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement
Copy link
Member

Choose a reason for hiding this comment

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

This is breaking change.

Copy link
Member

@bogdandrutu bogdandrutu left a comment

Choose a reason for hiding this comment

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

Since my feedback is mostly esthetic will let @mx-psi merge when he feels comfortable with this.

I can play later with componenattribute structure if you folks want to move faster with this PR.

@mx-psi
Copy link
Member

mx-psi commented Feb 6, 2025

Since componentattributes is a separate, experimental module, and the only addition to component is the LoggerWithout method, I think we can go ahead with merging this yes, and iterate on it.

@mx-psi mx-psi added this pull request to the merge queue Feb 6, 2025
Merged via the queue into open-telemetry:main with commit 5d5fb21 Feb 6, 2025
53 of 54 checks passed
@djaglowski djaglowski deleted the component-logger branch February 6, 2025 17:29
github-merge-queue bot pushed a commit that referenced this pull request Feb 10, 2025
…pd… (#12326)

…ate-otel in contrib

<!--Ex. Fixing a bug - Describe the bug and how this fixes the issue.
Ex. Adding a feature - Explain what this achieves.-->
#### Description
I was planning to run `update-otel` in contrib repo to test
open-telemetry/opentelemetry-collector-contrib#37706
before a new release. And found that it's blocked by the newly added
`component/componentattribute` module in #12259

This PR update its version to be latest dev to quickly unblock
`update-otel` task.

cc @bogdandrutu @codeboten @djaglowski @mx-psi 

<!-- Issue number if applicable -->
#### Link to tracking issue
n/a

<!--Describe what testing was performed and which tests were added.-->
#### Testing
n/a

<!--Describe the documentation added.-->
#### Documentation
n/a
<!--Please delete paragraphs that you did not use before submitting.-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Loggers for shared components should not report signal type.
3 participants