コード例 #1
0
        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());
        }
コード例 #2
0
        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();
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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();
        }
コード例 #5
0
        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());
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        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)}.");
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        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;
        }
コード例 #11
0
        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;
        }
コード例 #12
0
        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();
        }
コード例 #13
0
        // 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>();
        }
コード例 #14
0
        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();
        }
コード例 #15
0
        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());
        }
コード例 #16
0
        /// <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));
        }
コード例 #17
0
        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();
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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();
        }
コード例 #20
0
        /// <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));
        }
コード例 #21
0
        /// <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));
        }
コード例 #22
0
        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)}.");
        }
コード例 #23
0
        /// <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));
        }
コード例 #24
0
        /// <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);
        }
コード例 #25
0
        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);
        }