Skip to content
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Enhancements

- Add db.system and db.name attributes to db spans data ([#1629](https://github.com/getsentry/sentry-dart/pull/1629))

### Features

- Tracing without performance ([#1621](https://github.com/getsentry/sentry-dart/pull/1621))
Expand Down
4 changes: 4 additions & 0 deletions sqflite/lib/src/sentry_batch.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:sqflite/sqflite.dart';
import 'package:sqflite_common/src/sql_builder.dart';

import 'sentry_database.dart';
import 'utils/sentry_database_span_attributes.dart';

/// A [Batch] wrapper that adds Sentry support.
///
Expand Down Expand Up @@ -47,8 +48,10 @@ class SentryBatch implements Batch {
SentryDatabase.dbOp,
description: _buffer.toString().trim(),
);

// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteBatch;
setDatabaseAttributeData(span);

try {
final result = await _batch.apply(
Expand Down Expand Up @@ -86,6 +89,7 @@ class SentryBatch implements Batch {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteBatch;
setDatabaseAttributeData(span);

try {
final result = await _batch.commit(
Expand Down
31 changes: 31 additions & 0 deletions sqflite/lib/src/sentry_database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import 'package:meta/meta.dart';
import 'package:sentry/sentry.dart';
import 'package:sqflite/sqflite.dart';

import '../sentry_sqflite.dart';
import 'sentry_database_executor.dart';
import 'sentry_sqflite_transaction.dart';
import 'version.dart';
import 'utils/sentry_database_span_attributes.dart';

/// A [Database] wrapper that adds Sentry support.
///
Expand All @@ -31,6 +33,19 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database {
static const dbSqlQueryOp = 'db.sql.query';

static const _dbSqlOp = 'db.sql.transaction';
@internal
// ignore: public_member_api_docs
static const dbSystemKey = 'db.system';
@internal
// ignore: public_member_api_docs
static const dbSystem = 'sqlite';
@internal
// ignore: public_member_api_docs
static const dbNameKey = 'db.name';
@internal
// ignore: public_member_api_docs
static String? dbName;


/// ```dart
/// import 'package:sqflite/sqflite.dart';
Expand All @@ -48,6 +63,19 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database {
final options = _hub.options;
options.sdk.addIntegration('SentrySqfliteTracing');
options.sdk.addPackage(packageName, sdkVersion);
dbName = _basenameWithoutExtension(_database.path);
}

/// Gets the part of path after the last separator, and without any trailing file extension.
String _basenameWithoutExtension(String filePath) {
int lastIndex = filePath.lastIndexOf('/');
int dotIndex = filePath.lastIndexOf('.');

if (dotIndex == -1 || (lastIndex != -1 && dotIndex < lastIndex)) {
return filePath;
}

return filePath.substring(lastIndex + 1, dotIndex);
}

// TODO: check if perf is enabled
Expand All @@ -63,6 +91,8 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database {
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabase;

dbName = null;

try {
await _database.close();

Expand Down Expand Up @@ -113,6 +143,7 @@ class SentryDatabase extends SentryDatabaseExecutor implements Database {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabase;
setDatabaseAttributeData(span);

Future<T> newAction(Transaction txn) async {
final executor =
Expand Down
13 changes: 13 additions & 0 deletions sqflite/lib/src/sentry_database_executor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:sqflite_common/src/sql_builder.dart';

import 'sentry_batch.dart';
import 'sentry_database.dart';
import 'utils/sentry_database_span_attributes.dart';

@internal
// ignore: public_member_api_docs
Expand Down Expand Up @@ -41,6 +42,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result =
Expand Down Expand Up @@ -68,8 +70,10 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
SentryDatabase.dbSqlExecuteOp,
description: sql,
);
span?.setData(SentryDatabase.dbSystemKey, SentryDatabase.dbSystem);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
await _executor.execute(sql, arguments);
Expand Down Expand Up @@ -107,6 +111,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.insert(
Expand Down Expand Up @@ -163,6 +168,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.query(
Expand Down Expand Up @@ -226,6 +232,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.queryCursor(
Expand Down Expand Up @@ -266,6 +273,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.rawDelete(sql, arguments);
Expand Down Expand Up @@ -294,6 +302,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.rawInsert(sql, arguments);
Expand Down Expand Up @@ -325,6 +334,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.rawQuery(sql, arguments);
Expand Down Expand Up @@ -357,6 +367,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.rawQueryCursor(
Expand Down Expand Up @@ -389,6 +400,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.rawUpdate(sql, arguments);
Expand Down Expand Up @@ -430,6 +442,7 @@ class SentryDatabaseExecutor implements DatabaseExecutor {
);
// ignore: invalid_use_of_internal_member
span?.origin = SentryTraceOrigins.autoDbSqfliteDatabaseExecutor;
setDatabaseAttributeData(span);

try {
final result = await _executor.update(
Expand Down
12 changes: 12 additions & 0 deletions sqflite/lib/src/utils/sentry_database_span_attributes.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:sentry/sentry.dart';

import '../../sentry_sqflite.dart';

/// Sets the database attributes on the [span].
/// It contains the database system and the database name.
void setDatabaseAttributeData(ISentrySpan? span) {
span?.setData(SentryDatabase.dbSystemKey, SentryDatabase.dbSystem);
if (SentryDatabase.dbName != null) {
span?.setData(SentryDatabase.dbNameKey, SentryDatabase.dbName);
}
}
47 changes: 47 additions & 0 deletions sqflite/test/sentry_batch_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,53 @@ SELECT * FROM Product''';
await db.close();
});

test('apply creates db span with dbSystem and dbName attributes', () async {
final db = await fixture.getDatabase();
final batch = db.batch();

batch.insert('Product', <String, Object?>{'title': 'Product 1'});

await batch.apply();

final span = fixture.tracer.children.last;
expect(span.data[SentryDatabase.dbSystemKey], SentryDatabase.dbSystem);
expect(span.data[SentryDatabase.dbNameKey], SentryDatabase.dbName);

await db.close();
});

test('commit creates db span with dbSystem and dbName attributes',
() async {
final db = await fixture.getDatabase();
final batch = db.batch();

batch.insert('Product', <String, Object?>{'title': 'Product 1'});

await batch.commit();

final span = fixture.tracer.children.last;
expect(span.data[SentryDatabase.dbSystemKey], SentryDatabase.dbSystem);
expect(span.data[SentryDatabase.dbNameKey], SentryDatabase.dbName);

await db.close();
});

test('dbName attribute is null if currentDbName is null', () async {
final db = await fixture.getDatabase();
final batch = db.batch();
SentryDatabase.dbName = null;

batch.insert('Product', <String, Object?>{'title': 'Product 1'});

await batch.commit();

final span = fixture.tracer.children.last;
expect(span.data[SentryDatabase.dbSystemKey], SentryDatabase.dbSystem);
expect(span.data[SentryDatabase.dbNameKey], isNull);

await db.close();
});

tearDown(() {
databaseFactory = sqfliteDatabaseFactoryDefault;
});
Expand Down
Loading