internal PollAnswer(InternalApi.PollAnswer pollAnswer, InternalApi.Poll poll) { PollId = pollAnswer.PollId; Id = pollAnswer.Id; Name = pollAnswer.Name; VoteCount = poll.HideResultsUntilVotingComplete && poll.VotingEndDateUtc.HasValue && poll.VotingEndDateUtc > DateTime.UtcNow ? 0 : pollAnswer.VoteCount; }
internal PollVote(InternalApi.PollVote pollVote) { PollId = pollVote.PollId; Answer = new PollAnswer(InternalApi.PollingService.GetPollAnswer(pollVote.PollAnswerId), InternalApi.PollingService.GetPoll(pollVote.PollId)); CreatedDate = InternalApi.Formatting.FromUtcToUserTime(pollVote.CreatedDateUtc); LastUpdatedDate = InternalApi.Formatting.FromUtcToUserTime(pollVote.LastUpdatedDateUtc); User = new User(pollVote.UserId); }
public static void DisableBrowserMonitoring(bool overrideManual = false) { const ApiMethod apiMetric = ApiMethod.DisableBrowserMonitoring; const string apiName = nameof(DisableBrowserMonitoring); void work() { InternalApi.DisableBrowserMonitoring(overrideManual); } TryInvoke(work, apiName, apiMetric); }
public static void SetUserParameters(string?userName, string?accountName, string?productName) { const ApiMethod apiMetric = ApiMethod.SetUserParameters; const string apiName = nameof(SetUserParameters); void work() { InternalApi.SetUserParameters(userName, accountName, productName); } TryInvoke(work, apiName, apiMetric); }
public static void SetTransactionUri(Uri uri) { const ApiMethod apiMetric = ApiMethod.SetTransactionUri; const string apiName = nameof(SetTransactionUri); void work() { InternalApi.SetTransactionUri(uri); } TryInvoke(work, apiName, apiMetric); }
/// <summary> /// Notice an error identified by an exception report it to the New Relic service. /// If this method is called within a transaction, /// the exception will be reported with the transaction when it finishes. /// If it is invoked outside of a transaction, a traced error will be created and reported to the New Relic service. /// Only the exception/parameter pair for the first call to NoticeError during the course of a transaction is retained. /// Supports web applications only. /// </summary> /// <param name="exception">The exception to be reported. /// Only part of the exception's information may be retained to prevent the report from being too large. /// </param> /// <param name="customAttributes">Custom parameters to include in the traced error. /// May be null. /// Only 10,000 characters of combined key/value data is retained. /// </param> public static void NoticeError(Exception exception, IDictionary <string, object> customAttributes) { const ApiMethod apiMetric = ApiMethod.NoticeError; const string apiName = nameof(NoticeError); void work() { InternalApi.NoticeError(exception, customAttributes); } TryInvoke(work, apiName, apiMetric); }
public static void AddCustomParameter(string key, string value) { const ApiMethod apiMetric = ApiMethod.AddCustomParameter; const string apiName = nameof(AddCustomParameter); void work() { InternalApi.AddCustomParameter(key, value); } TryInvoke(work, apiName, apiMetric); }
/// <summary> /// Notice an error identified by an exception and report it to the New Relic service. /// If this method is called within a transaction, /// the exception will be reported with the transaction when it finishes. /// If it is invoked outside of a transaction, a traced error will be created and reported to the New Relic service. /// Only the exception/parameter pair for the first call to NoticeError during the course of a transaction is retained. /// Supports web applications only. /// </summary> /// <param name="exception">The exception to be reported. /// Only part of the exception's information may be retained to prevent the report from being too large. /// </param> public static void NoticeError(Exception exception) { const ApiMethod apiMetric = ApiMethod.NoticeError; const string apiName = nameof(NoticeError); void work() { InternalApi.NoticeError(exception); } TryInvoke(work, apiName, apiMetric); }
/// <summary> /// Increment the metric counter for the given name. /// </summary> /// <param name="name">The name of the metric to increment. /// Only the first 1000 characters are retained. /// </param> public static void IncrementCounter(string name) { const ApiMethod apiMetric = ApiMethod.IncrementCounter; const string apiName = nameof(IncrementCounter); void work() { InternalApi.IncrementCounter(name); } TryInvoke(work, apiName, apiMetric); }
public static void SetTransactionName(string?category, string name) { const ApiMethod apiMetric = ApiMethod.SetTransactionName; const string apiName = nameof(SetTransactionName); void work() { InternalApi.SetTransactionName(category, name); } TryInvoke(work, apiName, apiMetric); }
/// <summary> /// Record a response time in milliseconds for the given metric name. /// </summary> /// <param name="name">The name of the response time metric to record. /// Only the first 1000 characters are retained. /// </param> /// <param name="millis">The response time to record in milliseconds.</param> public static void RecordResponseTimeMetric(string name, long millis) { const ApiMethod apiMetric = ApiMethod.RecordResponseTimeMetric; const string apiName = nameof(RecordResponseTimeMetric); void work() { InternalApi.RecordResponseTimeMetric(name, millis); } TryInvoke(work, apiName, apiMetric); }
/// <summary> Record a metric value for the given name. </summary> /// <param name="name"> The name of the metric to record. Only the first 1000 characters are /// retained. </param> /// <param name="value"> The value to record. Only the first 1000 characters are retained. </param> public static void RecordMetric(string name, float value) { const ApiMethod apiMetric = ApiMethod.RecordMetric; const string apiName = nameof(RecordMetric); void work() { InternalApi.RecordMetric(name, value); } TryInvoke(work, apiName, apiMetric); }
/// <summary> Record a custom analytics event. </summary> /// <param name="eventType"> The name of the metric to record. Only the first 255 characters (256 /// including the null terminator) are retained. </param> /// <param name="attributes"> The value to record. Only the first 1000 characters are retained. </param> public static void RecordCustomEvent(string eventType, IEnumerable <KeyValuePair <string, object> > attributes) { const ApiMethod apiMetric = ApiMethod.RecordCustomEvent; const string apiName = nameof(RecordCustomEvent); void work() { InternalApi.RecordCustomEvent(eventType, attributes); } TryInvoke(work, apiName, apiMetric); }
public static void NoticeError(string message, IDictionary <string, object> customAttributes, bool isExpected) { const ApiMethod apiMetric = ApiMethod.NoticeError; const string apiName = nameof(NoticeError); void work() { InternalApi.NoticeError(message, customAttributes, isExpected); } TryInvoke(work, apiName, apiMetric); }
public void DeleteQueue() { using (var api = new InternalApi(true)) { api.CreateQueue("WiseMan"); Assert.Throws(Is.TypeOf <Exception>().And.Message.EqualTo("Queue not found"), delegate { api.DeleteQueue("WISEMEN"); } ); api.DeleteQueue("WiseMan"); Assert.Throws(Is.TypeOf <Exception>().And.Message.EqualTo("Queue not found"), delegate { api.DeleteQueue("WiseMan"); } ); } }
public void Add10000Messages() { using (var api = new InternalApi(true)) { var queue = api.CreateQueue("WiseMan"); var trans = api.StartTransaction(); for (int i = 0; i < 10000; i++) { api.AddMessage(trans, queue, new object(), ""); } api.CommitTransaction(trans); } }
public void DuplicateQueueName() { using (var api = new InternalApi(true)) { api.CreateQueue("WiseMan"); Assert.Throws(Is.TypeOf <Exception>().And.Message.EqualTo("Queue already exists"), delegate { api.CreateQueue("WiseMan"); } ); Assert.Throws(Is.TypeOf <Exception>().And.Message.EqualTo("Queue already exists"), delegate { api.CreateQueue("wiseman"); } ); Assert.Throws(Is.TypeOf <Exception>().And.Message.EqualTo("Queue already exists"), delegate { api.CreateQueue("WISEMAN"); } ); } }
internal Poll(InternalApi.Poll poll) { Id = poll.Id; ContentId = poll.Id; Name = poll.Name; Description = InternalApi.PollingService.RenderPollDescription(poll, "webservices"); IsEnabled = poll.IsEnabled; CreatedDate = InternalApi.Formatting.FromUtcToUserTime(poll.CreatedDateUtc); LastUpdatedDate = InternalApi.Formatting.FromUtcToUserTime(poll.LastUpdatedDateUtc); Url = TEApi.Url.Absolute(InternalApi.PollingUrlService.PollUrl(poll.Id)); Answers = new List<PollAnswer>(poll.Answers.Select(x => new PollAnswer(x, poll))); Group = new Group(poll.ApplicationId); AuthorUser = new User(poll.AuthorUserId); HideResultsUntilVotingComplete = poll.HideResultsUntilVotingComplete; VotingEndDate = !poll.VotingEndDateUtc.HasValue ? null : (DateTime?) InternalApi.Formatting.FromUtcToUserTime(poll.VotingEndDateUtc.Value); TotalVotes = poll.Answers.Sum(x => x.VoteCount); }
/// <summary> /// Creates an instance of the <see cref="AgentManager"/> class./> /// </summary> /// <remarks> /// The agent should be constructed as early as possible in order to perform /// initialization of the logging system. /// </remarks> private AgentManager() { _container = AgentServices.GetContainer(); AgentServices.RegisterServices(_container); // Resolve IConfigurationService (so that it starts listening to config changes) before loading newrelic.config _container.Resolve <IConfigurationService>(); var config = ConfigurationLoader.Initialize(); LoggerBootstrapper.ConfigureLogger(config.LogConfig); AssertAgentEnabled(config); EventBus <KillAgentEvent> .Subscribe(OnShutdownAgent); //Initialize the extensions loader with extensions folder based on the the install path ExtensionsLoader.Initialize(AgentInstallConfiguration.InstallPathExtensionsDirectory); // Resolve all services once we've ensured that the agent is enabled // The AgentApiImplementation needs to be resolved before the WrapperService, because // resolving the WrapperService triggers an agent connect but it doesn't instantiate // the CustomEventAggregator, so we need to resolve the AgentApiImplementation to // get the CustomEventAggregator instantiated before the connect process is triggered. // If that doesn't happen the CustomEventAggregator will not start its harvest timer // when the agent connect response comes back. The agent DI, startup, and connect // process really needs to be refactored so that it's more explicit in its behavior. var agentApi = _container.Resolve <IAgentApi>(); _wrapperService = _container.Resolve <IWrapperService>(); //We need to attempt to auto start the agent once all services have resolved _container.Resolve <IConnectionManager>().AttemptAutoStart(); AgentServices.StartServices(_container); // Setup the internal API first so that AgentApi can use it. InternalApi.SetAgentApiImplementation(agentApi); AgentApi.SetSupportabilityMetricCounters(_container.Resolve <IApiSupportabilityMetricCounters>()); Initialize(); _isInitialized = true; }
public static IEnumerable <KeyValuePair <string, string> > GetResponseMetadata() { return(InternalApi.GetResponseMetadata() ?? new Dictionary <string, string>()); }
public static void InitializePublicAgent(object publicAgent) { InternalApi.InitializePublicAgent(publicAgent); }
public CompositeTestAgent(bool shouldAllowThreads, bool includeAsyncLocalStorage) { Log.Initialize(new Logger()); _shouldAllowThreads = shouldAllowThreads; // Create the fake classes necessary to construct services var mockFactory = Mock.Create <IContextStorageFactory>(); Mock.Arrange(() => mockFactory.CreateContext <IInternalTransaction>(Arg.AnyString)).Returns(_primaryTransactionContextStorage); var transactionContextFactories = new List <IContextStorageFactory> { mockFactory }; if (includeAsyncLocalStorage) { transactionContextFactories.Add(new AsyncLocalStorageFactory()); } var wrappers = Enumerable.Empty <IWrapper>(); var mockEnvironment = Mock.Create <IEnvironment>(); var dataTransportService = Mock.Create <IDataTransportService>(); var scheduler = Mock.Create <IScheduler>(); NativeMethods = Mock.Create <INativeMethods>(); _harvestActions = new List <Action>(); Mock.Arrange(() => scheduler.ExecuteEvery(Arg.IsAny <Action>(), Arg.IsAny <TimeSpan>(), Arg.IsAny <TimeSpan?>())) .DoInstead <Action, TimeSpan, TimeSpan?>((action, _, __) => { lock (_harvestActionsLockObject) { _harvestActions.Add(action); } }); var threadPoolStatic = Mock.Create <IThreadPoolStatic>(); _queuedCallbacks = new List <WaitCallback>(); Mock.Arrange(() => threadPoolStatic.QueueUserWorkItem(Arg.IsAny <WaitCallback>())) .DoInstead <WaitCallback>(callback => { lock (_queuedCallbacksLockObject) { _queuedCallbacks.Add(callback); } }); var configurationManagerStatic = Mock.Create <IConfigurationManagerStatic>(); Mock.Arrange(() => configurationManagerStatic.GetAppSetting("NewRelic.LicenseKey")) .Returns("Composite test license key"); // Construct services _container = AgentServices.GetContainer(); AgentServices.RegisterServices(_container); // Replace existing registrations with mocks before resolving any services _container.ReplaceRegistration(mockEnvironment); _container.ReplaceRegistration <IEnumerable <IContextStorageFactory> >(transactionContextFactories); _container.ReplaceRegistration <ICallStackManagerFactory>( new TestCallStackManagerFactory()); _container.ReplaceRegistration(wrappers); _container.ReplaceRegistration(dataTransportService); _container.ReplaceRegistration(scheduler); _container.ReplaceRegistration(NativeMethods); _container.ReplaceRegistration(Mock.Create <ICATSupportabilityMetricCounters>()); if (!_shouldAllowThreads) { _container.ReplaceRegistration(threadPoolStatic); } _container.ReplaceRegistration(configurationManagerStatic); InstrumentationService = _container.Resolve <IInstrumentationService>(); InstrumentationWatcher = _container.Resolve <InstrumentationWatcher>(); AgentServices.StartServices(_container); DisableAgentInitializer(); InternalApi.SetAgentApiImplementation(_container.Resolve <IAgentApi>()); AgentApi.SetSupportabilityMetricCounters(_container.Resolve <IApiSupportabilityMetricCounters>()); // Update configuration (will also start services) LocalConfiguration = GetDefaultTestLocalConfiguration(); ServerConfiguration = GetDefaultTestServerConfiguration(); SecurityConfiguration = GetDefaultSecurityPoliciesConfiguration(); InstrumentationWatcher.Start(); PushConfiguration(); _attribDefSvc = _container.Resolve <IAttributeDefinitionService>(); // Redirect the mock DataTransportService to capture harvested wire models Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <MetricWireModel> >())) .Returns(SaveDataAndReturnSuccess(Metrics)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <CustomEventWireModel> >())) .Returns(SaveDataAndReturnSuccess(CustomEvents)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <TransactionTraceWireModel> >())) .Returns(SaveDataAndReturnSuccess(TransactionTraces)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <EventHarvestData>(), Arg.IsAny <IEnumerable <TransactionEventWireModel> >())) .Returns(SaveDataAndReturnSuccess(AdditionalHarvestData, TransactionEvents)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <ErrorTraceWireModel> >())) .Returns(SaveDataAndReturnSuccess(ErrorTraces)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >())) .Returns(SaveDataAndReturnSuccess(SqlTraces)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <EventHarvestData>(), Arg.IsAny <IEnumerable <ErrorEventWireModel> >())) .Returns(SaveDataAndReturnSuccess(AdditionalHarvestData, ErrorEvents)); Mock.Arrange(() => dataTransportService.Send(Arg.IsAny <EventHarvestData>(), Arg.IsAny <IEnumerable <ISpanEventWireModel> >())) .Returns(SaveDataAndReturnSuccess(AdditionalHarvestData, SpanEvents)); EnableAggregators(); }
public AfterWrappedMethodDelegate BeforeWrappedMethod(InstrumentedMethodCall instrumentedMethodCall, IAgentWrapperApi agentWrapperApi, ITransactionWrapperApi transactionWrapperApi) { /// Read and setup the configured headers from newrelic.config file if (configuredHeaders == null) { IReadOnlyDictionary <string, string> appSettings = agentWrapperApi.Configuration.GetAppSettings(); string reqHeaders = null; if (appSettings.TryGetValue("requestHeaders", out reqHeaders)) { configuredHeaders = reqHeaders?.Split(',').Select(p => p.Trim()).ToDictionary(t => t, t => $"http.{t}"); } else { configuredHeaders = new Dictionary <string, string>(); } } if (webOperationContextType == null) { Assembly webAssembly = Assembly.Load("System.ServiceModel.Web"); webOperationContextType = webAssembly?.GetType("System.ServiceModel.Web.WebOperationContext"); } if (configuredHeaders != null) { BindingFlags flags = BindingFlags.Static | BindingFlags.Public; object currentContext = webOperationContextType?.GetProperty("Current", flags)?.GetValue(null); object request = currentContext?.GetType()?.GetProperty("IncomingRequest")?.GetValue(currentContext); object headers = request?.GetType()?.GetProperty("Headers")?.GetValue(request); if (headers != null) { WebHeaderCollection headerCollection = headers as System.Net.WebHeaderCollection; if (headerCollection != null) { foreach (KeyValuePair <string, string> entry in configuredHeaders) { string headerValue = headerCollection.Get(entry.Key); if (headerValue != null) { InternalApi.AddCustomParameter(entry.Value, headerValue); } } } } } object[] methodArgs = instrumentedMethodCall.MethodCall.MethodArguments; if (methodArgs.Length > 1) { object requesturi = methodArgs[0]; string localpath = requesturi?.GetType().GetProperty("LocalPath")?.GetValue(requesturi)?.ToString()?.TrimStart('/'); if (!string.IsNullOrWhiteSpace(localpath)) { transactionWrapperApi.SetWebTransactionName(WebTransactionType.WCF, localpath, TransactionNamePriority.CustomTransactionName); } } /// does not work see-> https://referencesource.microsoft.com/#System.Data.Services/System/Data/Services/ProcessRequestArgs.cs,fe129b45e15d2da5 /// interface declared internal /* * if (configuredHeaders != null) * { * // Captures the method argument to be used in the local method later on. * object[] methodArgs = instrumentedMethodCall.MethodCall.MethodArguments; * if (methodArgs.Length > 1) * { * object requesturi = methodArgs[0]; * //Effectively calling something like this below: string header = controllerContext.HttpContext.Request.Headers.Get("HEADER_NAME"); * object dataserviceObject = methodArgs[1]; * if (dataserviceObject == null) * throw new NullReferenceException(nameof(dataserviceObject)); * BindingFlags flags = BindingFlags.FlattenHierarchy | BindingFlags.NonPublic ; * object operationContext = dataserviceObject?.GetType()?.GetProperty("OperationContext", flags)?.GetValue(dataserviceObject); * Inspect.GetAllProperties(dataserviceObject); * Inspect.GetAllFields(dataserviceObject); * Inspect.GetAllMethods(dataserviceObject); * Inspect.GetAllMembers(dataserviceObject); * object headers = operationContext?.GetType()?.GetProperty("RequestHeaders")?.GetValue(operationContext); * * if (headers != null) * { * NameValueCollection headerCollection = headers as NameValueCollection; * if (headerCollection != null) * { * foreach (var cHeader in configuredHeaders) * { * string headerValue = headerCollection.Get(cHeader); * if (headerValue != null) * { * InternalApi.AddCustomParameter("http." + cHeader, headerValue); * } * } * } * } * } * } */ return(Delegates.GetDelegateFor( onSuccess: () => { })); }
public void Init() { instance = new InternalApi(); }
internal PollAnswer(Internal.PollAnswer pollAnswer, InternalApi.Poll poll) : base() { _pollAnswer = pollAnswer; _hideVoteCounts = poll.HideResultsUntilVotingComplete && poll.VotingEndDateUtc.HasValue && DateTime.UtcNow > poll.VotingEndDateUtc.Value; }
public AgQueueService(ILogger <AgQueueService> logger, InternalApi internalApi) { _logger = logger; this.internalApi = internalApi; }