A ITextFormatter that supports the Serilog message template format. Formatting log events for display has a different set of requirements and expectations from rendering the data within them. To meet this, the formatter overrides some behavior: First, strings are always output as literals (not quoted) unless some other format is applied to them. Second, tokens without matching properties are skipped rather than being written as raw text.
Inheritance: ITextFormatter
        /// <summary>
        /// Adds a sink that sends log events via email.
        /// </summary>
        /// <param name="loggerConfiguration">The logger configuration.</param>
        /// <param name="fromEmail">The email address emails will be sent from</param>
        /// <param name="toEmail">The email address emails will be sent to</param>
        /// <param name="mailServer">The SMTP email server to use</param>
        /// <param name="networkCredential">The network credentials to use to authenticate with mailServer</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// the default is "{Timestamp} [{Level}] {Message:l}{NewLine:l}{Exception:l}".</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required in order to write an event to the sink.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration Email(
            this LoggerSinkConfiguration loggerConfiguration,
            string fromEmail, 
            string toEmail, 
            string mailServer,
            ICredentialsByHost networkCredential,
            string outputTemplate = DefaultOutputTemplate,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            int batchPostingLimit = EmailSink.DefaultBatchPostingLimit,
            TimeSpan? period = null,
            IFormatProvider formatProvider = null)
        {
            if (loggerConfiguration == null) throw new ArgumentNullException("loggerConfiguration");
            if (fromEmail == null) throw new ArgumentNullException("fromEmail");
            if (toEmail == null) throw new ArgumentNullException("toEmail");
            if (mailServer == null) throw new ArgumentNullException("mailServer");

            var defaultedPeriod = period ?? EmailSink.DefaultPeriod;

            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);

            return loggerConfiguration.Sink(
                new EmailSink(fromEmail, toEmail, mailServer, networkCredential, batchPostingLimit, defaultedPeriod, formatter),
                restrictedToMinimumLevel);
        }
 public void LowercaseFormatSpecifierIsSupportedForStrings()
 {
     var formatter = new MessageTemplateTextFormatter("{Name:w}", CultureInfo.InvariantCulture);
     var evt = DelegatingSink.GetLogEvent(l => l.Information("{Name}", "Nick"));
     var sw = new StringWriter();
     formatter.Format(evt, sw);
     Assert.AreEqual("nick", sw.ToString());
 }
 public void MessageTemplatesContainingFormatStringPropertiesRenderCorrectly()
 {
     var formatter = new MessageTemplateTextFormatter("{Message:l}", CultureInfo.InvariantCulture);
     var evt = DelegatingSink.GetLogEvent(l => l.Information("{Message}", "Hello, world!"));
     var sw = new StringWriter();
     formatter.Format(evt, sw);
     Assert.AreEqual("\"Hello, world!\"", sw.ToString());
 }
 public void DefaultLevelLengthIsFullText()
 {
     var formatter = new MessageTemplateTextFormatter("{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 AppliesCustomFormatterToEnums()
 {
     var formatter = new MessageTemplateTextFormatter("{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 AligmentAndWidthCanBeCombined()
 {
     var formatter = new MessageTemplateTextFormatter("{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 static LoggerConfiguration Debug(this LoggerSinkConfiguration loggerConfiguration,
            string outputTemplate = DefaultOutputTemplate,
            IFormatProvider formatProvider = null)
        {
            Guard.ArgumentNotNull(() => loggerConfiguration, loggerConfiguration);

            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
            return loggerConfiguration.Sink(new DebugLogSink(formatter));
        }
        public void ConfigureLogger()
        {
            var formatter = new MessageTemplateTextFormatter("${date} [${threadid}] ${level} ${logger} ${ndc} - ${message}${newline}", null);

            var channelFactory = Substitute.For<ChannelFactory>();
            _channel = Substitute.For<IEventChannel>();
            channelFactory.Create("localhost", 8765, 1).Returns(_channel);
            _sink = new BrowserConsoleSink(true, 8765, 1, formatter,false, channelFactory);
        }
 public void UsesFormatProvider()
 {
     var french = CultureInfo.GetCultureInfo("fr-FR");
     var formatter = new MessageTemplateTextFormatter("{Message:l}", french);
     var evt = DelegatingSink.GetLogEvent(l => l.Information("{0}", 12.345));
     var sw = new StringWriter();
     formatter.Format(evt, sw);
     Assert.AreEqual("12,345", sw.ToString());
 }
        public static LoggerConfiguration RollingFileAsText(this LoggerSinkConfiguration sinkConfiguration, string pathFormat, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum)
        {
            if (sinkConfiguration == null)
                throw new ArgumentNullException("sinkConfiguration");

            var formatter = new MessageTemplateTextFormatter(DefaultOutputTemplate, null);
            var sink = new RollingFileSink(pathFormat, formatter, DefaultFileSizeLimitBytes, DefaultRetainedFileCountLimit);
            return sinkConfiguration.Sink(sink, restrictedToMinimumLevel);
        }
        private const int DefaultRetainedFileCountLimit = 31; // A long month of logs

        /// <summary>
        ///     Writes log events to <see cref="IOutput" />.
        /// </summary>
        /// <param name="sinkConfiguration">Logger sink configuration.</param>
        /// <param name="factory"></param>
        /// <param name="outputLogFilterProvider"></param>
        /// <param name="restrictedToMinimumLevel">
        ///     The minimum level for
        ///     events passed through the sink.
        /// </param>
        /// <param name="outputTemplate">
        ///     A message template describing the format used to write to the sink.
        ///     the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".
        /// </param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        public static LoggerConfiguration OutputModule(this LoggerSinkConfiguration sinkConfiguration,
            Func<IOutput> factory, Func<IOutputLogFilter> outputLogFilterProvider = null, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            string outputTemplate = DefaultConsoleOutputTemplate, IFormatProvider formatProvider = null)
        {
            if (sinkConfiguration == null) throw new ArgumentNullException("sinkConfiguration");
            if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");
            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
            return sinkConfiguration.Sink(new OutputSink(factory, formatter, outputLogFilterProvider), restrictedToMinimumLevel);
        }
Beispiel #12
0
        public static LoggerConfiguration RedisStreamSink(
            this LoggerSinkConfiguration loggerConfiguration,
            RedisStreamSinkConfiguration redisStreamSinkConfiguration,
            string outputTemplate          = DefaultOutputTemplate,
            IFormatProvider formatProvider = null)
        {
            var formatter = new Serilog.Formatting.Display.MessageTemplateTextFormatter(outputTemplate, formatProvider);

            return(loggerConfiguration.Sink(new RedisStreamSink(redisStreamSinkConfiguration, formatter)));
        }
        // for testing
        internal BrowserConsoleSink(bool active, int port, int buffer, MessageTemplateTextFormatter formatter, bool logProperties, ChannelFactory channelFactory)
        {
            Active = active;
            Port = port;
            Buffer = buffer;
            LogProperties = logProperties;
            Formatter = formatter;

            CreateChannel(channelFactory);
        }
 /// <summary>
 /// Writes log events to <see cref="System.Console"/>.
 /// </summary>
 /// <param name="sinkConfiguration">Logger sink configuration.</param>
 /// <param name="restrictedToMinimumLevel">The minimum level for
 /// events passed through the sink.</param>
 /// <param name="outputTemplate">A message template describing the format used to write to the sink.
 /// the default is "{Timestamp} [{Level}] {Message:l}{NewLine:l}{Exception:l}".</param>
 /// <returns>Configuration object allowing method chaining.</returns>
 public static LoggerConfiguration Console(
     this LoggerSinkConfiguration sinkConfiguration,
     LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
     string outputTemplate = DefaultConsoleOutputTemplate)
 {
     if (sinkConfiguration == null) throw new ArgumentNullException("sinkConfiguration");
     if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");
     var formatter = new MessageTemplateTextFormatter(outputTemplate);
     return sinkConfiguration.Sink(new ConsoleSink(formatter), restrictedToMinimumLevel);
 }
 /// <summary>
 /// Writes log events to <see cref="System.Diagnostics.Debug"/>.
 /// </summary>
 /// <param name="sinkConfiguration">Logger sink configuration.</param>
 /// <param name="restrictedToMinimumLevel">The minimum level for events passed through the sink.</param>
 /// <param name="outputTemplate">A message template describing the format used to write to the sink.the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
 /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
 /// <returns>Configuration object allowing method chaining.</returns>
 public static LoggerConfiguration Debug(this LoggerSinkConfiguration sinkConfiguration,
     LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
     string outputTemplate = DefaultOutputTemplate,
     IFormatProvider formatProvider = null)
 {
     if (sinkConfiguration == null)
         throw new ArgumentNullException(nameof(sinkConfiguration));
     if (outputTemplate == null)
         throw new ArgumentNullException(nameof(outputTemplate));
     var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
     return sinkConfiguration.Sink(new DebugSink(formatter), restrictedToMinimumLevel);
 }
 /// <summary>
 /// Use Server Side Event to broadcast logs to a debugging browser console.
 /// </summary>
 /// <param name="sinkConfiguration">Logger sink configuration.</param>
 /// <param name="restrictedToMinimumLevel">The minimum level for
 /// events passed through the sink. Ignored when <paramref name="levelSwitch"/> is specified.</param>
 /// <param name="active">Activate or not the logging (default: false)</param>
 /// <param name="port">Port on which the browser should connect (default: 8082)</param>
 /// <param name="buffer">Size of the buffer (default: 100)</param>
 /// <param name="outputTemplate">The template used to format the message (default: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] {Message}{NewLine}{Exception}")</param>
 /// <param name="formatProvider">Format provider that should be used when formating the message (default: null)</param>
 /// <param name="logProperties">Enable logging of meta-properties (default: false)</param>
 /// <returns>Configuration object allowing method chaining.</returns>
 public static LoggerConfiguration BrowserConsole(
     this LoggerSinkConfiguration sinkConfiguration,
     LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
     bool active = false,
     int port = 8082,
     int buffer = 100,
     string outputTemplate = DefaultOutputTemplate,
     IFormatProvider formatProvider = null,
     bool logProperties = false)
 {
     var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
     return sinkConfiguration.Sink(new BrowserConsoleSink(active, port, buffer, formatter, logProperties), restrictedToMinimumLevel);
 }
 public static LoggerConfiguration TraceSource(
     this LoggerSinkConfiguration sinkConfiguration,
     string traceSourceName,
     LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
     string outputTemplate = DefaultOutputTemplate,
     IFormatProvider formatProvider = null)
 {
     if (string.IsNullOrWhiteSpace(traceSourceName)) throw new ArgumentNullException("traceSourceName");
     if (sinkConfiguration == null) throw new ArgumentNullException("sinkConfiguration");
     if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");
     
     var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
     return sinkConfiguration.Sink(new TraceSourceSink(formatter, traceSourceName), restrictedToMinimumLevel);
 }
        /// <summary>
        /// Adds a sink that writes log events to the output of an xUnit test.
        /// </summary>
        /// <param name="loggerConfiguration">The logger configuration.</param>
        /// <param name="testOutputHelper">Xunit <see cref="TestOutputHelper"/> that writes to test output</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required in order to write an event to the sink.</param>
        /// <param name="outputTemplate">Message template describing the output format.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration XunitTestOutput(
            this LoggerSinkConfiguration loggerConfiguration,
            ITestOutputHelper testOutputHelper,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            string outputTemplate = DefaultOutputTemplate,
            IFormatProvider formatProvider = null)
        {
            if (loggerConfiguration == null) throw new ArgumentNullException("loggerConfiguration");
            if (testOutputHelper == null) throw new ArgumentNullException("testOutputHelper");
            if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");

            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
            return loggerConfiguration.Sink(new XUnitTestOutputSink(testOutputHelper, formatter), restrictedToMinimumLevel);
        }
        /// <summary>
        /// Adds a sink that writes log events to the Windows event log.
        /// </summary>
        /// <param name="loggerConfiguration">The logger configuration.</param>
        /// <param name="source">The source name by which the application is registered on the local computer. </param>
        /// <param name="logName">The name of the log the source's entries are written to. Possible values include Application, System, or a custom event log. </param>
        /// <param name="machineName">The name of the machine hosting the event log written to.  The local machine by default.</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.  The default is "{Timestamp} [{Level}] {Message:l}{NewLine:l}{Exception:l}".</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required in order to write an event to the sink.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration EventLog(
			this LoggerSinkConfiguration loggerConfiguration,
			string source,
			string logName = null,
			string machineName = ".",
			string outputTemplate = DefaultOutputTemplate,
			IFormatProvider formatProvider = null,
			LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum
			)
        {
            if (loggerConfiguration == null) throw new ArgumentNullException("loggerConfiguration");

            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);

            return loggerConfiguration.Sink(new EventLogSink(source, logName, formatter, machineName), restrictedToMinimumLevel);
        }
        /// <summary>
        /// Adds a sink that sends log events via datadog.
        /// </summary>
        /// <param name="loggerConfiguration">The logger configuration.</param>
        /// <param name="datadogConfiguration">The configuration used for writing events to datadog.</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required in order to write an event to the sink.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <returns>Logger configuration, allowing datadogConfiguration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration Datadog(
            this LoggerSinkConfiguration loggerConfiguration,
            DatadogConfiguration datadogConfiguration,
            string outputTemplate = DefaultOutputTemplate,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            int batchPostingLimit = DatadogSink.DefaultBatchPostingLimit,
            TimeSpan? period = null,
            IFormatProvider formatProvider = null)
        {
            if (datadogConfiguration == null) throw new ArgumentNullException("datadogConfiguration");

            var defaultedPeriod = period ?? DatadogSink.DefaultPeriod;
            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
            var datadogSink = new DatadogSink(datadogConfiguration, batchPostingLimit, defaultedPeriod, formatter);

            return loggerConfiguration.Sink(datadogSink, restrictedToMinimumLevel);
        }
        public void Should_send_an_sse_message_when_receiving_a_logging_event()
        {
            // given
            var channelFactory = Substitute.For<ChannelFactory>();
            _channel = Substitute.For<IEventChannel>();
            channelFactory.Create(Arg.Any<string>(), 8765, 1).Returns(_channel);
            var messageTemplateTextFormatter = new MessageTemplateTextFormatter(BrowserConsoleLoggerConfigurationExtensions.DefaultOutputTemplate, null);
            var sink = new BrowserConsoleSink(true, 8765, 1, messageTemplateTextFormatter, false, channelFactory);

            var logEvent = new LogEvent(
                new DateTimeOffset(new DateTime(2010, 10, 12)),
                LogEventLevel.Information,
                null,
                GenerateMessageTemplate("Everything's fine with Serilog"),
                new List<LogEventProperty>() { new LogEventProperty("test", new ScalarValue("value"))});

            // when
            sink.Emit(logEvent);

            // then
            _channel.Received().Send(Arg.Is<ServerSentEvent>(evt => evt.ToString().Contains("Everything's fine with Serilog")), Arg.Any<CancellationToken>());
        }
 /// <summary>
 /// Write log events to a series of files. Each file will be named according to
 /// the date of the first log entry written to it. Only simple date-based rolling is
 /// currently supported.
 /// </summary>
 /// <param name="sinkConfiguration">Logger sink configuration.</param>
 /// <param name="pathFormat">.NET format string describing the location of the log files,
 /// with {0} in the place of the file date. E.g. "Logs\myapp-{0}.log" will result in log
 /// files such as "Logs\myapp-2013-10-20.log", "Logs\myapp-2013-10-21.log" and so on.</param>
 /// <param name="restrictedToMinimumLevel">The minimum level for
 /// events passed through the sink.</param>
 /// <param name="outputTemplate">A message template describing the format used to write to the sink.
 /// the default is "{Timestamp} [{Level}] {Message:l}{NewLine:l}{Exception:l}".</param>
 /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
 /// <returns>Configuration object allowing method chaining.</returns>
 public static LoggerConfiguration RollingFile(
     this LoggerSinkConfiguration sinkConfiguration,
     string pathFormat,
     LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
     string outputTemplate = DefaultOutputTemplate,
     IFormatProvider formatProvider = null)
 {
     if (sinkConfiguration == null) throw new ArgumentNullException("sinkConfiguration");
     if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");
     var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
     return sinkConfiguration.Sink(new RollingFileSink(pathFormat, formatter), restrictedToMinimumLevel);
 }
 /// <summary>
 /// Write log events to a series of files. Each file will be named according to
 /// the date of the first log entry written to it. Only simple date-based rolling is
 /// currently supported.
 /// </summary>
 /// <param name="pathFormat">.NET format string describing the location of the log files,
 /// with {0} in the place of the file date. E.g. "Logs\myapp-{0}.log" will result in log
 /// files such as "Logs\myapp-2013-10-20.log", "Logs\myapp-2013-10-21.log" and so on.</param>
 /// <param name="restrictedToMinimumLevel">The minimum level for
 /// events passed through the sink.</param>
 /// <param name="outputTemplate">A message template describing the format used to write to the sink.
 /// the default is "{TimeStamp} [{Level}] {Message:l}{NewLine:l}{Exception:l}".</param>
 /// <returns>Configuration object allowing method chaining.</returns>
 public LoggerConfiguration WithRollingFileSink(
     string pathFormat,
     LogEventLevel restrictedToMinimumLevel = LogEventLevel.Minimum,
     string outputTemplate = DefaultOutputTemplate)
 {
     var formatter = new MessageTemplateTextFormatter(outputTemplate);
     return WithSink(new RollingFileSink(pathFormat, formatter), restrictedToMinimumLevel);
 }
 /// <summary>
 /// Write log events to a series of files. Each file will be named according to
 /// the date of the first log entry written to it. Only simple date-based rolling is
 /// currently supported.
 /// </summary>
 /// <param name="sinkConfiguration">Logger sink configuration.</param>
 /// <param name="pathFormat">String describing the location of the log files,
 /// with {Date} in the place of the file date. E.g. "Logs\myapp-{Date}.log" will result in log
 /// files such as "Logs\myapp-2013-10-20.log", "Logs\myapp-2013-10-21.log" and so on.</param>
 /// <param name="restrictedToMinimumLevel">The minimum level for
 /// events passed through the sink.</param>
 /// <param name="outputTemplate">A message template describing the format used to write to the sink.
 /// the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
 /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
 /// <param name="fileSizeLimitBytes">The maximum size, in bytes, to which any single log file will be allowed to grow.
 /// For unrestricted growth, pass null. The default is 1 GB.</param>
 /// <param name="retainedFileCountLimit">The maximum number of log files that will be retained,
 /// including the current log file. For unlimited retention, pass null. The default is 31.</param>
 /// <returns>Configuration object allowing method chaining.</returns>
 /// <remarks>The file will be written using the UTF-8 character set.</remarks>
 public static LoggerConfiguration RollingFile(
     this LoggerSinkConfiguration sinkConfiguration,
     string pathFormat,
     LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
     string outputTemplate = DefaultOutputTemplate,
     IFormatProvider formatProvider = null,
     long? fileSizeLimitBytes = DefaultFileSizeLimitBytes,
     int? retainedFileCountLimit = DefaultRetainedFileCountLimit)
 {
     if (sinkConfiguration == null) throw new ArgumentNullException("sinkConfiguration");
     if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");
     var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
     var sink = new RollingFileSink(pathFormat, formatter, fileSizeLimitBytes, retainedFileCountLimit);
     return sinkConfiguration.Sink(sink, restrictedToMinimumLevel);
 }
        /// <summary>
        /// Adds a sink that sends log events via email.
        /// </summary>
        /// <param name="loggerConfiguration">The logger configuration.</param>
        /// <param name="connectionInfo">The connection info used for </param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required in order to write an event to the sink.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration Email(
            this LoggerSinkConfiguration loggerConfiguration,
            EmailConnectionInfo connectionInfo,
            string outputTemplate = DefaultOutputTemplate,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            int batchPostingLimit = EmailSink.DefaultBatchPostingLimit,
            TimeSpan? period = null,
            IFormatProvider formatProvider = null)
        {
            if (connectionInfo == null) throw new ArgumentNullException("connectionInfo");

            var defaultedPeriod = period ?? EmailSink.DefaultPeriod;
            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);

            return loggerConfiguration.Sink(
                new EmailSink(connectionInfo, batchPostingLimit, defaultedPeriod, formatter),
                restrictedToMinimumLevel);
        }
        /// <summary>
        /// Write log events to the specified file.
        /// </summary>
        /// <param name="sinkConfiguration">Logger sink configuration.</param>
        /// <param name="path">Path to the file.</param>
        /// <param name="restrictedToMinimumLevel">The minimum level for
        /// events passed through the sink.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
        /// <param name="fileSizeLimitBytes">The maximum size, in bytes, to which a log file will be allowed to grow.
        /// For unrestricted growth, pass null. The default is 1 GB.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        /// <remarks>The file will be written using the UTF-8 character set.</remarks>
        public static LoggerConfiguration File(
            this LoggerSinkConfiguration sinkConfiguration,
            string path,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            string outputTemplate = DefaultOutputTemplate,
            IFormatProvider formatProvider = null,
            long? fileSizeLimitBytes = DefaultFileSizeLimitBytes)
        {
            if (sinkConfiguration == null) throw new ArgumentNullException("sinkConfiguration");
            if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");
            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);

            FileSink sink;
            try
            {
                sink = new FileSink(path, formatter, fileSizeLimitBytes);
            }
            catch (ArgumentException)
            {
                throw;
            }
            catch (Exception ex)
            {
                SelfLog.WriteLine("Unable to open file sink for {0}: {1}", path, ex);
                return sinkConfiguration.Sink(new NullSink());
            }

            return sinkConfiguration.Sink(sink, restrictedToMinimumLevel);
        }
        public void Should_send_a_multiline_sse_message_received_logging_event_for_an_exception()
        {
            // given
            var channelFactory = Substitute.For<ChannelFactory>();
            _channel = Substitute.For<IEventChannel>();
            channelFactory.Create(Arg.Any<string>(), 8765, 1).Returns(_channel);
            var messageTemplateTextFormatter = new MessageTemplateTextFormatter(BrowserConsoleLoggerConfigurationExtensions.DefaultOutputTemplate, null);
            var sink = new BrowserConsoleSink(true, 8765, 1, messageTemplateTextFormatter, false, channelFactory);

            var logEvent = new LogEvent(
                new DateTimeOffset(new DateTime(2010, 10, 12)),
                LogEventLevel.Fatal,
                new Exception("Message of the exception"), 
                GenerateMessageTemplate("Displaying of an exception"),
                new List<LogEventProperty>() { new LogEventProperty("test", new ScalarValue("value")) });

            // when
            sink.Emit(logEvent);

            // then
            var lineSeparator = new string[] { "\r\n" };
            _channel.Received().Send(
                Arg.Is<ServerSentEvent>(
                    evt => evt.ToString()
                        .Split(lineSeparator, StringSplitOptions.RemoveEmptyEntries)
                        .Skip(1)
                        .All(l => l.StartsWith("data:"))
                    ), Arg.Any<CancellationToken>());
        }
        /// <summary>
        /// A sink that puts log events into a provided Azure Event Hub.
        /// </summary>
        /// <param name="loggerConfiguration">The logger configuration.</param>
        /// <param name="eventHubClient">The Event Hub to use to insert the log entries to.</param>
        /// <param name="partitionKey">The partition key used to group log events in the Event Hub.</param>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <param name="outputTemplate">A message template describing the format used to write to the sink.
        /// the default is "{Timestamp} [{Level}] {Message}{NewLine}{Exception}".</param>
        /// <param name="restrictedToMinimumLevel">The minimum log event level required in order to write an event to the sink.</param>
        /// <param name="writeInBatches">Use a periodic batching sink, as opposed to a synchronous one-at-a-time sink; this alters the partition
        /// key used for the events so is not enabled by default.</param>
        /// <param name="batchPostingLimit">The maximum number of events to post in a single batch.</param>
        /// <param name="period">The time to wait between checking for event batches.</param>
        /// <returns>Logger configuration, allowing configuration to continue.</returns>
        /// <exception cref="ArgumentNullException">A required parameter is null.</exception>
        public static LoggerConfiguration AzureEventHub(
            this LoggerSinkConfiguration loggerConfiguration,
            EventHubClient eventHubClient,
            string partitionKey = null,
            string outputTemplate = DefaultOutputTemplate,
            IFormatProvider formatProvider = null,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            bool writeInBatches = false,
            TimeSpan? period = null,
            int? batchPostingLimit = null
            )
        {
            if (loggerConfiguration == null)
                throw new ArgumentNullException("loggerConfiguration");
            if (eventHubClient == null)
                throw new ArgumentNullException("eventHubClient");
            if (outputTemplate == null)
                throw new ArgumentNullException("outputTemplate");

            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);

            var sink = writeInBatches ?
                (ILogEventSink) new AzureEventHubBatchingSink(
                    eventHubClient,
                    partitionKey ?? DefaultPartitionKey,
                    formatter,
                    batchPostingLimit ?? DefaultBatchPostingLimit,
                    period ?? DefaultPeriod) :
                new AzureEventHubSink(
                    eventHubClient,
                    partitionKey ?? DefaultPartitionKey,
                    formatter);

            return loggerConfiguration.Sink(sink, restrictedToMinimumLevel);
        }
 public DebugLogSink(MessageTemplateTextFormatter formatter)
 {
     this.formatter = formatter;
 }
        /// <summary>
        /// Write log events to the provided <see cref="TextWriter"/>.
        /// </summary>
        /// <param name="textWriter">The text writer to write log events to.</param>
        /// <param name="outputTemplate">Message template describing the output format.</param>
        /// <param name="restrictedToMinimumLevel">The minimum level for
        /// events passed through the sink.</param>
        /// <returns>Configuration object allowing method chaining.</returns>
        /// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
        /// <exception cref="ArgumentNullException"></exception>
        public LoggerConfiguration TextWriter(
            TextWriter textWriter,
            LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
            string outputTemplate = DefaultOutputTemplate,
            IFormatProvider formatProvider = null)
        {
            if (textWriter == null) throw new ArgumentNullException("textWriter");
            if (outputTemplate == null) throw new ArgumentNullException("outputTemplate");

            var formatter = new MessageTemplateTextFormatter(outputTemplate, formatProvider);
            var sink = new TextWriterSink(textWriter, formatter);
            return Sink(sink);
        }
 public TraceSourceSink(MessageTemplateTextFormatter formatter, string traceSourceName)
 {
     _formatter = formatter;
     _source = new TraceSource(traceSourceName);
 }