public ISegment StartDatastoreSegment(MethodCall methodCall, ParsedSqlStatement parsedSqlStatement, ConnectionInfo connectionInfo, string commandText, IDictionary <string, IConvertible> queryParameters = null, bool isLeaf = false)
        {
#if DEBUG
            Log.Finest("Skipping StartDatastoreSegment outside of a transaction");
#endif
            return(Segment.NoOpSegment);
        }
示例#2
0
 public DatastoreSegmentData(IDatabaseService databaseService, ParsedSqlStatement parsedSqlStatement, string commandText = null, ConnectionInfo connectionInfo = null, IDictionary <string, IConvertible> queryParameters = null)
 {
     _databaseService    = databaseService;
     _connectionInfo     = connectionInfo ?? EmptyConnectionInfo;
     _parsedSqlStatement = parsedSqlStatement;
     CommandText         = commandText;
     QueryParameters     = queryParameters;
 }
示例#3
0
        public void SetUp()
        {
            _environment                = Mock.Create <IEnvironment>();
            _processStatic              = Mock.Create <IProcessStatic>();
            _httpRuntimeStatic          = Mock.Create <IHttpRuntimeStatic>();
            _configurationManagerStatic = Mock.Create <IConfigurationManagerStatic>();
            _dnsStatic = Mock.Create <IDnsStatic>();
            _securityPoliciesConfiguration = new SecurityPoliciesConfiguration();

            _runTimeConfiguration = new RunTimeConfiguration();
            _serverConfig         = new ServerConfiguration();

            SetLocalConfigurationDefaults();
            PublishConfig();

            _configAutoResponder = new ConfigurationAutoResponder(_config);

            _configurationService = Mock.Create <IConfigurationService>();
            Mock.Arrange(() => _configurationService.Configuration).Returns(() => _config);

            _attribDefSvc = new AttributeDefinitionService((f) => new AttributeDefinitions(f));

            _metricNameSvc = new MetricNameService();
            _transactionMetricNameMaker = new TransactionMetricNameMaker(_metricNameSvc);

            _transactionAttribMaker = new TransactionAttributeMaker(_configurationService, _attribDefSvc);

            _spanEventMaker  = new SpanEventMaker(_attribDefSvc, _configurationService);
            _databaseService = new DatabaseService(Mock.Create <ICacheStatsReporter>());

            _transactionEventMaker = new TransactionEventMaker(_attribDefSvc);


            _transactionGuid = GuidGenerator.GenerateNewRelicGuid();
            _startTime       = new DateTime(2018, 7, 18, 7, 0, 0, DateTimeKind.Utc); // unixtime = 1531897200000

            // Generic Segments
            _baseGenericSegment = new Segment(CreateTransactionSegmentState(3, null, 777), new MethodCallData(MethodCallType, MethodCallMethod, 1));
            _baseGenericSegment.SetSegmentData(new SimpleSegmentData(SegmentName));

            _childGenericSegment = new Segment(CreateTransactionSegmentState(4, 3, 777), new MethodCallData(MethodCallType, MethodCallMethod, 1));
            _childGenericSegment.SetSegmentData(new SimpleSegmentData(SegmentName));

            // Datastore Segments
            _connectionInfo       = new ConnectionInfo("localhost", "1234", "default", "maininstance");
            _parsedSqlStatement   = SqlParser.GetParsedDatabaseStatement(DatastoreVendor.MSSQL, System.Data.CommandType.Text, ShortQuery);
            _obfuscatedSql        = _databaseService.GetObfuscatedSql(ShortQuery, DatastoreVendor.MSSQL);
            _baseDatastoreSegment = new Segment(CreateTransactionSegmentState(3, null, 777), new MethodCallData(MethodCallType, MethodCallMethod, 1));
            _baseDatastoreSegment.SetSegmentData(new DatastoreSegmentData(_databaseService, _parsedSqlStatement, ShortQuery, _connectionInfo));

            // Http Segments
            _baseHttpSegment = new Segment(CreateTransactionSegmentState(3, null, 777), new MethodCallData(MethodCallType, MethodCallMethod, 1));
            _baseHttpSegment.SetSegmentData(new ExternalSegmentData(new Uri(HttpUri), HttpMethod));
        }
