Skip to content

Sentry Supabase Integration #2913

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

Open
wants to merge 35 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
a8cee18
add sentry_supabase package
denrase Apr 22, 2025
30c089b
add to flutter/example app
denrase Apr 22, 2025
8bd9497
Merge branch 'main' into feat/supabase
denrase May 5, 2025
34b0923
instument with breadcrumbs for basic operations
denrase May 6, 2025
b104265
fix typo
denrase May 6, 2025
4459e95
only add breadcrumb when enabled
denrase May 6, 2025
cac23c4
add query to breadcrumb
denrase May 6, 2025
7bc29d3
format
denrase May 6, 2025
d4b1036
add body to breadcrumb
denrase May 6, 2025
56f7aa8
implement body redaction
denrase May 6, 2025
f1df16d
format
denrase May 6, 2025
a7b8b28
refactor
denrase May 6, 2025
0a08454
Merge branch 'main' into feat/supabase
denrase May 19, 2025
6ee6dfb
basic tracing support
denrase May 19, 2025
f6e68ae
cleanup
denrase May 20, 2025
6fc8c85
instument insert
denrase May 20, 2025
0f77a5f
add renamining span tests
denrase May 20, 2025
6df4a38
split responsibility for breadcrumbs, errors and tracing into multipl…
denrase May 21, 2025
f114e44
Merge branch 'main' into feat/supabase
denrase May 21, 2025
4c8accc
add SentrySupabaseClient
denrase May 21, 2025
63a5c67
update
denrase May 21, 2025
24bed61
only export client
denrase May 21, 2025
cb7f1f5
update example
denrase May 21, 2025
6b5ddc7
update github actions and scripts
denrase May 21, 2025
2d5495b
run fix & format
denrase May 21, 2025
5e3ca91
remove from sample app
denrase May 21, 2025
dedb01b
move mocks to folder
denrase May 21, 2025
c3cbf8a
attribute https://github.com/supabase-community/sentry-integration-js
denrase May 21, 2025
8693820
don’t send request body per default
denrase May 21, 2025
94320da
add docs
denrase May 21, 2025
b6a14af
treat query as pii
denrase May 21, 2025
c808725
add cl entry
denrase May 21, 2025
a39e9b4
remove supabase from flutter sample app
denrase May 21, 2025
e4d1bf6
format main
denrase May 21, 2025
d28daa6
add example to readme
denrase May 21, 2025
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
5 changes: 4 additions & 1 deletion .craft.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ targets:
isar:
link:
firebase_remote_config:
supabase:
- name: github
- name: registry
sdks:
Expand All @@ -34,4 +35,6 @@ targets:
# TODO: after we published link we need to add it to the registry repo and then uncomment here
# pub:sentry_link:
# TODO: after we published firebase we need to add it to the registry repo and then uncomment here
# pub:sentry_firebase_remote_config:
# pub:sentry_firebase_remote_config:
# TODO: after we published supabase we need to add it to the registry repo and then uncomment here
# pub:sentry_supabase:
4 changes: 4 additions & 0 deletions .github/workflows/diagrams.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ jobs:
working-directory: ./firebase_remote_config
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg

- name: supabase
working-directory: ./supabase
run: lakos . -i "{test/**,example/**}" | dot -Tsvg -o class-diagram.svg

# Source: https://stackoverflow.com/a/58035262
- name: Extract branch name
shell: bash
Expand Down
56 changes: 56 additions & 0 deletions .github/workflows/supabase.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: sentry-supabase
on:
push:
branches:
- main
- release/**
pull_request:
paths:
- '!**/*.md'
- '!**/class-diagram.svg'
- '.github/workflows/supabase.yml'
- '.github/workflows/analyze.yml'
- '.github/actions/dart-test/**'
- '.github/actions/coverage/**'
- 'dart/**'
- 'flutter/**'
- 'supabase/**'

# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
build:
name: '${{ matrix.os }} | ${{ matrix.sdk }}'
runs-on: ${{ matrix.os }}-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [macos, ubuntu, windows]
sdk: [stable, beta]

steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/flutter-test
with:
directory: supabase
web: false

