public static IApiRequestFactory Get(ImmutableExporterSettings settings)
        {
            var strategy = settings.TracesTransport;

            switch (strategy)
            {
            case TracesTransportType.CustomTcpProvider:
                Log.Information("Using {FactoryType} for trace transport.", nameof(TcpStreamFactory));
                return(new HttpStreamRequestFactory(new TcpStreamFactory(settings.AgentUri.Host, settings.AgentUri.Port), DatadogHttpClient.CreateTraceAgentClient()));

            case TracesTransportType.WindowsNamedPipe:
                Log.Information <string, string, int>("Using {FactoryType} for trace transport, with pipe name {PipeName} and timeout {Timeout}ms.", nameof(NamedPipeClientStreamFactory), settings.TracesPipeName, settings.TracesPipeTimeoutMs);
                return(new HttpStreamRequestFactory(new NamedPipeClientStreamFactory(settings.TracesPipeName, settings.TracesPipeTimeoutMs), DatadogHttpClient.CreateTraceAgentClient()));

            case TracesTransportType.UnixDomainSocket:
#if NETCOREAPP3_1_OR_GREATER
                Log.Information <string, string, int>("Using {FactoryType} for trace transport, with Unix Domain Sockets path {Path} and timeout {Timeout}ms.", nameof(UnixDomainSocketStreamFactory), settings.TracesUnixDomainSocketPath, settings.TracesPipeTimeoutMs);
                return(new HttpStreamRequestFactory(new UnixDomainSocketStreamFactory(settings.TracesUnixDomainSocketPath), DatadogHttpClient.CreateTraceAgentClient()));
#else
                Log.Error("Using Unix Domain Sockets for trace transport is only supported on .NET Core 3.1 and greater. Falling back to default transport.");
                goto case TracesTransportType.Default;
#endif
            case TracesTransportType.Default:
            default:
#if NETCOREAPP
                Log.Information("Using {FactoryType} for trace transport.", nameof(HttpClientRequestFactory));
                return(new HttpClientRequestFactory(AgentHttpHeaderNames.DefaultHeaders));
#else
                Log.Information("Using {FactoryType} for trace transport.", nameof(ApiWebRequestFactory));
                return(new ApiWebRequestFactory(AgentHttpHeaderNames.DefaultHeaders));
#endif
            }
        }
 public static ITelemetryTransport Create(
     TelemetrySettings telemetrySettings,
     ImmutableExporterSettings exporterSettings)
 {
     var requestFactory = telemetrySettings switch
     {
         { Agentless : { } a } => TelemetryTransportStrategy.GetDirectIntakeFactory(a.AgentlessUri, a.ApiKey),
        private static void DisplayInfoMessage(ImmutableExporterSettings settings)
        {
            string transport;
            string endpoint;

            if (settings.TracesTransport == TracesTransportType.UnixDomainSocket)
            {
                transport = "domain sockets";
                endpoint  = settings.TracesUnixDomainSocketPath;
            }
            else
            {
                transport = "HTTP";
                endpoint  = settings.AgentUri.ToString();
            }

            AnsiConsole.WriteLine(ConnectToEndpointFormat(endpoint, transport));
        }
        public static async Task <bool> RunAsync(ImmutableExporterSettings settings)
        {
            var payload = Vendors.MessagePack.MessagePackSerializer.Serialize(Array.Empty <Span[]>());

            var requestFactory = TracesTransportStrategy.Get(settings);

            DisplayInfoMessage(settings);

            var request = requestFactory.Create(new Uri(settings.AgentUri, "/v0.4/traces"));

            var content = new ByteArrayContent(payload);

            content.Headers.ContentType = new MediaTypeHeaderValue("application/msgpack");

            try
            {
                var response = await request.PostAsync(new ArraySegment <byte>(payload), "application/msgpack").ConfigureAwait(false);

                if (response.StatusCode != 200)
                {
                    Utils.WriteError(WrongStatusCodeFormat((HttpStatusCode)response.StatusCode));
                    return(false);
                }

                var versionHeader = response.GetHeader("Datadog-Agent-Version");

                if (versionHeader != null)
                {
                    AnsiConsole.WriteLine(DetectedAgentVersionFormat(versionHeader));
                }
                else
                {
                    Utils.WriteWarning(AgentDetectionFailed);
                }
            }
            catch (Exception ex)
            {
                Utils.WriteError(ErrorDetectingAgent(settings.AgentUri.ToString(), ex.Message));
                return(false);
            }

            return(true);
        }
        public void AllPropertyValuesMatch()
        {
            var equalityCheckers = new List <Func <ExporterSettings, ImmutableExporterSettings, bool> >()
            {
                (e, i) => e.MetricsPipeName == i.MetricsPipeName,
                (e, i) => e.TracesPipeName == i.TracesPipeName,
                (e, i) => e.DogStatsdPort == i.DogStatsdPort,
                (e, i) => e.MetricsTransport == i.MetricsTransport,
                (e, i) => e.TracesTransport == i.TracesTransport,
                (e, i) => e.TracesPipeTimeoutMs == i.TracesPipeTimeoutMs,
                (e, i) => e.AgentUri == i.AgentUri,
                (e, i) => e.PartialFlushEnabled == i.PartialFlushEnabled,
                (e, i) => e.PartialFlushMinSpans == i.PartialFlushMinSpans,
                (e, i) => e.MetricsUnixDomainSocketPath == i.MetricsUnixDomainSocketPath,
                (e, i) => e.TracesUnixDomainSocketPath == i.TracesUnixDomainSocketPath,
            };

            var mutableProperties = typeof(ExporterSettings)
                                    .GetProperties(Flags);

            // Ensure that all properties are represented
            Assert.Equal(mutableProperties.Count(), equalityCheckers.Count);

            var exporterSettings = new ExporterSettings();

            exporterSettings.MetricsUnixDomainSocketPath = "metricsuds";
            exporterSettings.TracesUnixDomainSocketPath  = "tracesuds";
            exporterSettings.MetricsPipeName             = "metricspipe";
            exporterSettings.TracesPipeName      = "tracespipe";
            exporterSettings.DogStatsdPort       = 1234;
            exporterSettings.MetricsTransport    = Vendors.StatsdClient.Transport.TransportType.NamedPipe;
            exporterSettings.TracesTransport     = TracesTransportType.WindowsNamedPipe;
            exporterSettings.TracesPipeTimeoutMs = 5556;
            exporterSettings.AgentUri            = new Uri("http://localhost:8282");

            var immutableSettings = new ImmutableExporterSettings(exporterSettings);

            foreach (var equalityCheck in equalityCheckers)
            {
                Assert.True(equalityCheck(exporterSettings, immutableSettings));
            }
        }
        public static IApiRequestFactory Get(ImmutableExporterSettings settings)
        {
            var strategy = settings.TracesTransport;

            switch (strategy)
            {
            case TracesTransportType.WindowsNamedPipe:
                Log.Information <string, string, int>("Using {FactoryType} for trace transport, with pipe name {PipeName} and timeout {Timeout}ms.", nameof(NamedPipeClientStreamFactory), settings.TracesPipeName, settings.TracesPipeTimeoutMs);
                // use http://localhost as base endpoint
                return(new HttpStreamRequestFactory(new NamedPipeClientStreamFactory(settings.TracesPipeName, settings.TracesPipeTimeoutMs), DatadogHttpClient.CreateTraceAgentClient(), new Uri("http://localhost")));

            case TracesTransportType.Default:
            default:
#if NETCOREAPP
                Log.Information("Using {FactoryType} for trace transport.", nameof(HttpClientRequestFactory));
                return(new HttpClientRequestFactory(settings.AgentUri, AgentHttpHeaderNames.DefaultHeaders));
#else
                Log.Information("Using {FactoryType} for trace transport.", nameof(ApiWebRequestFactory));
                return(new ApiWebRequestFactory(settings.AgentUri, AgentHttpHeaderNames.DefaultHeaders));
#endif
            }
        }
    public static IApiRequestFactory GetAgentIntakeFactory(ImmutableExporterSettings settings)
    {
        // use the same transport for telemetry as we do for traces
        var strategy = settings.TracesTransport;

        switch (strategy)
        {
        case TracesTransportType.WindowsNamedPipe:
            Log.Information <string, string, int>("Using {FactoryType} for telemetry transport, with pipe name {PipeName} and timeout {Timeout}ms.", nameof(NamedPipeClientStreamFactory), settings.TracesPipeName, settings.TracesPipeTimeoutMs);
            return(new HttpStreamRequestFactory(new NamedPipeClientStreamFactory(settings.TracesPipeName, settings.TracesPipeTimeoutMs), DatadogHttpClient.CreateTelemetryAgentClient(), GetBaseEndpoint()));

        case TracesTransportType.Default:
        default:
            var agentUri = UriHelpers.Combine(settings.AgentUri, TelemetryConstants.AgentTelemetryEndpoint);
#if NETCOREAPP
            Log.Information("Using {FactoryType} for telemetry transport.", nameof(HttpClientRequestFactory));
            return(new HttpClientRequestFactory(agentUri, TelemetryHttpHeaderNames.GetDefaultAgentHeaders(), timeout: Timeout));
#else
            Log.Information("Using {FactoryType} for telemetry transport.", nameof(ApiWebRequestFactory));
            return(new ApiWebRequestFactory(agentUri, TelemetryHttpHeaderNames.GetDefaultAgentHeaders(), timeout: Timeout));
#endif
        }