예제 #1
0
        public void WhenConcurrentEventsRaised()
        {
            var logger = MockEventSourceOutProc.Logger;
            EventTextFormatter  formatter = new EventTextFormatter();
            EventSourceSettings settings  = new EventSourceSettings("MockEventSourceOutProc", null, EventLevel.LogAlways);
            InMemorySink        sink      = new InMemorySink(formatter);

            SinkSettings sinkSettings = new SinkSettings("memorySink", sink, new List <EventSourceSettings>()
            {
                { settings }
            });
            List <SinkSettings> sinks = new List <SinkSettings>()
            {
                { sinkSettings }
            };
            TraceEventServiceConfiguration svcConfiguration = new TraceEventServiceConfiguration(sinks);

            TestScenario.WithConfiguration(
                svcConfiguration,
                () =>
            {
                sink.WaitSignalCondition = () => sink.EventWrittenCount == 100;
                for (int n = 0; n < 100; n++)
                {
                    logger.LogSomeMessage("some message" + n.ToString());
                }

                sink.WaitOnAsyncEvents.WaitOne(TimeSpan.FromSeconds(10));
            });

            StringAssert.Contains(sink.ToString(), "some message99");
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TestApiServer"/> class.
        /// </summary>
        /// <param name="logSink">The Serilog destination logging sink.</param>
        /// <param name="configureServices">The action to populate the required services in the current hosted test server.</param>
        /// <param name="outputWriter">The logger instance to write log messages during the lifetime of the test server.</param>
        /// <exception cref="ArgumentNullException">When the <paramref name="logSink"/> is <c>null</c>.</exception>
        public TestApiServer(InMemorySink logSink, Action <IServiceCollection> configureServices, ITestOutputHelper outputWriter)
        {
            Guard.NotNull(logSink, nameof(logSink), "Requires a log sink to write the log messages to");

            _configureServices = new Collection <Action <IServiceCollection> > {
                services => services.AddSingleton(logSink)
            };
            _filterActions           = new Collection <Action <FilterCollection> >();
            _configures              = new Collection <Action <IApplicationBuilder> >();
            _configurationCollection = new Dictionary <string, string>();

            if (configureServices != null)
            {
                _configureServices.Add(configureServices);
            }

            if (outputWriter is null)
            {
                _logger = NullLogger.Instance;
            }
            else
            {
                _logger = new XunitTestLogger(outputWriter);
            }

            LogSink = logSink;
        }
        public async Task SharedAccessKeyAuthorizedRoute_DoesntEmitSecurityEventsByDefault_RunsAuthentication()
        {
            // Arrange
            var spySink = new InMemorySink();
            var options = new TestApiServerOptions()
                          .ConfigureServices(services => services.AddSecretStore(stores => stores.AddInMemory(SecretName, $"secret-{Guid.NewGuid()}")))
                          .ConfigureHost(host => host.UseSerilog((context, config) =>
                                                                 config.WriteTo.Sink(spySink)));

            await using (var server = await TestApiServer.StartNewAsync(options, _logger))
            {
                var request = HttpRequestBuilder.Get(SharedAccessKeyAuthenticationController.AuthorizedGetRoute);

                // Act
                using (HttpResponseMessage response = await server.SendAsync(request))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                    IEnumerable <LogEvent> logEvents = spySink.DequeueLogEvents();
                    Assert.DoesNotContain(logEvents, logEvent =>
                    {
                        string message = logEvent.RenderMessage();
                        return(message.Contains("EventType") && message.Contains("Security"));
                    });
                }
            }
        }
        public async Task SharedAccessKeyAuthorizedRoute_EmitsSecurityEventsWhenRequested_RunsAuthentication(bool emitsSecurityEvents)
        {
            // Arrange
            var spySink = new InMemorySink();
            var options = new TestApiServerOptions()
                          .ConfigureServices(services =>
            {
                services.AddSecretStore(stores => stores.AddInMemory(SecretName, $"secret-{Guid.NewGuid()}"))
                .AddMvc(opt => opt.Filters.AddSharedAccessKeyAuthenticationOnHeader(HeaderName, SecretName, authOptions =>
                {
                    authOptions.EmitSecurityEvents = emitsSecurityEvents;
                }));
            })
                          .ConfigureHost(host => host.UseSerilog((context, config) =>
                                                                 config.WriteTo.Sink(spySink)));

            await using (var server = await TestApiServer.StartNewAsync(options, _logger))
            {
                var request = HttpRequestBuilder.Get(HealthController.GetRoute);

                // Act
                using (HttpResponseMessage response = await server.SendAsync(request))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                    IEnumerable <LogEvent> logEvents = spySink.DequeueLogEvents();
                    Assert.True(emitsSecurityEvents == logEvents.Any(logEvent =>
                    {
                        string message = logEvent.RenderMessage();
                        return(message.Contains("EventType") && message.Contains("Security"));
                    }));
                }
            }
        }
