-
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 WithStatus option to set Span status at the same time (#1677) #1817
Conversation
Codecov Report
@@ Coverage Diff @@
## main #1817 +/- ##
=====================================
Coverage 79.2% 79.2%
=====================================
Files 139 139
Lines 7459 7476 +17
=====================================
+ Hits 5908 5926 +18
Misses 1304 1304
+ Partials 247 246 -1
|
5d238e8
to
5ae2893
Compare
…etry#1677) Signed-off-by: lastchiliarch <[email protected]>
5ae2893
to
1d42dfa
Compare
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.
Looks good overall.
…etry#1677) Signed-off-by: lastchiliarch <[email protected]>
…etry#1677) Signed-off-by: lastchiliarch <[email protected]>
CHANGELOG.md
Outdated
@@ -141,6 +141,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm | |||
|
|||
### Added | |||
|
|||
- Added `WithStatus` event option to set Span status at the same time when call RecordError. (#1677) |
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.
- Added `WithStatus` event option to set Span status at the same time when call RecordError. (#1677) | |
- Added `WithStatus` event option to set Span status when passed to `RecordError`. (#1817) |
sdk/trace/span.go
Outdated
// This method does not change the Span status in default | ||
// To change Span status, pass `WithStatus` as options. | ||
// This method does nothing If this span is not being recorded or err is nil. |
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.
// This method does not change the Span status in default | |
// To change Span status, pass `WithStatus` as options. | |
// This method does nothing If this span is not being recorded or err is nil. | |
// This method does not change the Span status by default. | |
// To set the Span status, pass `WithStatus` as an option. | |
// This method does nothing if this span is not being recorded or err is nil. |
trace/config.go
Outdated
func (o withStatusSpanOption) apply(c *SpanConfig) { c.WithStatus = bool(o) } | ||
|
||
// WithStatus set the status at the same time when RecordError | ||
func WithStatus(o bool) LifeCycleOption { |
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.
Having this return a LifeCycleOption
means that the life-cycle methods of the span will accept this. I'm not sure we do or don't want to do this. IIRC the specification might state that we cannot set the status in these methods, you'll need to double check that. If we do, the life-cycle methods will need to be updated to set the status when they receive this option.
Additionally, having this accept a boolean as an argument doesn't seem that useful. Why not accept a code and message for the status to set?
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.
Additionally, having this accept a boolean as an argument doesn't seem that useful. Why not accept a code and message for the status to set?
I would second that, this at the minimum should accept a code and message as the span status concept has room to grow beyond the current tri-state values.
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'm not sure about this either. WithStatus
doesn't seems to be an EventOption
, it does not change or affect an Event
. It is only applicable to the RecordError
method.
For example, using span.AddEvent("some event", trace.WithStatus())
is syntactically correct but does nothing.
I would prefer if we create another method to record an error with status or create an ErrorOption
that wraps an EventOptions
, for example:
span.RecordErrorStatus(err, code, "description", EventOptions..)
or
span.RecordError(err, trace.WithErrorStatus(code, "description"), trace.WithEventOpts(EventOptions..))
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 like the creation of the ErrorOption
approach. I could see there being many more things we want to pass here (we talked about maybe an option that would signal the stacktrace needed to be recorded).
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.
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.
ErrorOption sounds good. I will use ErrorOption to replace WithStatusOption.
Thanks very much.
…rrorOption (open-telemetry#1677) * Change signature of the Span `RecordError, replace EventOption by ErrorOption * Add WithEventOpts, WithErrorStatus * Set status when WithErrorStatus is passed to RecordError Signed-off-by: lastchiliarch <[email protected]>
05cad56
to
ca16c7a
Compare
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'd really like to avoid the extra WithEventOptions()
wrapper.
bridge/opentracing/internal/mock.go
Outdated
@@ -255,11 +255,13 @@ func (s *MockSpan) RecordError(err error, opts ...trace.EventOption) { | |||
} | |||
|
|||
s.SetStatus(codes.Error, "") |
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.
This probably shouldn't be setting the status here. Looks like maybe it was missed in the removal of that functionality.
CHANGELOG.md
Outdated
@@ -212,6 +212,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm | |||
|
|||
### Changed | |||
|
|||
- Changed signature of the Span `RecordError` , replace EventOption by ErrorOption |
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.
- Changed signature of the Span `RecordError` , replace EventOption by ErrorOption | |
- Changed signature of the Span `RecordError`, replace EventOption with ErrorOption. (#1817) |
sdk/trace/span.go
Outdated
// This method does not change the Span status in default | ||
// To set the Span status, pass `WithErrorStatus` as an option. | ||
// This method does nothing If this span is not being recorded or err is nil. |
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.
// This method does not change the Span status in default | |
// To set the Span status, pass `WithErrorStatus` as an option. | |
// This method does nothing If this span is not being recorded or err is nil. | |
// This method does not change the Span status by default | |
// To set the Span status pass a `WithErrorStatus(status)` option. | |
// This method does nothing if this span is not being recorded or if err is nil. |
trace/config.go
Outdated
for _, option := range options { | ||
option.ApplyError(c) | ||
} |
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'd like to avoid the need to use WithEventOpts()
when calling RecordError()
. My first thought was that maybe something like this would work:
for _, option := range options {
if evopt, ok := option.(EventOption); ok {
c.EventOpts = append(c.EventOpts, option)
} else {
option.ApplyError(c)
}
}
But I don't think it does since the method signature now requires ErrorOption
s to be passed instead of EventOption
s. So, my next thought is could the relevant EventOption
implementations gain an ErrorOption
implementation that looks something like this:
func (o someOptionType) ApplyError(c *ErrorConfig) {
c.EventOpts = append(c.EventOpts, o)
}
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 don't like the wrap either, I had tried this way to make it work before the wrap.
But it can't work, beacuse the compile complains about the type mismatch.
Error message:
Cannot use 'trace.WithTimestamp(errTime)' (type LifeCycleOption) as the type ErrorOption Type does not implement
'ErrorOption' as some methods are missing: ApplyError(config *ErrorConfig)
Code looks like this:
config:
type timestampSpanOption time.Time
func (o timestampSpanOption) ApplySpan(c *SpanConfig) { o.apply(c) }
func (o timestampSpanOption) ApplyEvent(c *SpanConfig) { o.apply(c) }
func (o timestampSpanOption) ApplyError(c *ErrorConfig) {c.Timestamp = time.Time(o)}
func (timestampSpanOption) private() {}
func (o timestampSpanOption) apply(c *SpanConfig) { c.Timestamp = time.Time(o) }
client code:
span.RecordError(s.err, trace.WithTimestamp(errTime))
RecordError:
func (s *span) RecordError(err error, options ...trace.ErrorOption) {
if s == nil || err == nil || !s.IsRecording() {
return
}
c := trace.NewErrorConfig(options...)
if c.Code != codes.Unset {
s.SetStatus(c.Code, c.Message)
}
var eventOpts []trace.EventOption
for _, option := range options {
if option, ok := option.(trace.EventOption); ok {
eventOpts = append(eventOpts, option)
}
}
eventOpts = append(eventOpts, trace.WithAttributes(
semconv.ExceptionTypeKey.String(typeStr(err)),
semconv.ExceptionMessageKey.String(err.Error()),
))
s.addEvent(semconv.ExceptionEventName, eventOpts...)
}
I don't think it's a good idea to make LifeCycleOption implements ErrorOption.
If you know any idea, that will be a great help, I'd like to remove the wrap.
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.
Why not just embed the ErrorOption
in the EventOption
? https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md#dealing-with-overlap
trace/config.go
Outdated
func (eventOptsErrorOption) private() {} | ||
|
||
// WithEventOpts set event options, will be passed to addEvent | ||
func WithEventOpts(option ...EventOption) ErrorOption { |
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.
func WithEventOpts(option ...EventOption) ErrorOption { | |
func WithEventOptions(option ...EventOption) ErrorOption { |
If we can't get rid of this I'd like it to not use an abbreviated name.
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.
Thanks very much.
trace/trace.go
Outdated
// This method does not change the Span status by default. | ||
// To set the Span status, pass `WithErrorStatus` as an option. | ||
// This method does nothing if this span is not being recorded or err is nil. |
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.
// This method does not change the Span status by default. | |
// To set the Span status, pass `WithErrorStatus` as an option. | |
// This method does nothing if this span is not being recorded or err is nil. | |
// This method does not change the Span status by default | |
// To set the Span status pass a `WithErrorStatus(status)` option. | |
// This method does nothing if this span is not being recorded or if err is nil. |
…rrorOption (open-telemetry#1677) * Change signature of the Span `RecordError, replace EventOption by ErrorOption * Add WithEventOpts, WithErrorStatus * Set status when WithErrorStatus is passed to RecordError Signed-off-by: lastchiliarch <[email protected]>
Signed-off-by: lastchiliarch <[email protected]>
Signed-off-by: lastchiliarch <[email protected]>
trace/config.go
Outdated
|
||
// ErrorOption applies an option to a ErrorConfig. | ||
type ErrorOption interface { | ||
ApplyError(config *ErrorConfig) |
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.
ApplyError(config *ErrorConfig) | |
applyError(config *errorConfig) |
We're working on normalizing configuration and options and part of that will involve making the config type and apply methods unexported. Can we get out ahead of that here?
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.
Sure. I had renamed ApplyError to applyError.
But golangci-lint will fail if I changed ErrorConfig to errorConfig.
exported func NewErrorConfig returns unexported type *go.opentelemetry.io/otel/trace.errorConfig, which can be annoying to us.
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.
newErrorConfig
shouldn't need to be exported, either.
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.
Since newErrorConfig will be used in by bridge/opentracing/internal/mock.go , oteltest/span.go and sdk/trace/span.go, it will take a lot of work to make it unexported at this time.
I think it's better to move all the code which implements Span interface to the package trace, so we can easily make the config unexported.
But there is another problem, since sdk/trace/span.go needs some code in sdk/trace/internal, we must change it at the same time.
I'm not sure about this solution, it will cause a lot of files to be changed.
Maybe we can keep NewErrorConfig exported and make a new pr to make it unexported, I'd like to take it.
Signed-off-by: lastchiliarch <[email protected]>
Signed-off-by: lastchiliarch <[email protected]>
|
||
// A private method to prevent users implementing the | ||
// interface and so future additions to it will not | ||
// violate compatibility. | ||
private() |
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.
// A private method to prevent users implementing the | |
// interface and so future additions to it will not | |
// violate compatibility. | |
private() |
This is no longer necessary since the applyError()
method is unexported.
// than this method does nothing. | ||
func (s *span) RecordError(err error, opts ...trace.EventOption) { | ||
// RecordError will record err as a span event for this span. | ||
// This method does not change the Span status by default |
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.
// This method does not change the Span status by default | |
// This method does not change the Span status by default. |
@@ -203,3 +205,56 @@ func (i instrumentationVersionOption) ApplyTracer(config *TracerConfig) { | |||
} | |||
|
|||
func (instrumentationVersionOption) private() {} | |||
|
|||
// ErrorConfig is a group of options for error. |
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.
// ErrorConfig is a group of options for error. | |
// ErrorConfig is a group of options for error events. |
} | ||
func (statusErrorOption) private() {} | ||
|
||
// WithErrorStatus set the error code and message when code is not codes.Unset |
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.
// WithErrorStatus set the error code and message when code is not codes.Unset | |
// WithErrorStatus set the error code and message when code is not codes.Unset. |
// span is not being recorded or err is nil than this method does nothing. | ||
RecordError(err error, options ...EventOption) | ||
// RecordError will record err as an exception span event for this span. | ||
// This method does not change the Span status by default |
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.
// This method does not change the Span status by default | |
// This method does not change the Span status by default. |
trace/config.go
Outdated
for _, option := range options { | ||
option.ApplyError(c) | ||
} |
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.
Why not just embed the ErrorOption
in the EventOption
? https://github.com/open-telemetry/opentelemetry-go/blob/main/CONTRIBUTING.md#dealing-with-overlap
Closing as HEAD has progressed far enough this will likely need to be re-evaluated. |
Add WithStatus event option to set Span status at the same time, see #1677.
Signed-off-by: lastchiliarch [email protected]