# TODO: don't set coverage for now to finish publishing it
# - uses: ./.github/actions/coverage
# if: runner.os == 'Linux' && matrix.sdk == 'stable'
# with:
# token: ${{ secrets.CODECOV_TOKEN }}
# directory: supabase
# coverage: sentry_supabase
# min-coverage: 55

analyze:
uses: ./.github/workflows/analyze.yml
with:
package: supabase
sdk: flutter
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## Unreleased

### Features

- Sentry Supabase Integration ([#2913](https://github.com/getsentry/sentry-dart/pull/2913))
- Adds the `sentry_supabase` package to instrument supabase with Sentry breadcrumbs, traces and errors.

## 9.0.0-RC.3

### Features
Expand Down
1 change: 1 addition & 0 deletions flutter/example/pubspec_overrides.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ dependency_overrides:
isar_generator:
version: ^3.1.0
hosted: https://pub.isar-community.dev/

2 changes: 1 addition & 1 deletion scripts/bump-version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ NEW_VERSION="${2}"
echo "Current version: ${OLD_VERSION}"
echo "Bumping version: ${NEW_VERSION}"

for pkg in {dart,flutter,logging,dio,file,sqflite,drift,hive,isar,link,firebase_remote_config}; do
for pkg in {dart,flutter,logging,dio,file,sqflite,drift,hive,isar,link,firebase_remote_config,supabase}; do
# Bump version in pubspec.yaml
perl -pi -e "s/^version: .*/version: $NEW_VERSION/" $pkg/pubspec.yaml
# Bump sentry dependency version in pubspec.yaml
Expand Down
14 changes: 14 additions & 0 deletions supabase/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Omit committing pubspec.lock for library packages; see
# https://dart.dev/guides/libraries/private-files#pubspeclock.
pubspec.lock

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
1 change: 1 addition & 0 deletions supabase/CHANGELOG.md
21 changes: 21 additions & 0 deletions supabase/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Sentry

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
65 changes: 65 additions & 0 deletions supabase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<p align="center">
<a href="https://sentry.io" target="_blank" align="center">
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
</a>
<br />
</p>


===========

<p align="center">
<a href="https://sentry.io" target="_blank" align="center">
<img src="https://sentry-brand.storage.googleapis.com/sentry-logo-black.png" width="280">
</a>
<br />
</p>

Sentry integration for `supabase` package
===========

| package | build | pub | likes | popularity | pub points |
|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| ------- |
| sentry_supabase | [![build](https://github.com/getsentry/sentry-dart/actions/workflows/supabase.yml/badge.svg?branch=main)](https://github.com/getsentry/sentry-dart/actions?query=workflow%3Asentry-supabase) | [![pub package](https://img.shields.io/pub/v/sentry_supabase.svg)](https://pub.dev/packages/sentry_supabase) | [![likes](https://img.shields.io/pub/likes/sentry_supabase)](https://pub.dev/packages/sentry_supabase/score) | [![popularity](https://img.shields.io/pub/popularity/sentry_supabase)](https://pub.dev/packages/sentry_supabase/score) | [![pub points](https://img.shields.io/pub/points/sentry_supabase)](https://pub.dev/packages/sentry_supabase/score)

Integration for [`supabase`](https://pub.dev/packages/supabase) package.

#### Usage

- Sign up for a Sentry.io account and get a DSN at https://sentry.io.

- Follow the installing instructions on [pub.dev](https://pub.dev/packages/sentry/install).

- Initialize the Sentry SDK using the DSN issued by Sentry.io.

- Call...

```dart
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:sentry_supabase/sentry_supabase.dart';

// Create a [SentrySupabaseClient] and pass it to Supabase during initialization.

final sentrySupabaseClient = SentrySupabaseClient();
await Supabase.initialize(
url: '<YOUR_SUPABASE_URL>',
anonKey: '<YOUR_SUPABASE_ANON_KEY>',
httpClient: sentrySupabaseClient,
);

// Now all [Supabase] operations and queries will
// be instrumented with Sentry breadcrumbs, traces and errors.

final issues = await Supabase.instance.client
.from('issues')
.select();
```

#### Resources

* [![Flutter docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=flutter%20docs)](https://docs.sentry.io/platforms/flutter/)
* [![Dart docs](https://img.shields.io/badge/documentation-sentry.io-green.svg?label=dart%20docs)](https://docs.sentry.io/platforms/dart/)
* [![Discussions](https://img.shields.io/github/discussions/getsentry/sentry-dart.svg)](https://github.com/getsentry/sentry-dart/discussions)
* [![Discord Chat](https://img.shields.io/discord/621778831602221064?logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/PXa5Apfe7K)
* [![Stack Overflow](https://img.shields.io/badge/stack%20overflow-sentry-green.svg)](https://stackoverflow.com/questions/tagged/sentry)
* [![Twitter Follow](https://img.shields.io/twitter/follow/getsentry?label=getsentry&style=social)](https://twitter.com/intent/follow?screen_name=getsentry)
32 changes: 32 additions & 0 deletions supabase/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
include: package:lints/recommended.yaml

analyzer:
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: error
# treat missing returns as a warning (not a hint)
missing_return: error
# allow having TODOs in the code
todo: ignore
# allow self-reference to deprecated members (we do this because otherwise we have
# to annotate every member in every test, assert, etc, when we deprecate something)
deprecated_member_use_from_same_package: warning
# ignore sentry/path on pubspec as we change it on deployment
invalid_dependency: ignore
exclude:
- example/**
- test/mocks/mocks.mocks.dart

linter:
rules:
- prefer_final_locals
- prefer_single_quotes
- prefer_relative_imports
- unnecessary_brace_in_string_interps
- implementation_imports
- require_trailing_commas
- unawaited_futures
1 change: 1 addition & 0 deletions supabase/dartdoc_options.yaml
18 changes: 18 additions & 0 deletions supabase/example/supabase_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:sentry_supabase/sentry_supabase.dart';

// Create a [SentrySupabaseClient] and pass it to Supabase during initialization.

final sentrySupabaseClient = SentrySupabaseClient();
await Supabase.initialize(
url: '<YOUR_SUPABASE_URL>',
anonKey: '<YOUR_SUPABASE_ANON_KEY>',
httpClient: sentrySupabaseClient,
);

// Now all [Supabase] operations and queries will
// be instrumented with Sentry breadcrumbs, traces and errors.

final issues = await Supabase.instance.client
.from('issues')
.select();
3 changes: 3 additions & 0 deletions supabase/lib/sentry_supabase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
library;

export 'src/sentry_supabase_client.dart';
10 changes: 10 additions & 0 deletions supabase/lib/src/operation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
enum Operation {
select('select'),
insert('insert'),
upsert('upsert'),
update('update'),
delete('delete');

final String value;
const Operation(this.value);
}
46 changes: 46 additions & 0 deletions supabase/lib/src/sentry_supabase_breadcrumb_client.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:http/http.dart';
import 'package:sentry/sentry.dart';

import 'sentry_supabase_request.dart';

class SentrySupabaseBreadcrumbClient extends BaseClient {
final Client _innerClient;
final Hub _hub;

SentrySupabaseBreadcrumbClient(this._innerClient, this._hub);

@override
Future<StreamedResponse> send(BaseRequest request) async {
final supabaseRequest = SentrySupabaseRequest.fromRequest(request);

final breadcrumb = Breadcrumb(
message: 'from(${supabaseRequest.table})',
category: 'db.${supabaseRequest.operation.value}',
type: 'supabase',
);

breadcrumb.data ??= {};

breadcrumb.data?['table'] = supabaseRequest.table;
breadcrumb.data?['operation'] = supabaseRequest.operation.value;

// ignore: invalid_use_of_internal_member
if (supabaseRequest.query.isNotEmpty && _hub.options.sendDefaultPii) {
breadcrumb.data?['query'] = supabaseRequest.query;
}

// ignore: invalid_use_of_internal_member
if (supabaseRequest.body != null && _hub.options.sendDefaultPii) {
breadcrumb.data?['body'] = supabaseRequest.body;
}

await _hub.addBreadcrumb(breadcrumb);

return _innerClient.send(request);
}

@override
void close() {
_innerClient.close();
}
}
Loading
Loading