Esempio n. 1
0
        /// <summary>
        /// Writes log events to an <see cref="IRichTextBox"/> control, used only for unit-testing purposes.
        /// </summary>
        /// <param name="sinkConfiguration">Logger sink configuration.</param>
        /// <param name="richTextBox">The RichTextBox control to write to.</param>
        /// <param name="restrictedToMinimumLevel">The minimum level for
        /// events passed through the sink. Ignored when <paramref name="levelSwitch"/> is specified.</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// The default is <code>"[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"</code>.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <param name="levelSwitch">A switch allowing the pass-through minimum level
        /// to be changed at runtime.</param>
        /// <param name="theme">The theme to apply to the styled output. If not specified,
        /// uses <see cref="RichTextBoxConsoleTheme.Literate"/>.</param>
        /// <param name="dispatcherPriority">The priority at which messages will be sent to the UI thread when logging from a non-UI thread.</param>
        /// <param name="syncRoot">An object that will be used to `lock` (sync) access to the <see cref="IRichTextBox"/> instance. If you specify this, you
        /// will have the ability to lock on this object, and guarantee that the RichTextBox sink will not be about to output anything while
        /// the lock is held.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        /// <exception cref="ArgumentNullException">When <paramref name="sinkConfiguration"/> is <code>null</code></exception>
        /// <exception cref="ArgumentNullException">When <paramref name="outputTemplate"/> is <code>null</code></exception>
        internal static LoggerConfiguration RichTextBox(
            this LoggerSinkConfiguration sinkConfiguration,
            IRichTextBox richTextBox,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            string outputTemplate                 = _defaultRichTextBoxOutputTemplate,
            IFormatProvider formatProvider        = null,
            LoggingLevelSwitch levelSwitch        = null,
            RichTextBoxTheme theme                = null,
            DispatcherPriority dispatcherPriority = DispatcherPriority.Background,
            object syncRoot = null)
        {
            if (sinkConfiguration is null)
            {
                throw new ArgumentNullException(nameof(sinkConfiguration));
            }

            if (outputTemplate is null)
            {
                throw new ArgumentNullException(nameof(outputTemplate));
            }

            var appliedTheme = theme ?? RichTextBoxConsoleThemes.Literate;

            syncRoot ??= _defaultSyncRoot;

            var formatter = new XamlOutputTemplateRenderer(appliedTheme, outputTemplate, formatProvider);

            return(sinkConfiguration.Sink(new RichTextBoxSink(richTextBox, formatter, dispatcherPriority, syncRoot),
                                          restrictedToMinimumLevel, levelSwitch));
        }
        public void FormatProviderWithDestructuredProperties(string format, bool shouldUseCustomFormatter)
        {
            var frenchFormatProvider  = new CultureInfo("fr-FR");
            var defaultFormatProvider = CultureInfo.InvariantCulture;

            var          date   = new DateTime(2018, 01, 01);
            const double number = 12.345;

            var expectedFormattedDate = shouldUseCustomFormatter
                ? date.ToString(frenchFormatProvider)
                : date.ToString("O", defaultFormatProvider);
            var expectedFormattedNumber = shouldUseCustomFormatter
                ? number.ToString(frenchFormatProvider)
                : number.ToString(defaultFormatProvider);

            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Message" + format + "}", frenchFormatProvider);
            var evt       = DelegatingSink.GetLogEvent(l =>
            {
                l.Information("{@Item}", new
                {
                    MyDate   = date,
                    MyNumber = number,
                });
            });

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Contains(expectedFormattedDate, sw.ToString());
            Assert.Contains(expectedFormattedNumber, sw.ToString());
        }
        public void LowercaseFormatSpecifierIsSupportedForStrings()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Name:w}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("{Name}", "Nick"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("nick", sw.ToString());
        }
        public void MessageTemplatesContainingFormatStringPropertiesRenderCorrectly()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Message}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("{Message}", "Hello, world!"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("\"Hello, world!\"", sw.ToString());
        }
        public void AppliesJsonFormattingToPropertiesTokenWhenSpecified(string format, string expected)
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Properties" + format + "}", null);
            var evt       = DelegatingSink.GetLogEvent(l => l.ForContext("Name", "World").Information("Hello"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal(expected, sw.ToString());
        }
        public void AppliesJsonFormattingToMessageStructuresWhenSpecified(string format, string expected)
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Message" + format + "}", null);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("{@Obj}", new { Name = "World" }));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal(expected, sw.ToString());
        }
        public void DoNotDuplicatePropertiesAlreadyRenderedInOutputTemplate()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Foo} {Properties}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).ForContext("Bar", 42).Information("Hello from bar!"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("42 {Bar=42}", sw.ToString());
        }
        public void NonMessagePositionalPropertiesAreRendered()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Properties}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.ForContext("Foo", 42).Information("Hello from {0}!", "bar"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("{Foo=42}", sw.ToString());
        }
        public void AppliesCustomFormatterToEnums()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Message}", new SizeFormatter(CultureInfo.InvariantCulture));
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("Size {Size}", Size.Large));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("Size Huge", sw.ToString());
        }
        public void AlignmentAndWidthCanBeCombined()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Level,5:w3}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("Hello"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("  inf", sw.ToString());
        }
        public void DefaultLevelLengthIsFullText()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Level}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("Hello"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("Information", sw.ToString());
        }
        public void FixedLengthLevelSupportsLowerCasing()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Level:w3}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("Hello"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("inf", sw.ToString());
        }
        public void UsesFormatProvider()
        {
            var french    = new CultureInfo("fr-FR");
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Message}", french);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("{0}", 12.345));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal("12,345", sw.ToString());
        }
        public void FixedLengthLevelIsSupported(
            LogEventLevel level,
            int width,
            string expected)
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, $"{{Level:t{width}}}", CultureInfo.InvariantCulture);
            var evt       = DelegatingSink.GetLogEvent(l => l.Write(level, "Hello"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            Assert.Equal(expected, sw.ToString());
        }
        public void AnEmptyPropertiesTokenIsAnEmptyStructureValue()
        {
            var formatter = new XamlOutputTemplateRenderer(RichTextBoxTheme.None, "{Properties}", null);
            var evt       = DelegatingSink.GetLogEvent(l => l.Information("Hello"));

            var sw = new StringWriter();

            formatter.Format(evt, sw);

            // /!\ different behavior from Serilog Core : https://github.com/serilog/serilog/blob/5c3a7821aa0f654e551dc21e8e19089f6767666b/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs#L268-L278
            //
            // var expected = new StructureValue(Enumerable.Empty<LogEventProperty>()).ToString();
            // // expected == "{  }"
            // Assert.Equal(expected, sw.ToString());
            //
            Assert.Equal("{}", sw.ToString());
        }