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.Requestobject - 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 databasePros
- 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