Skip to content

Commit 25e81f0

Browse files
authored
Revisited APM spans/transactions set (#1306)
This PR reviews the APM spans that are set in Elastic Package Registry. It add news spans to allow us to have a better knowledge of the requests, specially for the proxied requests.
1 parent 6a39224 commit 25e81f0

File tree

6 files changed

+155
-55
lines changed

6 files changed

+155
-55
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
* Update Go runtime to 1.24.2. [#1299](https://github.com/elastic/package-registry/pull/1299)
1414
* Ignore unknown categories instead of producing fatal errors. [#1297](https://github.com/elastic/package-registry/pull/1297)
1515
* Fix usages of time.Since in defer statements used to obtain duration Prometheus metrics in the indexer. [#1304](https://github.com/elastic/package-registry/pull/1304)
16+
* Rename some spans to avoid conflicts. [#1306](https://github.com/elastic/package-registry/pull/1306)
1617

1718
### Added
1819

1920
* Change license from Elastic License to Elastic License 2.0. [#1298](https://github.com/elastic/package-registry/pull/1298)
21+
* Add APM spans for proxy requests and storage indexer Get calls. [#1306](https://github.com/elastic/package-registry/pull/1306)
2022

2123
### Deprecated
2224

packages/http.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ func ServePackageSignature(logger *zap.Logger, w http.ResponseWriter, r *http.Re
6363
}
6464

6565
func serveLocalPackage(logger *zap.Logger, w http.ResponseWriter, r *http.Request, p *Package, packagePath string) {
66-
span, _ := apm.StartSpan(r.Context(), "ServePackage", "app")
66+
span, _ := apm.StartSpan(r.Context(), "ServeLocalPackage", "app")
67+
span.Context.SetLabel("file.name", packagePath)
6768
defer span.End()
6869

6970
logger = logger.With(zap.String("file.name", packagePath))
@@ -93,7 +94,8 @@ func serveLocalPackage(logger *zap.Logger, w http.ResponseWriter, r *http.Reques
9394

9495
// ServePackageResource is used by staticHandler.
9596
func ServePackageResource(logger *zap.Logger, w http.ResponseWriter, r *http.Request, p *Package, packageFilePath string) {
96-
span, _ := apm.StartSpan(r.Context(), "ServePackage", "app")
97+
span, _ := apm.StartSpan(r.Context(), "ServePackageResource", "app")
98+
span.Context.SetLabel("file.name", packageFilePath)
9799
defer span.End()
98100

99101
if p.RemoteResolver() != nil {

packages/packages.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ func (i *FileSystemIndexer) Get(ctx context.Context, opts *GetOptions) (Packages
198198
defer func() {
199199
metrics.IndexerGetDurationSeconds.With(prometheus.Labels{"indexer": i.label}).Observe(time.Since(start).Seconds())
200200
}()
201+
span, ctx := apm.StartSpan(ctx, "GetFileSystemIndexer", "app")
202+
span.Context.SetLabel("indexer", i.label)
203+
defer span.End()
204+
201205
if opts == nil {
202206
return i.packageList, nil
203207
}

proxymode/proxymode.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/gorilla/mux"
1818
"github.com/hashicorp/go-retryablehttp"
19+
"go.elastic.co/apm/v2"
1920

2021
"go.uber.org/zap"
2122

@@ -112,6 +113,9 @@ func (pm *ProxyMode) Enabled() bool {
112113
}
113114

114115
func (pm *ProxyMode) Search(r *http.Request) (packages.Packages, error) {
116+
span, _ := apm.StartSpan(r.Context(), "Proxy Search", "app")
117+
defer span.End()
118+
115119
proxyURL := *r.URL
116120
proxyURL.Host = pm.destinationURL.Host
117121
proxyURL.Scheme = pm.destinationURL.Scheme
@@ -140,6 +144,9 @@ func (pm *ProxyMode) Search(r *http.Request) (packages.Packages, error) {
140144
}
141145

142146
func (pm *ProxyMode) Categories(r *http.Request) ([]packages.Category, error) {
147+
span, _ := apm.StartSpan(r.Context(), "Proxy Categories", "app")
148+
defer span.End()
149+
143150
proxyURL := *r.URL
144151
proxyURL.Host = pm.destinationURL.Host
145152
proxyURL.Scheme = pm.destinationURL.Scheme
@@ -165,6 +172,9 @@ func (pm *ProxyMode) Categories(r *http.Request) ([]packages.Category, error) {
165172
}
166173

167174
func (pm *ProxyMode) Package(r *http.Request) (*packages.Package, error) {
175+
span, _ := apm.StartSpan(r.Context(), "Proxy Package", "app")
176+
defer span.End()
177+
168178
vars := mux.Vars(r)
169179
packageName, ok := vars["packageName"]
170180
if !ok {

storage/indexer.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ func (i *Indexer) Get(ctx context.Context, opts *packages.GetOptions) (packages.
208208
metrics.IndexerGetDurationSeconds.With(prometheus.Labels{"indexer": indexerGetDurationPrometheusLabel}).Observe(time.Since(start).Seconds())
209209
}()
210210

211+
span, ctx := apm.StartSpan(ctx, "GetStorageIndexer", "app")
212+
defer span.End()
213+
211214
i.m.RLock()
212215
defer i.m.RUnlock()
213216

storage/indexer_test.go

Lines changed: 132 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"fmt"
1010
"testing"
1111

12+
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
1314
"go.uber.org/zap/zapcore"
1415

@@ -86,70 +87,148 @@ func BenchmarkIndexerGet(b *testing.B) {
8687
})
8788
}
8889

89-
func TestGet_ListAllPackages(t *testing.T) {
90+
func TestGet_ListPackages(t *testing.T) {
9091
// given
9192
fs := PrepareFakeServer(t, "testdata/search-index-all-full.json")
9293
defer fs.Stop()
9394
storageClient := fs.Client()
9495
indexer := NewIndexer(util.NewTestLogger(), storageClient, FakeIndexerOptions)
9596

96-
err := indexer.Init(context.Background())
97+
ctx := context.Background()
98+
err := indexer.Init(ctx)
9799
require.NoError(t, err, "storage indexer must be initialized properly")
98100

99-
// when
100-
foundPackages, err := indexer.Get(context.Background(), &packages.GetOptions{})
101-
102-
// then
103-
require.NoError(t, err, "packages should be returned")
104-
require.Len(t, foundPackages, 1133)
105-
}
106-
107-
func TestGet_FindLatestPackage(t *testing.T) {
108-
// given
109-
fs := PrepareFakeServer(t, "testdata/search-index-all-full.json")
110-
defer fs.Stop()
111-
storageClient := fs.Client()
112-
indexer := NewIndexer(util.NewTestLogger(), storageClient, FakeIndexerOptions)
113-
114-
err := indexer.Init(context.Background())
115-
require.NoError(t, err, "storage indexer must be initialized properly")
116-
117-
// when
118-
foundPackages, err := indexer.Get(context.Background(), &packages.GetOptions{
119-
Filter: &packages.Filter{
120-
PackageName: "apm",
121-
PackageType: "integration",
101+
cases := []struct {
102+
name string
103+
options *packages.GetOptions
104+
expected int
105+
expectedName string
106+
expectedVersion string
107+
}{
108+
{
109+
name: "all packages filter nil",
110+
options: &packages.GetOptions{},
111+
expected: 1133,
122112
},
123-
})
124-
125-
// then
126-
require.NoError(t, err, "packages should be returned")
127-
require.Len(t, foundPackages, 1)
128-
require.Equal(t, "apm", foundPackages[0].Name)
129-
require.Equal(t, "8.2.0", foundPackages[0].Version)
130-
}
131-
132-
func TestGet_UnknownPackage(t *testing.T) {
133-
// given
134-
fs := PrepareFakeServer(t, "testdata/search-index-all-full.json")
135-
defer fs.Stop()
136-
storageClient := fs.Client()
137-
indexer := NewIndexer(util.NewTestLogger(), storageClient, FakeIndexerOptions)
138-
139-
err := indexer.Init(context.Background())
140-
require.NoError(t, err, "storage indexer must be initialized properly")
141-
142-
// when
143-
foundPackages, err := indexer.Get(context.Background(), &packages.GetOptions{
144-
Filter: &packages.Filter{
145-
PackageName: "qwertyuiop",
146-
PackageType: "integration",
113+
{
114+
name: "all versions of packages including prerelease",
115+
options: &packages.GetOptions{
116+
Filter: &packages.Filter{
117+
AllVersions: true,
118+
Prerelease: true,
119+
},
120+
},
121+
expected: 1133,
147122
},
148-
})
123+
{
124+
name: "latest versions of packages not including prerelease",
125+
options: &packages.GetOptions{
126+
Filter: &packages.Filter{
127+
AllVersions: false,
128+
Prerelease: false,
129+
},
130+
},
131+
expected: 99,
132+
},
133+
{
134+
name: "all packages with all versions and no prerelease",
135+
options: &packages.GetOptions{
136+
Filter: &packages.Filter{
137+
AllVersions: true,
138+
},
139+
},
140+
expected: 494,
141+
},
142+
{
143+
name: "all packages with latest versions and no prerelease",
144+
options: &packages.GetOptions{
145+
Filter: &packages.Filter{
146+
Prerelease: false,
147+
},
148+
},
149+
expected: 99,
150+
},
151+
{
152+
name: "all packages prerelease",
153+
options: &packages.GetOptions{
154+
Filter: &packages.Filter{
155+
Prerelease: true,
156+
},
157+
},
158+
expected: 147,
159+
},
160+
{
161+
name: "all zeek packages with prerelease",
162+
options: &packages.GetOptions{
163+
Filter: &packages.Filter{
164+
AllVersions: true,
165+
Prerelease: true,
166+
PackageName: "zeek",
167+
},
168+
},
169+
expected: 17,
170+
},
171+
{
172+
name: "all packages with all versions of a giventype",
173+
options: &packages.GetOptions{
174+
Filter: &packages.Filter{
175+
AllVersions: true,
176+
Prerelease: true,
177+
PackageType: "solution",
178+
},
179+
},
180+
expected: 2,
181+
},
182+
{
183+
name: "one package of a giventype",
184+
options: &packages.GetOptions{
185+
Filter: &packages.Filter{
186+
Prerelease: true,
187+
PackageName: "tomcat",
188+
PackageVersion: "0.3.0",
189+
},
190+
},
191+
expected: 1,
192+
},
193+
{
194+
name: "unknown package",
195+
options: &packages.GetOptions{
196+
Filter: &packages.Filter{
197+
PackageName: "qwertyuiop",
198+
PackageType: "integration",
199+
},
200+
},
201+
expected: 0,
202+
},
203+
{
204+
name: "latest package",
205+
options: &packages.GetOptions{
206+
Filter: &packages.Filter{
207+
PackageName: "apm",
208+
PackageType: "integration",
209+
},
210+
},
211+
expected: 1,
212+
expectedName: "apm",
213+
expectedVersion: "8.2.0",
214+
},
215+
}
149216

150-
// then
151-
require.NoError(t, err, "packages should be returned")
152-
require.Len(t, foundPackages, 0)
217+
for _, c := range cases {
218+
t.Run(c.name, func(t *testing.T) {
219+
// when
220+
foundPackages, err := indexer.Get(ctx, c.options)
221+
// then
222+
require.NoError(t, err, "packages should be returned")
223+
require.Len(t, foundPackages, c.expected)
224+
if c.expectedName != "" {
225+
assert.Equal(t, c.expectedName, foundPackages[0].Name)
226+
}
227+
if c.expectedVersion != "" {
228+
assert.Equal(t, c.expectedVersion, foundPackages[0].Version)
229+
}
230+
})
231+
}
153232
}
154233

155234
func TestGet_IndexUpdated(t *testing.T) {

0 commit comments

Comments
 (0)