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

[7.14] Service specific source maps (backport #5410) #5680

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions apmpackage/apm/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ policy_templates:
required: false
show_user: false
default: 10000
<<<<<<< HEAD
- name: rum_library_pattern
type: text
title: RUM - Library Frame Pattern
Expand All @@ -134,6 +135,8 @@ policy_templates:
required: false
show_user: false
default: '"^/webpack"'
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))
- name: api_key_limit
type: integer
title: Maximum number of API Keys for Agent authentication
Expand Down
20 changes: 20 additions & 0 deletions beater/beater.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import (
"context"
"net"
"net/http"
<<<<<<< HEAD
"os"
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))
"regexp"
"runtime"
"strings"
Expand All @@ -31,7 +34,10 @@ import (
"github.com/elastic/beats/v7/libbeat/common/fleetmode"
"github.com/elastic/beats/v7/libbeat/common/transport"
"github.com/elastic/beats/v7/libbeat/common/transport/tlscommon"
<<<<<<< HEAD
"github.com/elastic/go-ucfg"
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))

"github.com/pkg/errors"
"go.elastic.co/apm"
Expand Down Expand Up @@ -284,7 +290,10 @@ type serverRunner struct {
acker *waitPublishedAcker
namespace string
config *config.Config
<<<<<<< HEAD
rawConfig *common.Config
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))
fleetConfig *config.Fleet
beat *beat.Beat
logger *logp.Logger
Expand Down Expand Up @@ -324,7 +333,10 @@ func newServerRunner(ctx context.Context, args serverRunnerParams) (*serverRunne
cancelRunServerContext: cancel,

config: cfg,
<<<<<<< HEAD
rawConfig: args.RawConfig,
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))
fleetConfig: args.FleetConfig,
acker: args.Acker,
pipeline: args.Pipeline,
Expand Down Expand Up @@ -655,7 +667,15 @@ func newSourcemapStore(beatInfo beat.Info, cfg config.SourceMapping, fleetCfg *c
// Default for es is 90s :shrug:
timeout := 30 * time.Second
dialer := transport.NetDialer(timeout)
<<<<<<< HEAD
tlsDialer := transport.TLSDialer(dialer, tlsConfig, timeout)
=======
tlsDialer, err := transport.TLSDialer(dialer, tlsConfig, timeout)
if err != nil {
return nil, err
}

>>>>>>> 9453fe24 (Service specific source maps (#5410))
rt = &http.Transport{
Proxy: http.ProxyFromEnvironment,
Dial: dialer.Dial,
Expand Down
4 changes: 4 additions & 0 deletions beater/beater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,11 @@ func TestFleetStoreUsed(t *testing.T) {
called = true
wr := zlib.NewWriter(w)
defer wr.Close()
<<<<<<< HEAD
wr.Write([]byte(fmt.Sprintf(`{"sourceMap":%s}`, test.ValidSourcemap)))
=======
wr.Write([]byte(test.ValidSourcemap))
>>>>>>> 9453fe24 (Service specific source maps (#5410))
}))
defer ts.Close()

Expand Down
41 changes: 41 additions & 0 deletions changelogs/head.asciidoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
[[release-notes-head]]
== APM Server version HEAD

https://github.com/elastic/apm-server/compare/7.13\...master[View commits]

[float]
==== Breaking Changes
* Removed monitoring counters `apm-server.processor.stream.errors.{queue,server,closed}` {pull}5453[5453]

[float]
==== Bug fixes
* Fix panic due to misaligned 64-bit access on 32-bit architectures {pull}5277[5277]
* Fixed tail-based sampling pubsub to use _seq_no correctly {pull}5126[5126]
* Removed service name from dataset {pull}5451[5451]

[float]
==== Intake API Changes

[float]
==== Added
* Support setting agent configuration from apm-server.yml {pull}5177[5177]
* Add metric_type and unit to field metadata of system metrics {pull}5230[5230]
* Display apm-server url in fleet ui's apm-server integration {pull}4895[4895]
* Translate otel messaging.* semantic conventions to ECS {pull}5334[5334]
* Add support for dynamic histogram metrics {pull}5239[5239]
* Tail-sampling processor now resumes subscription from previous position after restart {pull}5350[5350]
* Add support for histograms to metrics intake {pull}5360[5360]
* Upgrade Go to 1.16.5 {pull}5454[5454]
* Add units to metric fields {pull}5395[5395]
* Support fetching sourcemaps from fleet {pull}5410[5410]
* Add support for adjusting OTel event timestamps using `telemetry.sdk.elastic_export_timestamp` {pull}5433[5433]
* Add support for OpenTelemetry labels describing mobile connectivity {pull}5436[5436]
* Introduce `apm-server.auth.*` config {pull}5457[5457]
* Add debug logging of OpenTelemetry payloads {pull}5474[5474]
* Add support for more input variables in fleet integration {pull}5444[5444]

[float]
==== Deprecated
* Make destination.service.name and destination.service.type fields optional and deprecated {pull}5468[5468]
* `apm-server.secret_token` is now `apm-server.auth.secret_token` {pull}5457[5457]
* `apm-server.api_key` is now `apm-server.auth.api_key` {pull}5457[5457]
17 changes: 17 additions & 0 deletions sourcemap/fleet_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@
package sourcemap

import (
<<<<<<< HEAD
"compress/zlib"
"context"
"encoding/json"
"fmt"
=======
"bytes"
"compress/zlib"
"context"
"fmt"
"io"
>>>>>>> 9453fe24 (Service specific source maps (#5410))
"io/ioutil"
"net/http"
"time"
Expand Down Expand Up @@ -129,9 +137,18 @@ func (f fleetStore) fetch(ctx context.Context, name, version, path string) (stri
return "", err
}

<<<<<<< HEAD
var m map[string]json.RawMessage
if err := json.NewDecoder(r).Decode(&m); err != nil {
return "", err
}
return string(m["sourceMap"]), nil
=======
buf := new(bytes.Buffer)
if _, err := io.Copy(buf, r); err != nil {
return "", err
}

return buf.String(), nil
>>>>>>> 9453fe24 (Service specific source maps (#5410))
}
20 changes: 20 additions & 0 deletions sourcemap/fleet_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ import (
"github.com/elastic/apm-server/beater/config"

"github.com/stretchr/testify/assert"
<<<<<<< HEAD
"github.com/stretchr/testify/require"
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))
)

func TestFleetFetch(t *testing.T) {
Expand All @@ -37,6 +40,10 @@ func TestFleetFetch(t *testing.T) {
name = "webapp"
version = "1.0.0"
path = "/my/path/to/bundle.js.map"
<<<<<<< HEAD
=======
wantRes = "sourcemap response"
>>>>>>> 9453fe24 (Service specific source maps (#5410))
c = http.DefaultClient
sourceMapPath = "/api/fleet/artifact"
)
Expand All @@ -48,7 +55,11 @@ func TestFleetFetch(t *testing.T) {
// zlib compress
wr := zlib.NewWriter(w)
defer wr.Close()
<<<<<<< HEAD
wr.Write([]byte(resp))
=======
wr.Write([]byte(wantRes))
>>>>>>> 9453fe24 (Service specific source maps (#5410))
}))
defer ts.Close()

Expand All @@ -71,10 +82,19 @@ func TestFleetFetch(t *testing.T) {
assert.NoError(t, err)

gotRes, err := fb.fetch(context.Background(), name, version, path)
<<<<<<< HEAD
require.NoError(t, err)

assert.Contains(t, gotRes, "webpack:///bundle.js")
assert.True(t, hasAuth)
}

var resp = "{\"serviceName\":\"web-app\",\"serviceVersion\":\"1.0.0\",\"bundleFilepath\":\"/test/e2e/general-usecase/bundle.js.map\",\"sourceMap\":{\"version\":3,\"sources\":[\"webpack:///bundle.js\",\"\",\"webpack:///./scripts/index.js\",\"webpack:///./index.html\",\"webpack:///./scripts/app.js\"],\"names\":[\"modules\",\"__webpack_require__\",\"moduleId\",\"installedModules\",\"exports\",\"module\",\"id\",\"loaded\",\"call\",\"m\",\"c\",\"p\",\"foo\",\"console\",\"log\",\"foobar\"],\"mappings\":\"CAAS,SAAUA,GCInB,QAAAC,GAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,GAGAI,EAAAE,QAAA,EAGAF,EAAAD,QAvBA,GAAAD,KAqCA,OATAF,GAAAQ,EAAAT,EAGAC,EAAAS,EAAAP,EAGAF,EAAAU,EAAA,GAGAV,EAAA,KDMM,SAASI,EAAQD,EAASH,GE3ChCA,EAAA,GAEAA,EAAA,GAEAW,OFmDM,SAASP,EAAQD,EAASH,GGxDhCI,EAAAD,QAAAH,EAAAU,EAAA,cH8DM,SAASN,EAAQD,GI9DvB,QAAAQ,KACAC,QAAAC,IAAAC,QAGAH\",\"file\":\"bundle.js\",\"sourcesContent\":[\"/******/ (function(modules) { // webpackBootstrap\\n/******/ \\t// The module cache\\n/******/ \\tvar installedModules = {};\\n/******/\\n/******/ \\t// The require function\\n/******/ \\tfunction __webpack_require__(moduleId) {\\n/******/\\n/******/ \\t\\t// Check if module is in cache\\n/******/ \\t\\tif(installedModules[moduleId])\\n/******/ \\t\\t\\treturn installedModules[moduleId].exports;\\n/******/\\n/******/ \\t\\t// Create a new module (and put it into the cache)\\n/******/ \\t\\tvar module = installedModules[moduleId] = {\\n/******/ \\t\\t\\texports: {},\\n/******/ \\t\\t\\tid: moduleId,\\n/******/ \\t\\t\\tloaded: false\\n/******/ \\t\\t};\\n/******/\\n/******/ \\t\\t// Execute the module function\\n/******/ \\t\\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\\n/******/\\n/******/ \\t\\t// Flag the module as loaded\\n/******/ \\t\\tmodule.loaded = true;\\n/******/\\n/******/ \\t\\t// Return the exports of the module\\n/******/ \\t\\treturn module.exports;\\n/******/ \\t}\\n/******/\\n/******/\\n/******/ \\t// expose the modules object (__webpack_modules__)\\n/******/ \\t__webpack_require__.m = modules;\\n/******/\\n/******/ \\t// expose the module cache\\n/******/ \\t__webpack_require__.c = installedModules;\\n/******/\\n/******/ \\t// __webpack_public_path__\\n/******/ \\t__webpack_require__.p = \\\"\\\";\\n/******/\\n/******/ \\t// Load entry module and return exports\\n/******/ \\treturn __webpack_require__(0);\\n/******/ })\\n/************************************************************************/\\n/******/ ([\\n/* 0 */\\n/***/ function(module, exports, __webpack_require__) {\\n\\n\\t// Webpack\\n\\t__webpack_require__(1)\\n\\t\\n\\t__webpack_require__(2)\\n\\t\\n\\tfoo()\\n\\n\\n/***/ },\\n/* 1 */\\n/***/ function(module, exports, __webpack_require__) {\\n\\n\\tmodule.exports = __webpack_require__.p + \\\"index.html\\\"\\n\\n/***/ },\\n/* 2 */\\n/***/ function(module, exports) {\\n\\n\\tfunction foo() {\\n\\t console.log(foobar)\\n\\t}\\n\\t\\n\\tfoo()\\n\\n\\n/***/ }\\n/******/ ]);\\n\\n\\n/** WEBPACK FOOTER **\\n ** bundle.js\\n **/\",\" \\t// The module cache\\n \\tvar installedModules = {};\\n\\n \\t// The require function\\n \\tfunction __webpack_require__(moduleId) {\\n\\n \\t\\t// Check if module is in cache\\n \\t\\tif(installedModules[moduleId])\\n \\t\\t\\treturn installedModules[moduleId].exports;\\n\\n \\t\\t// Create a new module (and put it into the cache)\\n \\t\\tvar module = installedModules[moduleId] = {\\n \\t\\t\\texports: {},\\n \\t\\t\\tid: moduleId,\\n \\t\\t\\tloaded: false\\n \\t\\t};\\n\\n \\t\\t// Execute the module function\\n \\t\\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\\n\\n \\t\\t// Flag the module as loaded\\n \\t\\tmodule.loaded = true;\\n\\n \\t\\t// Return the exports of the module\\n \\t\\treturn module.exports;\\n \\t}\\n\\n\\n \\t// expose the modules object (__webpack_modules__)\\n \\t__webpack_require__.m = modules;\\n\\n \\t// expose the module cache\\n \\t__webpack_require__.c = installedModules;\\n\\n \\t// __webpack_public_path__\\n \\t__webpack_require__.p = \\\"\\\";\\n\\n \\t// Load entry module and return exports\\n \\treturn __webpack_require__(0);\\n\\n\\n\\n/** WEBPACK FOOTER **\\n ** webpack/bootstrap 6002740481c9666b0d38\\n **/\",\"// Webpack\\nrequire('../index.html')\\n\\nrequire('./app')\\n\\nfoo()\\n\\n\\n\\n/*****************\\n ** WEBPACK FOOTER\\n ** ./scripts/index.js\\n ** module id = 0\\n ** module chunks = 0\\n **/\",\"module.exports = __webpack_public_path__ + \\\"index.html\\\"\\n\\n\\n/*****************\\n ** WEBPACK FOOTER\\n ** ./index.html\\n ** module id = 1\\n ** module chunks = 0\\n **/\",\"function foo() {\\n console.log(foobar)\\n}\\n\\nfoo()\\n\\n\\n\\n/*****************\\n ** WEBPACK FOOTER\\n ** ./scripts/app.js\\n ** module id = 2\\n ** module chunks = 0\\n **/\"],\"sourceRoot\":\"\"}}"
=======
assert.NoError(t, err)

assert.Equal(t, wantRes, gotRes)

assert.True(t, hasAuth)
}
>>>>>>> 9453fe24 (Service specific source maps (#5410))
31 changes: 31 additions & 0 deletions sourcemap/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,22 @@ func TestStore_Fetch(t *testing.T) {
})
}

<<<<<<< HEAD
func TestFetchContext(t *testing.T) {
var (
=======
func TestFetchTimeout(t *testing.T) {
var (
errs int64

>>>>>>> 9453fe24 (Service specific source maps (#5410))
apikey = "supersecret"
name = "webapp"
version = "1.0.0"
path = "/my/path/to/bundle.js.map"
c = http.DefaultClient
)
<<<<<<< HEAD

requestReceived := make(chan struct{})
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand All @@ -170,6 +178,9 @@ func TestFetchContext(t *testing.T) {
return
}
// block until the client cancels the request
=======
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
>>>>>>> 9453fe24 (Service specific source maps (#5410))
<-r.Context().Done()
}))
defer ts.Close()
Expand All @@ -192,6 +203,7 @@ func TestFetchContext(t *testing.T) {
assert.NoError(t, err)
logger := logp.NewLogger(logs.Sourcemap)
store, err := newStore(b, logger, time.Minute)
<<<<<<< HEAD
require.NoError(t, err)

ctx, cancel := context.WithCancel(context.Background())
Expand All @@ -216,6 +228,18 @@ func TestFetchContext(t *testing.T) {
case <-time.After(10 * time.Second):
t.Fatal("timed out waiting for Fetch to return")
}
=======
assert.NoError(t, err)

ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
defer cancel()

_, err = store.Fetch(ctx, name, version, path)
assert.True(t, errors.Is(err, context.DeadlineExceeded))
atomic.AddInt64(&errs, 1)

assert.Equal(t, int64(1), errs)
>>>>>>> 9453fe24 (Service specific source maps (#5410))
}

func TestConcurrentFetch(t *testing.T) {
Expand All @@ -234,7 +258,10 @@ func TestConcurrentFetch(t *testing.T) {
version = "1.0.0"
path = "/my/path/to/bundle.js.map"
c = http.DefaultClient
<<<<<<< HEAD
res = fmt.Sprintf(`{"sourceMap":%s}`, test.ValidSourcemap)
=======
>>>>>>> 9453fe24 (Service specific source maps (#5410))

errsLeft = tc.errWant
)
Expand All @@ -250,7 +277,11 @@ func TestConcurrentFetch(t *testing.T) {
}
wr := zlib.NewWriter(w)
defer wr.Close()
<<<<<<< HEAD
wr.Write([]byte(res))
=======
wr.Write([]byte(test.ValidSourcemap))
>>>>>>> 9453fe24 (Service specific source maps (#5410))
}))
defer ts.Close()

Expand Down
Loading