Skip to content

Commit

Permalink
meta: add telemetry via OpenTracing
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdecaf committed Aug 12, 2024
1 parent a13ccf2 commit 39606a4
Show file tree
Hide file tree
Showing 22 changed files with 279 additions and 74 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ build:

.PHONY: setup
setup:
docker-compose up -d --force-recreate --remove-orphans
docker compose up -d --force-recreate --remove-orphans

.PHONY: check
check:
Expand All @@ -50,7 +50,7 @@ endif

.PHONY: teardown
teardown:
-docker-compose down --remove-orphans
-docker compose down --remove-orphans

docker: update
docker build --pull --build-arg VERSION=${VERSION} -t moov/ach-test-harness:${VERSION} -f Dockerfile .
Expand Down
16 changes: 16 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ require (

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.6.0 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gobuffalo/here v0.6.7 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/igrmk/treemap/v2 v2.0.1 // indirect
github.com/magiconair/properties v1.8.7 // indirect
Expand All @@ -44,12 +49,23 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.19.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.opentelemetry.io/otel v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 // indirect
go.opentelemetry.io/otel/metric v1.28.0 // indirect
go.opentelemetry.io/otel/sdk v1.28.0 // indirect
go.opentelemetry.io/otel/trace v1.28.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
32 changes: 32 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -17,6 +19,11 @@ github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM=
github.com/gobuffalo/here v0.6.7 h1:hpfhh+kt2y9JLDfhYUxxCRxQol540jsVfKUZzjlbp8o=
github.com/gobuffalo/here v0.6.7/go.mod h1:vuCfanjqckTuRlqAitJz6QC4ABNnS27wLb816UhsPcc=
Expand All @@ -27,6 +34,8 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/igrmk/treemap/v2 v2.0.1 h1:Jhy4z3yhATvYZMWCmxsnHO5NnNZBdueSzvxh6353l+0=
Expand Down Expand Up @@ -112,6 +121,22 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0 h1:R3X6ZXmNPRR8ul6i3WgFURCHzaXjHdm0karRG/+dj3s=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.28.0/go.mod h1:QWFXnDavXWwMx2EEcZsf3yxgEKAqsxQ+Syjp+seyInw=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0 h1:EVSnY9JbEEW92bEkIYOVMw4q1WJxIAGoFTrtYOzWuRQ=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.28.0/go.mod h1:Ea1N1QQryNXpCD0I1fdLibBAIpQuBkznMmkdKrapk1Y=
go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE=
go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg=
go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
goftp.io/server v0.4.1 h1:x7KG4HIxSMdK/rpYhExMinRN/aO/T9icvaG/B5e/XfY=
Expand Down Expand Up @@ -141,6 +166,13 @@ golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 h1:6whtk83KtD3FkGrVb2hFXuQ+ZMbCNdakARIn/aHMmG8=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0=
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094/go.mod h1:fJ/e3If/Q67Mj99hin0hMhiNyCRmt6BQ2aWIJshUSJw=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
12 changes: 11 additions & 1 deletion pkg/batches/api_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"net/http"

"github.com/moov-io/base/log"
"github.com/moov-io/base/telemetry"

"github.com/gorilla/mux"
"go.opentelemetry.io/otel/attribute"
)

