Skip to content
This repository has been archived by the owner on Mar 1, 2022. It is now read-only.

Commit

Permalink
Merge pull request #16 from serilog/dev
Browse files Browse the repository at this point in the history
Release 4.0.1
  • Loading branch information
nblumhardt authored Apr 11, 2017
2 parents 599547b + f4a31fb commit 390ee76
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 25 deletions.
38 changes: 33 additions & 5 deletions sample/sampleDurableLogger/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Globalization;
using Loggly;
using Loggly.Config;
using Serilog;
Expand All @@ -25,7 +26,7 @@ public static void Main(string[] args)
Console.ReadLine();

logger.Information("Second test message");
logger.Warning("Second test message with {@Data}", new {P1 = "sample2", P2 = DateTime.Now});
logger.Warning("Second test message with {@Data}", new {P1 = "sample2", P2 = DateTime.Now, P3 = DateTime.UtcNow, P4 = DateTimeOffset.Now, P5 = DateTimeOffset.UtcNow});


Console.WriteLine(
Expand Down Expand Up @@ -54,15 +55,17 @@ static Logger CreateLogger(string logFilePath)
.Enrich.With(new PropertyEnricher("Environment", "development"))
//Add sinks
.WriteTo.Async(s => s.Loggly(
bufferBaseFilename: logFilePath + "buffer")
bufferBaseFilename: logFilePath + "buffer",
formatProvider: CreateLoggingCulture())
.MinimumLevel.Information()
)
.WriteTo.Async(s => s.RollingFileAlternate(
logFilePath,
outputTemplate:
"[{ProcessId}] {Timestamp:yyyy-MM-dd HH:mm:ss.fff K} [{ThreadId}] [{Level}] [{SourceContext}] [{Category}] {Message}{NewLine}{Exception}",
"[{ProcessId}] {Timestamp} [{ThreadId}] [{Level}] [{SourceContext}] [{Category}] {Message}{NewLine}{Exception}",
fileSizeLimitBytes: 10 * 1024 * 1024,
retainedFileCountLimit: 100)
retainedFileCountLimit: 100,
formatProvider: CreateLoggingCulture())
.MinimumLevel.Debug()
)
.CreateLogger();
Expand All @@ -71,7 +74,7 @@ static Logger CreateLogger(string logFilePath)

static void SetupLogglyConfiguration()
{
///CHANGE THESE TWO TO YOUR LOGGLY ACCOUNT: DO NOT COMMIT TO Source control!!!
//CHANGE THESE TWO TO YOUR LOGGLY ACCOUNT: DO NOT COMMIT TO Source control!!!
const string appName = "AppNameHere";
const string customerToken = "yourkeyhere";

Expand All @@ -93,5 +96,30 @@ static void SetupLogglyConfiguration()
new HostnameTag { Formatter = "host-{0}" }
});
}