示例#4
0
        public void GetSpanEvent_ReturnsSpanEventPerSegment_DatastoreTruncateLongStatement()
        {
            var customerStmt = new string[]
            {
                new string('U', 2015),                          //1-byte per char
                new string('仮', 1015)                           //3-bytes per char
            };

            var expectedStmtTrunc = new string[]
            {
                new string('U', 1996) + "...",          //1-byte per char
                new string('仮', 666) + "..."            //3-bytes per char
            };

            for (int i = 0; i < customerStmt.Length; i++)
            {
                // ARRANGE
                var longSqlStatement     = new ParsedSqlStatement(DatastoreVendor.MSSQL, customerStmt[i], "select");
                var longDatastoreSegment = new Segment(CreateTransactionSegmentState(3, null, 777), new MethodCallData(MethodCallType, MethodCallMethod, 1));
                longDatastoreSegment.SetSegmentData(new DatastoreSegmentData(_databaseService, longSqlStatement, customerStmt[i], _connectionInfo));

                var segments = new List <Segment>()
                {
                    longDatastoreSegment.CreateSimilar(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(5), new List <KeyValuePair <string, object> >()),
                };
                var immutableTransaction  = BuildTestTransaction(segments, true, false);
                var transactionMetricName = _transactionMetricNameMaker.GetTransactionMetricName(immutableTransaction.TransactionName);
                var metricStatsCollection = new TransactionMetricStatsCollection(transactionMetricName);
                var transactionAttribs    = _transactionAttribMaker.GetAttributes(immutableTransaction, transactionMetricName, TimeSpan.FromSeconds(1), immutableTransaction.Duration, metricStatsCollection);

                // ACT
                var spanEvents = _spanEventMaker.GetSpanEvents(immutableTransaction, TransactionName, transactionAttribs);
                var spanEvent  = spanEvents.ToList()[1];

                // ASSERT
                var attribStatement    = (string)spanEvent.AgentAttributes()["db.statement"];
                var attribStmtLenBytes = Encoding.UTF8.GetByteCount(attribStatement);

                Assert.AreEqual(expectedStmtTrunc[i], attribStatement);
                Assert.True(attribStmtLenBytes <= 1999);
                Assert.True(attribStmtLenBytes >= 1996);
            }
        }
        public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction)
        {
            if (instrumentedMethodCall.IsAsync)
            {
                transaction.AttachToAsync();
            }

            var operation      = Common.GetRedisCommand(instrumentedMethodCall.MethodCall, AssemblyName);
            var connectionInfo = Common.GetConnectionInfoFromConnectionMultiplexer(instrumentedMethodCall.MethodCall, AssemblyName);

            var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.Redis, operation), connectionInfo);

            //We're not using Delegates.GetAsyncDelegateFor(agent, segment) because if an async redis call is made from an asp.net mvc action,
            //the continuation may not run until that mvc action has finished executing, or has yielded execution, because the synchronization context
            //will only allow one thread to execute at a time. To work around this limitation, since we don't need access to HttpContext in our continuation,
            //we can just provide the TaskContinuationOptions.HideScheduler flag so that we will use the default ThreadPool scheduler to schedule our
            //continuation. Using the ThreadPool scheduler allows our continuation to run without needing to wait for the mvc action to finish executing or
            //yielding its execution. We're not applying this change across the board, because we still need to better understand the impact of making this
            //change more broadly vs just fixing a known customer issue.

            return(Delegates.GetAsyncDelegateFor <Task>(agent, segment, TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.HideScheduler));
        }
        public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction)
        {
            var operation = GetOperationName(instrumentedMethodCall.MethodCall);
            var segment   = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.MongoDB, operation));

            return(Delegates.GetDelegateFor(segment));
        }
        public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction)
        {
            var redisCommandWithArgumentsAsBytes = instrumentedMethodCall.MethodCall.MethodArguments.ExtractNotNullAs <byte[][]>(0);
            var redisCommand = redisCommandWithArgumentsAsBytes[0];

            if (redisCommand == null)
            {
                return(Delegates.NoOp);
            }

            var operation     = GetRedisCommand(redisCommand);
            var contextObject = instrumentedMethodCall.MethodCall.InvocationTarget;

            if (contextObject == null)
            {
                throw new NullReferenceException(nameof(contextObject));
            }

            var host = TryGetPropertyName(PropertyHost, contextObject) ?? "unknown";

            host = ConnectionStringParserHelper.NormalizeHostname(host);
            var portPathOrId   = TryGetPropertyName(PropertyPortPathOrId, contextObject);
            var databaseName   = TryGetPropertyName(PropertyDatabaseName, contextObject);
            var connectionInfo = new ConnectionInfo(host, portPathOrId, databaseName);

            var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.Redis, operation), connectionInfo);

            return(Delegates.GetDelegateFor(segment));
        }
示例#8
0
        public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgent agent, ITransaction transaction)
        {
            var operation      = Common.GetRedisCommand(instrumentedMethodCall.MethodCall, AssemblyName);
            var connectionInfo = Common.GetConnectionInfoFromConnectionMultiplexer(instrumentedMethodCall.MethodCall, AssemblyName);

            var segment = transaction.StartDatastoreSegment(instrumentedMethodCall.MethodCall, ParsedSqlStatement.FromOperation(DatastoreVendor.Redis, operation), connectionInfo);

            return(Delegates.GetDelegateFor(segment));
        }
        public static VendorExplainValidationResult ShouldGenerateExplainPlan(string sql, ParsedSqlStatement parsedSqlStatement)
        {
            var validationMessage = "";
            var isValid           = true;

            var isSelectStatement = parsedSqlStatement.Operation.Equals("select", StringComparison.CurrentCultureIgnoreCase);

            if (!isSelectStatement)
            {
                validationMessage += "Will not run EXPLAIN on non-select statements. ";
                isValid            = false;
            }

            var isSingleStatement = SqlParser.IsSingleSqlStatement(sql);

            if (!isSingleStatement)
            {
                validationMessage += "Will not run EXPLAIN on multi-statement SQL query. ";
                isValid            = false;
            }

            return(new VendorExplainValidationResult(isValid, validationMessage));
        }