Skip to content

We need to log all requests and response to the 3rd party services

We want to store http request and response headers and data in log_logs table

Idea

Variety of requests and responses

  • Some services providing direct access to http.Request object
  • Some services providing an sdk without direct access to http.Request
  • We also want to log incoming request / webhooks

Georgy found a great idea on how to use http.Transport field:

The mechanism

Go’s http.Client executes HTTP requests via its Transport field, which implements http.RoundTripper. RoundTripper has one method: RoundTrip(*http.Request) (*http.Response, error). This is the heart of http.Client.

We need to extend http.Transport which implements RoundTripper and wraps other RoundTripper (normally http.DefaultTransport) with logging functionality.

Proposal one

Turn on / off logging directly in app layer

app/app.go:

golang
func (app *App) CreateTrade(ctx context.Context, pg PostgresRepository, profileID int, result interface{}) error {
  // some code

  // turn on logging when needed
	app.TurnOnAppLogging(   // pass all required paramters to logging
    ctx,
    app.repo,
  )

  app.dwolla.CreateTrade(ctx, ...)
  app.dwolla.FundTransfer(ctx, ...)

  app.TurnOffAppLogging()  // revert back default transporter
	return nil
}

app/logging.go:

golang
import (
	"net/http"

	"github.com/webdevelop-pro/go-logging/http2db"
)

func (app *App) TurnOnAppLogging(ctx context.Context, pg PostgresRepository) error {
  http.DefaultTransport = http2db.PostgresTransport(ctx, pg)
}

http2db.go:

golang
// similar to
// https://github.com/motemen/go-loghttp/blob/master/loghttp.go
// but with store to database
Pros
  • adapters can turn on / off logging when
  • no need to change anything in adapters
  • no need to pass any additional paramters to adapters to logging (like database connection)
Cons
  • Need to make changes in app
  • custom code required for incoming wehook requests

Proposal two

Turn on / off logging directly in adapters layer

adapters/dwolla.go:

golang
func (dwolla Dwolla) TurnOnAppLogging(client *http.Client) {
	d.client.HTTPClient = client
}

func (dwolla Dwolla) CreateTrade(ctx context.Context, pg PostgresRepository, profileID int, result interface{}) error {
	dwolla.TurnOnAppLogging(   // pass all required paramters to logging
    ctx,
    app.repo,
  )

  dwolla.client.CreateTrade(ctx, ...)

  // revert back default transporter
  app.TurnOffAppLogging()

	return nil
}
Pros
  • adapters can turn on / off logging when needed
Cons
  • Need to make changes in adapters
  • Adapters need to have connection to database
  • custom code required for incoming wehook requests

Future ideas

  • Migrate to enterprice ready solution
  • Collect logs from pods
  • Store logs to different postgres database or in loki