/// <summary> /// Initializes a new instance of the <see cref="HttpEventCollectorSender"/> class. /// </summary> /// <param name="uri">Splunk server uri, for example https://localhost:8088.</param> /// <param name="token">HTTP event collector authorization token.</param> /// <param name="channel">HTTP event collector data channel.</param> /// <param name="metadata">Logger metadata.</param> /// <param name="sendMode">Send mode of the events.</param> /// <param name="batchInterval">Batch interval in milliseconds.</param> /// <param name="batchSizeBytes">Batch max size.</param> /// <param name="batchSizeCount">Max number of individual events in batch.</param> /// <param name="ignoreSslErrors">Server validation callback should always return true</param> /// <param name="useProxy">Default web proxy is used if set to true; otherwise, no proxy is used</param> /// <param name="middleware">HTTP client middleware. This allows to plug an HttpClient handler that /// intercepts logging HTTP traffic.</param> /// <param name="formatter">The formatter.</param> /// <remarks> /// Zero values for the batching params mean that batching is off. /// </remarks> public HttpEventCollectorSender( Uri uri, string token, string channel, HttpEventCollectorEventInfo.Metadata metadata, SendMode sendMode, int batchInterval, int batchSizeBytes, int batchSizeCount, bool ignoreSslErrors, ProxyConfiguration proxy, int maxConnectionsPerServer, HttpEventCollectorMiddleware middleware, HttpEventCollectorFormatter formatter = null, bool httpVersion10Hack = false) { NLog.Common.InternalLogger.Debug("Initializing Splunk HttpEventCollectorSender"); this.httpEventCollectorEndpointUri = new Uri(uri, HttpEventCollectorPath); this.jsonSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; this.jsonSerializerSettings.Formatting = Formatting.None; this.jsonSerializerSettings.Converters = new[] { new Newtonsoft.Json.Converters.StringEnumConverter() }; this.jsonSerializer = JsonSerializer.CreateDefault(this.jsonSerializerSettings); this.sendMode = sendMode; this.batchInterval = batchInterval; this.batchSizeBytes = batchSizeBytes; this.batchSizeCount = batchSizeCount; this.metadata = metadata; this.token = token; this.channel = channel; this.middleware = middleware; this.formatter = formatter; this.applyHttpVersion10Hack = httpVersion10Hack; // special case - if batch interval is specified without size and count // they are set to "infinity", i.e., batch may have any size if (this.batchInterval > 0 && this.batchSizeBytes == 0 && this.batchSizeCount == 0) { this.batchSizeBytes = this.batchSizeCount = int.MaxValue; } // when size configuration setting is missing it's treated as "infinity", // i.e., any value is accepted. if (this.batchSizeCount == 0 && this.batchSizeBytes > 0) { this.batchSizeCount = int.MaxValue; } else if (this.batchSizeBytes == 0 && this.batchSizeCount > 0) { this.batchSizeBytes = int.MaxValue; } // setup the timer if (batchInterval != 0) // 0 means - no timer { timer = new Timer(OnTimer, null, batchInterval, batchInterval); } // setup HTTP client try { var httpMessageHandler = BuildHttpMessageHandler(ignoreSslErrors, proxy, maxConnectionsPerServer); httpClient = new HttpClient(httpMessageHandler); } catch { // Fallback on PlatformNotSupported and other funny exceptions httpClient = new HttpClient(); } // setup splunk header token httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AuthorizationHeaderScheme, token); if (this.applyHttpVersion10Hack) { httpClient.BaseAddress = uri; httpClient.DefaultRequestHeaders.ConnectionClose = false; httpClient.DefaultRequestHeaders.Add("Connection", "keep-alive"); } // setup splunk channel request header if (!string.IsNullOrWhiteSpace(channel)) { httpClient.DefaultRequestHeaders.Add(ChannelRequestHeaderName, channel); } }
/// <summary> /// Builds the HTTP message handler. /// </summary> /// <param name="ignoreSslErrors">if set to <c>true</c> [ignore SSL errors].</param> /// <param name="maxConnectionsPerServer"></param> /// <param name="proxyConfig"></param> /// <returns></returns> private HttpMessageHandler BuildHttpMessageHandler(bool ignoreSslErrors, int maxConnectionsPerServer, ProxyConfiguration proxyConfig) { #if NET45 || NET462 // Uses the WebRequestHandler for .NET 4.5 - 4.7.0 var httpMessageHandler = new WebRequestHandler(); if (ignoreSslErrors) { httpMessageHandler.ServerCertificateValidationCallback = IgnoreServerCertificateCallback; } #else // Uses the new and improved HttpClientHandler() for .NET 4.7.1+ and .NET Standard 2.0+ var httpMessageHandler = new HttpClientHandler(); if (ignoreSslErrors) { httpMessageHandler.ServerCertificateCustomValidationCallback = (msg, cert, chain, errors) => IgnoreServerCertificateCallback(msg, cert, chain, errors); } if (maxConnectionsPerServer > 0) { httpMessageHandler.MaxConnectionsPerServer = maxConnectionsPerServer; } #endif // Setup proxy httpMessageHandler.UseProxy = proxyConfig.UseProxy; if (proxyConfig.UseProxy && !string.IsNullOrWhiteSpace(proxyConfig.ProxyUrl)) { httpMessageHandler.Proxy = new WebProxy(new Uri(proxyConfig.ProxyUrl)); if (!String.IsNullOrWhiteSpace(proxyConfig.ProxyUser) && !String.IsNullOrWhiteSpace(proxyConfig.ProxyPassword)) { httpMessageHandler.Proxy.Credentials = new NetworkCredential(proxyConfig.ProxyUser, proxyConfig.ProxyPassword); } } return(httpMessageHandler); }