static CultureInfo CreateLoggingCulture()
{
var loggingCulture = new CultureInfo("");

//with this DateTime and DateTimeOffset string representations will be sortable. By default,
// serialization without a culture or formater will use InvariantCulture. This may or may not be
// desirable, depending on the sorting needs you require or even the region your in. In this sample
// the invariant culture is used as a base, but the DateTime format is changed to a specific representation.
// Instead of the dd/MM/yyyy hh:mm:ss, we'll force yyyy-MM-dd HH:mm:ss.fff which is sortable and obtainable
// by overriding ShortDatePattern and LongTimePattern.
//
//Do note that they don't include the TimeZone by default, so a datetime will not have the TZ
// while a DateTimeOffset will in it's string representation.
// Both use the longTimePattern for time formatting, but including the time zone in the
// pattern will duplicate the TZ representation when using DateTimeOffset which serilog does
// for the timestamp.
//
//If you do not require specific formats, this method will not be required. Just pass in null (the default)
// for IFormatProvider in the Loggly() sink configuration method.
loggingCulture.DateTimeFormat.ShortDatePattern = "yyyy-MM-dd";
loggingCulture.DateTimeFormat.LongTimePattern = "HH:mm:ss.fff";

return loggingCulture;
}
}
}
1 change: 0 additions & 1 deletion sample/sampleDurableLogger/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public static LoggerConfiguration Loggly(
LoggingLevelSwitch controlLevelSwitch = null,
long? retainedInvalidPayloadsLimitBytes = null)
{
if (loggerConfiguration == null) throw new ArgumentNullException("loggerConfiguration");
if (loggerConfiguration == null) throw new ArgumentNullException(nameof(loggerConfiguration));
if (bufferFileSizeLimitBytes.HasValue && bufferFileSizeLimitBytes < 0)
throw new ArgumentOutOfRangeException(nameof(bufferFileSizeLimitBytes), "Negative value provided; file size limit must be non-negative.");

Expand All @@ -82,7 +82,8 @@ public static LoggerConfiguration Loggly(
bufferFileSizeLimitBytes,
eventBodyLimitBytes,
controlLevelSwitch,
retainedInvalidPayloadsLimitBytes);
retainedInvalidPayloadsLimitBytes,
formatProvider);
}

