getsentry / sentry

Developer-first error tracking and performance monitoring
https://sentry.io
Other
39.11k stars 4.2k forks source link

Sentry JS lazily-loadable loader doesn't work #22715

Open fabis94 opened 3 years ago

fabis94 commented 3 years ago

Version Information

Version: 20.10.1

Description

According to the documentation (https://docs.sentry.io/platforms/javascript/install/lazy-load-sentry/#sdk-version) Sentry offers a lightweight lazy-loadable version of the Sentry JS SDK which is a lot smaller than the default bundles.

I tried to use it, but when I open the script that's shown inside the "JavaScript Loader" input box as shown in the docs, the entire contents of the script look like this:

function _sentry_noopWarning() {
  console.warn("The Sentry loader you are trying to use isn't working anymore, check your configuration.");
}
var Sentry = {
    addBreadcrumb: _sentry_noopWarning,
    captureEvent: _sentry_noopWarning,
    captureException: _sentry_noopWarning,
    captureMessage: _sentry_noopWarning,
    configureScope: _sentry_noopWarning,
    forceLoad: _sentry_noopWarning,
    init: _sentry_noopWarning,
    onLoad: _sentry_noopWarning,
    showReportDialog: _sentry_noopWarning,
    withScope: _sentry_noopWarning,
};
_sentry_noopWarning();

I tried grep-ing through the Sentry source code about this, but I was only able to find the template that generates this script (https://github.com/getsentry/sentry/blob/master/src/sentry/templates/sentry/js-sdk-loader-noop.js.tmpl) and couldn't figure out further how does Sentry decide to show this broken version instead of the real script.

The documentation isn't helpful either.

Steps to Reproduce

Install Sentry on-premises and check the JavaScript Loader, I guess.

Logs

No logs

aldy505 commented 3 months ago

Good news, people. Alex (@stayallive) has found a fix! https://github.com/getsentry/self-hosted/pull/3213

Daniel15 commented 3 months ago

That's a good PR, but it's a workaround rather than a fix. One of the reasons people use self-hosted Sentry is to avoid hitting third-party servers.

On July 21, 2024 4:17:23 AM PDT, Reinaldy Rafli @.***> wrote:

Good news, people. Alex @.***) has found a fix! https://github.com/getsentry/self-hosted/pull/3213

-- Reply to this email directly or view it on GitHub: https://github.com/getsentry/sentry/issues/22715#issuecomment-2241571798 You are receiving this because you were mentioned.

Message ID: @.***>

stayallive commented 3 months ago

True, not a fix for the fully self-host part but a fix to restore "broken" functionality if you want to and are OK with the Sentry provided JS CDN.

You could also proxy the JS CDN (with a simple (caching) reverse proxy) if you do trust it's contents but don't want your users traffic to hit the CDN.

All not perfect solutions I agree but at least there is one available if you want to and are OK with Sentry hosting the JS SDK files.

aldy505 commented 3 months ago

That's a good PR, but it's a workaround rather than a fix. One of the reasons people use self-hosted Sentry is to avoid hitting third-party servers.

Okay so here's another workaround, add this script before running wrap-up.sh on ./install.sh file.

echo "${_group}Setting up JS SDK assets"

latest_js_v7=$($dc exec web cat /usr/src/sentry/src/sentry/loader/_registry.json | jq '.versions | reverse' | grep -m1 '"7.' | awk -F'"' '{print $2}')
latest_js_v8=$($dc exec web cat /usr/src/sentry/src/sentry/loader/_registry.json | jq '.versions | reverse' | grep -m1 '"8.' | awk -F'"' '{print $2}')

# Download those two using curl
mkdir -p js-sdk/{$latest_js_v7,$latest_js_v8}
cd js-sdk/${latest_js_v8}/
curl -Z 'https://browser.sentry-cdn.com/${latest_js_v8}/bundle.{tracing,tracing.replay,replay}.min.js' -O
cd ../${latest_js_v7}
curl -Z 'https://browser.sentry-cdn.com/${latest_js_v7}/bundle.{tracing,tracing.replay,replay}.min.js' -O
cd ../..

# Copy the result into nginx container
$dc exec nginx mkdir -p /var/www/
$dc cp js-sdk nginx:/var/www/js-sdk
rm -rf js-sdk

echo "${_endgroup}"

Then modify your nginx.conf, to add:

server {
   listen 80;

   location ^~ /js-sdk/ {
    autoindex on;
    root  /var/www/js-sdk;
   } 
}

Then on sentry/sentry.conf.py, set this:

JS_SDK_LOADER_DEFAULT_SDK_URL = "https://sentry.example.com/js-sdk/%s/bundle%s.min.js"

That should be it.

BYK commented 3 months ago

@aldy505 just curious, if you have jq already available, why bother with grep and awk afterwards? 😅

aldy505 commented 3 months ago

@aldy505 just curious, if you have jq already available, why bother with grep and awk afterwards? 😅

I don't know what you can do with jq really lol 😆

piradata commented 2 months ago

I don't know what you can do with jq really lol 😆

actually is hard to say what you cant do with it

aldy505 commented 1 month ago

Okay so here's another PR to enable hosting the JS SDK from your own instance: https://github.com/getsentry/self-hosted/pull/3365

aldy505 commented 2 weeks ago

Been 2 weeks. But has anyone enabled this on their instance (starting 24.10.0) yet? Any good news?

https://github.com/getsentry/self-hosted/blob/8fd24d02312f9fd7990c1ad0808d561c7b4f80b5/.env#L20-L21

Set that ☝ to SETUP_JS_SDK_ASSETS=1. With optional hidden feature flag of SETUP_JS_SDK_KEEP_OLD_ASSETS=1 that keeps the old assets so the JS SDK cleanup script won't be executed.

https://github.com/getsentry/self-hosted/blob/8fd24d02312f9fd7990c1ad0808d561c7b4f80b5/sentry/sentry.conf.example.py#L381-L391

The URL should include the /js-sdk prefix like so:

JS_SDK_LOADER_DEFAULT_SDK_URL = "https://sentry.example.com/js-sdk/%s/bundle%s.min.js"
gander commented 2 weeks ago

I forgot to turn it on during the upgrade. When I set everything up and wanted to run the package installation to get it started, it turned out that the installer is broken and could not be started during the installation. So, I waiting for a newer version to enable it during the next upgrade.

aldy505 commented 2 weeks ago

I forgot to turn it on during the upgrade. When I set everything up and wanted to run the package installation to get it started, it turned out that the installer is broken and could not be started during the installation. So, I waiting for a newer version to enable it during the next upgrade.

@gander Can you share the "broken installer" message?

gander commented 2 weeks ago

I forgot to turn it on during the upgrade. When I set everything up and wanted to run the package installation to get it started, it turned out that the installer is broken and could not be started during the installation. So, I waiting for a newer version to enable it during the next upgrade.

@gander Can you share the "broken installer" message?

https://github.com/getsentry/self-hosted/issues/3393

gander commented 2 weeks ago

Is this what it was supposed to look like?

!function (n, e, r, t, o, i, a, c, s) {
    for (var u = s, f = 0; f < document.scripts.length; f++) if (document.scripts[f].src.indexOf(i) > -1) {
        u && "no" === document.scripts[f].getAttribute("data-lazy") && (u = !1);
        break;
    }
    var p = [];

    function l(n) {
        return "e" in n;
    }

    function d(n) {
        return "p" in n;
    }

    function _(n) {
        return "f" in n;
    }

    var v = [];

    function y(n) {
        u && (l(n) || d(n) || _(n) && n.f.indexOf("capture") > -1 || _(n) && n.f.indexOf("showReportDialog") > -1) && L(), v.push(n);
    }

    function h() {
        y({e: [].slice.call(arguments)});
    }

    function g(n) {
        y({p: n});
    }

    function E() {
        try {
            n.SENTRY_SDK_SOURCE = "loader";
            var e = n[o], i = e.init;
            e.init = function (o) {
                n.removeEventListener(r, h), n.removeEventListener(t, g);
                var a = c;
                for (var s in o) Object.prototype.hasOwnProperty.call(o, s) && (a[s] = o[s]);
                !function (n, e) {
                    var r = n.integrations || [];
                    if (!Array.isArray(r)) return;
                    var t = r.map((function (n) {
                        return n.name;
                    }));
                    n.tracesSampleRate && -1 === t.indexOf("BrowserTracing") && (e.browserTracingIntegration ? r.push(e.browserTracingIntegration({enableInp: !0})) : e.BrowserTracing && r.push(new e.BrowserTracing));
                    (n.replaysSessionSampleRate || n.replaysOnErrorSampleRate) && -1 === t.indexOf("Replay") && (e.replayIntegration ? r.push(e.replayIntegration()) : e.Replay && r.push(new e.Replay));
                    n.integrations = r;
                }(a, e), i(a);
            }, setTimeout((function () {
                return function (e) {
                    try {
                        "function" == typeof n.sentryOnLoad && (n.sentryOnLoad(), n.sentryOnLoad = void 0);
                    } catch (n) {
                        console.error("Error while calling `sentryOnLoad` handler:"), console.error(n);
                    }
                    try {
                        for (var r = 0; r < p.length; r++) "function" == typeof p[r] && p[r]();
                        p.splice(0);
                        for (r = 0; r < v.length; r++) {
                            _(i = v[r]) && "init" === i.f && e.init.apply(e, i.a);
                        }
                        m() || e.init();
                        var t = n.onerror, o = n.onunhandledrejection;
                        for (r = 0; r < v.length; r++) {
                            var i;
                            if (_(i = v[r])) {
                                if ("init" === i.f) continue;
                                e[i.f].apply(e, i.a);
                            } else l(i) && t ? t.apply(n, i.e) : d(i) && o && o.apply(n, [i.p]);
                        }
                    } catch (n) {
                        console.error(n);
                    }
                }(e);
            }));
        } catch (n) {
            console.error(n);
        }
    }

    var O = !1;

    function L() {
        if (!O) {
            O = !0;
            var n = e.scripts[0], r = e.createElement("script");
            r.src = a, r.crossOrigin = "anonymous", r.addEventListener("load", E, {once: !0, passive: !0}), n.parentNode.insertBefore(r, n);
        }
    }

    function m() {
        var e = n.__SENTRY__, r = void 0 !== e && e.version;
        return r ? !!e[r] : !(void 0 === e || !e.hub || !e.hub.getClient());
    }

    n[o] = n[o] || {}, n[o].onLoad = function (n) {
        m() ? n() : p.push(n);
    }, n[o].forceLoad = function () {
        setTimeout((function () {
            L();
        }));
    }, ["init", "addBreadcrumb", "captureMessage", "captureException", "captureEvent", "configureScope", "withScope", "showReportDialog"].forEach((function (e) {
        n[o][e] = function () {
            y({f: e, a: arguments});
        };
    })), n.addEventListener(r, h), n.addEventListener(t, g), u || setTimeout((function () {
        L();
    }));
}(window, document, "error", "unhandledrejection", "Sentry", 'REDACTED', 'https://browser.sentry-cdn.com/8.34.0/bundle.tracing.replay.debug.min.js', {"dsn": "https://REDACTED@my.self.hosted.tld/3", "debug": true, "tracesSampleRate": 1, "replaysSessionSampleRate": 0.1, "replaysOnErrorSampleRate": 1}, false);
dlouzan commented 4 days ago

@BYK @aldy505 I'm not sure the new feature introduced in https://github.com/getsentry/self-hosted/pull/3365 is working as intended for self-hosting. I tried adapting the feature into our self-hosted setup to make it not depend on the external CDN, and I'm seeing the following issues:

Image

If I'm missing anything here, I'll be happy to learn something. Thanks!

/cc @max-wittig @ercanucan

aldy505 commented 4 days ago
  • The sdk install script is only installing the 7.x & 8.x versions to be served by the self-hosted nginx, but when going to a project configuration, any user of our system can see sdk versions going all the way back to 4.x, so that will probably cause issues for people that expect that those versions still work (see screenshot below)

@dlouzan Interesting to see that your dropdown has 6.x and lower. I need to find out what's giving that output, but probably what we need to do best is to provide the SDK version all the way to 4.x.

Image

  • The script is also downloading several variants of the js files (bundle, feedback, replay, etc), but not the base unnamed variants that end up as {version}/bundle.min.js and that are the defaults chosen when no config options are chosen on the web UI.

This is easy, will add that to the script! Thanks for giving these feedbacks!

dlouzan commented 4 days ago

I made a comment on the PR you linked, but for completeness, there was another issue: busybox's wget does not play nice with our corporate proxy, so I replaced the part in the script with curl.

aldy505 commented 3 days ago

@BYK can you reopen this ticket?