예제 #5
0
        public void WhenNoLoggerIsSpecified_LoggingShouldGoToAutodiscoveredLogger()
        {
            var defaultLogger = Serilog.Log.Logger;

            try
            {
                var capturedLogs = new InMemorySink();
                Serilog.Log.Logger = new Serilog.LoggerConfiguration()
                                     .WriteTo.Sink(capturedLogs)
                                     .CreateLogger();

                var engine = DeployChanges.To
                             .SQLiteDatabase("Data Source=:memory:")
                             .WithScript(new SqlScript("1234", "SELECT 1"))
                             .JournalTo(new NullJournal())
                             .Build();

                var result = engine.PerformUpgrade();
                result.Successful.ShouldBe(true);
                capturedLogs.Events.ShouldContain(e => e.MessageTemplate.Text == "Executing Database Server script '{0}'");
            }
            finally
            {
                Serilog.Log.Logger = defaultLogger;
            }
        }
        public async Task SendRequest_WithSerilogCorrelationEnrichment_ReturnsOkWithEnrichedCorrelationLogProperties()
        {
            // Arrange
            var spySink = new InMemorySink();
            var options = new TestApiServerOptions()
                          .ConfigureServices(services => services.AddHttpCorrelation())
                          .PreConfigure(app => app.UseHttpCorrelation())
                          .ConfigureHost(host => host.UseSerilog((context, serviceProvider, config) =>
                                                                 config.Enrich.WithHttpCorrelationInfo(serviceProvider)
                                                                 .WriteTo.Sink(spySink)));

            await using (var server = await TestApiServer.StartNewAsync(options, _logger))
            {
                var request = HttpRequestBuilder.Get(CorrelationController.GetRoute);

                // Act
                using (HttpResponseMessage response = await server.SendAsync(request))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    CorrelationInfo correlationInfo = await AssertAppCorrelationInfoAsync(response);

                    AssertLoggedCorrelationProperties(spySink, correlationInfo);
                }
            }
        }
        public async Task JwtAuthorizedRoute_EmitSecurityEventsWhenRequested_RunsAuthorization(bool emitSecurityEvents)
        {
            // Arrange
            var spySink = new InMemorySink();
            var options = new TestApiServerOptions()
                          .ConfigureServices(services =>
            {
                services.AddMvc(opt => opt.Filters.AddJwtTokenAuthorization(jwt => jwt.EmitSecurityEvents = emitSecurityEvents));
            })
                          .ConfigureHost(host => host.UseSerilog((context, config) => config.WriteTo.Sink(spySink)));

            await using (var server = await TestApiServer.StartNewAsync(options, _logger))
            {
                string accessToken = $"Bearer {_bogusGenerator.Random.AlphaNumeric(10)}.{_bogusGenerator.Random.AlphaNumeric(50)}";
                var    request     = HttpRequestBuilder
                                     .Get(HealthController.GetRoute)
                                     .WithHeader(JwtTokenAuthorizationOptions.DefaultHeaderName, accessToken);

                // Act
                using (HttpResponseMessage response = await server.SendAsync(request))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                    IEnumerable <LogEvent> logEvents = spySink.DequeueLogEvents();
                    Assert.True(emitSecurityEvents == logEvents.Any(logEvent =>
                    {
                        string message = logEvent.RenderMessage();
                        return(message.Contains("EventType") && message.Contains("Security"));
                    }));
                }
            }
        }
        public void WhenConcurrentEventsRaised()
        {
            var logger = MockEventSourceOutProc.Logger;
            EventTextFormatter formatter = new EventTextFormatter();
            EventSourceSettings settings = new EventSourceSettings("MockEventSourceOutProc", null, EventLevel.LogAlways);
            InMemorySink sink = new InMemorySink(formatter);

            SinkSettings sinkSettings = new SinkSettings("memorySink", sink, new List<EventSourceSettings>() { { settings } });
            List<SinkSettings> sinks = new List<SinkSettings>() { { sinkSettings } };
            TraceEventServiceConfiguration svcConfiguration = new TraceEventServiceConfiguration(sinks);
            TestScenario.WithConfiguration(
                svcConfiguration,
                () =>
                {
                    sink.WaitSignalCondition = () => sink.EventWrittenCount == 100;
                    for (int n = 0; n < 100; n++)
                    {
                        logger.LogSomeMessage("some message" + n.ToString());
                    }

                    sink.WaitOnAsyncEvents.WaitOne(TimeSpan.FromSeconds(10));
                });

            StringAssert.Contains(sink.ToString(), "some message99");
        }