return loggerConfiguration.Sink(sink, restrictedToMinimumLevel);
Expand Down
5 changes: 3 additions & 2 deletions src/Serilog.Sinks.Loggly/Sinks/Loggly/DurableLogglySink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public DurableLogglySink(
long? bufferFileSizeLimitBytes,
long? eventBodyLimitBytes,
LoggingLevelSwitch levelControlSwitch,
long? retainedInvalidPayloadsLimitBytes)
long? retainedInvalidPayloadsLimitBytes,
IFormatProvider formatProvider = null)
{
if (bufferBaseFilename == null) throw new ArgumentNullException(nameof(bufferBaseFilename));

Expand All @@ -48,7 +49,7 @@ public DurableLogglySink(
//writes events to the file to support connection recovery
_sink = new RollingFileSink(
bufferBaseFilename + "-{Date}.json",
new LogglyFormatter(), //serializes as LogglyEvent
new LogglyFormatter(formatProvider), //serializes as LogglyEvent
bufferFileSizeLimitBytes,
null,
Encoding.UTF8);
Expand Down
2 changes: 0 additions & 2 deletions src/Serilog.Sinks.Loggly/Sinks/Loggly/HttpLogShipper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ class HttpLogShipper : IDisposable
readonly string _candidateSearchPath;
readonly ExponentialBackoffConnectionSchedule _connectionSchedule;
readonly long? _retainedInvalidPayloadsLimitBytes;

readonly object _stateLock = new object();
readonly PortableTimer _timer;

readonly ControlledLevelSwitch _controlledSwitch;
volatile bool _unloading;

Expand Down
3 changes: 2 additions & 1 deletion src/Serilog.Sinks.Loggly/Sinks/Loggly/LogEventConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ public LogglyEvent CreateLogglyEvent(LogEvent logEvent)
var isHttpTransport = LogglyConfig.Instance.Transport.LogTransport == LogTransport.Https;
logglyEvent.Syslog.Level = ToSyslogLevel(logEvent);


logglyEvent.Data.AddIfAbsent("Message", logEvent.RenderMessage(_formatProvider));

foreach (var key in logEvent.Properties.Keys)
{
var propertyValue = logEvent.Properties[key];
var simpleValue = LogglyPropertyFormatter.Simplify(propertyValue);
var simpleValue = LogglyPropertyFormatter.Simplify(propertyValue, _formatProvider);
logglyEvent.Data.AddIfAbsent(key, simpleValue);
}

Expand Down
9 changes: 8 additions & 1 deletion src/Serilog.Sinks.Loggly/Sinks/Loggly/LogglyFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.IO;
using Newtonsoft.Json;
using Serilog.Events;
Expand All @@ -25,8 +26,14 @@ namespace Serilog.Sinks.Loggly
class LogglyFormatter : ITextFormatter
{
readonly JsonSerializer _serializer = JsonSerializer.Create();
readonly LogEventConverter _converter = new LogEventConverter(null);
readonly LogEventConverter _converter;

public LogglyFormatter(IFormatProvider formatProvider)
{
//the converter should receive the format provider used, in order to
// handle dateTimes and dateTimeOffsets in a controlled manner
_converter = new LogEventConverter(formatProvider);
}
public void Format(LogEvent logEvent, TextWriter output)
{
//Serializing the LogglyEvent means we can work with it from here on out and
Expand Down
29 changes: 19 additions & 10 deletions src/Serilog.Sinks.Loggly/Sinks/Loggly/LogglyPropertyFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Serilog.Debugging;
using Serilog.Events;
Expand All @@ -32,50 +33,51 @@ static class LogglyPropertyFormatter
typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal),
typeof(byte[])
};
};

/// <summary>
/// Simplify the object so as to make handling the serialized
/// representation easier.
/// </summary>
/// <param name="value">The value to simplify (possibly null).</param>
/// <param name="formatProvider">A formatProvider to format DateTime values if a specific format is required.</param>
/// <returns>A simplified representation.</returns>
public static object Simplify(LogEventPropertyValue value)
public static object Simplify(LogEventPropertyValue value, IFormatProvider formatProvider)
{
var scalar = value as ScalarValue;
if (scalar != null)
return SimplifyScalar(scalar.Value);
return SimplifyScalar(scalar.Value, formatProvider);

var dict = value as DictionaryValue;
if (dict != null)
{
var result = new Dictionary<object, object>();
foreach (var element in dict.Elements)
{
var key = SimplifyScalar(element.Key.Value);
var key = SimplifyScalar(element.Key.Value, formatProvider);
if (result.ContainsKey(key))
{
SelfLog.WriteLine("The key {0} is not unique in the provided dictionary after simplification to {1}.", element.Key, key);
return dict.Elements.Select(e => new Dictionary<string, object>
{
{ "Key", SimplifyScalar(e.Key.Value) },
{ "Value", Simplify(e.Value) }
{ "Key", SimplifyScalar(e.Key.Value, formatProvider) },
{ "Value", Simplify(e.Value, formatProvider) }
})
.ToArray();
}
result.Add(key, Simplify(element.Value));
result.Add(key, Simplify(element.Value, formatProvider));
}
return result;
}

var seq = value as SequenceValue;
if (seq != null)
return seq.Elements.Select(Simplify).ToArray();
return seq.Elements.Select(propertyValue => Simplify(propertyValue, formatProvider)).ToArray();

var str = value as StructureValue;
if (str != null)
{
var props = str.Properties.ToDictionary(p => p.Name, p => Simplify(p.Value));
var props = str.Properties.ToDictionary(p => p.Name, p => Simplify(p.Value, formatProvider));
if (str.TypeTag != null)
props["$typeTag"] = str.TypeTag;
return props;
Expand All @@ -84,13 +86,20 @@ public static object Simplify(LogEventPropertyValue value)
return null;
}

static object SimplifyScalar(object value)
static object SimplifyScalar(object value, IFormatProvider formatProvider)
{
if (value == null) return null;

var valueType = value.GetType();
if (LogglyScalars.Contains(valueType)) return value;

//handle dateTimes with the format provider
if (value is DateTime)
return ((DateTime)value).ToString(formatProvider ?? CultureInfo.InvariantCulture);

if (value is DateTimeOffset)
return ((DateTimeOffset)value).ToString(formatProvider ?? CultureInfo.InvariantCulture);

return value.ToString();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Serilog.Sinks.Loggly/project.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "4.0.0-*",
"version": "4.0.1-*",
"description": "Serilog sink for Loggly.com service",
"authors": [ "Serilog Contributors", "Michiel van Oudheusden" ],
"packOptions": {
Expand Down

0 comments on commit 390ee76

Please sign in to comment.