Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: fetch sourcemaps from Elasticsearch #9722

Merged
merged 152 commits into from
Feb 7, 2023
Merged
Show file tree
Hide file tree
Changes from 82 commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
8bcf7b4
feat: fetch sourcemaps from Elasticsearch
kruskall Dec 2, 2022
3d61fc1
lint: fix linter issues
kruskall Dec 2, 2022
d18afa0
lint: fix staticcheck issue
kruskall Dec 4, 2022
6b13bb3
feat: update code to support latest kibana PR
kruskall Dec 12, 2022
27883df
test: udpdate sourcemap test to use the kibana sourcemap API
kruskall Dec 12, 2022
4d8c011
feat: implement cache invalidation in sourcemap cache
kruskall Dec 12, 2022
f04473e
feat: remove fleet and kibana sourcemap fetchers
kruskall Dec 12, 2022
7a64c06
refactor: code cleanup
kruskall Dec 13, 2022
c96587d
fix: do not try to decode the body if the sourcemap was not found
kruskall Dec 13, 2022
855cb02
test: update tests for sourcemap changes
kruskall Dec 13, 2022
cd01a10
lint: revert update task changes
kruskall Dec 13, 2022
9890493
Merge remote-tracking branch 'upstream/main' into feat/es-sourcemap
kruskall Dec 19, 2022
9518384
build: remove unused imports
kruskall Dec 19, 2022
761802b
Merge remote-tracking branch 'upstream/main' into feat/es-sourcemap
kruskall Dec 19, 2022
ac529cd
lint: fix linter issues
kruskall Dec 19, 2022
a9957ea
feat: add support for relative path
kruskall Dec 19, 2022
260d3d5
Merge branch 'main' into feat/es-sourcemap
kruskall Dec 22, 2022
995e254
feat: add support for injected api key
kruskall Dec 23, 2022
cf86bb3
lint: fix formatting issue
kruskall Dec 23, 2022
813cdfb
Merge branch 'main' into feat/es-sourcemap
kruskall Dec 29, 2022
6f0fb18
refactor: use meaningful variable names
kruskall Dec 29, 2022
094dbfc
lint: fix linter issues
kruskall Dec 29, 2022
3f0c2be
refactor: use map data structure to reduce iteration count and improv…
kruskall Dec 29, 2022
cc35612
refactor: do not block when retrieving a sourcemap before the cache i…
kruskall Dec 29, 2022
a3e65cb
refactor: reduce diff noise
kruskall Dec 29, 2022
b1a2bf2
fix: actually add new sourcemaps to the metadata cache
kruskall Dec 29, 2022
0f4b3fa
refactor: don't send the whole metadata as part of the update
kruskall Dec 29, 2022
a5ea7bf
Merge remote-tracking branch 'upstream/main' into feat/es-sourcemap
kruskall Jan 9, 2023
3041003
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 16, 2023
9486691
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 16, 2023
b0b8646
feat: use sourcemapping rum es api_key
kruskall Jan 16, 2023
0942d3d
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 18, 2023
3d72922
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 18, 2023
77ed8f1
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 18, 2023
5e80d77
fix: forward the request to the backend fetcher if the metadata cache…
kruskall Jan 18, 2023
61fed2d
fix: update ES sourcemap result format
kruskall Jan 18, 2023
2131a33
refactor: do not sort by score if we limited the size to 1
kruskall Jan 18, 2023
4d66334
test: always wait for document to be indexed when creating sourcemaps
kruskall Jan 18, 2023
16839e8
test: create sourcemap in ES before starting APM server
kruskall Jan 18, 2023
1031ac2
test: add read privilege for .apm-source-map index to apm_server role
kruskall Jan 18, 2023
413385a
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 19, 2023
4532dfb
fix: ignore query and fragment on bundlefilepath and avoid double fet…
kruskall Jan 19, 2023
cff8dd0
test: empty sourcemap index as part of the cleanup process
kruskall Jan 19, 2023
7946c09
feat: add debug log statement when forwarding requesting before init
kruskall Jan 19, 2023
39510c4
fix: try with both names when forwarding requests
kruskall Jan 19, 2023
020f869
test: update RUM test to use standalone APM server
kruskall Jan 19, 2023
870b635
fix: properly support aliases
kruskall Jan 19, 2023
06a59b1
test: clean path before waiting for sourcemap to be indexed
kruskall Jan 19, 2023
b881da3
test: only run absolute and relative bundle filepath test on standalone
kruskall Jan 19, 2023
df99000
refactor: add more debug messages for empty search results
kruskall Jan 19, 2023
ffa8941
fix: do not include url path twice in identifiers
kruskall Jan 19, 2023
c5508d9
fix: refactor aliases handling and avoid init deadlock
kruskall Jan 19, 2023
b342665
fix: do not return duplicate alias if bundlefilepath is a full url
kruskall Jan 19, 2023
695c495
refactor: add more verbose debug messages to make metadata fetcher co…
kruskall Jan 19, 2023
b3c5792
refactor: clarify cache size log message
kruskall Jan 19, 2023
b48a882
fix: try to lookup the aliases in the metadata cache to account for e…
kruskall Jan 19, 2023
7aded27
refactor: cleanup and reduce duplicate code
kruskall Jan 19, 2023
ba117b4
lint: fix linter issues
kruskall Jan 19, 2023
d4fccb2
fix: use correct log format method
kruskall Jan 19, 2023
54ab5b9
fix: readd support and test for indexpattern
kruskall Jan 19, 2023
1aa9654
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 19, 2023
529b129
test: add back system tests for apm integration
kruskall Jan 21, 2023
778ec6d
feat: bump sourcemap error log message level to error
kruskall Jan 21, 2023
69e2859
fix: prevent sourcemapping specific ES config from being overwritten
kruskall Jan 21, 2023
faece2a
fix: defer closing the init channel to avoid potential deadlock
kruskall Jan 21, 2023
8c03743
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 21, 2023
878b025
refactor: reduce diff noise
kruskall Jan 21, 2023
558a473
refactor: remove unused approval document
kruskall Jan 21, 2023
7df5419
lint: remove unused methods
kruskall Jan 21, 2023
e186512
fix: ignore error when sourcemapping ES config is missing
kruskall Jan 21, 2023
c194073
test: update config test for sourcemap indexpattern changes
kruskall Jan 22, 2023
b56a1ea
refactor: improve metadata fetcher
kruskall Jan 22, 2023
7757b55
fix: document edge cases and try to maximize cache hits
kruskall Jan 23, 2023
0b38f0d
refactor: improve sourcemap es query
kruskall Jan 23, 2023
a890a2f
feat: add back kibana fetcher as fallback
kruskall Jan 23, 2023
174e87e
test: add systemtest for kibana fetcher
kruskall Jan 23, 2023
d12ebdf
fix: do not leak sourcemap sync goroutine
kruskall Jan 23, 2023
90bc423
fix: use scroll search to populate metadata cache
kruskall Jan 23, 2023
88f78a0
refactor: cleanup search query functions
kruskall Jan 23, 2023
873b4c6
refactor: reduce duplicate code
kruskall Jan 23, 2023
c919996
docs: add documentation on why we need to renew scrollID
kruskall Jan 23, 2023
b674d5d
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 23, 2023
4bc95f7
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 25, 2023
e13870b
docs: fix typo
kruskall Jan 25, 2023
3066ce0
refactor: do not encode scroll id in the body manually
kruskall Jan 25, 2023
42bc926
refactor: use result hits instead of manual comparison
kruskall Jan 25, 2023
f258815
docs: fix unicode chars
kruskall Jan 25, 2023
0c34f3c
fix: close invalidation channel
kruskall Jan 25, 2023
444c55b
refactor: add missing json struct tag to essourcemapresponse fields
kruskall Jan 25, 2023
b7389a6
refactor: remove unused fleetcfg parameter
kruskall Jan 25, 2023
4610931
refactor: rename sourcemapfetcher cancel func for clarity
kruskall Jan 25, 2023
ed99eb5
feat: remove sourcemapping metadata option
kruskall Jan 26, 2023
29d329d
lint: fix linter issues
kruskall Jan 26, 2023
cd6ae96
test: improve TestStoreUsesRUMElasticsearchConfig to make sure the co…
kruskall Jan 26, 2023
e2b24a0
feat: return an error if sourcemap is missing
kruskall Jan 26, 2023
0c3eef4
test: update approvals document
kruskall Jan 26, 2023
1d4d261
refactor: rework sync logic and decouple fetchers
kruskall Jan 27, 2023
240da96
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 27, 2023
26ecdfe
fix: prevent race condition between sync goroutines
kruskall Jan 27, 2023
cf94883
refactor: abstract alias retrieval
kruskall Jan 27, 2023
5c92302
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 27, 2023
c8ca86d
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 28, 2023
c593dfc
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 29, 2023
c87ce27
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 30, 2023
cc5a01a
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 30, 2023
f353cd1
refactor: rework fetchers and improve errors
kruskall Jan 31, 2023
04dc1fb
Merge branch 'main' into feat/es-sourcemap
kruskall Jan 31, 2023
88c8011
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 2, 2023
824c68f
refactor: print routine completion message on success
kruskall Feb 2, 2023
9efecb9
lint: fix variable name typo
kruskall Feb 2, 2023
d466045
feat: remove index pattern setting
kruskall Feb 2, 2023
ed6c474
docs remove outdated comment
kruskall Feb 2, 2023
ffaef7f
refactor: reduce data type visibility
kruskall Feb 2, 2023
c4e9407
lint: fix linter issues
kruskall Feb 2, 2023
6d1472c
fix: update sourcemap hash if changed
kruskall Feb 2, 2023
ab147c5
test: add es unavailable sourcemap test
kruskall Feb 2, 2023
dccaec4
fix: handle es unreachable and clarify status code handling code
kruskall Feb 2, 2023
067202b
test: fix kibana sourcemap test
kruskall Feb 2, 2023
5ff04ac
fix: handle http status 401 correctly
kruskall Feb 2, 2023
e64ddb3
refactor: simplify chained fetcher logic
kruskall Feb 2, 2023
a65af2a
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 2, 2023
0db75d9
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 5, 2023
711ed63
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 6, 2023
9c19470
refactor: update invalidation goroutine log message level
kruskall Feb 6, 2023
55f95c9
fix: create a new context when falling back in the chained fetcher
kruskall Feb 6, 2023
868eb55
refactor: update elasticsearch fetcher error message
kruskall Feb 6, 2023
be3ea36
lint: fix method name typo
kruskall Feb 6, 2023
54be00c
refactor: avoid additional gorutine
kruskall Feb 6, 2023
17b485b
refactor: remove isdebug check
kruskall Feb 6, 2023
557e4a3
refactor: update es fetcher to use get api
kruskall Feb 6, 2023
af66eda
refactor: use es library source field instead of encoding the request…
kruskall Feb 6, 2023
6eb7746
refactor: remove unused search.go file
kruskall Feb 6, 2023
2ac90e0
fix: encode document id when building the search query
kruskall Feb 6, 2023
a44b82a
feat: block until the metadata cache is populated
kruskall Feb 7, 2023
ee25e37
fix: handle 401 unauthorized in metadata fetcher
kruskall Feb 7, 2023
11c097b
fix: set the init error during init
kruskall Feb 7, 2023
3530b49
refactor: cleanup metadata updating to avoid useless map operations
kruskall Feb 7, 2023
14d230a
fix: do not block forever when invalidating sourcemaps
kruskall Feb 7, 2023
d8924cc
lint: fix linter issues
kruskall Feb 7, 2023
3ef10e5
test: refactor sourcemap test for clarity and duplicate code
kruskall Feb 7, 2023
bbebe6a
test: update unit test for new es response format
kruskall Feb 7, 2023
c24db8d
docs: remove stale comment
kruskall Feb 7, 2023
08ae602
fix: close ping request response body
kruskall Feb 7, 2023
5b0dfb6
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 7, 2023
2e814f4
fix: do not send empty invalidations
kruskall Feb 7, 2023
53c7d97
test: add metadata fetcher tests
kruskall Feb 7, 2023
8028c46
test: add sourcemap fetcher tests
kruskall Feb 7, 2023
8c61b76
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 7, 2023
4de127a
docs: remove todo
kruskall Feb 7, 2023
7b75446
feat: remove cache expiration option
kruskall Feb 7, 2023
a182dd2
Merge branch 'main' into feat/es-sourcemap
kruskall Feb 7, 2023
1d74a28
lint: fix linter issues
kruskall Feb 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 25 additions & 71 deletions internal/beater/beater.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"fmt"
"net"
"net/http"
"net/url"
"os"
"runtime"
"strings"
Expand All @@ -33,14 +32,12 @@ import (
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
"go.elastic.co/apm/module/apmgrpc/v2"
"go.elastic.co/apm/module/apmhttp/v2"
"go.elastic.co/apm/v2"
"go.uber.org/zap"
"golang.org/x/sync/errgroup"
"google.golang.org/grpc"

"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/common"
"github.com/elastic/beats/v7/libbeat/esleg/eslegclient"
"github.com/elastic/beats/v7/libbeat/instrumentation"
"github.com/elastic/beats/v7/libbeat/licenser"
Expand All @@ -51,8 +48,6 @@ import (
agentconfig "github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/monitoring"
"github.com/elastic/elastic-agent-libs/transport"
"github.com/elastic/elastic-agent-libs/transport/tlscommon"
"github.com/elastic/go-docappender"
"github.com/elastic/go-ucfg"

Expand Down Expand Up @@ -330,20 +325,15 @@ func (s *Runner) Run(ctx context.Context) error {

var sourcemapFetcher sourcemap.Fetcher
if s.config.RumConfig.Enabled && s.config.RumConfig.SourceMapping.Enabled {
fetcher, err := newSourcemapFetcher(
fetcher, cleanup, err := newSourcemapFetcher(
kruskall marked this conversation as resolved.
Show resolved Hide resolved
s.config.RumConfig.SourceMapping, s.fleetConfig,
kibanaClient, newElasticsearchClient,
)
if err != nil {
return err
}
cachingFetcher, err := sourcemap.NewCachingFetcher(
fetcher, s.config.RumConfig.SourceMapping.Cache.Expiration,
)
if err != nil {
return err
}
sourcemapFetcher = cachingFetcher
defer cleanup()
sourcemapFetcher = fetcher
}

// Create the runServer function. We start with newBaseRunServer, and then
Expand Down Expand Up @@ -823,73 +813,37 @@ func newSourcemapFetcher(
fleetCfg *config.Fleet,
kruskall marked this conversation as resolved.
Show resolved Hide resolved
kibanaClient *kibana.Client,
newElasticsearchClient func(*elasticsearch.Config) (*elasticsearch.Client, error),
) (sourcemap.Fetcher, error) {
// When running under Fleet we only fetch via Fleet Server.
if fleetCfg != nil {
var tlsConfig *tlscommon.TLSConfig
var err error
if fleetCfg.TLS.IsEnabled() {
if tlsConfig, err = tlscommon.LoadTLSConfig(fleetCfg.TLS); err != nil {
return nil, err
}
}

timeout := 30 * time.Second
dialer := transport.NetDialer(timeout)
tlsDialer := transport.TLSDialer(dialer, tlsConfig, timeout)
) (sourcemap.Fetcher, context.CancelFunc, error) {
esClient, err := newElasticsearchClient(cfg.ESConfig)
if err != nil {
return nil, nil, err
}

client := *http.DefaultClient
client.Transport = apmhttp.WrapRoundTripper(&http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: dialer.Dial,
DialTLS: tlsDialer.Dial,
TLSClientConfig: tlsConfig.ToConfig(),
})
// For standalone, we query both Kibana and Elasticsearch for backwards compatibility.
kruskall marked this conversation as resolved.
Show resolved Hide resolved
var chained sourcemap.ChainedFetcher

fleetServerURLs := make([]*url.URL, len(fleetCfg.Hosts))
for i, host := range fleetCfg.Hosts {
urlString, err := common.MakeURL(fleetCfg.Protocol, "", host, 8220)
if err != nil {
return nil, err
}
u, err := url.Parse(urlString)
if err != nil {
return nil, err
}
fleetServerURLs[i] = u
}
size := 128
invalidationChan := make(chan sourcemap.Identifier, size)
kruskall marked this conversation as resolved.
Show resolved Hide resolved

artifactRefs := make([]sourcemap.FleetArtifactReference, len(cfg.Metadata))
for i, meta := range cfg.Metadata {
artifactRefs[i] = sourcemap.FleetArtifactReference{
ServiceName: meta.ServiceName,
ServiceVersion: meta.ServiceVersion,
BundleFilepath: meta.BundleFilepath,
FleetServerURLPath: meta.SourceMapURL,
}
}
index := strings.ReplaceAll(cfg.IndexPattern, "%{[observer.version]}", version.Version)

return sourcemap.NewFleetFetcher(
&client,
fleetCfg.AccessAPIKey,
fleetServerURLs,
artifactRefs,
)
esFetcher := sourcemap.NewElasticsearchFetcher(esClient, index)
cachingFetcher, err := sourcemap.NewCachingFetcher(esFetcher, invalidationChan, size)
if err != nil {
return nil, nil, err
}
metadataCachingFetcher := sourcemap.NewMetadataCachingFetcher(esClient, cachingFetcher, index, invalidationChan)

ctx, cancel := context.WithCancel(context.Background())
metadataCachingFetcher.StartBackgroundSync(ctx)

chained = append(chained, metadataCachingFetcher)

// For standalone, we query both Kibana and Elasticsearch for backwards compatibility.
var chained sourcemap.ChainedFetcher
if kibanaClient != nil {
chained = append(chained, sourcemap.NewKibanaFetcher(kibanaClient))
}
esClient, err := newElasticsearchClient(cfg.ESConfig)
if err != nil {
return nil, err
}
index := strings.ReplaceAll(cfg.IndexPattern, "%{[observer.version]}", version.Version)
esFetcher := sourcemap.NewElasticsearchFetcher(esClient, index)
chained = append(chained, esFetcher)
return chained, nil

return chained, cancel, nil
}

// TODO: This is copying behavior from libbeat:
Expand Down
51 changes: 12 additions & 39 deletions internal/beater/beater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
package beater

import (
"compress/zlib"
"context"
"fmt"
"net/http"
Expand All @@ -40,6 +39,13 @@ func TestSourcemapIndexPattern(t *testing.T) {
test := func(t *testing.T, indexPattern, expected string) {
var requestPaths []string
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Ignore duplicates: we might have two requests since the first one
// will be from the init goroutine
for _, v := range requestPaths {
if v == r.URL.Path {
return
}
}
requestPaths = append(requestPaths, r.URL.Path)
}))
defer srv.Close()
Expand All @@ -51,11 +57,12 @@ func TestSourcemapIndexPattern(t *testing.T) {
cfg.RumConfig.SourceMapping.IndexPattern = indexPattern
}

fetcher, err := newSourcemapFetcher(
fetcher, cleanup, err := newSourcemapFetcher(
cfg.RumConfig.SourceMapping, nil,
nil, elasticsearch.NewClient,
)
require.NoError(t, err)
defer cleanup()
fetcher.Fetch(context.Background(), "name", "version", "path")
require.Len(t, requestPaths, 1)

Expand All @@ -65,7 +72,7 @@ func TestSourcemapIndexPattern(t *testing.T) {
assert.Equal(t, expected, path)
}
t.Run("default-pattern", func(t *testing.T) {
test(t, "", "apm-*-sourcemap*")
test(t, "", ".apm-source-map")
})
t.Run("with-observer-version", func(t *testing.T) {
test(t, "blah-%{[observer.version]}-blah", fmt.Sprintf("blah-%s-blah", version.Version))
Expand All @@ -89,11 +96,12 @@ func TestStoreUsesRUMElasticsearchConfig(t *testing.T) {
cfg.RumConfig.SourceMapping.ESConfig = elasticsearch.DefaultConfig()
cfg.RumConfig.SourceMapping.ESConfig.Hosts = []string{ts.URL}

fetcher, err := newSourcemapFetcher(
fetcher, cleanup, err := newSourcemapFetcher(
cfg.RumConfig.SourceMapping, nil,
nil, elasticsearch.NewClient,
)
require.NoError(t, err)
defer cleanup()
// Check that the provided rum elasticsearch config was used and
// Fetch() goes to the test server.
_, err = fetcher.Fetch(context.Background(), "app", "1.0", "/bundle/path")
Expand All @@ -102,41 +110,6 @@ func TestStoreUsesRUMElasticsearchConfig(t *testing.T) {
assert.True(t, called)
}

func TestFleetStoreUsed(t *testing.T) {
var called bool
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
called = true
wr := zlib.NewWriter(w)
defer wr.Close()
wr.Write([]byte(fmt.Sprintf(`{"sourceMap":%s}`, validSourcemap)))
}))
defer ts.Close()

cfg := config.DefaultConfig()
cfg.RumConfig.Enabled = true
cfg.RumConfig.SourceMapping.Enabled = true
cfg.RumConfig.SourceMapping.Metadata = []config.SourceMapMetadata{{
ServiceName: "app",
ServiceVersion: "1.0",
BundleFilepath: "/bundle/path",
SourceMapURL: "/my/path",
}}

fleetCfg := &config.Fleet{
Hosts: []string{ts.URL[7:]},
Protocol: "http",
AccessAPIKey: "my-key",
TLS: nil,
}

fetcher, err := newSourcemapFetcher(cfg.RumConfig.SourceMapping, fleetCfg, nil, nil)
require.NoError(t, err)
_, err = fetcher.Fetch(context.Background(), "app", "1.0", "/bundle/path")
require.NoError(t, err)

assert.True(t, called)
}

func TestQueryClusterUUIDRegistriesExist(t *testing.T) {
stateRegistry := monitoring.GetNamespace("state").GetRegistry()
stateRegistry.Clear()
Expand Down
2 changes: 1 addition & 1 deletion internal/beater/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ func TestUnpackConfig(t *testing.T) {
Cache: Cache{
Expiration: 7 * time.Second,
},
IndexPattern: "apm-*-sourcemap*",
IndexPattern: ".apm-source-map",
ESConfig: elasticsearch.DefaultConfig(),
Metadata: []SourceMapMetadata{
{
Expand Down
34 changes: 28 additions & 6 deletions internal/beater/config/rum.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/go-ucfg"

"github.com/elastic/apm-server/internal/elasticsearch"
)
Expand All @@ -34,7 +35,7 @@ const (
defaultExcludeFromGrouping = "^/webpack"
defaultLibraryPattern = "node_modules|bower_components|~"
defaultSourcemapCacheExpiration = 5 * time.Minute
defaultSourcemapIndexPattern = "apm-*-sourcemap*"
defaultSourcemapIndexPattern = ".apm-source-map"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't aware that the actual sourcemap index in ES changes, we had discussed that the index already exists. With this change, existing standalone APM Server that rely on fetching sourcemaps from ES might be broken on upgrade, as the configured credentials need to have privileges to query this index.

Can you clarify why the index itself changed and if this is really necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct. Both the index and the way sourcemaps are stored in ES changed. This happened in the kibana PR (https://github.com/elastic/kibana/pull/147208/files#diff-a968c157df4cd16bb68294e0741431359aba6574abbed2020b7ca10e4f592159R28), it is necessary and we are just defaulting to what they use

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agree that as long as the Kibana side changes this, we have to adapt, but I'd like to question whether the changes in the Kibana UI code are necessary. @kruskall and I discussed that he will follow up with the UI folks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was of the impression that apm-*-sourcemap* was no longer used, and the ability to configure the index was removed to simplify things:
elastic/kibana@4050578

My concern was that if the end user could configure the source map index, the internal kibana user might not have permissions to query it. With a hardcoded index (.apm-source-map) I was sure this was not the case.

I can easily change this back to apm-{version}-sourcemap. It won't be user configurable but it'll match the old pattern.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw. I suppose we still need to create the index for recent versions of the stack. Or does APM Server still create the index at startup?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern was that if the end user could configure the source map index, the internal kibana user might not have permissions to query it. With a hardcoded index (.apm-source-map) I was sure this was not the case.

Understood, and this is a valid concern.@kruskall could you check how the sourcemap index is currently setup (before your changes) when the server runs in standalone mode and Kibana is not enabled?

Copy link
Member

@sorenlouv sorenlouv Jan 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this solve the problem on your end? elastic/kibana#149403

Btw I changed the index to apm-agent-sourcemap so it still matches apm-*-sourcemap*

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed that we would keep the currently implemented logic and move forward with .apm-source-map.

defaultSourcemapTimeout = 5 * time.Second
)

Expand All @@ -58,6 +59,7 @@ type SourceMapping struct {
Metadata []SourceMapMetadata `config:"metadata"`
Timeout time.Duration `config:"timeout" validate:"positive"`
esConfigured bool
es *config.C
}

func (c *RumConfig) setup(log *logp.Logger, outputESCfg *config.C) error {
Expand All @@ -72,20 +74,35 @@ func (c *RumConfig) setup(log *logp.Logger, outputESCfg *config.C) error {
return errors.Wrapf(err, "Invalid regex for `exclude_from_grouping`: ")
}

// No need to unpack the ESConfig if SourceMapMetadata exist
if len(c.SourceMapping.Metadata) > 0 {
return nil
// We don't have the fleet fetcher anymore.
// Ignore metadata and setup the elasticsearch config.
log.Warn("Ignoring sourcemap metadata")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd completely remove SourceMapping.Metadata. Afaics this is not used anywhere anymore and was only used with the FleetFetcher, so it should never reach this code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not used in the APM Server but I think kibana (?) might be injecting this option.

For example, in TestRUMErrorSourcemapping this code path is triggered and we're logging a warning.

I agree we can remove it here 👍

}

// fall back to elasticsearch output configuration for sourcemap storage if possible
if outputESCfg == nil {
log.Info("Unable to determine sourcemap storage, sourcemaps will not be applied")
return nil
}
log.Info("Falling back to elasticsearch output for sourcemap storage")

// Unpack the output elasticsearch config first
if err := outputESCfg.Unpack(c.SourceMapping.ESConfig); err != nil {
return errors.Wrap(err, "unpacking Elasticsearch config into Sourcemap config")
return errors.Wrap(err, "unpacking Elasticsearch output config into Sourcemap config")
}

// SourceMapping ES config not configured, use the main one and return early
if c.SourceMapping.es == nil {
log.Info("Using default sourcemap Elasticsearch config")
return nil
}

// Unpack the SourceMapping ES config on top of the output elasticsearch config
if err := c.SourceMapping.es.Unpack(c.SourceMapping.ESConfig); err != nil {
return errors.Wrap(err, "unpacking Elasticsearch sourcemap config into Sourcemap config")
}

c.SourceMapping.es = nil

return nil
}

Expand All @@ -95,6 +112,11 @@ func (s *SourceMapping) Unpack(inp *config.C) error {
return errors.Wrap(err, "error unpacking sourcemapping config")
}
s.esConfigured = inp.HasField("elasticsearch")
var err error
var e ucfg.Error
if s.es, err = inp.Child("elasticsearch", -1); err != nil && (!errors.As(err, &e) || e.Reason() != ucfg.ErrMissing) {
return errors.Wrap(err, "error storing sourcemap elasticsearch config")
}
return nil
}

Expand Down
Loading