Exemplo n.º 1
1
 static async void DoItLogging()
 {
     var middleware = new HttpEventCollectorResendMiddleware(100);
     var ecSender = new HttpEventCollectorSender(new Uri("https://localhost:8088"),
         "3E712E99-63C5-4C5A-841D-592DD070DA51",
         null,
         HttpEventCollectorSender.SendMode.Sequential,
         0,
         0,
         0,
         middleware.Plugin
     );
     ecSender.OnError += o => Console.WriteLine(o.Message);
     ecSender.Send(Guid.NewGuid().ToString(), "INFO", null, new { Foo = "Bar" });
     dynamic obj = new JObject();
     obj.Bar = "Baz";
     ecSender.Send(Guid.NewGuid().ToString(), "INFO", null, (JObject)obj);
     await ecSender.FlushAsync();
 }
        public void HttpEventCollectorBatchingSizeTest()
        {
            // estimate serialized event size
            HttpEventCollectorEventInfo ei =
                new HttpEventCollectorEventInfo(null, TraceEventType.Information.ToString(), "info ?", null, null);
            int size = HttpEventCollectorSender.SerializeEventInfo(ei).Length;

            var trace = Trace(
                handler: (token, events) =>
            {
                Assert.True(events.Count == 4);
                Assert.True(events[0].Event.Message == "info 1");
                Assert.True(events[1].Event.Message == "info 2");
                Assert.True(events[2].Event.Message == "info 3");
                Assert.True(events[3].Event.Message == "info 4");
                return(new Response());
            },
                batchSizeBytes: 4 * size - size / 2 // 4 events trigger post
                );

            trace.TraceInformation("info 1");
            trace.TraceInformation("info 2");
            trace.TraceInformation("info 3");
            trace.TraceInformation("info 4");

            trace.TraceInformation("info 1");
            trace.TraceInformation("info 2");
            trace.TraceInformation("info 3");
            trace.TraceInformation("info 4");

            trace.Close();
        }
 /// <summary>
 /// Callback that should be used as middleware in HttpEventCollectorSender
 /// </summary>
 /// <param name="request"></param>
 /// <param name="next"></param>
 /// <returns></returns>
 public async Task<HttpResponseMessage> Plugin(
     string token, 
     List<HttpEventCollectorEventInfo> events, 
     HttpEventCollectorSender.HttpEventCollectorHandler next)
 {          
     HttpResponseMessage response = null;
     HttpStatusCode statusCode = HttpStatusCode.OK;
     Exception webException = null;
     string serverReply = null;
     int retryDelay = 1000; // start with 1 second
     // retry sending data until success
     for (int retriesCount = 0; retriesCount <= retriesOnError; retriesCount++)
     {
         try
         {
             response = await next(token, events);
             statusCode = response.StatusCode;
             if (statusCode == HttpStatusCode.OK)
             {
                 // the data has been sent successfully
                 webException = null;
                 break;
             }
             else if (Array.IndexOf(HttpEventCollectorApplicationErrors, statusCode) >= 0)
             {
                 // HTTP event collector application error detected - resend wouldn't help
                 // in this case. Record server reply and break.
                 if (response.Content != null)
                 {
                     serverReply = await response.Content.ReadAsStringAsync();
                 }
                 break;
             }
             else
             {
                 // retry
             }
         }
         catch (Exception e)
         {
             // connectivity problem - record exception and retry
             webException = e;
         }
         // wait before next retry
         await Task.Delay(retryDelay);
         // increase delay exponentially
         retryDelay = Math.Min(RetryDelayCeiling, retryDelay * 2);
     }
     if (statusCode != HttpStatusCode.OK || webException != null)
     {
         throw new HttpEventCollectorException(
             code: statusCode,
             webException: webException,
             reply: serverReply,
             response: response
         );
     }
     return response;
 }
 /// <summary>
 /// HttpEventCollectorEventSink c-or with middleware parameter.
 /// </summary>
 /// <param name="uri">Splunk server uri, for example https://localhost:8088.</param>
 /// <param name="token">HTTP event collector authorization token.</param>
 /// <param name="formatter">Event formatter converting EventEntry instance into a string.</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">MNax number of individual events in batch.</param>
 /// <param name="middleware">
 /// HTTP client middleware. This allows to plug an HttpClient handler that
 /// intercepts logging HTTP traffic.
 /// </param>
 public HttpEventCollectorSink(
     Uri uri, string token,
     IEventTextFormatter formatter,
     HttpEventCollectorEventInfo.Metadata metadata = null,
     HttpEventCollectorSender.SendMode sendMode    = HttpEventCollectorSender.SendMode.Sequential,
     int batchInterval  = HttpEventCollectorSender.DefaultBatchInterval,
     int batchSizeBytes = HttpEventCollectorSender.DefaultBatchSize,
     int batchSizeCount = HttpEventCollectorSender.DefaultBatchCount,
     HttpEventCollectorSender.HttpEventCollectorMiddleware middleware = null)
 {
     this.formatter = formatter;
     sender         = new HttpEventCollectorSender(
         uri, token, metadata,
         sendMode,
         batchInterval, batchSizeBytes, batchSizeCount,
         middleware);
 }
        public void HttpEventCollectorSenderMetadataOverrideTest()
        {
            Func <String, List <HttpEventCollectorEventInfo>, Response> noopHandler = (token, events) =>
            {
                return(new Response());
            };

            HttpEventCollectorEventInfo.Metadata defaultmetadata = new HttpEventCollectorEventInfo.Metadata(index: "defaulttestindex",
                                                                                                            source: "defaulttestsource", sourceType: "defaulttestsourcetype", host: "defaulttesthost");

            HttpEventCollectorEventInfo.Metadata overridemetadata = new HttpEventCollectorEventInfo.Metadata(index: "overridetestindex",
                                                                                                             source: "overridetestsource", sourceType: "overridetestsourcetype", host: "overridetesthost");

            HttpEventCollectorSender httpEventCollectorSender =
                new HttpEventCollectorSender(uri, "TOKEN-GUID",
                                             defaultmetadata,
                                             HttpEventCollectorSender.SendMode.Sequential,
                                             100000,
                                             100000,
                                             3,
                                             new HttpEventCollectorSender.HttpEventCollectorMiddleware((token, events, next) => {
                Assert.True(events.Count == 3);

                // Id = id1 should have the default meta data values.
                Assert.True(events[0].Event.Id == "id1");
                Assert.True(events[0].Index == defaultmetadata.Index);
                Assert.True(events[0].Source == defaultmetadata.Source);
                Assert.True(events[0].SourceType == defaultmetadata.SourceType);
                Assert.True(events[0].Host == defaultmetadata.Host);

                // Id = id2 should have the metadataOverride values.
                Assert.True(events[1].Event.Id == "id2");
                Assert.True(events[1].Index == overridemetadata.Index);
                Assert.True(events[1].Source == overridemetadata.Source);
                Assert.True(events[1].SourceType == overridemetadata.SourceType);
                Assert.True(events[1].Host == overridemetadata.Host);

                // Id = id3 should have the default meta data values.
                Assert.True(events[2].Event.Id == "id3");
                Assert.True(events[2].Index == defaultmetadata.Index);
                Assert.True(events[2].Source == defaultmetadata.Source);
                Assert.True(events[2].SourceType == defaultmetadata.SourceType);
                Assert.True(events[2].Host == defaultmetadata.Host);

                Response response = noopHandler(token, events);
                HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
                httpResponseMessage.StatusCode          = response.Code;
                byte[] buf = Encoding.UTF8.GetBytes(response.Context);
                httpResponseMessage.Content = new StringContent(response.Context);
                var task = new Task <HttpResponseMessage>(() => {
                    return(httpResponseMessage);
                });
                task.RunSynchronously();
                return(task);
            })
                                             );

            httpEventCollectorSender.Send(id: "id1");
            httpEventCollectorSender.Send(id: "id2", metadataOverride: overridemetadata);
            httpEventCollectorSender.Send(id: "id3");

            httpEventCollectorSender.FlushSync();
            httpEventCollectorSender.Dispose();
        }
 /// <summary>
 /// HttpEventCollectorTraceListener c-or. Instantiates HttpEventCollectorTraceListener 
 /// when retriesOnError parameter is specified.
 /// </summary>
 /// <param name="uri">Splunk server uri, for example https://localhost:8089.</param>
 /// <param name="token">HTTP event collector authorization token.</param>
 /// <param name="retriesOnError">Number of retries when network problem is detected</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">MNax number of individual events in batch.</param>        
 public HttpEventCollectorTraceListener(
     Uri uri, string token,
     int retriesOnError,
     HttpEventCollectorEventInfo.Metadata metadata = null,
     HttpEventCollectorSender.SendMode sendMode = HttpEventCollectorSender.SendMode.Sequential,
     int batchInterval = HttpEventCollectorSender.DefaultBatchInterval,
     int batchSizeBytes = HttpEventCollectorSender.DefaultBatchSize,
     int batchSizeCount = HttpEventCollectorSender.DefaultBatchCount)
     : this(uri, token, metadata, 
            sendMode,
            batchInterval, batchSizeBytes, batchSizeCount,
            (new HttpEventCollectorResendMiddleware(retriesOnError)).Plugin)
 {
 }
 /// <summary>
 /// HttpEventCollectorTraceListener c-or.
 /// </summary>
 /// <param name="uri">Splunk server uri, for example https://localhost:8089.</param>
 /// <param name="token">HTTP event collector authorization token.</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">MNax number of individual events in batch.</param>
 /// <param name="middleware">
 /// HTTP client middleware. This allows to plug an HttpClient handler that 
 /// intercepts logging HTTP traffic.
 /// </param>
 public HttpEventCollectorTraceListener(
     Uri uri, string token,
     HttpEventCollectorEventInfo.Metadata metadata = null,
     HttpEventCollectorSender.SendMode sendMode = HttpEventCollectorSender.SendMode.Sequential,
     int batchInterval = HttpEventCollectorSender.DefaultBatchInterval,
     int batchSizeBytes = HttpEventCollectorSender.DefaultBatchSize,
     int batchSizeCount = HttpEventCollectorSender.DefaultBatchCount,
     HttpEventCollectorSender.HttpEventCollectorMiddleware middleware = null)
 {
     sender = new HttpEventCollectorSender(
         uri, token, metadata,
         sendMode,
         batchInterval, batchSizeBytes, batchSizeCount,
         middleware);
 }
        private SinkTrace TraceSource(
            RequestHandler handler,
            HttpEventCollectorEventInfo.Metadata metadata = null,
            HttpEventCollectorSender.SendMode sendMode = HttpEventCollectorSender.SendMode.Parallel,
            int batchInterval = 0,
            int batchSizeBytes = 0,
            int batchSizeCount = 0,
            HttpEventCollectorSender.HttpEventCollectorMiddleware middleware = null)
        {
            var listener = new ObservableEventListener();
            var sink = new HttpEventCollectorSink(
                 uri: uri,
                 token: token,
                 formatter: new TestEventFormatter(),
                 metadata: metadata,
                 sendMode: sendMode,
                 batchInterval: batchInterval,
                 batchSizeBytes: batchSizeBytes,
                 batchSizeCount: batchSizeCount,
                 middleware: MiddlewareInterceptor(handler, middleware));
            listener.Subscribe(sink);

            var eventSource = TestEventSource.GetInstance();
            listener.EnableEvents(eventSource, EventLevel.LogAlways, Keywords.All);
            return new SinkTrace() {
                Source = eventSource,
                Sink = sink,
                Listener = listener
            };
        }
 // Input trace listener
 private TraceSource Trace(
     RequestHandler handler, 
     HttpEventCollectorEventInfo.Metadata metadata = null,
     int batchInterval = 0, 
     int batchSizeBytes = 0, 
     int batchSizeCount = 0,
     HttpEventCollectorSender.SendMode sendMode = HttpEventCollectorSender.SendMode.Parallel,
     HttpEventCollectorSender.HttpEventCollectorMiddleware middleware = null)
 {
     var trace = new TraceSource("HttpEventCollectorLogger");
     trace.Switch.Level = SourceLevels.All;
     trace.Listeners.Add(
         new HttpEventCollectorTraceListener(
             uri: uri,
             token: token,
             metadata: metadata,
             sendMode: sendMode,
             batchInterval: batchInterval,
             batchSizeBytes: batchSizeBytes,
             batchSizeCount: batchSizeCount,
             middleware: MiddlewareInterceptor(handler, middleware))
     );
     return trace;
 }
 // we inject this method into HTTP event collector middleware chain to mimic a Splunk
 // server
 private HttpEventCollectorSender.HttpEventCollectorMiddleware MiddlewareInterceptor(
     RequestHandler handler,
     HttpEventCollectorSender.HttpEventCollectorMiddleware middleware)
 {
     HttpEventCollectorSender.HttpEventCollectorMiddleware interceptor =
     (string token, List<HttpEventCollectorEventInfo> events, HttpEventCollectorSender.HttpEventCollectorHandler next) =>
     {
         Response response = handler(token, events);
         HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
         httpResponseMessage.StatusCode = response.Code;
         byte[] buf = Encoding.UTF8.GetBytes(response.Context);
         httpResponseMessage.Content = new StringContent(response.Context);
         var task = new Task<HttpResponseMessage>(() => {
             return httpResponseMessage;
         });
         task.RunSynchronously();
         return task;
     };
     if (middleware != null)
     {
         // chain middleware to interceptor
         var temp = interceptor;
         interceptor = (token, events, next) =>
         {
             return middleware(token, events, (t, e) =>
             {
                 return temp(t, e, next);
             });
         };
     }
     return interceptor;
 }