예제 #9
0
        internal void OnEtlFileReadStart(string fileName, bool isActiveEtl, string currentBookmark)
        {
            // Trace file subfolder to write bookmarks to
            this.traceFileSubFolder = this.GetTraceFileSubFolder(fileName);

            // Reset the last event index
            this.lastEventIndex.Set(DateTime.MinValue, -1);

            // Get the index up to which we have already processed.
            this.maxIndexAlreadyProcessed = this.GetMaxIndexAlreadyProcessed(this.traceFileSubFolder);

            // Create a new in-memory sink.
            this.inMemorySink = new InMemorySink(
                this.TraceSource,
                this.LogSourceId,
                this.traceFileSubFolder,
                this.inMemoryConsumer.ConsumerProcessTraceEventAction);

            // Signal start of processing to consumer
            this.inMemoryConsumer.OnProcessingPeriodStart(fileName, isActiveEtl, this.traceFileSubFolder);

            this.TraceSource.WriteInfo(
                this.LogSourceId,
                "Filtered traces from {0} will be written to an in-memory buffer.",
                fileName);
        }
예제 #10
0
        public void WhenWriting_WriteToMemory()
        {
            var sink = new InMemorySink(new CompactKeyValueFormatter(), () => new DefaultDataRenderer())
            {
                AppendNewLine = false
            };

            sink.Write(GenericLogLevelName.Debug, GenericLogEntries);

            Assert.Equal(GenericLogText, sink.GetLogs().Substring(30));
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TestApiServer"/> class.
        /// </summary>
        /// <param name="logSink">The Serilog destination logging sink.</param>
        /// <param name="configureServices">The action to populate the required services in the current hosted test server.</param>
        /// <exception cref="ArgumentNullException">When the <paramref name="configureServices"/> is <c>null</c>.</exception>
        public TestApiServer(InMemorySink logSink, Action <IServiceCollection> configureServices)
        {
            Guard.NotNull(configureServices, "Configure services cannot be 'null'");

            _configureServices = new Collection <Action <IServiceCollection> > {
                configureServices, services => services.AddSingleton(logSink)
            };
            _filterActions           = new Collection <Action <FilterCollection> >();
            _configures              = new Collection <Action <IApplicationBuilder> >();
            _configurationCollection = new Dictionary <string, string>();

            LogSink = logSink;
        }
예제 #12
0
        public MainWindow()
        {
            InitializeComponent();

            // Setup logging
            var sink = new InMemorySink(tbLog);

            Log.Logger = new LoggerConfiguration()
                         .WriteTo.Sink(sink)
                         .CreateLogger();

            Log.Information("Cirilla v" + Assembly.GetExecutingAssembly().GetName().Version);
            Log.Information("Cirilla.Core v" + Assembly.GetAssembly(typeof(Core.Models.GMD)).GetName().Version);
        }
        private static void AssertLoggedCorrelationProperties(InMemorySink testSink, CorrelationInfo correlationInfo)
        {
            KeyValuePair <string, LogEventPropertyValue>[] properties =
                testSink.DequeueLogEvents()
                .SelectMany(ev => ev.Properties)
                .ToArray();

            Assert.Contains(
                properties.Where(prop => prop.Key == TransactionIdPropertyName),
                prop => correlationInfo.TransactionId == prop.Value.ToStringValue());

            Assert.Contains(
                properties.Where(prop => prop.Key == OperationIdPropertyName),
                prop => correlationInfo.OperationId == prop.Value.ToStringValue());
        }
예제 #14
0
        public async Task SharedAccessKeyAuthorizedRoute_EmitsSecurityEventsWhenRequested_RunsAuthentication(bool emitsSecurityEvents)
        {
            // Arrange
            const string issuerKey = "issuer";
            var          spySink   = new InMemorySink();
            var          options   = new TestApiServerOptions()
                                     .ConfigureServices(services =>
            {
                var certificateValidator =
                    new CertificateAuthenticationValidator(
                        new CertificateAuthenticationConfigBuilder()
                        .WithIssuer(X509ValidationLocation.SecretProvider, issuerKey)
                        .Build());

                services.AddSecretStore(stores => stores.AddInMemory(issuerKey, "CN=issuer"))
                .AddSingleton(certificateValidator)
                .AddMvc(opt => opt.Filters.AddCertificateAuthentication(authOptions =>
                {
                    authOptions.EmitSecurityEvents = emitsSecurityEvents;
                }));
            })
                                     .ConfigureHost(host => host.UseSerilog((context, config) => config.WriteTo.Sink(spySink)));

            await using (var server = await TestApiServer.StartNewAsync(options, _logger))
            {
                var request = HttpRequestBuilder.Get(NoneAuthenticationController.GetRoute);

                // Act
                using (HttpResponseMessage response = await server.SendAsync(request))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                    IEnumerable <LogEvent> logEvents = spySink.DequeueLogEvents();
                    Assert.True(emitsSecurityEvents == logEvents.Any(logEvent =>
                    {
                        string message = logEvent.RenderMessage();
                        return(message.Contains("EventType") && message.Contains("Security"));
                    }));
                }
            }
        }
        private void SetupSeriLog()
        {
            // Create Local Log Directory
            FileIO.CreateDirectory(GetLocalLogDir());


            var testSink  = new InMemorySink();
            var logWindow = new LogWindowSink(richTextBoxLogWindow);

            string fileName = $@"{GetLocalLogDir()}\app-releaser" + "-{Date}.txt";


            Log.Logger = new LoggerConfiguration()
                         .WriteTo.Sink(testSink)
                         .WriteTo.Sink(logWindow)
                         .WriteTo.RollingFile(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level}] {Message}{NewLine}{Exception}", pathFormat: fileName)
                         .CreateLogger();

            Log.Information("Application Starting Up.");
            Log.Information("SeriLog Setup.");
        }
