2020using System . ComponentModel ;
2121using System . Data ;
2222using System . Data . Common ;
23+ using System . Diagnostics ;
2324using System . Text ;
2425using System . Threading ;
2526using System . Threading . Tasks ;
2627using FirebirdSql . Data . Common ;
2728using FirebirdSql . Data . Logging ;
29+ using FirebirdSql . Data . Trace ;
2830using Microsoft . Extensions . Logging ;
2931
3032namespace FirebirdSql . Data . FirebirdClient ;
@@ -50,6 +52,7 @@ public sealed class FbCommand : DbCommand, IFbPreparedCommand, IDescriptorFiller
5052 private int ? _commandTimeout ;
5153 private int _fetchSize ;
5254 private Type [ ] _expectedColumnTypes ;
55+ private Activity _currentActivity ;
5356
5457 #endregion
5558
@@ -1064,6 +1067,13 @@ internal void Release()
10641067 _statement . Dispose2 ( ) ;
10651068 _statement = null ;
10661069 }
1070+
1071+ if ( _currentActivity != null )
1072+ {
1073+ // Do not set status to Ok: https://opentelemetry.io/docs/concepts/signals/traces/#span-status
1074+ _currentActivity . Dispose ( ) ;
1075+ _currentActivity = null ;
1076+ }
10671077 }
10681078 Task IFbPreparedCommand . ReleaseAsync ( CancellationToken cancellationToken ) => ReleaseAsync ( cancellationToken ) ;
10691079 internal async Task ReleaseAsync ( CancellationToken cancellationToken = default )
@@ -1082,6 +1092,13 @@ internal async Task ReleaseAsync(CancellationToken cancellationToken = default)
10821092 await _statement . Dispose2Async ( cancellationToken ) . ConfigureAwait ( false ) ;
10831093 _statement = null ;
10841094 }
1095+
1096+ if ( _currentActivity != null )
1097+ {
1098+ // Do not set status to Ok: https://opentelemetry.io/docs/concepts/signals/traces/#span-status
1099+ _currentActivity . Dispose ( ) ;
1100+ _currentActivity = null ;
1101+ }
10851102 }
10861103
10871104 void IFbPreparedCommand . TransactionCompleted ( ) => TransactionCompleted ( ) ;
@@ -1302,6 +1319,26 @@ private async ValueTask UpdateParameterValuesAsync(Descriptor descriptor, Cancel
13021319
13031320 #endregion
13041321
1322+ #region Tracing
1323+
1324+ private void TraceCommandStart ( )
1325+ {
1326+ Debug . Assert ( _currentActivity == null ) ;
1327+ if ( FbActivitySource . Source . HasListeners ( ) )
1328+ _currentActivity = FbActivitySource . CommandStart ( this ) ;
1329+ }
1330+
1331+ private void TraceCommandException ( Exception e )
1332+ {
1333+ if ( _currentActivity != null )
1334+ {
1335+ FbActivitySource . CommandException ( _currentActivity , e ) ;
1336+ _currentActivity = null ;
1337+ }
1338+ }
1339+
1340+ #endregion Tracing
1341+
13051342 #region Private Methods
13061343
13071344 private void Prepare ( bool returnsSet )
@@ -1446,57 +1483,73 @@ private async Task PrepareAsync(bool returnsSet, CancellationToken cancellationT
14461483 private void ExecuteCommand ( CommandBehavior behavior , bool returnsSet )
14471484 {
14481485 LogMessages . CommandExecution ( Log , this ) ;
1486+ TraceCommandStart ( ) ;
1487+ try
1488+ {
1489+ Prepare ( returnsSet ) ;
14491490
1450- Prepare ( returnsSet ) ;
1491+ if ( ( behavior & CommandBehavior . SequentialAccess ) == CommandBehavior . SequentialAccess ||
1492+ ( behavior & CommandBehavior . SingleResult ) == CommandBehavior . SingleResult ||
1493+ ( behavior & CommandBehavior . SingleRow ) == CommandBehavior . SingleRow ||
1494+ ( behavior & CommandBehavior . CloseConnection ) == CommandBehavior . CloseConnection ||
1495+ behavior == CommandBehavior . Default )
1496+ {
1497+ // Set the fetch size
1498+ _statement . FetchSize = _fetchSize ;
14511499
1452- if ( ( behavior & CommandBehavior . SequentialAccess ) == CommandBehavior . SequentialAccess ||
1453- ( behavior & CommandBehavior . SingleResult ) == CommandBehavior . SingleResult ||
1454- ( behavior & CommandBehavior . SingleRow ) == CommandBehavior . SingleRow ||
1455- ( behavior & CommandBehavior . CloseConnection ) == CommandBehavior . CloseConnection ||
1456- behavior == CommandBehavior . Default )
1457- {
1458- // Set the fetch size
1459- _statement . FetchSize = _fetchSize ;
1500+ // Set if it's needed the Records Affected information
1501+ _statement . ReturnRecordsAffected = _connection . ConnectionOptions . ReturnRecordsAffected ;
14601502
1461- // Set if it's needed the Records Affected information
1462- _statement . ReturnRecordsAffected = _connection . ConnectionOptions . ReturnRecordsAffected ;
1503+ // Validate input parameter count
1504+ if ( _namedParameters . Count > 0 && ! HasParameters )
1505+ {
1506+ throw FbException . Create ( "Must declare command parameters." ) ;
1507+ }
14631508
1464- // Validate input parameter count
1465- if ( _namedParameters . Count > 0 && ! HasParameters )
1466- {
1467- throw FbException . Create ( "Must declare command parameters." ) ;
1509+ // Execute
1510+ _statement . Execute ( CommandTimeout * 1000 , this ) ;
14681511 }
1469-
1470- // Execute
1471- _statement . Execute ( CommandTimeout * 1000 , this ) ;
1512+ }
1513+ catch ( Exception e )
1514+ {
1515+ TraceCommandException ( e ) ;
1516+ throw ;
14721517 }
14731518 }
14741519 private async Task ExecuteCommandAsync ( CommandBehavior behavior , bool returnsSet , CancellationToken cancellationToken = default )
14751520 {
14761521 LogMessages . CommandExecution ( Log , this ) ;
1522+ TraceCommandStart ( ) ;
1523+ try
1524+ {
1525+ await PrepareAsync ( returnsSet , cancellationToken ) . ConfigureAwait ( false ) ;
14771526
1478- await PrepareAsync ( returnsSet , cancellationToken ) . ConfigureAwait ( false ) ;
1527+ if ( ( behavior & CommandBehavior . SequentialAccess ) == CommandBehavior . SequentialAccess ||
1528+ ( behavior & CommandBehavior . SingleResult ) == CommandBehavior . SingleResult ||
1529+ ( behavior & CommandBehavior . SingleRow ) == CommandBehavior . SingleRow ||
1530+ ( behavior & CommandBehavior . CloseConnection ) == CommandBehavior . CloseConnection ||
1531+ behavior == CommandBehavior . Default )
1532+ {
1533+ // Set the fetch size
1534+ _statement . FetchSize = _fetchSize ;
14791535
1480- if ( ( behavior & CommandBehavior . SequentialAccess ) == CommandBehavior . SequentialAccess ||
1481- ( behavior & CommandBehavior . SingleResult ) == CommandBehavior . SingleResult ||
1482- ( behavior & CommandBehavior . SingleRow ) == CommandBehavior . SingleRow ||
1483- ( behavior & CommandBehavior . CloseConnection ) == CommandBehavior . CloseConnection ||
1484- behavior == CommandBehavior . Default )
1485- {
1486- // Set the fetch size
1487- _statement . FetchSize = _fetchSize ;
1536+ // Set if it's needed the Records Affected information
1537+ _statement . ReturnRecordsAffected = _connection . ConnectionOptions . ReturnRecordsAffected ;
14881538
1489- // Set if it's needed the Records Affected information
1490- _statement . ReturnRecordsAffected = _connection . ConnectionOptions . ReturnRecordsAffected ;
1539+ // Validate input parameter count
1540+ if ( _namedParameters . Count > 0 && ! HasParameters )
1541+ {
1542+ throw FbException . Create ( "Must declare command parameters." ) ;
1543+ }
14911544
1492- // Validate input parameter count
1493- if ( _namedParameters . Count > 0 && ! HasParameters )
1494- {
1495- throw FbException . Create ( "Must declare command parameters." ) ;
1545+ // Execute
1546+ await _statement . ExecuteAsync ( CommandTimeout * 1000 , this , cancellationToken ) . ConfigureAwait ( false ) ;
14961547 }
1497-
1498- // Execute
1499- await _statement . ExecuteAsync ( CommandTimeout * 1000 , this , cancellationToken ) . ConfigureAwait ( false ) ;
1548+ }
1549+ catch ( Exception e )
1550+ {
1551+ TraceCommandException ( e ) ;
1552+ throw ;
15001553 }
15011554 }
15021555
0 commit comments