Skip to content

Commit

Permalink
Add very basic yet useful implementation of logging
Browse files Browse the repository at this point in the history
  • Loading branch information
bassosimone committed Mar 24, 2020
1 parent c4e41ab commit 3c27eeb
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 0 deletions.
101 changes: 101 additions & 0 deletions internal/logging/logging.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Package logging adds logging to measurable objects.
package logging

import (
"context"
"crypto/tls"
"net"
"net/http"

"github.com/ooni/probe-engine/internal/measurable"
)

// The Logger interface describes a generic logger. This is designed
// to be compatible with https://github.com/apex/log logger.
type Logger interface {
Debugf(format string, v ...interface{})
Debug(msg string)
}

// Resolver is a logging resolver.
type Resolver struct {
measurable.Resolver
Logger
}

// LookupHost implements measurable.Resolver.LookupHost
func (r Resolver) LookupHost(ctx context.Context, domain string) ([]string, error) {
r.Logger.Debugf("LookupHostStart %s", domain)
addrs, err := r.Resolver.LookupHost(ctx, domain)
r.Logger.Debugf("LookupHostDone %+v %+v", addrs, err)
return addrs, err
}

// Connector is a logging connector.
type Connector struct {
measurable.Connector
Logger
}

// DialContext implements measurable.Connector.DialContext
func (d Connector) DialContext(
ctx context.Context, network, address string) (net.Conn, error) {
d.Logger.Debugf("DialContextStart %s %s", network, address)
conn, err := d.Connector.DialContext(ctx, network, address)
d.Logger.Debugf("DialContextDone %+v %+v", conn, err)
return conn, err
}

// TLSHandshaker is a logging TLS handshaker
type TLSHandshaker struct {
measurable.TLSHandshaker
Logger
}

// Handshake implements measurable.TLSHandshaker.Handshake
func (th TLSHandshaker) Handshake(
ctx context.Context, conn net.Conn, config *tls.Config) (
net.Conn, tls.ConnectionState, error) {
th.Logger.Debugf("TLSHandshakeStart %+v %+v", conn, config)
tlsconn, state, err := th.TLSHandshaker.Handshake(ctx, conn, config)
th.Logger.Debugf("TLSHandshakeDone %+v %+v", state, err)
return tlsconn, state, err
}

// HTTPTransport is a loggable HTTPTransport
type HTTPTransport struct {
measurable.HTTPTransport
Logger
}

// RoundTrip implements measurable.HTTPTransport.RoundTrip
func (txp HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
txp.Logger.Debugf("RoundTripStart %+v", req)
resp, err := txp.HTTPTransport.RoundTrip(req)
txp.Logger.Debugf("RoundTripDone %+v %+v", resp, err)
return resp, err
}

// WithLogger creates a copy of the provided context that is configured
// to use the specified logger for every dial, request, etc.
func WithLogger(ctx context.Context, logger Logger) context.Context {
config := measurable.ContextConfigOrDefault(ctx)
return measurable.WithConfig(ctx, &measurable.Config{
Connector: &Connector{
Connector: config.Connector,
Logger: logger,
},
HTTPTransport: &HTTPTransport{
HTTPTransport: config.HTTPTransport,
Logger: logger,
},
Resolver: &Resolver{
Resolver: config.Resolver,
Logger: logger,
},
TLSHandshaker: &TLSHandshaker{
TLSHandshaker: config.TLSHandshaker,
Logger: logger,
},
})
}
28 changes: 28 additions & 0 deletions internal/logging/logging_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package logging_test

import (
"context"
"io/ioutil"
"net/http"
"testing"

"github.com/apex/log"
"github.com/ooni/probe-engine/internal/logging"
"github.com/ooni/probe-engine/internal/measurable"
)

func TestIntegration(t *testing.T) {
log.SetLevel(log.DebugLevel)
defer log.SetLevel(log.InfoLevel)
ctx := logging.WithLogger(context.Background(), log.Log)
req, err := http.NewRequestWithContext(ctx, "GET", "http://facebook.com", nil)
if err != nil {
t.Fatal(err)
}
resp, err := measurable.DefaultHTTPClient.Do(req)
if err != nil {
t.Fatal(err)
}
ioutil.ReadAll(resp.Body)
resp.Body.Close()
}

0 comments on commit 3c27eeb

Please sign in to comment.