/// <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)); }
public DurableKinesisSink(KinesisSinkOptions options) { var state = KinesisSinkState.Create(options); if (string.IsNullOrWhiteSpace(options.BufferBaseFilename)) { throw new ArgumentException("Cannot create the durable Amazon Kinesis sink without a buffer base file name."); } _sink = new RollingFileSink( options.BufferBaseFilename + "-{Date}.json", state.DurableFormatter, options.BufferFileSizeLimitBytes, null); _shipper = new HttpLogShipper(state); if (options.OnLogSendError != null) { _shipper.LogSendError += options.OnLogSendError; } }
public DurableSeqSink( string serverUrl, string bufferBaseFilename, string apiKey, int batchPostingLimit, TimeSpan period, long?bufferFileSizeLimitBytes, long?eventBodyLimitBytes, LoggingLevelSwitch levelControlSwitch, HttpMessageHandler messageHandler, long?retainedInvalidPayloadsLimitBytes) { if (serverUrl == null) { throw new ArgumentNullException(nameof(serverUrl)); } if (bufferBaseFilename == null) { throw new ArgumentNullException(nameof(bufferBaseFilename)); } _shipper = new HttpLogShipper( serverUrl, bufferBaseFilename, apiKey, batchPostingLimit, period, eventBodyLimitBytes, levelControlSwitch, messageHandler, retainedInvalidPayloadsLimitBytes); _sink = new RollingFileSink( bufferBaseFilename + "-{Date}.json", new RawJsonFormatter(), bufferFileSizeLimitBytes, null, encoding: Encoding.UTF8); }
public DurableLogglySink( string bufferBaseFilename, int batchPostingLimit, TimeSpan period, long?bufferFileSizeLimitBytes, long?eventBodyLimitBytes, LoggingLevelSwitch levelControlSwitch, long?retainedInvalidPayloadsLimitBytes, int?retainedFileCountLimit = null, IFormatProvider formatProvider = null ) { if (bufferBaseFilename == null) { throw new ArgumentNullException(nameof(bufferBaseFilename)); } //use a consistent UTF encoding with BOM so no confusion will exist when reading / deserializing var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false); //handles sending events to Loggly's API through LogglyClient and manages the pending list _shipper = new HttpLogShipper( bufferBaseFilename, batchPostingLimit, period, eventBodyLimitBytes, levelControlSwitch, retainedInvalidPayloadsLimitBytes, encoding); //writes events to the file to support connection recovery _sink = new RollingFileSink( bufferBaseFilename + "-{Date}.json", new LogglyFormatter(formatProvider), //serializes as LogglyEvent bufferFileSizeLimitBytes, retainedFileCountLimit, encoding); }
public static ILogger Configure(IConfigurationRoot config) { var logFilename = config["Serilog:LogFilename"]; var seqEnabled = bool.Parse(config["Serilog:SeqEnabled"]); var seqApiKey = config["Serilog:SeqApiKey"]; var seqUrl = config["Serilog:SeqUrl"]; var directory = logFilename.Replace("${basedir}", Directory.GetCurrentDirectory()); var logSink = new RollingFileSink(directory, new JsonFormatter(), null, 100); var loggerConfiguration = new LoggerConfiguration() .MinimumLevel.Debug() .Enrich.FromLogContext() .WriteTo.Sink(logSink); if (seqEnabled) { return(loggerConfiguration .WriteTo.Seq(seqUrl, apiKey: seqApiKey) .CreateLogger()); } return(loggerConfiguration.CreateLogger()); }
/// <summary> /// Write log events to a series of files asynchronously. 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="formatter">Formatter to control how events are rendered into the file. To control /// plain text formatting, use the overload that accepts an output template instead.</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. Ignored when <paramref name="levelSwitch"/> is specified.</param> /// <param name="levelSwitch">A switch allowing the pass-through minimum level /// to be changed at runtime.</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> /// <param name="buffered">Indicates if flushing to the output file can be buffered or not. The default /// is false.</param> /// <param name="shared">Allow the log files to be shared by multiple processes. The default is false.</param> /// <param name="flushToDiskInterval">If provided, a full disk flush will be performed periodically at the specified interval.</param> /// <param name="queueSize">The size of the concurrent queue used to feed the background worker thread. If /// the thread is unable to process events quickly enough and the queue is filled, subsequent events will be /// dropped until room is made in the queue.</param> /// <returns>Configuration object allowing method chaining.</returns> /// <remarks>The file will be written using the UTF-8 encoding without a byte-order mark.</remarks> public static LoggerConfiguration AsyncRollingFile( this LoggerSinkConfiguration sinkConfiguration, ITextFormatter formatter, string pathFormat, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, long?fileSizeLimitBytes = DefaultFileSizeLimitBytes, int?retainedFileCountLimit = DefaultRetainedFileCountLimit, LoggingLevelSwitch levelSwitch = null, bool buffered = false, bool shared = false, TimeSpan?flushToDiskInterval = null, int queueSize = 65536) { if (sinkConfiguration == null) { throw new ArgumentNullException(nameof(sinkConfiguration)); } if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } if (shared && buffered) { throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered)); } ILogEventSink sink = new RollingFileSink(pathFormat, formatter, fileSizeLimitBytes, retainedFileCountLimit, buffered: buffered, shared: shared); if (flushToDiskInterval.HasValue) { sink = new PeriodicFlushToDiskSink(sink, flushToDiskInterval.Value); } return(sinkConfiguration.Async(c => c.Sink(sink, restrictedToMinimumLevel, levelSwitch), queueSize)); }
public DurableKinesisFirehoseSink(KinesisFirehoseSinkOptions options, IAmazonKinesisFirehose kinesisFirehoseClient) { var state = new KinesisSinkState(options, kinesisFirehoseClient); if (string.IsNullOrWhiteSpace(options.BufferBaseFilename)) { throw new ArgumentException("Cannot create the durable Amazon Kinesis Firehose sink without a buffer base file name."); } _sink = new RollingFileSink( options.BufferBaseFilename + "-{Date}.json", state.DurableFormatter, options.BufferFileSizeLimitBytes, null, shared: options.Shared); _shipper = new HttpLogShipper(state); _logSendErrorHandler = options.OnLogSendError; if (_logSendErrorHandler != null) { _shipper.LogSendError += _logSendErrorHandler; } }
static LoggerConfiguration ConfigureFile( this Func <ILogEventSink, LogEventLevel, LoggingLevelSwitch, LoggerConfiguration> addSink, ITextFormatter formatter, string path, LogEventLevel restrictedToMinimumLevel, long?fileSizeLimitBytes, LoggingLevelSwitch levelSwitch, bool buffered, bool propagateExceptions, bool shared, TimeSpan?flushToDiskInterval, Encoding encoding, PersistentFileRollingInterval persistentFileRollingInterval, bool rollOnFileSizeLimit, int?retainedFileCountLimit, FileLifecycleHooks hooks, bool preserveLogFilename = true, bool rollOnEachProcessRun = true, bool useLastWriteAsTimestamp = false) { if (addSink == null) { throw new ArgumentNullException(nameof(addSink)); } if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } if (path == null) { throw new ArgumentNullException(nameof(path)); } if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 0) { throw new ArgumentException("Negative value provided; file size limit must be non-negative.", nameof(fileSizeLimitBytes)); } if (retainedFileCountLimit.HasValue && retainedFileCountLimit < 1) { throw new ArgumentException("At least one file must be retained.", nameof(retainedFileCountLimit)); } if (shared && buffered) { throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered)); } if (shared && hooks != null) { throw new ArgumentException("File lifecycle hooks are not currently supported for shared log files.", nameof(hooks)); } ILogEventSink sink; if (rollOnFileSizeLimit || persistentFileRollingInterval != PersistentFileRollingInterval.Infinite) { sink = new RollingFileSink(path, formatter, fileSizeLimitBytes, retainedFileCountLimit, encoding, buffered, shared, persistentFileRollingInterval, rollOnFileSizeLimit, hooks, preserveLogFilename, rollOnEachProcessRun, useLastWriteAsTimestamp); } else { try { if (shared) { #pragma warning disable 618 sink = new SharedFileSink(path, formatter, fileSizeLimitBytes, encoding); #pragma warning restore 618 } else { sink = new FileSink(path, formatter, fileSizeLimitBytes, encoding, buffered, hooks); } } catch (Exception ex) { SelfLog.WriteLine("Unable to open file sink for {0}: {1}", path, ex); if (propagateExceptions) { throw; } return(addSink(new NullSink(), LevelAlias.Maximum, null)); } } if (flushToDiskInterval.HasValue) { #pragma warning disable 618 sink = new PeriodicFlushToDiskSink(sink, flushToDiskInterval.Value); #pragma warning restore 618 } return(addSink(sink, restrictedToMinimumLevel, levelSwitch)); }
static LoggerConfiguration ConfigureFile( this Func <ILogEventSink, LogEventLevel, LoggingLevelSwitch, LoggerConfiguration> addSink, ITextFormatter formatter, string path, LogEventLevel restrictedToMinimumLevel, long?fileSizeLimitBytes, LoggingLevelSwitch levelSwitch, bool buffered, bool propagateExceptions, bool shared, TimeSpan?flushToDiskInterval, Encoding encoding, RollingInterval rollingInterval, bool rollOnFileSizeLimit, int?retainedFileCountLimit) { if (addSink == null) { throw new ArgumentNullException(nameof(addSink)); } if (formatter == null) { throw new ArgumentNullException(nameof(formatter)); } if (path == null) { throw new ArgumentNullException(nameof(path)); } if (fileSizeLimitBytes.HasValue && fileSizeLimitBytes < 0) { throw new ArgumentException("Negative value provided; file size limit must be non-negative.", nameof(fileSizeLimitBytes)); } if (retainedFileCountLimit.HasValue && retainedFileCountLimit < 1) { throw new ArgumentException("At least one file must be retained.", nameof(retainedFileCountLimit)); } if (shared && buffered) { throw new ArgumentException("Buffered writes are not available when file sharing is enabled.", nameof(buffered)); } ILogEventSink sink; if (rollOnFileSizeLimit || rollingInterval != RollingInterval.Infinite) { sink = new RollingFileSink(path, formatter, fileSizeLimitBytes, retainedFileCountLimit, encoding, buffered, shared, rollingInterval, rollOnFileSizeLimit); } else { try { #pragma warning disable 618 if (shared) { sink = new SharedFileSink(path, formatter, fileSizeLimitBytes); } else { sink = new FileSink(path, formatter, fileSizeLimitBytes, buffered: buffered); } #pragma warning restore 618 } catch (Exception ex) { SelfLog.WriteLine("Unable to open file sink for {0}: {1}", path, ex); if (propagateExceptions) { throw; } return(addSink(new NullSink(), LevelAlias.Maximum, null)); } } if (flushToDiskInterval.HasValue) { sink = new PeriodicFlushToDiskSink(sink, flushToDiskInterval.Value); } return(addSink(sink, restrictedToMinimumLevel, levelSwitch)); }