예제 #16
0
        public async Task CertificateAuthorizedRoute_EmitsSecurityEventsWhenRequested_RunsAuthentication()
        {
            // Arrange
            using (X509Certificate2 clientCertificate = SelfSignedCertificate.CreateWithSubject("unrecognized-subject-name"))
            {
                var spySink = new InMemorySink();
                var options = new TestApiServerOptions()
                              .ConfigureServices(services =>
                {
                    var certificateValidator =
                        new CertificateAuthenticationValidator(
                            new CertificateAuthenticationConfigBuilder()
                            .WithSubject(X509ValidationLocation.SecretProvider, SubjectKey)
                            .Build());

                    services.AddSecretStore(stores => stores.AddInMemory(SubjectKey, "CN=subject"))
                    .AddClientCertificate(clientCertificate)
                    .AddSingleton(certificateValidator);
                })
                              .ConfigureHost(host => host.UseSerilog((context, config) => config.WriteTo.Sink(spySink)));

                await using (var server = await TestApiServer.StartNewAsync(options, _logger))
                {
                    var request = HttpRequestBuilder.Get(CertificateAuthenticationOnMethodController.AuthorizedGetRouteEmitSecurityEvents);

                    // Act
                    using (HttpResponseMessage response = await server.SendAsync(request))
                    {
                        // Assert
                        Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
                        IEnumerable <LogEvent> logEvents = spySink.DequeueLogEvents();
                        Assert.Contains(logEvents, logEvent =>
                        {
                            string message = logEvent.RenderMessage();
                            return(message.Contains("EventType") && message.Contains("Security"));
                        });
                    }
                }
            }
        }