func NewBatchController(logger log.Logger, service BatchService) *batchController {
Expand All @@ -33,9 +35,17 @@ func (c *batchController) AppendRoutes(router *mux.Router) *mux.Router {

func (c *batchController) Search() func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
ctx, span := telemetry.StartSpan(r.Context(), "api-batch-search")
defer span.End()

w.Header().Set("Content-Type", "application/json; charset=utf-8")

batches, err := c.service.Search(readSearchOptions(r))
opts := readSearchOptions(r)
span.SetAttributes(
attribute.String("search.trace_number", opts.TraceNumber),
)

batches, err := c.service.Search(ctx, opts)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
Expand Down
28 changes: 25 additions & 3 deletions pkg/batches/repository_batch.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package batches

import (
"context"
"fmt"
"io/fs"
"path/filepath"
Expand All @@ -9,10 +10,14 @@ import (
"github.com/moov-io/ach"
"github.com/moov-io/ach-test-harness/pkg/response/match"
"github.com/moov-io/ach-test-harness/pkg/service"
"github.com/moov-io/base/telemetry"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)

type BatchRepository interface {
Search(opts SearchOptions) ([]ach.Batcher, error)
Search(ctx context.Context, opts SearchOptions) ([]ach.Batcher, error)
}

type batchRepository struct {
Expand All @@ -25,9 +30,14 @@ func NewFTPRepository(cfg *service.FTPConfig) *batchRepository {
}
}

func (r *batchRepository) Search(opts SearchOptions) ([]ach.Batcher, error) {
func (r *batchRepository) Search(ctx context.Context, opts SearchOptions) ([]ach.Batcher, error) {
_, span := telemetry.StartSpan(ctx, "repo-batch-search")
defer span.End()

out := make([]ach.Batcher, 0)

var filesProcessed int

//nolint:gosimple
var search fs.WalkDirFunc
search = func(path string, d fs.DirEntry, err error) error {
Expand All @@ -42,14 +52,26 @@ func (r *batchRepository) Search(opts SearchOptions) ([]ach.Batcher, error) {
if strings.ToLower(filepath.Ext(path)) != ".ach" {
return nil
}
filesProcessed += 1

batches, err := filterBatches(path, opts)
if err != nil {
return err
}
out = append(out, batches...)

if len(batches) > 0 {
span.AddEvent("found-batches", trace.WithAttributes(
attribute.Int("search.batches", len(batches)),
attribute.String("search.filename", path),
))

out = append(out, batches...)
}
return nil
}
span.SetAttributes(
attribute.Int("search.files_processed", filesProcessed),
)

var walkingPath = r.rootPath
if opts.Path != "" {
Expand Down
11 changes: 7 additions & 4 deletions pkg/batches/repository_batch_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package batches

import (
"context"
"testing"

"github.com/moov-io/ach-test-harness/pkg/service"
"github.com/stretchr/testify/require"
)

func TestRepository(t *testing.T) {
ctx := context.Background()

repo := NewFTPRepository(&service.FTPConfig{
RootPath: "./testdata",
Paths: service.Paths{
Expand All @@ -17,12 +20,12 @@ func TestRepository(t *testing.T) {
})

// return all
batches, err := repo.Search(SearchOptions{})
batches, err := repo.Search(ctx, SearchOptions{})
require.NoError(t, err)
require.Len(t, batches, 2)

// search by account number
batches, err = repo.Search(SearchOptions{
batches, err = repo.Search(ctx, SearchOptions{
AccountNumber: "987654321",
})

Expand All @@ -32,7 +35,7 @@ func TestRepository(t *testing.T) {
// search by timestamp in our files:
// returned/2.ach was created on 1908161055 and has 1 entry
// outbound/1.ach was created on 1908161059 and has 2 batches
batches, err = repo.Search(SearchOptions{
batches, err = repo.Search(ctx, SearchOptions{
CreatedAfter: "2019-08-16T10:56:00+00:00",
})

Expand All @@ -42,7 +45,7 @@ func TestRepository(t *testing.T) {

// search by subdirectory in our files:
// outbound/1.ach was created on 1908161059 and has 2 batches
batches, err = repo.Search(SearchOptions{
batches, err = repo.Search(ctx, SearchOptions{
Path: "outbound",
})

Expand Down
7 changes: 4 additions & 3 deletions pkg/batches/service_batch.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package batches

import (
"context"
"fmt"
"time"

Expand All @@ -9,7 +10,7 @@ import (
)

type BatchService interface {
Search(ops SearchOptions) ([]ach.Batcher, error)
Search(ctx context.Context, ops SearchOptions) ([]ach.Batcher, error)
}

type batchService struct {
Expand All @@ -31,8 +32,8 @@ type SearchOptions struct {
Path string
}

func (s *batchService) Search(opts SearchOptions) ([]ach.Batcher, error) {
return s.repository.Search(opts)
func (s *batchService) Search(ctx context.Context, opts SearchOptions) ([]ach.Batcher, error) {
return s.repository.Search(ctx, opts)
}

func (opts SearchOptions) fileTooOld(file *ach.File) (bool, error) {
Expand Down
12 changes: 11 additions & 1 deletion pkg/entries/api_entry.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"strconv"

"github.com/moov-io/base/log"
"github.com/moov-io/base/telemetry"

"github.com/gorilla/mux"
"go.opentelemetry.io/otel/attribute"
)

func NewEntryController(logger log.Logger, service EntryService) *entryController {
Expand All @@ -34,9 +36,17 @@ func (c *entryController) AppendRoutes(router *mux.Router) *mux.Router {

func (c *entryController) Search() func(w http.ResponseWriter, r *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
ctx, span := telemetry.StartSpan(r.Context(), "api-entry-search")
defer span.End()

w.Header().Set("Content-Type", "application/json; charset=utf-8")

entries, err := c.service.Search(readSearchOptions(r))
opts := readSearchOptions(r)
span.SetAttributes(
attribute.String("search.trace_number", opts.TraceNumber),
)

entries, err := c.service.Search(ctx, opts)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
Expand Down
File renamed without changes.
28 changes: 25 additions & 3 deletions pkg/entries/repository_entry.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package entries

import (
"context"
"fmt"
"io/fs"
"path/filepath"
Expand All @@ -9,10 +10,14 @@ import (
"github.com/moov-io/ach"
"github.com/moov-io/ach-test-harness/pkg/response/match"
"github.com/moov-io/ach-test-harness/pkg/service"
"github.com/moov-io/base/telemetry"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)

type EntryRepository interface {
Search(opts SearchOptions) ([]*ach.EntryDetail, error)
Search(ctx context.Context, opts SearchOptions) ([]*ach.EntryDetail, error)
}

type ftpRepository struct {
Expand All @@ -25,9 +30,14 @@ func NewFTPRepository(cfg *service.FTPConfig) *ftpRepository {
}
}

func (r *ftpRepository) Search(opts SearchOptions) ([]*ach.EntryDetail, error) {
func (r *ftpRepository) Search(ctx context.Context, opts SearchOptions) ([]*ach.EntryDetail, error) {
_, span := telemetry.StartSpan(ctx, "repo-entry-search")
defer span.End()

out := make([]*ach.EntryDetail, 0)

var filesProcessed int

//nolint:gosimple
var search fs.WalkDirFunc
search = func(path string, d fs.DirEntry, err error) error {
Expand All @@ -42,14 +52,26 @@ func (r *ftpRepository) Search(opts SearchOptions) ([]*ach.EntryDetail, error) {
if strings.ToLower(filepath.Ext(path)) != ".ach" {
return nil
}
filesProcessed += 1

entries, err := filterEntries(path, opts)
if err != nil {
return err
}
out = append(out, entries...)

if len(entries) > 0 {
span.AddEvent("found-entries", trace.WithAttributes(
attribute.Int("search.entries", len(entries)),
attribute.String("search.filename", path),
))

out = append(out, entries...)
}
return nil
}
span.SetAttributes(
attribute.Int("search.files_processed", filesProcessed),
)

var walkingPath = r.rootPath
if opts.Path != "" {
Expand Down
Loading

0 comments on commit 39606a4

Please sign in to comment.