-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Trace ssh sessions #14966
Trace ssh sessions #14966
Conversation
56f6e01
to
642ab9b
Compare
ec4aa71
to
9531434
Compare
Adds a wrapper around `ssh.Session` which injects tracing context in a similar manner to the `ssh.Client` wrapper. All usages of `ssh.Session` have now been replaced and have the appropriate `context.Context` passed along Part of #12241
9531434
to
f67c8f8
Compare
ctx, span := tracer.Start( | ||
c.ctx, | ||
fmt.Sprintf("ssh.OpenChannel/%s", name), | ||
oteltrace.WithSpanKind(oteltrace.SpanKindClient), | ||
oteltrace.WithAttributes( | ||
append( | ||
peerAttr(c.Conn.RemoteAddr()), | ||
semconv.RPCServiceKey.String("ssh.Client"), | ||
semconv.RPCMethodKey.String("OpenChannel"), | ||
semconv.RPCSystemKey.String("ssh"), | ||
)..., | ||
), | ||
) |
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 is duplicated quite a few times, with the only things changing are what's in line #365 and #371, and some having extra attributes - whats your thoughts on abstracting it out?
Something like
func StartSSHTrace(ctx context.Context, kind, name string, tracer *tracing.Provider, attributes ...attribute.KeyValue) (*context.Context, trace.error) {
return tracer.Start(
ctx,
fmt.Sprintf("ssh.%s/%s", kind, name),
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(
append(
semconv.RPCServiceKey.String("ssh.Client"),
semconv.RPCMethodKey.String(kind),
semconv.RPCSystemKey.String("ssh"),
attributes...,
)...,
),
)
}
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 did toy around with this, but I'm not sure that it adds much value or makes things any easier or less verbose.
I ended up with a slightly different function than the one your proposed:
func newSpan(ctx context.Context, name string, cfg *tracing.Config, attributes ...attribute.KeyValue) (context.Context, oteltrace.Span) {
tracer := cfg.TracerProvider.Tracer(instrumentationName)
return tracer.Start(
ctx,
name,
oteltrace.WithSpanKind(oteltrace.SpanKindClient),
oteltrace.WithAttributes(semconv.RPCSystemKey.String("ssh")),
oteltrace.WithAttributes(
attributes...,
),
)
}
Which turns the call site into:
ctx, span := newSpan(
ctx,
fmt.Sprintf("ssh.SessionRequest/%s", name),
config,
[]attribute.KeyValue{
attribute.Bool("want_reply", wantReply),
semconv.RPCServiceKey.String("ssh.Session"),
semconv.RPCMethodKey.String("SendRequest"),
}...,
)
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.
Yeah I was hesitant to suggest it, as I realise it's still pretty verbose - I was just thinking of keeping similar attributes the same across the board. Happy either way!
opts []tracing.Option | ||
|
||
// lock protects the context queue | ||
lock sync.Mutex |
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 could be a sync.RWMutex
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.
RWMutexes aren't more efficient unless you expect fairly high numbers of concurrent reads, both in absolute, and relative to the number of concurrent writes. Near as I can tell that isn't true for this type.
c.lock.Lock() | ||
defer c.lock.Unlock() |
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.
& then this becomes
c.lock.Lock() | |
defer c.lock.Unlock() | |
c.lock.RLock() | |
defer c.lock.RUnlock() |
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 function modifies c.contexts
.
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.
LGTM. I think if we add any more instrumentation to the ssh types we might want to consider creating interfaces to abstract over them. Feels fiddly to have to change the types all over to add a wrapper.
@rosstimothy See the table below for backport results.
|
Adds a wrapper around
ssh.Session
which injects tracing contextin a similar manner to the
ssh.Client
wrapper.All usages of
ssh.Session
have now been replaced and have the appropriatecontext.Context
passed alongPart of #12241