예제 #17
0
        public LighthouseViewModel(
            Db db,
            ILogger logger,
            InMemorySink inMemmorySink,
            IWatchBuilds buildsWatcher,
            IControlBuildStatusLight buildStatusLightController,
            IControlSignalLight signalLightController)
        {
            _db           = db;
            _logger       = logger;
            _inMemorySink = inMemmorySink;
            _inMemorySink.Events.CollectionChanged += LogEventsCollectionChangedHandler;
            _buildsWatcher = buildsWatcher;
            _buildStatusLightController = buildStatusLightController;
            _signalLightController      = signalLightController;

            IsRunning          = false;
            ButtonText         = "Start";
            LighthouseSettings = GetSettings();
            SetValidationRules();
            StartStopLighthouse = ReactiveCommand.Create(OnStartStopClick, this.IsValid());
        }
        public async Task SendRequest_WithSerilogCorrelationenrichment_ReturnsOkWithDifferentOperationIdAndSameTransactionId()
        {
            // Arrange
            var spySink = new InMemorySink();
            var options = new TestApiServerOptions()
                          .ConfigureServices(services => services.AddHttpCorrelation())
                          .PreConfigure(app => app.UseHttpCorrelation())
                          .ConfigureHost(host => host.UseSerilog((context, serviceProvider, config) =>
                                                                 config.Enrich.WithHttpCorrelationInfo(serviceProvider)
                                                                 .WriteTo.Sink(spySink)));

            await using (var server = await TestApiServer.StartNewAsync(options, _logger))
            {
                var firstRequest = HttpRequestBuilder.Get(CorrelationController.GetRoute);
                using (HttpResponseMessage firstResponse = await server.SendAsync(firstRequest))
                {
                    // Assert
                    Assert.Equal(HttpStatusCode.OK, firstResponse.StatusCode);
                    CorrelationInfo firstCorrelationInfo = await AssertAppCorrelationInfoAsync(firstResponse);

                    AssertLoggedCorrelationProperties(spySink, firstCorrelationInfo);

                    var secondRequest = HttpRequestBuilder
                                        .Get(CorrelationController.GetRoute)
                                        .WithHeader("X-Transaction-ID", firstCorrelationInfo.TransactionId);

                    using (HttpResponseMessage secondResponse = await server.SendAsync(secondRequest))
                    {
                        Assert.Equal(HttpStatusCode.OK, secondResponse.StatusCode);
                        CorrelationInfo secondCorrelationInfo = await AssertAppCorrelationInfoAsync(secondResponse);

                        AssertLoggedCorrelationProperties(spySink, secondCorrelationInfo);

                        Assert.NotEqual(firstCorrelationInfo.OperationId, secondCorrelationInfo.OperationId);
                        Assert.Equal(firstCorrelationInfo.TransactionId, secondCorrelationInfo.TransactionId);
                    }
                }
            }
        }
예제 #19
0
        public void AssertionShouldNotFailWhenInstanceIsLoggedToAfterInvokingTheAssertion()
        {
            /*
             * This test is meant to verify the behaviour of the assertions
             * when a message is logged to the instance we're asserting on
             * after we invoked the assertion.
             *
             * The behaviour is that when calling Should(), the assertion
             * should (pun intended) capture a snapshot of the log events
             * at the point in time it was invoked.
             *
             * This prevents InvalidOperationExceptions because the internal
             * collection is modified.
             *
             * See https://github.com/sandermvanvliet/SerilogSinksInMemory/issues/16
             */
            var sink = new InMemorySink();

            var logger = new LoggerConfiguration()
                         .WriteTo.Sink(sink)
                         .CreateLogger();

            // Log 2 messages
            logger.Information("Message");
            logger.Information("Message");

            // Start assertion
            var assertion = sink.Should();

            // Pretend another thread/task/fiber logs another message
            logger.Information("Message");

            // Continue with the assertion
            assertion
            .HaveMessage("Message")
            .Appearing().Times(2);
        }
 public static InMemorySinkAssertions Should(this InMemorySink instance)
 {
     return(new InMemorySinkAssertions(instance));
 }