Remove all external dependencies and Sentry integration

- Remove external Leaflet CDN links from info page (now uses vendor bundles)
- Remove all Sentry error tracking integration:
  - Remove sentry dependency from mix.exs
  - Remove Sentry plugs from endpoint.ex
  - Remove Sentry logger handler from application.ex
  - Remove Sentry configs from dev.exs and prod.exs
  - Remove Sentry domains from runtime.exs check_origin
  - Remove Sentry JavaScript initialization
  - Delete sentry_filter.ex module
  - Remove Sentry loader script from root layout

The application now loads all assets locally with no external runtime dependencies.
This commit is contained in:
Graham McIntire 2025-10-03 12:53:47 -05:00
parent 5ca07bcbe0
commit 93e19ff517
No known key found for this signature in database
10 changed files with 1 additions and 160 deletions

View file

@ -25,25 +25,6 @@ import { LiveSocket } from "phoenix_live_view";
// topbar is loaded globally from vendor bundle
const topbar = window.topbar;
// Sentry initialization happens via the loader script in the HTML
// Configure additional Sentry settings if needed
if (typeof window.Sentry !== "undefined" && window.Sentry.onLoad) {
window.Sentry.onLoad(function () {
window.Sentry.init({
environment: "production",
integrations: [new window.Sentry.BrowserTracing()],
tracesSampleRate: 1.0, // Capture 100% of transactions for performance monitoring
sampleRate: 1.0, // Capture 100% of errors
beforeSend(event, hint) {
// Filter out known non-critical errors
if (hint.originalException?.message?.includes("ResizeObserver loop limit exceeded")) {
return null;
}
return event;
},
});
});
}
let csrfToken = document.querySelector("meta[name='csrf-token']")?.getAttribute("content") || "";
if (!csrfToken) {

View file

@ -110,11 +110,4 @@ config :phoenix, :plug_init_mode, :runtime
# configured to run both http and https servers on
config :phoenix, :stacktrace_depth, 20
# Configure Sentry for development (disabled by default)
config :sentry,
environment_name: :dev,
enable_source_code_context: true,
root_source_code_paths: [File.cwd!()],
before_send: {Aprsme.SentryFilter, :before_send}
config :swoosh, :api_client, false

View file

@ -29,12 +29,5 @@ config :esbuild,
# of environment variables, is done on config/runtime.exs.
config :logger, level: :info
config :sentry,
dsn: "https://337ece4c07ff53c6719d900adfddd6e4@o4509627566063616.ingest.us.sentry.io/4509691336785920",
environment_name: Mix.env(),
enable_source_code_context: true,
root_source_code_paths: [File.cwd!()],
before_send: {Aprsme.SentryFilter, :before_send}
# Configures Swoosh API Client
config :swoosh, :api_client, Swoosh.ApiClient.Req

View file

@ -175,8 +175,6 @@ if config_env() == :prod do
"http://10.0.19.222:33897",
"https://aprs.me",
"https://www.aprs.me",
"https://js.sentry-cdn.com",
"https://sentry.io",
"https://www.openstreetmap.org",
"https://tile.openstreetmap.org",
"https://static.cloudflareinsights.com"

View file

@ -15,10 +15,6 @@ defmodule Aprsme.Application do
# Run migrations on startup
migrate()
:logger.add_handler(:my_sentry_handler, Sentry.LoggerHandler, %{
config: %{metadata: [:file, :line]}
})
children = [
# Start the Telemetry supervisor
AprsmeWeb.Telemetry,

View file

@ -1,101 +0,0 @@
defmodule Aprsme.SentryFilter do
@moduledoc """
Filters out certain errors from being sent to Sentry.
This module helps reduce noise in Sentry by filtering out expected errors
like malformed HTTP requests that are missing required headers.
"""
require Logger
@doc """
Callback function for Sentry's before_send hook.
Returns nil to prevent the event from being sent to Sentry,
or returns the event to allow it to be sent.
"""
def before_send(event) do
if should_filter_event?(event) do
# Log locally but don't send to Sentry
Logger.debug("Filtered Sentry event: #{inspect_error(event)}")
nil
else
event
end
end
# Check if the event should be filtered out
defp should_filter_event?(event) do
# Access the first exception from the list if it exists
first_exception =
case event.exception do
[first | _] -> first
_ -> nil
end
error_type = if first_exception, do: first_exception.type
error_message = if first_exception, do: first_exception.value
cond do
# Filter out Bandit errors for missing Host header
error_type == "Bandit.HTTPError" and
String.contains?(error_message || "", "No host header") ->
true
# Filter out other common bot/scanner errors
error_type == "Bandit.HTTPError" and
String.contains?(error_message || "", "Unable to obtain host and port") ->
true
# Filter out Phoenix.Router.NoRouteError for common bot paths
error_type == "Phoenix.Router.NoRouteError" and
is_bot_path?(event) ->
true
# Allow all other errors through
true ->
false
end
end
# Check if the request path looks like a bot/scanner
defp is_bot_path?(event) do
request_path =
case event.request do
%{url: url} when is_binary(url) -> url
_ -> ""
end
bot_patterns = [
~r/\.php$/i,
~r/\.asp$/i,
~r/\.aspx$/i,
~r/wp-admin/i,
~r/wp-login/i,
~r/wordpress/i,
~r/admin/i,
~r/\.env$/,
~r/\.git/,
~r/phpmyadmin/i,
~r/mysql/i,
~r/config\./i,
~r/\.xml$/i,
~r/sitemap/i,
~r/robots\.txt$/i
]
Enum.any?(bot_patterns, &Regex.match?(&1, request_path))
end
# Extract a readable error description
defp inspect_error(event) do
# Access the first exception from the list if it exists
{error_type, error_message} =
case event.exception do
[%{type: type, value: value} | _] -> {type || "Unknown", value || "No message"}
_ -> {"Unknown", "No message"}
end
"#{error_type}: #{error_message}"
end
end

View file

@ -75,9 +75,6 @@
<!-- App scripts -->
<script phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
</script>
<script>
(function(c,u,v,n,p,e,z,A,w){function k(a){if(!x){x=!0;var l=u.getElementsByTagName(v)[0],d=u.createElement(v);d.src=A;d.crossOrigin="anonymous";d.addEventListener("load",function(){try{c[n]=r;c[p]=t;var b=c[e],d=b.init;b.init=function(a){for(var b in a)Object.prototype.hasOwnProperty.call(a,b)&&(w[b]=a[b]);d(w)};B(a,b)}catch(g){console.error(g)}});l.parentNode.insertBefore(d,l)}}function B(a,l){try{for(var d=m.data,b=0;b<a.length;b++)if("function"===typeof a[b])a[b]();var e=!1,g=c.__SENTRY__;"undefined"!==typeof g&&g.hub&&g.hub.getClient()&&(e=!0);g=!1;for(b=0;b<d.length;b++)if(d[b].f){g=!0;var f=d[b];!1===e&&"init"!==f.f&&l.init();e=!0;l[f.f].apply(l,f.a)}!1===e&&!1===g&&l.init();var h=c[n],k=c[p];for(b=0;b<d.length;b++)d[b].e&&h?h.apply(c,d[b].e):d[b].p&&k&&k.apply(c,[d[b].p])}catch(C){console.error(C)}}for(var f=!0,y=!1,q=0;q<document.scripts.length;q++)if(-1<document.scripts[q].src.indexOf(z)){f="no"!==document.scripts[q].getAttribute("data-lazy");break}var x=!1,h=[],m=function(a){(a.e||a.p||a.f&&-1<a.f.indexOf("capture")||a.f&&-1<a.f.indexOf("showReportDialog"))&&f&&k(h);m.data.push(a)};m.data=[];c[e]=c[e]||{};c[e].onLoad=function(a){h.push(a);f&&!y||k(h)};c[e].forceLoad=function(){y=!0;f&&setTimeout(function(){k(h)})};"init addBreadcrumb captureMessage captureException captureEvent configureScope withScope showReportDialog".split(" ").forEach(function(a){c[e][a]=function(){m({f:a,a:arguments})}});var r=c[n];c[n]=function(a,e,d,b,f){m({e:[].slice.call(arguments)});r&&r.apply(c,arguments)};var t=c[p];c[p]=function(a){m({p:a.reason});t&&t.apply(c,arguments)};f||setTimeout(function(){k(h)})})(window,document,"script","onerror","onunhandledrejection","Sentry","be4b53768e7c243cc72fa78ee7b7ec8c","https://js.sentry-cdn.com/be4b53768e7c243cc72fa78ee7b7ec8c.min.js",{"dsn":"https://337ece4c07ff53c6719d900adfddd6e4@o4509627566063616.ingest.us.sentry.io/4509691336785920"});
</script>
</head>
<body class={body_class(assigns)}>
{@inner_content}

View file

@ -1,7 +1,6 @@
defmodule AprsmeWeb.Endpoint do
@moduledoc false
use Phoenix.Endpoint, otp_app: :aprsme
use Sentry.PlugCapture
# The session will be stored in the cookie and signed,
# this means its contents can be read but not tampered with.
@ -48,7 +47,6 @@ defmodule AprsmeWeb.Endpoint do
pass: ["*/*"],
json_decoder: Phoenix.json_library()
plug Sentry.PlugContext
plug Plug.MethodOverride
plug Plug.Head
plug Plug.Session, @session_options

View file

@ -1,16 +1,4 @@
<!-- Leaflet CSS for the map -->
<link
rel="stylesheet"
href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""
/>
<script
src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""
>
</script>
<!-- Leaflet is already loaded via vendor bundles in the layout -->
<div class="min-h-screen bg-base-200">
<!-- Page header -->

View file

@ -105,10 +105,8 @@ defmodule Aprsme.MixProject do
{:hammer, "~> 7.0"},
{:cachex, "~> 4.1"},
{:gettext_pseudolocalize, "~> 0.1"},
{:sentry, "~> 11.0.4"},
{:wallaby, "~> 0.30.10", only: :test},
{:lazy_html, "~> 0.1.8", only: :test}
# Gleam dependencies
]
end