//----------------------------------------------------------------------------- // // Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). // You may not use this file except in compliance with the License. // A copy of the License is located at // // http://aws.amazon.com/apache2.0 // // or in the "license" file accompanying this file. This file is distributed // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either // express or implied. See the License for the specific language governing // permissions and limitations under the License. // //----------------------------------------------------------------------------- using System.Data.Common; using Microsoft.EntityFrameworkCore.Diagnostics; using System.Threading; using System.Threading.Tasks; namespace Amazon.XRay.Recorder.Handlers.EntityFramework { /// /// Intercepts DbCommands and records them in new Subsegments. /// public class EFInterceptor : DbCommandInterceptor { private readonly bool? _collectSqlQueriesOverride; /// /// Initializes a new instance of the class. /// public EFInterceptor(bool? collectSqlQueries = null) : base() { _collectSqlQueriesOverride = collectSqlQueries; } /// /// Trace before executing reader. /// /// Instance of . /// Instance of . /// Result from . /// Result from . public override InterceptionResult ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ReaderExecuting(command, eventData, result); } /// /// Trace after executing reader. /// /// Instance of . /// Instance of . /// Instance of . /// Instance of . public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result) { EFUtil.ProcessEndCommand(); return base.ReaderExecuted(command, eventData, result); } /// /// Trace before executing reader asynchronously. /// /// Instance of . /// Instance of . /// Result from . /// Instance of . /// Task representing the async operation. #if NET6_0_OR_GREATER public override ValueTask> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) #else public override Task> ReaderExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) #endif { EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ReaderExecutingAsync(command, eventData, result, cancellationToken); } /// /// Trace after executing reader asynchronously. /// /// Instance of . /// Instance of . /// Result from . /// Instance of . /// Task representing the async operation. #if NET6_0_OR_GREATER public override ValueTask ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default) #else public override Task ReaderExecutedAsync(DbCommand command, CommandExecutedEventData eventData, DbDataReader result, CancellationToken cancellationToken = default) #endif { EFUtil.ProcessEndCommand(); return base.ReaderExecutedAsync(command, eventData, result, cancellationToken); } /// /// Trace after command fails. /// /// Instance of . /// Instance of . public override void CommandFailed(DbCommand command, CommandErrorEventData eventData) { EFUtil.ProcessCommandError(eventData.Exception); base.CommandFailed(command, eventData); } /// /// Trace after async command fails. /// /// Instance of . /// Instance of . /// Instance of . /// Task representing the async operation. public override Task CommandFailedAsync(DbCommand command, CommandErrorEventData eventData, CancellationToken cancellationToken = default) { EFUtil.ProcessCommandError(eventData.Exception); return base.CommandFailedAsync(command, eventData, cancellationToken); } /// /// Trace before excuting. /// /// Instance of . /// Instance of . /// Result from . /// Task representing the operation. public override InterceptionResult NonQueryExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.NonQueryExecuting(command, eventData, result); } /// /// Trace before executing asynchronously. /// /// Instance of . /// Instance of . /// Result from . /// Instance of . /// Task representing the async operation. #if NET6_0_OR_GREATER public override ValueTask> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) #else public override Task> NonQueryExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) #endif { EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken); } /// /// Trace after executing. /// /// Instance of . /// Instance of . /// Result as integer. /// Result as integer. public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result) { EFUtil.ProcessEndCommand(); return base.NonQueryExecuted(command, eventData, result); } /// /// Trace after executing asynchronously. /// /// Instance of . /// Instance of . /// Result as integer. /// Instance of . /// Task representing the async operation. #if NET6_0_OR_GREATER public override ValueTask NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default) #else public override Task NonQueryExecutedAsync(DbCommand command, CommandExecutedEventData eventData, int result, CancellationToken cancellationToken = default) #endif { EFUtil.ProcessEndCommand(); return base.NonQueryExecutedAsync(command, eventData, result, cancellationToken); } /// /// Trace before executing scalar. /// /// Instance of . /// Instance of . /// Result from . /// Result from . public override InterceptionResult ScalarExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ScalarExecuting(command, eventData, result); } /// /// Trace before executing scalar asynchronously. /// /// Instance of . /// Instance of . /// Result from . /// Instance of . /// Task representing the async operation. #if NET6_0_OR_GREATER public override ValueTask> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) #else public override Task> ScalarExecutingAsync(DbCommand command, CommandEventData eventData, InterceptionResult result, CancellationToken cancellationToken = default) #endif { EFUtil.ProcessBeginCommand(command, _collectSqlQueriesOverride); return base.ScalarExecutingAsync(command, eventData, result, cancellationToken); } /// /// Trace after executing scalar. /// /// Instance of . /// Instance of . /// Result object. /// Result object. public override object ScalarExecuted(DbCommand command, CommandExecutedEventData eventData, object result) { EFUtil.ProcessEndCommand(); return base.ScalarExecuted(command, eventData, result); } /// /// Trace after executing scalar asynchronously. /// /// Instance of . /// Instance of . /// Result object. /// Instance of . /// Task representing the async operation. #if NET6_0_OR_GREATER public override ValueTask ScalarExecutedAsync(DbCommand command, CommandExecutedEventData eventData, object result, CancellationToken cancellationToken = default) #else public override Task ScalarExecutedAsync(DbCommand command, CommandExecutedEventData eventData, object result, CancellationToken cancellationToken = default) #endif { EFUtil.ProcessEndCommand(); return base.ScalarExecutedAsync(command, eventData, result, cancellationToken); } } }