Skip to content
Snippets Groups Projects
Commit 438dda6c authored by ale's avatar ale
Browse files

Add tracing support to LDAP requests

parent fd088454
Branches
No related tags found
Loading
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/cenkalti/backoff" "github.com/cenkalti/backoff"
"go.opencensus.io/trace"
"gopkg.in/ldap.v2" "gopkg.in/ldap.v2"
) )
...@@ -147,9 +148,18 @@ func NewConnectionPool(uri, bindDN, bindPw string, cacheSize int) (*ConnectionPo ...@@ -147,9 +148,18 @@ func NewConnectionPool(uri, bindDN, bindPw string, cacheSize int) (*ConnectionPo
}, nil }, nil
} }
func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) error) error { func (p *ConnectionPool) doRequest(ctx context.Context, name string, attrs []trace.Attribute, fn func(*ldap.Conn) error) error {
return backoff.Retry(func() error { // Tracing: initialize a new client span.
conn, err := p.Get(ctx) sctx, span := trace.StartSpan(ctx, name,
trace.WithSpanKind(trace.SpanKindClient))
defer span.End()
if len(attrs) > 0 {
span.AddAttributes(attrs...)
}
rerr := backoff.Retry(func() error {
conn, err := p.Get(sctx)
if err != nil { if err != nil {
// Here conn is nil, so we don't need to Release it. // Here conn is nil, so we don't need to Release it.
if isTemporaryLDAPError(err) { if isTemporaryLDAPError(err) {
...@@ -158,7 +168,7 @@ func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) erro ...@@ -158,7 +168,7 @@ func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) erro
return backoff.Permanent(err) return backoff.Permanent(err)
} }
if deadline, ok := ctx.Deadline(); ok { if deadline, ok := sctx.Deadline(); ok {
conn.SetTimeout(time.Until(deadline)) conn.SetTimeout(time.Until(deadline))
} }
...@@ -169,30 +179,42 @@ func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) erro ...@@ -169,30 +179,42 @@ func (p *ConnectionPool) doRequest(ctx context.Context, fn func(*ldap.Conn) erro
} }
return err return err
}, backoff.WithContext(newExponentialBackOff(), ctx)) }, backoff.WithContext(newExponentialBackOff(), ctx))
// Tracing: set the final status.
span.SetStatus(errorToTraceStatus(rerr))
return rerr
} }
// Search performs the given search request. It will retry the request // Search performs the given search request. It will retry the request
// on temporary errors. // on temporary errors.
func (p *ConnectionPool) Search(ctx context.Context, searchRequest *ldap.SearchRequest) (*ldap.SearchResult, error) { func (p *ConnectionPool) Search(ctx context.Context, searchRequest *ldap.SearchRequest) (*ldap.SearchResult, error) {
var result *ldap.SearchResult var result *ldap.SearchResult
err := p.doRequest(ctx, func(conn *ldap.Conn) error { err := p.doRequest(ctx, "ldap.Search", []trace.Attribute{
var err error trace.StringAttribute("ldap.base", searchRequest.BaseDN),
result, err = conn.Search(searchRequest) trace.StringAttribute("ldap.filter", searchRequest.Filter),
return err trace.Int64Attribute("ldap.scope", int64(searchRequest.Scope)),
}, func(conn *ldap.Conn) (cerr error) {
result, cerr = conn.Search(searchRequest)
return
}) })
return result, err return result, err
} }
// Modify issues a ModifyRequest to the LDAP server. // Modify issues a ModifyRequest to the LDAP server.
func (p *ConnectionPool) Modify(ctx context.Context, modifyRequest *ldap.ModifyRequest) error { func (p *ConnectionPool) Modify(ctx context.Context, modifyRequest *ldap.ModifyRequest) error {
return p.doRequest(ctx, func(conn *ldap.Conn) error { return p.doRequest(ctx, "ldap.Modify", []trace.Attribute{
trace.StringAttribute("ldap.dn", modifyRequest.DN),
}, func(conn *ldap.Conn) error {
return conn.Modify(modifyRequest) return conn.Modify(modifyRequest)
}) })
} }
// Add issues an AddRequest to the LDAP server. // Add issues an AddRequest to the LDAP server.
func (p *ConnectionPool) Add(ctx context.Context, addRequest *ldap.AddRequest) error { func (p *ConnectionPool) Add(ctx context.Context, addRequest *ldap.AddRequest) error {
return p.doRequest(ctx, func(conn *ldap.Conn) error { return p.doRequest(ctx, "ldap.Add", []trace.Attribute{
trace.StringAttribute("ldap.dn", addRequest.DN),
}, func(conn *ldap.Conn) error {
return conn.Add(addRequest) return conn.Add(addRequest)
}) })
} }
...@@ -219,3 +241,16 @@ func isTemporaryLDAPError(err error) bool { ...@@ -219,3 +241,16 @@ func isTemporaryLDAPError(err error) bool {
return false return false
} }
} }
func errorToTraceStatus(err error) trace.Status {
switch err {
case nil:
return trace.Status{Code: trace.StatusCodeOK, Message: "OK"}
case context.Canceled:
return trace.Status{Code: trace.StatusCodeCancelled, Message: "CANCELED"}
case context.DeadlineExceeded:
return trace.Status{Code: trace.StatusCodeDeadlineExceeded, Message: "DEADLINE_EXCEEDED"}
default:
return trace.Status{Code: trace.StatusCodeUnknown, Message: err.Error()}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment