static ElasticApmModule() { var configReader = new FullFrameworkConfigReader(ConsoleLogger.Instance); var agentComponents = new AgentComponents(configurationReader: configReader); // Logger should be set ASAP because other initialization steps depend on it Logger = agentComponents.Logger.Scoped(nameof(ElasticApmModule)); Logger.Debug() ?.Log($"Entered {nameof(ElasticApmModule)} static ctor" + $"; .NET Runtime description: {PlatformDetection.DotNetRuntimeDescription}" + $"; IIS: {IisVersion}"); // FindAspNetVersion uses Logger var aspNetVersion = FindAspNetVersion(); Logger.Debug()?.Log($"ASP.NET version: {aspNetVersion}"); SetServiceInformation(agentComponents.Service, aspNetVersion); Agent.Setup(agentComponents); IsCaptureHeadersEnabled = Agent.Instance.ConfigurationReader.CaptureHeaders; Agent.Instance.Subscribe(new HttpDiagnosticsSubscriber()); }
public async Task MetricsWithRealAgent() { // Note: If XunitOutputLogger is used with MetricsCollector it might cause issues because // MetricsCollector's Dispose is currently broken - it doesn't guarantee that MetricsCollector's behaves correctly (i.e., ignores) // timer callbacks after Dispose completed. // This bug in turn causes MetricsCollector to possibly use XunitOutputLogger even after the current test has exited // and ITestOutputHelper on which XunitOutputLogger is based became invalid. // // After https://github.com/elastic/apm-agent-dotnet/issues/494 is fixed the line below can be uncommented. // // var logger = _logger; // var logger = new NoopLogger(); // var payloadSender = new MockPayloadSender(); var configReader = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug"); using var agentComponents = new AgentComponents(payloadSender: payloadSender, logger: logger, configurationReader: configReader); using (var agent = new ApmAgent(agentComponents)) { await Task.Delay(10000); //make sure we wait enough to collect 1 set of metrics agent.ConfigurationReader.MetricsIntervalInMilliseconds.Should().Be(1000); } payloadSender.Metrics.Should().NotBeEmpty(); payloadSender.Metrics.First().Samples.Should().NotBeEmpty(); }
public async Task ToggleRecordingAndCaptureMetrics() { var logger = new NoopLogger(); var payloadSender = new MockPayloadSender(); var configReader = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug", recording: "false"); using var agentComponents = new AgentComponents(payloadSender: payloadSender, logger: logger, configurationReader: configReader); using var agent = new ApmAgent(agentComponents); await Task.Delay(10000); //make sure we wait enough to collect 1 set of metrics agent.ConfigurationReader.MetricsIntervalInMilliseconds.Should().Be(1000); payloadSender.Metrics.Should().BeEmpty(); //start recording agent.ConfigStore.CurrentSnapshot = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug", recording: "true"); await Task.Delay(10000); //make sure we wait enough to collect 1 set of metrics //stop recording agent.ConfigStore.CurrentSnapshot = new MockConfigSnapshot(logger, metricsInterval: "1s", logLevel: "Debug", recording: "false"); payloadSender.Metrics.Should().NotBeEmpty(); await Task.Delay(500); //make sure collection on the MetricCollector is finished var numberOfEvents = payloadSender.Metrics.Count; await Task.Delay(10000); //make sure we wait enough to collect 1 set of metrics payloadSender.Metrics.Count.Should().Be(numberOfEvents); }
private void CreateNugetPackage(AgentComponents components, AgentComponents x86Components, string nuspecPath) { var rootDir = $@"{StagingDirectory}\Nuget{components.Platform}"; var stagingDir = $@"{rootDir}\content\newrelic"; FileHelpers.CopyFile(nuspecPath, rootDir); var package = new NugetPackage(rootDir, FilesToZipFolderName); package.SetVersion(components.Version); var configFilePath = $@"{rootDir}\content\newrelic\newrelic.config"; package.CopyToContent(components.RootInstallDirectoryComponents, @"newrelic"); package.CopyToContent(components.RootInstallDirectoryComponents.Where(x => !x.Contains("newrelic.config") && !x.Contains("newrelic.xsd")), @"newrelic\ProgramFiles\NewRelic\NetAgent"); package.CopyToContent(components.ExtensionDirectoryComponents.Where(x => x.Contains(".dll")), @"newrelic\ProgramFiles\NewRelic\NetAgent\Extensions"); package.CopyToContent(x86Components.RootInstallDirectoryComponents.Where(x => x.Contains("NewRelic.Profiler.dll")), @"newrelic\ProgramFiles\NewRelic\NetAgent\x86"); package.CopyToContent(components.WrapperXmlFiles, $@"newrelic\ProgramData\NewRelic\NetAgent\Extensions"); package.CopyToContent(components.ExtensionXsd, $@"newrelic\ProgramData\NewRelic\NetAgent\Extensions"); package.CopyToContent(components.NewRelicXsd, $@"newrelic\ProgramData\NewRelic\NetAgent"); package.CopyToContent(configFilePath, $@"newrelic\ProgramData\NewRelic\NetAgent"); //not sure why we create these folders Directory.CreateDirectory($@"{stagingDir}\Extensions"); Directory.CreateDirectory($@"{stagingDir}\ProgramData\NewRelic\NetAgent\NewRelic\NetAgent\Extensions"); Directory.CreateDirectory($@"{stagingDir}\ProgramData\NewRelic\NetAgent\NewRelic\NetAgent\Logs"); File.Delete(configFilePath); package.Pack(); }
public MongoApmTests(MongoFixture <MongoConfiguration, BsonDocument> fixture) { _documents = fixture.Collection ?? throw new ArgumentNullException(nameof(fixture.Collection)); _payloadSender = new MockPayloadSender(); var configurationReaderMock = new Mock <IConfigurationReader>(); configurationReaderMock.Setup(x => x.TransactionSampleRate) .Returns(() => 1.0); configurationReaderMock.Setup(x => x.TransactionMaxSpans) .Returns(() => 50); configurationReaderMock.Setup(x => x.Enabled) .Returns(() => true); configurationReaderMock.Setup(x => x.Recording) .Returns(() => true); var config = new AgentComponents(configurationReader: configurationReaderMock.Object, payloadSender: _payloadSender); var apmAgentType = typeof(IApmAgent).Assembly.GetType("Elastic.Apm.ApmAgent"); if (apmAgentType == null) { throw new InvalidOperationException("Cannot get `Elastic.Apm.ApmAgent` type with reflection"); } _agent = (IApmAgent)apmAgentType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).First() .Invoke(new object[] { config }); _agent.Subscribe(new MongoDiagnosticsSubscriber()); }
protected override void InternalBuild() { var x64Components = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); var x86Components = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, "x86", RepoRootDirectory, HomeRootDirectory); x64Components.ValidateComponents(); x86Components.ValidateComponents(); FileHelpers.CopyAll($@"{PackageDirectory}\Installer", FilesToZipFolderName); var replacements = new Dictionary <string, string>() { { "AGENT_VERSION_STRING", x64Components.Version } }; FileHelpers.ReplaceTextInFile($@"{FilesToZipFolderName}\install.ps1", replacements); var agentInfo = new AgentInfo { InstallType = "ScriptableFramework" }; agentInfo.WriteToDisk(FilesToZipFolderName); CreateNugetPackage(x64Components, x86Components, $@"{PackageDirectory}\NewRelic.Net.Agent.x64.nuspec"); CreateNugetPackage(x86Components, x86Components, $@"{PackageDirectory}\NewRelic.Net.Agent.nuspec"); var zipFilePath = $@"{OutputDirectory}\NewRelic.Agent.Installer.{x64Components.Version}.zip"; Directory.CreateDirectory(OutputDirectory); System.IO.Compression.ZipFile.CreateFromDirectory(FilesToZipFolderName, zipFilePath); File.WriteAllText($@"{OutputDirectory}\checksum.sha256", FileHelpers.GetSha256Checksum(zipFilePath)); }
/// <summary> /// Register Elastic APM .NET Agent with components in the container. /// You can customize the agent by passing additional IDiagnosticsSubscriber components to this method. /// Use this method if you want to control what tracing capability of the agent you would like to use /// or in case you want to minimize the number of dependencies added to your application. /// If you want to simply enable every tracing component without configuration please use the /// UseAllElasticApm extension method from the Elastic.Apm.NetCoreAll package. /// </summary> /// <param name="builder">Builder.</param> /// <param name="subscribers">Specify which diagnostic source subscribers you want to connect.</param> public static IHostBuilder UseElasticApm(this IHostBuilder builder, params IDiagnosticsSubscriber[] subscribers) { builder.ConfigureServices((ctx, services) => { services.AddSingleton <IApmLogger, NetCoreLogger>(); services.AddSingleton <IConfigurationReader>(sp => new MicrosoftExtensionsConfig(ctx.Configuration, sp.GetService <IApmLogger>(), ctx.HostingEnvironment.EnvironmentName)); services.AddSingleton(sp => { var components = new AgentComponents(sp.GetService <IApmLogger>(), sp.GetService <IConfigurationReader>()); UpdateServiceInformation(components.Service); return(components); }); services.AddSingleton <IApmAgent, ApmAgent>(sp => { var apmAgent = new ApmAgent(sp.GetService <AgentComponents>()); Agent.Setup(sp.GetService <AgentComponents>()); return(apmAgent); }); if (subscribers != null && subscribers.Any() && Agent.IsConfigured) { Agent.Subscribe(subscribers); } services.AddSingleton(sp => sp.GetRequiredService <IApmAgent>().Tracer); }); return(builder); }
protected override void InternalBuild() { var agentComponents = AgentComponents.GetAgentComponents(AgentType, Configuration, Platform, RepoRootDirectory, HomeRootDirectory); agentComponents.ValidateComponents(); agentComponents.CopyComponents(StagingDirectory); var agentInfo = new AgentInfo { InstallType = $"ZipWin{Platform}{AgentType.ToString()}" }; agentInfo.WriteToDisk(StagingDirectory); var zipFilePath = AgentType == AgentType.Framework ? $@"{OutputDirectory}\newrelic-framework-agent_{agentComponents.Version}_{Platform}.zip" : $@"{OutputDirectory}\newrelic-netcore20-agent-win_{agentComponents.Version}_{Platform}.zip"; Directory.CreateDirectory(OutputDirectory); System.IO.Compression.ZipFile.CreateFromDirectory(StagingDirectory, zipFilePath); File.WriteAllText($@"{OutputDirectory}\checksum.sha256", FileHelpers.GetSha256Checksum(zipFilePath)); // For now, the DotNet-Core20-Agent-DeployToS3 job expects core agent artifacts to be in the following directory // At some point we should change the job to pull from the new location under the Build\BuildArtifacts directory if (AgentType == AgentType.Core) { FileHelpers.CopyFile(zipFilePath, $@"{RepoRootDirectory}\src\_build\CoreArtifacts"); } Console.WriteLine($"Successfully created artifact for {nameof(ZipArchive)}."); }
/// <summary> /// Register Elastic APM .NET Agent with components in the container. /// You can customize the agent by passing additional IDiagnosticsSubscriber components to this method. /// Use this method if you want to control what tracing capability of the agent you would like to use /// or in case you want to minimize the number of dependencies added to your application. /// If you want to simply enable every tracing component without configuration please use the /// UseAllElasticApm extension method from the Elastic.Apm.NetCoreAll package. /// </summary> /// <param name="builder">Builder.</param> /// <param name="subscribers">Specify which diagnostic source subscribers you want to connect.</param> public static IHostBuilder UseElasticApm(this IHostBuilder builder, params IDiagnosticsSubscriber[] subscribers) { builder.ConfigureServices((ctx, services) => { //If the static agent doesn't exist, we create one here. If there is already 1 agent created, we reuse it. if (!Agent.IsConfigured) { services.AddSingleton <IApmLogger, NetCoreLogger>(); services.AddSingleton <IConfigurationReader>(sp => new MicrosoftExtensionsConfig(ctx.Configuration, sp.GetService <IApmLogger>(), ctx.HostingEnvironment.EnvironmentName)); } else { services.AddSingleton <IApmLogger>(Agent.Instance.Logger); services.AddSingleton <IConfigurationReader>(Agent.Instance.ConfigurationReader); } services.AddSingleton(sp => { if (!Agent.IsConfigured) { var logger = sp.GetService <IApmLogger>(); var configReader = sp.GetService <IConfigurationReader>(); var components = new AgentComponents(logger, configReader); UpdateServiceInformation(components.Service); return(components); } else { return(Agent.Components); } }); services.AddSingleton <IApmAgent, ApmAgent>(sp => { if (!Agent.IsConfigured) { var apmAgent = new ApmAgent(sp.GetService <AgentComponents>()); Agent.Setup(sp.GetService <AgentComponents>()); return(apmAgent); } else { return(Agent.Instance); } }); if (subscribers != null && subscribers.Any() && Agent.IsConfigured) { Agent.Subscribe(subscribers); } services.AddSingleton(sp => sp.GetRequiredService <IApmAgent>().Tracer); }); return(builder); }
public DownloadSiteArtifact(string configuration) : base("DownloadSite") { OutputDirectory = $@"{RepoRootDirectory}\build\BuildArtifacts\{Name}"; ShaDirectory = OutputDirectory + @"\SHA256"; var agentComponents = AgentComponents.GetAgentComponents(AgentType.Framework, configuration, "x64", RepoRootDirectory, HomeRootDirectory); Version = agentComponents.Version; }
public static void Setup(AgentComponents agentComponents) { if (Lazy.IsValueCreated) { throw new Exception("The singleton APM agent has already been instantiated and can no longer be configured"); } _components = agentComponents; }
protected override void InternalBuild() { var rootDirectory = $@"{StagingDirectory}\content\newrelic"; var frameworkAgentComponents = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); var frameworkAgentX86Components = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, "x86", RepoRootDirectory, HomeRootDirectory); var coreAgentComponents = AgentComponents.GetAgentComponents(AgentType.Core, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); var coreAgentX86Components = AgentComponents.GetAgentComponents(AgentType.Core, Configuration, "x86", RepoRootDirectory, HomeRootDirectory); frameworkAgentComponents.ValidateComponents(); frameworkAgentX86Components.ValidateComponents(); coreAgentComponents.ValidateComponents(); coreAgentX86Components.ValidateComponents(); var package = new NugetPackage(StagingDirectory, OutputDirectory); frameworkAgentComponents.CopyComponents($@"{package.ContentDirectory}\newrelic"); FileHelpers.CopyFile(frameworkAgentX86Components.WindowsProfiler, $@"{package.ContentDirectory}\newrelic\x86"); Directory.CreateDirectory($@"{rootDirectory}\logs"); System.IO.File.Create($@"{rootDirectory}\logs\placeholder").Dispose(); frameworkAgentComponents.CopyComponents($@"{package.GetContentFilesDirectory("any", "net45")}\newrelic"); FileHelpers.CopyFile(frameworkAgentX86Components.WindowsProfiler, $@"{package.GetContentFilesDirectory("any", "net45")}\newrelic\x86"); Directory.CreateDirectory($@"{StagingDirectory}\contentFiles\any\net45\newrelic\logs"); System.IO.File.Create($@"{StagingDirectory}\contentFiles\any\net45\newrelic\logs\placeholder").Dispose(); coreAgentComponents.CopyComponents($@"{package.GetContentFilesDirectory("any", "netstandard2.0")}\newrelic"); FileHelpers.CopyFile(coreAgentX86Components.WindowsProfiler, $@"{package.GetContentFilesDirectory("any", "netstandard2.0")}\newrelic\x86"); package.CopyToContentFiles(coreAgentComponents.LinuxProfiler, @"any\netstandard2.0\newrelic"); package.CopyToContentFiles(coreAgentComponents.GRPCExtensionsLibLinux, @"any\netstandard2.0\newrelic"); Directory.CreateDirectory($@"{StagingDirectory}\contentFiles\any\netstandard2.0\newrelic\logs"); System.IO.File.Create($@"{StagingDirectory}\contentFiles\any\netstandard2.0\newrelic\logs\placeholder").Dispose(); package.CopyAll(PackageDirectory); var agentInfo = new AgentInfo { InstallType = "NugetAgent" }; var newRelicConfigPaths = new[] { $@"{rootDirectory}\newrelic.config", $@"{StagingDirectory}\contentFiles\any\net45\newrelic\newrelic.config", $@"{StagingDirectory}\contentFiles\any\netstandard2.0\newrelic\newrelic.config", }; foreach (var newRelicConfigPath in newRelicConfigPaths) { TransformNewRelicConfig(newRelicConfigPath); agentInfo.WriteToDisk(Path.GetDirectoryName(newRelicConfigPath)); } package.SetVersion(frameworkAgentComponents.Version); package.Pack(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var components = new AgentComponents(new MyConsoleLogger(Elastic.Apm.Logging.LogLevel.Information)); Agent.Setup(components); //NOTE: Capturing the PayloadSender as a singleton services.AddSingleton(components.PayloadSender); services.AddSingleton <IMetricService, MetricService>(); }
protected override void InternalBuild() { var frameworkAgentComponents = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); frameworkAgentComponents.ValidateComponents(); var package = new NugetPackage(StagingDirectory, OutputDirectory); package.CopyAll(PackageDirectory); DoInstallerReplacements($"NewRelicAgent_x64_{frameworkAgentComponents.Version}.msi"); package.CopyToLib(frameworkAgentComponents.AgentApiDll); package.CopyToContent($@"{RepoRootDirectory}\src\_build\x64-{Configuration}\Installer\NewRelicAgent_x64_{frameworkAgentComponents.Version}.msi"); package.SetVersion(frameworkAgentComponents.Version); package.Pack(); }
static ElasticApmModule() { var configReader = new FullFrameworkConfigReader(ConsoleLogger.Instance); var agentComponents = new AgentComponents(configurationReader: configReader); SetServiceInformation(agentComponents.Service); Agent.Setup(agentComponents); Logger = Agent.Instance.Logger.Scoped(nameof(ElasticApmModule)); Logger.Debug() ?.Log($"Entered {nameof(ElasticApmModule)} static ctor: ASP.NET: {AspNetVersion}, CLR: {ClrDescription}, IIS: {IisVersion}"); IsCaptureHeadersEnabled = Agent.Instance.ConfigurationReader.CaptureHeaders; Agent.Instance.Subscribe(new HttpDiagnosticsSubscriber()); }
/// <summary> /// Adds the Elastic APM Middleware to the ASP.NET Core pipeline /// </summary> /// <returns>The elastic apm.</returns> /// <param name="builder">Builder.</param> /// <param name="configuration"> /// You can optionally pass the IConfiguration of your application to the Elastic APM Agent. By /// doing this the agent will read agent related configurations through this IConfiguration instance. /// If no <see cref="IConfiguration" /> is passed to the agent then it will read configs from environment variables. /// </param> /// <param name="subscribers"> /// Specify which diagnostic source subscribers you want to connect. The /// <see cref="AspNetCoreDiagnosticsSubscriber" /> is by default enabled. /// </param> public static IApplicationBuilder UseElasticApm( this IApplicationBuilder builder, IConfiguration configuration = null, params IDiagnosticsSubscriber[] subscribers ) { var logger = ConsoleLogger.Instance; var configReader = configuration == null ? new EnvironmentConfigurationReader(logger) : new MicrosoftExtensionsConfig(configuration, logger) as IConfigurationReader; var config = new AgentComponents(configurationReader: configReader); UpdateServiceInformation(config.Service); Agent.Setup(config); return(UseElasticApm(builder, Agent.Instance, subscribers)); }
protected override void InternalBuild() { var frameworkAgentComponents = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); var coreAgentComponents = AgentComponents.GetAgentComponents(AgentType.Core, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); frameworkAgentComponents.ValidateComponents(); coreAgentComponents.ValidateComponents(); var package = new NugetPackage(StagingDirectory, OutputDirectory); package.CopyAll(PackageDirectory); package.CopyToLib(frameworkAgentComponents.AgentApiDll, "net45"); package.CopyToLib(coreAgentComponents.AgentApiDll, "netstandard2.0"); package.CopyToRoot(frameworkAgentComponents.NewRelicLicenseFile); package.CopyToRoot(frameworkAgentComponents.NewRelicThirdPartyNoticesFile); package.SetVersion(frameworkAgentComponents.Version); package.Pack(); }
private (ApmAgent, BreakdownMetricsProvider) SetUpAgent() { var breakdownMetricsProvider = new BreakdownMetricsProvider(new NoopLogger()); var agentComponents = new AgentComponents( new NoopLogger(), new MockConfigSnapshot(metricsInterval: "1s"), new NoopPayloadSender(), new FakeMetricsCollector(), //metricsCollector will be set in AgentComponents.ctor new CurrentExecutionSegmentsContainer(), new NoopCentralConfigFetcher(), new MockApmServerInfo(new ElasticVersion(7, 12, 0, string.Empty)), breakdownMetricsProvider); var agent = new ApmAgent(agentComponents); return(agent, breakdownMetricsProvider); }
protected override void InternalBuild() { _agentComponents = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, Platform, RepoRootDirectory, HomeRootDirectory); _agentComponents.ValidateComponents(); var package = new NugetPackage(StagingDirectory, OutputDirectory); _agentComponents.CopyComponents($@"{package.ContentDirectory}\newrelic"); package.CopyToLib(_agentComponents.AgentApiDll); package.CopyAll(PackageDirectory); TransformNewRelicConfig(); var agentInfo = new AgentInfo { InstallType = $"NugetAzureWebsites{Platform}" }; agentInfo.WriteToDisk(RootDirectory); package.SetVersion(_agentComponents.Version); package.Pack(); }
/// <summary> /// Adds the Elastic APM Middleware to the ASP.NET Core pipeline. /// You can customize the agent by passing additional IDiagnosticsSubscriber components to this method. /// Use this method if you want to control what tracing capability of the agent you would like to use /// or in case you want to minimize the number of dependencies added to your application. /// Please note that by default without additional parameters this method only enables ASP.NET Core /// monitoring - e.g. database statements or outgoing HTTP calls won't be traced. /// If you want to simply enable every tracing component without configuration please use the /// UseAllElasticApm extension method from the Elastic.Apm.NetCoreAll package. /// </summary> /// <returns>The elastic apm.</returns> /// <param name="builder">Builder.</param> /// <param name="configuration"> /// You can optionally pass the IConfiguration of your application to the Elastic APM Agent. By /// doing this the agent will read agent related configurations through this IConfiguration instance. /// If no <see cref="IConfiguration" /> is passed to the agent then it will read configs from environment variables. /// </param> /// <param name="subscribers"> /// Specify which diagnostic source subscribers you want to connect. The /// <see cref="AspNetCoreErrorDiagnosticsSubscriber" /> is by default enabled. /// </param> public static IApplicationBuilder UseElasticApm( this IApplicationBuilder builder, IConfiguration configuration = null, params IDiagnosticsSubscriber[] subscribers ) { var logger = builder.ApplicationServices.GetApmLogger(); var configReader = configuration == null ? new EnvironmentConfigurationReader(logger) : new MicrosoftExtensionsConfig(configuration, logger, builder.ApplicationServices.GetEnvironmentName()) as IConfigurationReader; var config = new AgentComponents(configurationReader: configReader, logger: logger); HostBuilderExtensions.UpdateServiceInformation(config.Service); // Agent.Setup must be called, even if agent is disabled. This way static public API usage won't implicitly initialize an agent with default values, instead, this will be reused. Agent.Setup(config); return(UseElasticApm(builder, Agent.Instance, logger, subscribers)); }
/// <summary> /// Adds the Elastic APM Middleware to the ASP.NET Core pipeline /// </summary> /// <returns>The elastic apm.</returns> /// <param name="builder">Builder.</param> /// <param name="configuration"> /// You can optionally pass the IConfiguration of your application to the Elastic APM Agent. By /// doing this the agent will read agent related configurations through this IConfiguration instance. /// </param> /// <param name="payloadSender">Payload sender.</param> /// <param name="subscribers">Specify which diagnostic source subscribers you want to connect</param> public static IApplicationBuilder UseElasticApm( this IApplicationBuilder builder, IConfiguration configuration = null, params IDiagnosticsSubscriber[] subscribers ) { var configReader = configuration != null ? new MicrosoftExtensionsConfig(configuration) : null; var service = Service.GetDefaultService((configReader)); service.Framework = new Framework { Name = "ASP.NET Core", Version = "2.1" }; //TODO: Get version service.Language = new Language { Name = "C#" }; //TODO var config = new AgentComponents(configurationReader: configReader, service: service); Agent.Setup(config); return(UseElasticApm(builder, Agent.Instance, subscribers)); }
protected override void InternalBuild() { var x64Components = AgentComponents.GetAgentComponents(AgentType.Core, Configuration, "x64", RepoRootDirectory, HomeRootDirectory); var x86Components = AgentComponents.GetAgentComponents(AgentType.Core, Configuration, "x86", RepoRootDirectory, HomeRootDirectory); x64Components.ValidateComponents(); x86Components.ValidateComponents(); FileHelpers.DeleteDirectories(StagingDirectory, OutputDirectory); var agentInfox64 = new AgentInfo { InstallType = "ScriptableCore" }; x64Components.CopyComponents($@"{StagingDirectory}\x64"); x86Components.CopyComponents($@"{StagingDirectory}\x86"); agentInfox64.WriteToDisk($@"{StagingDirectory}\x64"); agentInfox64.WriteToDisk($@"{StagingDirectory}\x86"); FileHelpers.CopyFile($@"{RepoRootDirectory}\build\Packaging\CoreInstaller\installAgent.ps1", StagingDirectory); FileHelpers.CopyFile($@"{RepoRootDirectory}\build\Packaging\CoreInstaller\installAgentUsage.txt", StagingDirectory); var zipFilePath = $@"{OutputDirectory}\newrelic-netcore20-agent-win-installer_{x64Components.Version}.zip"; Directory.CreateDirectory(OutputDirectory); System.IO.Compression.ZipFile.CreateFromDirectory(StagingDirectory, zipFilePath); File.WriteAllText($@"{OutputDirectory}\checksum.sha256", FileHelpers.GetSha256Checksum(zipFilePath)); // For now, the DotNet-Core20-Agent-DeployToS3 job expects core agent artifacts to be in the following directory // At some point we should change the job to pull from the new location under the Build\BuildArtifacts directory FileHelpers.CopyFile(zipFilePath, $@"{RepoRootDirectory}\src\_build\CoreArtifacts"); // We put a readme file for the core agent on the download site: http://download.newrelic.com/dot_net_agent/core_20/current/ // This readme also gets picked up by the DotNet-Core20-Agent-DeployToS3 job. CopyCoreReadme(); Console.WriteLine($"Successfully created artifact for {nameof(CoreInstaller)}."); }
/// <summary> /// Adds the Elastic APM Middleware to the ASP.NET Core pipeline. /// You can customize the agent by passing additional IDiagnosticsSubscriber components to this method. /// Use this method if you want to control what tracing capability of the agent you would like to use /// or in case you want to minimize the number of dependencies added to your application. /// Please note that by default without additional parameters this method only enables ASP.NET Core /// monitoring - e.g. database statements or outgoing HTTP calls won't be traced. /// If you want to simply enable every tracing component without configuration please use the /// UseAllElasticApm extension method from the Elastic.Apm.NetCoreAll package. /// </summary> /// <returns>The elastic apm.</returns> /// <param name="builder">Builder.</param> /// <param name="configuration"> /// You can optionally pass the IConfiguration of your application to the Elastic APM Agent. By /// doing this the agent will read agent related configurations through this IConfiguration instance. /// If no <see cref="IConfiguration" /> is passed to the agent then it will read configs from environment variables. /// </param> /// <param name="subscribers"> /// Specify which diagnostic source subscribers you want to connect. The /// <see cref="AspNetCoreErrorDiagnosticsSubscriber" /> is by default enabled. /// </param> public static IApplicationBuilder UseElasticApm( this IApplicationBuilder builder, IConfiguration configuration = null, params IDiagnosticsSubscriber[] subscribers ) { var logger = builder.ApplicationServices.GetApmLogger(); var configReader = configuration == null ? new EnvironmentConfigurationReader(logger) : new MicrosoftExtensionsConfig(configuration, logger, builder.ApplicationServices.GetEnvironmentName()) as IConfigurationReader; if (!configReader.Enabled) { return(builder); } var config = new AgentComponents(configurationReader: configReader, logger: logger); HostBuilderExtensions.UpdateServiceInformation(config.Service); Agent.Setup(config); return(UseElasticApm(builder, Agent.Instance, logger, subscribers)); }
/// <summary> /// Register Elastic APM .NET Agent with components in the container. /// You can customize the agent by passing additional IDiagnosticsSubscriber components to this method. /// Use this method if you want to control what tracing capability of the agent you would like to use /// or in case you want to minimize the number of dependencies added to your application. /// If you want to simply enable every tracing component without configuration please use the /// UseAllElasticApm extension method from the Elastic.Apm.NetCoreAll package. /// </summary> /// <param name="builder">Builder.</param> /// <param name="subscribers">Specify which diagnostic source subscribers you want to connect.</param> public static IHostBuilder UseElasticApm(this IHostBuilder builder, params IDiagnosticsSubscriber[] subscribers) { builder.ConfigureServices((ctx, services) => { //If the static agent doesn't exist, we create one here. If there is already 1 agent created, we reuse it. if (!Agent.IsConfigured) { services.AddSingleton <IApmLogger, NetCoreLogger>(); services.AddSingleton <IConfigurationReader>(sp => new MicrosoftExtensionsConfig(ctx.Configuration, sp.GetService <IApmLogger>(), ctx.HostingEnvironment.EnvironmentName)); } else { services.AddSingleton(Agent.Instance.Logger); services.AddSingleton(Agent.Instance.ConfigurationReader); } services.AddSingleton(sp => { if (Agent.IsConfigured) { return(Agent.Components); } var logger = sp.GetService <IApmLogger>(); var configReader = sp.GetService <IConfigurationReader>(); var payloadSender = sp.GetService <IPayloadSender>(); var components = new AgentComponents(logger, configReader, payloadSender); UpdateServiceInformation(components.Service); return(components); }); services.AddSingleton <IApmAgent, ApmAgent>(sp => { if (Agent.IsConfigured) { return(Agent.Instance); } Agent.Setup(sp.GetService <AgentComponents>()); return(Agent.Instance); }); services.AddSingleton(sp => sp.GetRequiredService <IApmAgent>().Tracer); // Force to create agent var serviceProvider = services.BuildServiceProvider(); var agent = serviceProvider.GetService <IApmAgent>(); if (!(agent is ApmAgent apmAgent)) { return; } if (!Agent.IsConfigured || !apmAgent.ConfigurationReader.Enabled) { return; } // Only add ElasticApmErrorLoggingProvider after the agent is created, because it depends on the agent services.AddSingleton <ILoggerProvider, ApmErrorLoggingProvider>(sp => new ApmErrorLoggingProvider(sp.GetService <IApmAgent>())); if (subscribers != null && subscribers.Any() && Agent.IsConfigured) { apmAgent.Subscribe(subscribers); } }); return(builder); }
private void ValidateWxsDefinitionFileForInstaller() { //Verify that the expected agent components are in the homebuilder for the installer var frameworkAgentComponents = AgentComponents.GetAgentComponents(AgentType.Framework, Configuration, Platform, RepoRootDirectory, HomeRootDirectory); frameworkAgentComponents.ValidateComponents(); var coreAgentComponents = AgentComponents.GetAgentComponents(AgentType.Core, Configuration, Platform, RepoRootDirectory, HomeRootDirectory); coreAgentComponents.ValidateComponents(); var productWxs = GetParsedProductWxsData(); // Framework var extensionGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "NewRelic.Agent.Extensions"); var instrumentationGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "NewRelic.Agent.Extensions.Instrumentation"); var frameworkExtensionsComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "ExtensionsComponents"); var frameworkConfigurationComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "ConfigurationComponents"); var frameworkRegistryComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "RegistryComponents"); var frameworkProgramsComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "ProgramsComponents"); var frameworkIISRegistryComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "IISRegistryComponents"); var frameworkProductComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "ProductComponents"); // Core var coreExtensionGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "CoreNewRelic.Agent.Extensions"); var coreInstrumentationGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "CoreNewRelic.Agent.Extensions.Instrumentation"); var coreIISRegistryComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "CoreIISRegistryComponents"); var coreProductComponentsGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "CoreProductComponents"); // All installs var uninstallComponent = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "UninstallComponents") .Component.First(); var globalApiComponentGroup = productWxs.Fragment.Items .OfType <WixFragmentComponentGroup>() .First(cg => cg.Id == "ApiComponents"); ValidateWixFileExtensionDefinitions(extensionGroup); ValidateWixFileExtensionDefinitions(coreExtensionGroup, isCore: true); ValidateWixFileExtensionDefinitions(instrumentationGroup); ValidateWixFileExtensionDefinitions(coreInstrumentationGroup, isCore: true); ValidateWixFileExtensionDefinitions(frameworkExtensionsComponentsGroup); ValidateWixRegistryDefinitions(frameworkRegistryComponentsGroup); ValidateWixRegistryDefinitions(frameworkProgramsComponentsGroup); ValidateWixRegistryDefinitions(frameworkProductComponentsGroup); ValidateWixRegistryDefinitions(coreProductComponentsGroup); ValidateWixUninstallComponents(uninstallComponent); ValidateWixIisRegistryDefinitions(frameworkIISRegistryComponentsGroup, coreIISRegistryComponentsGroup); ValidateAgentComponentsAndWixReferenceTheSameFiles(frameworkAgentComponents.ExtensionDirectoryComponents, extensionGroup, frameworkExtensionsComponentsGroup); ValidateAgentComponentsAndWixReferenceTheSameFiles(frameworkAgentComponents.WrapperXmlFiles, instrumentationGroup); ValidateAgentComponentsAndWixReferenceTheSameFiles(frameworkAgentComponents.ConfigurationComponents, frameworkConfigurationComponentsGroup); ValidateAgentComponentsAndWixReferenceTheSameFiles(CreateReadOnlyCollection(coreAgentComponents.AgentApiDll), globalApiComponentGroup); ValidateAgentComponentsAndWixReferenceTheSameFiles(CreateReadOnlyCollection(frameworkAgentComponents.AgentApiDll), globalApiComponentGroup); }