diff --git a/Serilog.sln.DotSettings b/Serilog.sln.DotSettings
index 77a52ea2d..a84b8ae38 100644
--- a/Serilog.sln.DotSettings
+++ b/Serilog.sln.DotSettings
@@ -2,10 +2,13 @@
True
+ True
True
True
False
SOLUTION
+ DO_NOT_SHOW
+ DO_NOT_SHOW
DO_NOT_SHOW
ERROR
DO_NOT_SHOW
@@ -16,6 +19,7 @@
ERROR
WARNING
ERROR
+ HINT
ERROR
ERROR
ERROR
@@ -27,8 +31,9 @@
ERROR
DO_NOT_SHOW
DO_NOT_SHOW
- HINT
+ DO_NOT_SHOW
DO_NOT_SHOW
+ HINT
DO_NOT_SHOW
HINT
ERROR
@@ -103,6 +108,7 @@
DO_NOT_SHOW
SUGGESTION
ERROR
+ HINT
ERROR
ERROR
ERROR
@@ -111,6 +117,8 @@
<?xml version="1.0" encoding="utf-16"?><Profile name="Format My Code Using "Particular" conventions"><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_IMPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_IMPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><JsInsertSemicolon>True</JsInsertSemicolon><JsReformatCode>True</JsReformatCode><CssReformatCode>True</CssReformatCode><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><HtmlReformatCode>True</HtmlReformatCode><CSShortenReferences>True</CSShortenReferences><CSharpFormatDocComments>True</CSharpFormatDocComments><CssAlphabetizeProperties>True</CssAlphabetizeProperties></Profile>
Default: Reformat Code
Format My Code Using "Particular" conventions
+ Implicit
+ Implicit
False
DO_NOT_CHANGE
DO_NOT_CHANGE
@@ -477,10 +485,13 @@ II.2.12 <HandlesEvent />
True
Automatic property
True
+ False
False
False
+ AD
DB
DTC
+ GT
ID
NSB
SLA
diff --git a/src/Serilog/Parameters/DepthLimiter.cs b/src/Serilog/Capturing/DepthLimiter.cs
similarity index 98%
rename from src/Serilog/Parameters/DepthLimiter.cs
rename to src/Serilog/Capturing/DepthLimiter.cs
index 6785198ab..005a3be55 100644
--- a/src/Serilog/Parameters/DepthLimiter.cs
+++ b/src/Serilog/Capturing/DepthLimiter.cs
@@ -19,7 +19,7 @@
using Serilog.Events;
using Serilog.Parsing;
-namespace Serilog.Parameters
+namespace Serilog.Capturing
{
partial class PropertyValueConverter
{
diff --git a/src/Serilog/Parameters/GetablePropertyFinder.cs b/src/Serilog/Capturing/GetablePropertyFinder.cs
similarity index 98%
rename from src/Serilog/Parameters/GetablePropertyFinder.cs
rename to src/Serilog/Capturing/GetablePropertyFinder.cs
index e7304547f..9c0f74e06 100644
--- a/src/Serilog/Parameters/GetablePropertyFinder.cs
+++ b/src/Serilog/Capturing/GetablePropertyFinder.cs
@@ -17,7 +17,7 @@
using System.Linq;
using System.Reflection;
-namespace Serilog.Parameters
+namespace Serilog.Capturing
{
static class GetablePropertyFinder
{
diff --git a/src/Serilog/Parameters/MessageTemplateProcessor.cs b/src/Serilog/Capturing/MessageTemplateProcessor.cs
similarity index 92%
rename from src/Serilog/Parameters/MessageTemplateProcessor.cs
rename to src/Serilog/Capturing/MessageTemplateProcessor.cs
index 780fed64d..974f6fe8a 100644
--- a/src/Serilog/Parameters/MessageTemplateProcessor.cs
+++ b/src/Serilog/Capturing/MessageTemplateProcessor.cs
@@ -18,11 +18,11 @@
using Serilog.Events;
using Serilog.Parsing;
-namespace Serilog.Parameters
+namespace Serilog.Capturing
{
class MessageTemplateProcessor : ILogEventPropertyFactory
{
- readonly IMessageTemplateParser _parser = new MessageTemplateCache(new MessageTemplateParser());
+ readonly MessageTemplateCache _parser = new MessageTemplateCache(new MessageTemplateParser());
readonly PropertyBinder _propertyBinder;
readonly PropertyValueConverter _propertyValueConverter;
diff --git a/src/Serilog/Parameters/PropertyBinder.cs b/src/Serilog/Capturing/PropertyBinder.cs
similarity index 99%
rename from src/Serilog/Parameters/PropertyBinder.cs
rename to src/Serilog/Capturing/PropertyBinder.cs
index 1461f61c5..23ebd6047 100644
--- a/src/Serilog/Parameters/PropertyBinder.cs
+++ b/src/Serilog/Capturing/PropertyBinder.cs
@@ -19,7 +19,7 @@
using Serilog.Events;
using Serilog.Parsing;
-namespace Serilog.Parameters
+namespace Serilog.Capturing
{
// Performance relevant - on the hot path when creating log events from existing templates.
class PropertyBinder
diff --git a/src/Serilog/Parameters/PropertyValueConverter.cs b/src/Serilog/Capturing/PropertyValueConverter.cs
similarity index 99%
rename from src/Serilog/Parameters/PropertyValueConverter.cs
rename to src/Serilog/Capturing/PropertyValueConverter.cs
index 325799a63..d244271c9 100644
--- a/src/Serilog/Parameters/PropertyValueConverter.cs
+++ b/src/Serilog/Capturing/PropertyValueConverter.cs
@@ -24,7 +24,7 @@
using Serilog.Policies;
using System.Runtime.CompilerServices;
-namespace Serilog.Parameters
+namespace Serilog.Capturing
{
// Values in Serilog are simplified down into a lowest-common-denominator internal
// type system so that there is a better chance of code written with one sink in
@@ -351,7 +351,7 @@ IEnumerable GetProperties(object value)
if (_propagateExceptions)
throw;
- propValue = "The property accessor threw an exception: " + ex.InnerException.GetType().Name;
+ propValue = "The property accessor threw an exception: " + ex.InnerException?.GetType().Name;
}
yield return new LogEventProperty(prop.Name, _depthLimiter.CreatePropertyValue(propValue, Destructuring.Destructure));
}
diff --git a/src/Serilog/Context/LogContext.cs b/src/Serilog/Context/LogContext.cs
index b4ebd2e37..8d2657134 100644
--- a/src/Serilog/Context/LogContext.cs
+++ b/src/Serilog/Context/LogContext.cs
@@ -20,7 +20,6 @@
using Serilog.Events;
#if ASYNCLOCAL
-using System.Collections.Generic;
using System.Threading;
#elif REMOTING
using System.Runtime.Remoting;
diff --git a/src/Serilog/Core/Logger.cs b/src/Serilog/Core/Logger.cs
index 141b6363d..b9207c31d 100644
--- a/src/Serilog/Core/Logger.cs
+++ b/src/Serilog/Core/Logger.cs
@@ -14,10 +14,10 @@
using System;
using System.Collections.Generic;
+using Serilog.Capturing;
using Serilog.Core.Enrichers;
using Serilog.Debugging;
using Serilog.Events;
-using Serilog.Parameters;
#pragma warning disable Serilog004 // Constant MessageTemplate verifier
diff --git a/src/Serilog/Core/Pipeline/MessageTemplateCache.cs b/src/Serilog/Core/Pipeline/MessageTemplateCache.cs
index 0688ee0e1..459a224a5 100644
--- a/src/Serilog/Core/Pipeline/MessageTemplateCache.cs
+++ b/src/Serilog/Core/Pipeline/MessageTemplateCache.cs
@@ -13,9 +13,13 @@
// limitations under the License.
using System;
-using System.Collections.Generic;
using Serilog.Events;
+
+#if HASHTABLE
using System.Collections;
+#else
+using System.Collections.Generic;
+#endif
namespace Serilog.Core.Pipeline
{
diff --git a/src/Serilog/Data/LogEventPropertyValueVisitor.cs b/src/Serilog/Data/LogEventPropertyValueVisitor.cs
index dd1ae1687..d4bea708c 100644
--- a/src/Serilog/Data/LogEventPropertyValueVisitor.cs
+++ b/src/Serilog/Data/LogEventPropertyValueVisitor.cs
@@ -15,6 +15,8 @@
using System;
using Serilog.Events;
+// ReSharper disable VirtualMemberNeverOverridden.Global
+
namespace Serilog.Data
{
///
@@ -40,7 +42,6 @@ public abstract class LogEventPropertyValueVisitor
/// Operation state.
/// The value to visit.
/// The result of visiting .
- // ReSharper disable once VirtualMemberNeverOverriden.Global
protected virtual TResult Visit(TState state, LogEventPropertyValue value)
{
if (value == null) throw new ArgumentNullException(nameof(value));
@@ -103,7 +104,6 @@ protected virtual TResult Visit(TState state, LogEventPropertyValue value)
/// The value to visit.
/// The result of visiting .
// ReSharper disable once UnusedParameter.Global
- // ReSharper disable once VirtualMemberNeverOverriden.Global
protected virtual TResult VisitUnsupportedValue(TState state, LogEventPropertyValue value)
{
if (value == null) throw new ArgumentNullException(nameof(value));
diff --git a/src/Serilog/Events/MessageTemplate.cs b/src/Serilog/Events/MessageTemplate.cs
index bb75f7234..b1664aeea 100644
--- a/src/Serilog/Events/MessageTemplate.cs
+++ b/src/Serilog/Events/MessageTemplate.cs
@@ -18,6 +18,7 @@
using System.Linq;
using Serilog.Debugging;
using Serilog.Parsing;
+using Serilog.Rendering;
namespace Serilog.Events
{
@@ -35,15 +36,14 @@ public class MessageTemplate
readonly MessageTemplateToken[] _tokens;
- // Optimisation for when the template is bound to
- // property values.
-
///
/// Construct a message template using manually-defined text and property tokens.
///
/// The text and property tokens defining the template.
public MessageTemplate(IEnumerable tokens)
+ // ReSharper disable PossibleMultipleEnumeration
: this(string.Join("", tokens), tokens)
+ // ReSharper enable PossibleMultipleEnumeration
{
}
@@ -91,7 +91,7 @@ public MessageTemplate(string text, IEnumerable tokens)
///
/// Similar to , but faster.
///
- static TResult[] GetElementsOfTypeToArray(object[] tokens)
+ static TResult[] GetElementsOfTypeToArray(MessageTemplateToken[] tokens)
where TResult: class
{
var result = new List(tokens.Length / 2);
@@ -125,6 +125,8 @@ public override string ToString()
///
public IEnumerable Tokens => _tokens;
+ internal MessageTemplateToken[] TokenArray => _tokens;
+
internal PropertyToken[] NamedProperties { get; }
internal PropertyToken[] PositionalProperties { get; }
@@ -156,10 +158,9 @@ public string Render(IReadOnlyDictionary properti
/// Supplies culture-specific formatting information, or null.
public void Render(IReadOnlyDictionary properties, TextWriter output, IFormatProvider formatProvider = null)
{
- foreach (var token in _tokens)
- {
- token.Render(properties, output, formatProvider);
- }
+ if (properties == null) throw new ArgumentNullException(nameof(properties));
+ if (output == null) throw new ArgumentNullException(nameof(output));
+ MessageTemplateRenderer.Render(this, properties, output, null, formatProvider);
}
}
}
diff --git a/src/Serilog/Events/ScalarValue.cs b/src/Serilog/Events/ScalarValue.cs
index e5b280d6f..01f514fe5 100644
--- a/src/Serilog/Events/ScalarValue.cs
+++ b/src/Serilog/Events/ScalarValue.cs
@@ -46,16 +46,21 @@ public ScalarValue(object value)
/// A format provider to apply to the value, or null to use the default.
/// .
public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
+ {
+ Render(Value, output, format, formatProvider);
+ }
+
+ internal static void Render(object value, TextWriter output, string format = null, IFormatProvider formatProvider = null)
{
if (output == null) throw new ArgumentNullException(nameof(output));
- if (Value == null)
+ if (value == null)
{
output.Write("null");
return;
}
- var s = Value as string;
+ var s = value as string;
if (s != null)
{
if (format != "l")
@@ -76,19 +81,19 @@ public override void Render(TextWriter output, string format = null, IFormatProv
var custom = (ICustomFormatter)formatProvider.GetFormat(typeof(ICustomFormatter));
if (custom != null)
{
- output.Write(custom.Format(format, Value, formatProvider));
+ output.Write(custom.Format(format, value, formatProvider));
return;
}
}
- var f = Value as IFormattable;
+ var f = value as IFormattable;
if (f != null)
{
output.Write(f.ToString(format, formatProvider ?? CultureInfo.InvariantCulture));
}
else
{
- output.Write(Value.ToString());
+ output.Write(value.ToString());
}
}
diff --git a/src/Serilog/Formatting/Display/LevelOutputFormat.cs b/src/Serilog/Formatting/Display/LevelOutputFormat.cs
new file mode 100644
index 000000000..76f9b3d5e
--- /dev/null
+++ b/src/Serilog/Formatting/Display/LevelOutputFormat.cs
@@ -0,0 +1,97 @@
+// Copyright 2017 Serilog Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using Serilog.Events;
+using Serilog.Rendering;
+
+namespace Serilog.Formatting.Display
+{
+ ///
+ /// Implements the {Level} element.
+ /// can now have a fixed width applied to it, as well as casing rules.
+ /// Width is set through formats like "u3" (uppercase three chars),
+ /// "w1" (one lowercase char), or "t4" (title case four chars).
+ ///
+ static class LevelOutputFormat
+ {
+ static readonly string[][] _titleCaseLevelMap = {
+ new []{ "V", "Vb", "Vrb", "Verb" },
+ new []{ "D", "De", "Dbg", "Dbug" },
+ new []{ "I", "In", "Inf", "Info" },
+ new []{ "W", "Wn", "Wrn", "Warn" },
+ new []{ "E", "Er", "Err", "Eror" },
+ new []{ "F", "Fa", "Ftl", "Fatl" }
+ };
+
+ static readonly string[][] _lowercaseLevelMap = {
+ new []{ "v", "vb", "vrb", "verb" },
+ new []{ "d", "de", "dbg", "dbug" },
+ new []{ "i", "in", "inf", "info" },
+ new []{ "w", "wn", "wrn", "warn" },
+ new []{ "e", "er", "err", "eror" },
+ new []{ "f", "fa", "ftl", "fatl" }
+ };
+
+ static readonly string[][] _uppercaseLevelMap = {
+ new []{ "V", "VB", "VRB", "VERB" },
+ new []{ "D", "DE", "DBG", "DBUG" },
+ new []{ "I", "IN", "INF", "INFO" },
+ new []{ "W", "WN", "WRN", "WARN" },
+ new []{ "E", "ER", "ERR", "EROR" },
+ new []{ "F", "FA", "FTL", "FATL" }
+ };
+
+ public static string GetLevelMoniker(LogEventLevel value, string format = null)
+ {
+ if (format == null || format.Length != 2 && format.Length != 3)
+ return Casing.Format(value.ToString(), format);
+
+ // Using int.Parse() here requires allocating a string to exclude the first character prefix.
+ // Junk like "wxy" will be accepted but produce benign results.
+ var width = format[1] - '0';
+ if (format.Length == 3)
+ {
+ width *= 10;
+ width += format[2] - '0';
+ }
+
+ if (width < 1)
+ return string.Empty;
+
+ if (width > 4)
+ {
+ var stringValue = value.ToString();
+ if (stringValue.Length > width)
+ stringValue = stringValue.Substring(0, width);
+ return Casing.Format(stringValue);
+ }
+
+ var index = (int)value;
+ if (index >= 0 && index <= (int) LogEventLevel.Fatal)
+ {
+ switch (format[0])
+ {
+ case 'w':
+ return _lowercaseLevelMap[index][width - 1];
+ case 'u':
+ return _uppercaseLevelMap[index][width - 1];
+ case 't':
+ return _titleCaseLevelMap[index][width - 1];
+ }
+ }
+
+ return Casing.Format(value.ToString(), format);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Serilog/Formatting/Display/LogEventLevelValue.cs b/src/Serilog/Formatting/Display/LogEventLevelValue.cs
deleted file mode 100644
index d850722c3..000000000
--- a/src/Serilog/Formatting/Display/LogEventLevelValue.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2013-2015 Serilog Contributors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-using System;
-using System.IO;
-
-using Serilog.Events;
-
-namespace Serilog.Formatting.Display
-{
- // Allows for the specific handling of the {Level} element.
- // can now have a fixed width applied to it, as well as casing rules.
- // Width is set through formats like "u3" (uppercase three chars),
- // "w1" (one lowercase char), or "t4" (title case four chars).
- class LogEventLevelValue : LogEventPropertyValue
- {
- readonly LogEventLevel _value;
-
- static readonly string[][] _titleCaseLevelMap = {
- new []{ "V", "Vb", "Vrb", "Verb" },
- new []{ "D", "De", "Dbg", "Dbug" },
- new []{ "I", "In", "Inf", "Info" },
- new []{ "W", "Wn", "Wrn", "Warn" },
- new []{ "E", "Er", "Err", "Eror" },
- new []{ "F", "Fa", "Ftl", "Fatl" }
- };
-
- static readonly string[][] _lowercaseLevelMap = {
- new []{ "v", "vb", "vrb", "verb" },
- new []{ "d", "de", "dbg", "dbug" },
- new []{ "i", "in", "inf", "info" },
- new []{ "w", "wn", "wrn", "warn" },
- new []{ "e", "er", "err", "eror" },
- new []{ "f", "fa", "ftl", "fatl" }
- };
-
- static readonly string[][] _uppercaseLevelMap = {
- new []{ "V", "VB", "VRB", "VERB" },
- new []{ "D", "DE", "DBG", "DBUG" },
- new []{ "I", "IN", "INF", "INFO" },
- new []{ "W", "WN", "WRN", "WARN" },
- new []{ "E", "ER", "ERR", "EROR" },
- new []{ "F", "FA", "FTL", "FATL" }
- };
-
- public LogEventLevelValue(LogEventLevel value)
- {
- _value = value;
- }
-
- ///
- /// This method will apply only upper or lower case formatting, not fixed width
- ///
- public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
- {
- if (format != null && (format.Length == 2 || format.Length == 3))
- {
- // Using int.Parse() here requires allocating a string to exclude the first character prefix.
- // Junk like "wxy" will be accepted but produce benign results.
- var width = format[1] - '0';
- if (format.Length == 3)
- {
- width *= 10;
- width += format[2] - '0';
- }
-
- if (width < 1)
- return;
-
- if (width > 4)
- {
- var value = _value.ToString();
- if (value.Length > width)
- value = value.Substring(0, width);
- output.Write(Casing.Format(value));
- return;
- }
-
- var index = (int)_value;
- if (index >= 0 && index <= (int) LogEventLevel.Fatal)
- {
- switch (format[0])
- {
- case 'w':
- output.Write(_lowercaseLevelMap[index][width - 1]);
- return;
- case 'u':
- output.Write(_uppercaseLevelMap[index][width - 1]);
- return;
- case 't':
- output.Write(_titleCaseLevelMap[index][width - 1]);
- return;
- }
- }
- }
-
- output.Write(Casing.Format(_value.ToString(), format));
- }
- }
-}
\ No newline at end of file
diff --git a/src/Serilog/Formatting/Display/MessageTemplateTextFormatter.cs b/src/Serilog/Formatting/Display/MessageTemplateTextFormatter.cs
index 0c1ae7f8d..ac45223db 100644
--- a/src/Serilog/Formatting/Display/MessageTemplateTextFormatter.cs
+++ b/src/Serilog/Formatting/Display/MessageTemplateTextFormatter.cs
@@ -1,4 +1,4 @@
-// Copyright 2013-2015 Serilog Contributors
+// Copyright 2013-2017 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -13,10 +13,10 @@
// limitations under the License.
using System;
-using System.Collections.Generic;
using System.IO;
using Serilog.Events;
using Serilog.Parsing;
+using Serilog.Rendering;
namespace Serilog.Formatting.Display
{
@@ -58,42 +58,70 @@ public void Format(LogEvent logEvent, TextWriter output)
if (logEvent == null) throw new ArgumentNullException(nameof(logEvent));
if (output == null) throw new ArgumentNullException(nameof(output));
- // This could be lazier: the output properties include
- // everything from the log event, but often we won't need any more than
- // just the standard timestamp/message etc.
- var outputProperties = OutputProperties.GetOutputProperties(logEvent, _outputTemplate);
-
foreach (var token in _outputTemplate.Tokens)
{
- var pt = token as PropertyToken;
- if (pt == null)
+ if (token is TextToken tt)
{
- token.Render(outputProperties, output, _formatProvider);
+ MessageTemplateRenderer.RenderTextToken(tt, output);
continue;
}
- // First variation from normal rendering - if a property is missing,
- // don't render anything (message templates render the raw token here).
- LogEventPropertyValue propertyValue;
- if (!outputProperties.TryGetValue(pt.PropertyName, out propertyValue))
- continue;
-
- // Second variation; if the value is a scalar string, use literal
- // rendering and support some additional formats: 'u' for uppercase
- // and 'w' for lowercase.
- var sv = propertyValue as ScalarValue;
- if (sv != null && sv.Value is string)
+ var pt = (PropertyToken)token;
+ if (pt.PropertyName == OutputProperties.LevelPropertyName)
{
- var overridden = new Dictionary
- {
- { pt.PropertyName, new LiteralStringValue((string) sv.Value) }
- };
-
- token.Render(overridden, output, _formatProvider);
+ var moniker = LevelOutputFormat.GetLevelMoniker(logEvent.Level, pt.Format);
+ Padding.Apply(output, moniker, pt.Alignment);
+ }
+ else if (pt.PropertyName == OutputProperties.NewLinePropertyName)
+ {
+ Padding.Apply(output, Environment.NewLine, pt.Alignment);
+ }
+ else if (pt.PropertyName == OutputProperties.ExceptionPropertyName)
+ {
+ var exception = logEvent.Exception == null ? "" : logEvent.Exception + Environment.NewLine;
+ Padding.Apply(output, exception, pt.Alignment);
}
else
{
- token.Render(outputProperties, output, _formatProvider);
+ // In this block, `writer` may be used to buffer output so that
+ // padding can be applied.
+ var writer = pt.Alignment.HasValue ? new StringWriter() : output;
+
+ if (pt.PropertyName == OutputProperties.MessagePropertyName)
+ {
+ MessageTemplateRenderer.Render(logEvent.MessageTemplate, logEvent.Properties, writer, pt.Format, _formatProvider);
+ }
+ else if (pt.PropertyName == OutputProperties.TimestampPropertyName)
+ {
+ ScalarValue.Render(logEvent.Timestamp, writer, pt.Format, _formatProvider);
+ }
+ else if (pt.PropertyName == OutputProperties.PropertiesPropertyName)
+ {
+ PropertiesOutputFormat.Render(logEvent.MessageTemplate, logEvent.Properties, _outputTemplate, writer, _formatProvider);
+ }
+ else
+ {
+ // If a property is missing, don't render anything (message templates render the raw token here).
+ LogEventPropertyValue propertyValue;
+ if (!logEvent.Properties.TryGetValue(pt.PropertyName, out propertyValue))
+ continue;
+
+ // If the value is a scalar string, support some additional formats: 'u' for uppercase
+ // and 'w' for lowercase.
+ var sv = propertyValue as ScalarValue;
+ if (sv?.Value is string literalString)
+ {
+ var cased = Casing.Format(literalString, pt.Format);
+ writer.Write(cased);
+ }
+ else
+ {
+ propertyValue.Render(output, pt.Format, _formatProvider);
+ }
+ }
+
+ if (pt.Alignment.HasValue)
+ Padding.Apply(output, ((StringWriter)writer).ToString(), pt.Alignment);
}
}
}
diff --git a/src/Serilog/Formatting/Display/LiteralStringValue.cs b/src/Serilog/Formatting/Display/Obsolete/LiteralStringValue.cs
similarity index 86%
rename from src/Serilog/Formatting/Display/LiteralStringValue.cs
rename to src/Serilog/Formatting/Display/Obsolete/LiteralStringValue.cs
index 82f172536..e7bc44023 100644
--- a/src/Serilog/Formatting/Display/LiteralStringValue.cs
+++ b/src/Serilog/Formatting/Display/Obsolete/LiteralStringValue.cs
@@ -15,19 +15,20 @@
using System;
using System.IO;
using Serilog.Events;
+using Serilog.Rendering;
-namespace Serilog.Formatting.Display
+namespace Serilog.Formatting.Display.Obsolete
{
// A special case (non-null) string value for use in output
// templates. Does not apply "quoted" formatting by default.
+ [Obsolete("Not used by the current output formatting implementation.")]
class LiteralStringValue : LogEventPropertyValue
{
readonly string _value;
public LiteralStringValue(string value)
{
- if (value == null) throw new ArgumentNullException(nameof(value));
- _value = value;
+ _value = value ?? throw new ArgumentNullException(nameof(value));
}
public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
diff --git a/src/Serilog/Formatting/Display/Obsolete/LogEventLevelValue.cs b/src/Serilog/Formatting/Display/Obsolete/LogEventLevelValue.cs
new file mode 100644
index 000000000..293990f5a
--- /dev/null
+++ b/src/Serilog/Formatting/Display/Obsolete/LogEventLevelValue.cs
@@ -0,0 +1,40 @@
+// Copyright 2013-2015 Serilog Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.IO;
+
+using Serilog.Events;
+
+namespace Serilog.Formatting.Display.Obsolete
+{
+ [Obsolete("Not used by the current output formatting implementation.")]
+ class LogEventLevelValue : LogEventPropertyValue
+ {
+ readonly LogEventLevel _value;
+
+ public LogEventLevelValue(LogEventLevel value)
+ {
+ _value = value;
+ }
+
+ ///
+ /// This method will apply only upper or lower case formatting, not fixed width
+ ///
+ public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
+ {
+ output.Write(LevelOutputFormat.GetLevelMoniker(_value, format));
+ }
+ }
+}
diff --git a/src/Serilog/Formatting/Display/Obsolete/LogEventPropertiesValue.cs b/src/Serilog/Formatting/Display/Obsolete/LogEventPropertiesValue.cs
new file mode 100644
index 000000000..a0b089152
--- /dev/null
+++ b/src/Serilog/Formatting/Display/Obsolete/LogEventPropertiesValue.cs
@@ -0,0 +1,41 @@
+// Copyright 2017 Serilog Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Serilog.Events;
+
+namespace Serilog.Formatting.Display.Obsolete
+{
+ [Obsolete("Not used by the current output formatting implementation.")]
+ class LogEventPropertiesValue : LogEventPropertyValue
+ {
+ readonly MessageTemplate _template;
+ readonly IReadOnlyDictionary _properties;
+ readonly MessageTemplate _outputTemplate;
+
+ public LogEventPropertiesValue(MessageTemplate template, IReadOnlyDictionary properties, MessageTemplate outputTemplate)
+ {
+ _template = template;
+ _properties = properties;
+ _outputTemplate = outputTemplate;
+ }
+
+ public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
+ {
+ PropertiesOutputFormat.Render(_template, _properties, _outputTemplate, output, formatProvider);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Serilog/Formatting/Display/LogEventPropertyMessageValue.cs b/src/Serilog/Formatting/Display/Obsolete/LogEventPropertyMessageValue.cs
similarity index 91%
rename from src/Serilog/Formatting/Display/LogEventPropertyMessageValue.cs
rename to src/Serilog/Formatting/Display/Obsolete/LogEventPropertyMessageValue.cs
index f021962cd..9507a7fb2 100644
--- a/src/Serilog/Formatting/Display/LogEventPropertyMessageValue.cs
+++ b/src/Serilog/Formatting/Display/Obsolete/LogEventPropertyMessageValue.cs
@@ -17,8 +17,9 @@
using System.IO;
using Serilog.Events;
-namespace Serilog.Formatting.Display
+namespace Serilog.Formatting.Display.Obsolete
{
+ [Obsolete("Not used by the current output formatting implementation.")]
class LogEventPropertyMessageValue : LogEventPropertyValue
{
readonly MessageTemplate _template;
diff --git a/src/Serilog/Formatting/Display/OutputProperties.cs b/src/Serilog/Formatting/Display/OutputProperties.cs
index 14065c4db..c1b2cf8c8 100644
--- a/src/Serilog/Formatting/Display/OutputProperties.cs
+++ b/src/Serilog/Formatting/Display/OutputProperties.cs
@@ -1,4 +1,4 @@
-// Copyright 2013-2015 Serilog Contributors
+// Copyright 2013-2017 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
using System.Collections.Generic;
using System.Linq;
using Serilog.Events;
+using Serilog.Formatting.Display.Obsolete;
+
+#pragma warning disable 618
namespace Serilog.Formatting.Display
{
@@ -62,7 +65,7 @@ public static class OutputProperties
///
/// The log event.
/// A dictionary with properties representing the log event.
- [Obsolete("Pass the full output template using the other overload.")]
+ [Obsolete("These implementation details of output formatting will not be exposed in a future version.")]
public static IReadOnlyDictionary GetOutputProperties(LogEvent logEvent)
{
return GetOutputProperties(logEvent, MessageTemplate.Empty);
@@ -74,7 +77,7 @@ public static IReadOnlyDictionary GetOutputProper
/// The log event.
/// The output template.
/// A dictionary with properties representing the log event.
- public static IReadOnlyDictionary GetOutputProperties(LogEvent logEvent, MessageTemplate outputTemplate)
+ internal static IReadOnlyDictionary GetOutputProperties(LogEvent logEvent, MessageTemplate outputTemplate)
{
var result = logEvent.Properties.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
@@ -94,4 +97,4 @@ public static IReadOnlyDictionary GetOutputProper
return result;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Serilog/Formatting/Display/Padding.cs b/src/Serilog/Formatting/Display/Padding.cs
deleted file mode 100644
index de6744f34..000000000
--- a/src/Serilog/Formatting/Display/Padding.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using System.IO;
-
-using Serilog.Parsing;
-
-namespace Serilog.Formatting.Display
-{
- static class Padding
- {
- ///
- /// Writes the provided value to the output, applying direction-based padding when is provided.
- ///
- public static void Apply(TextWriter output, string value, Alignment? alignment)
- {
- if (!alignment.HasValue)
- {
- output.Write(value);
- return;
- }
-
- var pad = alignment.Value.Width - value.Length;
-
- if (alignment.Value.Direction == AlignmentDirection.Right)
- output.Write(new string(' ', pad));
-
- output.Write(value);
-
- if (alignment.Value.Direction == AlignmentDirection.Left)
- output.Write(new string(' ', pad));
- }
- }
-}
\ No newline at end of file
diff --git a/src/Serilog/Formatting/Display/LogEventPropertiesValue.cs b/src/Serilog/Formatting/Display/PropertiesOutputFormat.cs
similarity index 66%
rename from src/Serilog/Formatting/Display/LogEventPropertiesValue.cs
rename to src/Serilog/Formatting/Display/PropertiesOutputFormat.cs
index 1e47f0ee7..ac2b5b807 100644
--- a/src/Serilog/Formatting/Display/LogEventPropertiesValue.cs
+++ b/src/Serilog/Formatting/Display/PropertiesOutputFormat.cs
@@ -1,4 +1,4 @@
-// Copyright 2017 Serilog Contributors
+// Copyright 2017 Serilog Contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,32 +19,21 @@
namespace Serilog.Formatting.Display
{
- class LogEventPropertiesValue : LogEventPropertyValue
+ static class PropertiesOutputFormat
{
- readonly MessageTemplate _template;
- readonly IReadOnlyDictionary _properties;
- readonly MessageTemplate _outputTemplate;
-
- public LogEventPropertiesValue(MessageTemplate template, IReadOnlyDictionary properties, MessageTemplate outputTemplate)
- {
- _template = template;
- _properties = properties;
- _outputTemplate = outputTemplate;
- }
-
- public override void Render(TextWriter output, string format = null, IFormatProvider formatProvider = null)
+ public static void Render(MessageTemplate template, IReadOnlyDictionary properties, MessageTemplate outputTemplate, TextWriter output, IFormatProvider formatProvider = null)
{
output.Write('{');
var delim = "";
- foreach (var kvp in _properties)
+ foreach (var kvp in properties)
{
- if (TemplateContainsPropertyName(_template, kvp.Key))
+ if (TemplateContainsPropertyName(template, kvp.Key))
{
continue;
}
- if (TemplateContainsPropertyName(_outputTemplate, kvp.Key))
+ if (TemplateContainsPropertyName(outputTemplate, kvp.Key))
{
continue;
}
diff --git a/src/Serilog/Formatting/Json/JsonFormatter.cs b/src/Serilog/Formatting/Json/JsonFormatter.cs
index aded1eb29..5e762ad7c 100644
--- a/src/Serilog/Formatting/Json/JsonFormatter.cs
+++ b/src/Serilog/Formatting/Json/JsonFormatter.cs
@@ -21,6 +21,7 @@
using System.Linq;
using Serilog.Events;
using Serilog.Parsing;
+using Serilog.Rendering;
namespace Serilog.Formatting.Json
{
@@ -207,7 +208,7 @@ protected virtual void WriteRenderingsValues(IGrouping[]
WriteJsonProperty("Format", format.Format, ref eldelim, output);
var sw = new StringWriter();
- format.Render(properties, sw);
+ MessageTemplateRenderer.RenderPropertyToken(format, properties, sw, _formatProvider, true, false);
WriteJsonProperty("Rendering", sw.ToString(), ref eldelim, output);
output.Write("}");
diff --git a/src/Serilog/Formatting/Raw/RawFormatter.cs b/src/Serilog/Formatting/Raw/RawFormatter.cs
index 95ad05e3b..6138c190e 100644
--- a/src/Serilog/Formatting/Raw/RawFormatter.cs
+++ b/src/Serilog/Formatting/Raw/RawFormatter.cs
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+using System;
using System.IO;
using Serilog.Events;
@@ -20,6 +21,7 @@ namespace Serilog.Formatting.Raw
///
/// Formats log events as a raw dump of the message template and properties.
///
+ [Obsolete("A JSON-based formatter such as `Serilog.Formatting.Compact.CompactJsonFormatter` is recommended for this task.")]
public class RawFormatter : ITextFormatter
{
///
diff --git a/src/Serilog/LoggerConfiguration.cs b/src/Serilog/LoggerConfiguration.cs
index bc39b5e4b..f24e2dc6c 100644
--- a/src/Serilog/LoggerConfiguration.cs
+++ b/src/Serilog/LoggerConfiguration.cs
@@ -15,12 +15,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Serilog.Capturing;
using Serilog.Configuration;
using Serilog.Core;
using Serilog.Core.Enrichers;
using Serilog.Core.Sinks;
using Serilog.Events;
-using Serilog.Parameters;
namespace Serilog
{
diff --git a/src/Serilog/Parsing/MessageTemplateToken.cs b/src/Serilog/Parsing/MessageTemplateToken.cs
index 52a3abcb2..a7cc83ba1 100644
--- a/src/Serilog/Parsing/MessageTemplateToken.cs
+++ b/src/Serilog/Parsing/MessageTemplateToken.cs
@@ -50,6 +50,7 @@ protected MessageTemplateToken(int startIndex)
/// Properties that may be represented by the token.
/// Output for the rendered string.
/// Supplies culture-specific formatting information, or null.
+ // ReSharper disable once UnusedMemberInSuper.Global
public abstract void Render(IReadOnlyDictionary properties, TextWriter output, IFormatProvider formatProvider = null);
}
}
\ No newline at end of file
diff --git a/src/Serilog/Parsing/PropertyToken.cs b/src/Serilog/Parsing/PropertyToken.cs
index ef4db7c3a..01dcc2109 100644
--- a/src/Serilog/Parsing/PropertyToken.cs
+++ b/src/Serilog/Parsing/PropertyToken.cs
@@ -18,14 +18,14 @@
using System.Globalization;
using System.IO;
using Serilog.Events;
-using Serilog.Formatting.Display;
+using Serilog.Rendering;
namespace Serilog.Parsing
{
///
/// A message template token representing a log event property.
///
- public class PropertyToken : MessageTemplateToken
+ public sealed class PropertyToken : MessageTemplateToken
{
readonly string _rawText;
readonly int? _position;
@@ -57,12 +57,10 @@ public PropertyToken(string propertyName, string rawText, string formatObsolete,
public PropertyToken(string propertyName, string rawText, string format = null, Alignment? alignment = null, Destructuring destructuring = Destructuring.Default, int startIndex = -1)
: base(startIndex)
{
- if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
- if (rawText == null) throw new ArgumentNullException(nameof(rawText));
- PropertyName = propertyName;
+ PropertyName = propertyName ?? throw new ArgumentNullException(nameof(propertyName));
Format = format;
Destructuring = destructuring;
- _rawText = rawText;
+ _rawText = rawText ?? throw new ArgumentNullException(nameof(rawText));
Alignment = alignment;
int position;
@@ -89,30 +87,7 @@ public override void Render(IReadOnlyDictionary p
if (properties == null) throw new ArgumentNullException(nameof(properties));
if (output == null) throw new ArgumentNullException(nameof(output));
- LogEventPropertyValue propertyValue;
- if (!properties.TryGetValue(PropertyName, out propertyValue))
- {
- output.Write(_rawText);
- return;
- }
-
- if (!Alignment.HasValue)
- {
- propertyValue.Render(output, Format, formatProvider);
- return;
- }
-
- var valueOutput = new StringWriter();
- propertyValue.Render(valueOutput, Format, formatProvider);
- var value = valueOutput.ToString();
-
- if (value.Length >= Alignment.Value.Width)
- {
- output.Write(value);
- return;
- }
-
- Padding.Apply(output, value, Alignment.Value);
+ MessageTemplateRenderer.RenderPropertyToken(this, properties, output, formatProvider, false, false);
}
///
@@ -140,6 +115,8 @@ public override void Render(IReadOnlyDictionary p
///
public bool IsPositional => _position.HasValue;
+ internal string RawText => _rawText;
+
///
/// Try to get the integer value represented by the property name.
///
diff --git a/src/Serilog/Parsing/TextToken.cs b/src/Serilog/Parsing/TextToken.cs
index 9035d57d1..493a1b56d 100644
--- a/src/Serilog/Parsing/TextToken.cs
+++ b/src/Serilog/Parsing/TextToken.cs
@@ -16,13 +16,14 @@
using System.Collections.Generic;
using System.IO;
using Serilog.Events;
+using Serilog.Rendering;
namespace Serilog.Parsing
{
///
/// A message template token representing literal text.
///
- public class TextToken : MessageTemplateToken
+ public sealed class TextToken : MessageTemplateToken
{
///
/// Construct a .
@@ -32,8 +33,7 @@ public class TextToken : MessageTemplateToken
///
public TextToken(string text, int startIndex = -1) : base(startIndex)
{
- if (text == null) throw new ArgumentNullException(nameof(text));
- Text = text;
+ Text = text ?? throw new ArgumentNullException(nameof(text));
}
///
@@ -50,7 +50,7 @@ public TextToken(string text, int startIndex = -1) : base(startIndex)
public override void Render(IReadOnlyDictionary properties, TextWriter output, IFormatProvider formatProvider = null)
{
if (output == null) throw new ArgumentNullException(nameof(output));
- output.Write(Text);
+ MessageTemplateRenderer.RenderTextToken(this, output);
}
///
diff --git a/src/Serilog/Formatting/Display/Casing.cs b/src/Serilog/Rendering/Casing.cs
similarity index 53%
rename from src/Serilog/Formatting/Display/Casing.cs
rename to src/Serilog/Rendering/Casing.cs
index b024e8b87..62aa022f5 100644
--- a/src/Serilog/Formatting/Display/Casing.cs
+++ b/src/Serilog/Rendering/Casing.cs
@@ -1,4 +1,18 @@
-namespace Serilog.Formatting.Display
+// Copyright 2013-2017 Serilog Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Serilog.Rendering
{
static class Casing
{
diff --git a/src/Serilog/Rendering/MessageTemplateRenderer.cs b/src/Serilog/Rendering/MessageTemplateRenderer.cs
new file mode 100644
index 000000000..090e39e98
--- /dev/null
+++ b/src/Serilog/Rendering/MessageTemplateRenderer.cs
@@ -0,0 +1,109 @@
+// Copyright 2013-2017 Serilog Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+using Serilog.Events;
+using Serilog.Formatting.Json;
+using Serilog.Parsing;
+
+namespace Serilog.Rendering
+{
+ static class MessageTemplateRenderer
+ {
+ static JsonValueFormatter JsonValueFormatter = new JsonValueFormatter("$type");
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void Render(MessageTemplate messageTemplate, IReadOnlyDictionary properties, TextWriter output, string format = null, IFormatProvider formatProvider = null)
+ {
+ bool isLiteral = false, isJson = false;
+
+ if (format != null)
+ {
+ for (var i = 0; i < format.Length; ++i)
+ {
+ if (format[i] == 'l')
+ isLiteral = true;
+ else if (format[i] == 'j')
+ isJson = true;
+ }
+ }
+
+ for (var ti = 0; ti < messageTemplate.TokenArray.Length; ++ti)
+ {
+ var token = messageTemplate.TokenArray[ti];
+ if (token is TextToken tt)
+ {
+ RenderTextToken(tt, output);
+ }
+ else
+ {
+ var pt = (PropertyToken) token;
+ RenderPropertyToken(pt, properties, output, formatProvider, isLiteral, isJson);
+ }
+ }
+ }
+
+ public static void RenderTextToken(TextToken tt, TextWriter output)
+ {
+ output.Write(tt.Text);
+ }
+
+ public static void RenderPropertyToken(PropertyToken pt, IReadOnlyDictionary properties, TextWriter output, IFormatProvider formatProvider, bool isLiteral, bool isJson)
+ {
+ LogEventPropertyValue propertyValue;
+ if (!properties.TryGetValue(pt.PropertyName, out propertyValue))
+ {
+ output.Write(pt.RawText);
+ return;
+ }
+
+ if (!pt.Alignment.HasValue)
+ {
+ RenderValue(propertyValue, isLiteral, isJson, output, pt.Format, formatProvider);
+ return;
+ }
+
+ var valueOutput = new StringWriter();
+ RenderValue(propertyValue, isLiteral, isJson, valueOutput, pt.Format, formatProvider);
+ var value = valueOutput.ToString();
+
+ if (value.Length >= pt.Alignment.Value.Width)
+ {
+ output.Write(value);
+ return;
+ }
+
+ Padding.Apply(output, value, pt.Alignment.Value);
+ }
+
+ static void RenderValue(LogEventPropertyValue propertyValue, bool literal, bool json, TextWriter output, string format, IFormatProvider formatProvider)
+ {
+ if (literal && propertyValue is ScalarValue sv && sv.Value is string str)
+ {
+ output.Write(str);
+ }
+ else if (json)
+ {
+ JsonValueFormatter.Format(propertyValue, output);
+ }
+ else
+ {
+ propertyValue.Render(output, format, formatProvider);
+ }
+ }
+ }
+}
diff --git a/src/Serilog/Rendering/Padding.cs b/src/Serilog/Rendering/Padding.cs
new file mode 100644
index 000000000..23ea8206e
--- /dev/null
+++ b/src/Serilog/Rendering/Padding.cs
@@ -0,0 +1,53 @@
+// Copyright 2013-2017 Serilog Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System.IO;
+using Serilog.Parsing;
+
+namespace Serilog.Rendering
+{
+ static class Padding
+ {
+ static readonly char[] PaddingChars = new string(' ', 80).ToCharArray();
+
+ ///
+ /// Writes the provided value to the output, applying direction-based padding when is provided.
+ ///
+ public static void Apply(TextWriter output, string value, Alignment? alignment)
+ {
+ if (!alignment.HasValue || value.Length >= alignment.Value.Width)
+ {
+ output.Write(value);
+ return;
+ }
+
+ var pad = alignment.Value.Width - value.Length;
+
+ if (alignment.Value.Direction == AlignmentDirection.Left)
+ output.Write(value);
+
+ if (pad <= PaddingChars.Length)
+ {
+ output.Write(PaddingChars, 0, pad);
+ }
+ else
+ {
+ output.Write(new string(' ', pad));
+ }
+
+ if (alignment.Value.Direction == AlignmentDirection.Right)
+ output.Write(value);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Serilog/Serilog.csproj b/src/Serilog/Serilog.csproj
index ad479c83b..0e6af3504 100644
--- a/src/Serilog/Serilog.csproj
+++ b/src/Serilog/Serilog.csproj
@@ -18,6 +18,8 @@
false
true
+ True
+
diff --git a/test/Serilog.PerformanceTests/LevelControlBenchmark.cs b/test/Serilog.PerformanceTests/LevelControlBenchmark.cs
index 899212357..6f29e9883 100644
--- a/test/Serilog.PerformanceTests/LevelControlBenchmark.cs
+++ b/test/Serilog.PerformanceTests/LevelControlBenchmark.cs
@@ -1,11 +1,7 @@
using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Running;
-using Serilog;
using Serilog.Core;
using Serilog.Events;
-using System;
using Serilog.PerformanceTests.Support;
-using Xunit;
namespace Serilog.PerformanceTests
{
diff --git a/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs b/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs
index c353fccfb..e7ea19867 100644
--- a/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs
+++ b/test/Serilog.PerformanceTests/LogContextEnrichmentBenchmark.cs
@@ -1,10 +1,6 @@
using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Running;
-using Serilog;
using Serilog.Context;
-using System;
using Serilog.PerformanceTests.Support;
-using Xunit;
using Serilog.Events;
namespace Serilog.PerformanceTests
diff --git a/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs b/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs
index d9c3fcfe3..e5ae2fd9b 100644
--- a/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs
+++ b/test/Serilog.PerformanceTests/MessageTemplateParsingBenchmark.cs
@@ -1,19 +1,12 @@
using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Running;
-using Serilog;
-using Serilog.Events;
using Serilog.Parsing;
-using System;
-using System.Linq;
-using System.Collections;
-using System.Collections.Generic;
-using Xunit;
namespace Serilog.PerformanceTests
{
///
/// Tests the cost of parsing various message templates.
///
+ [MemoryDiagnoser]
public class MessageTemplateParsingBenchmark
{
MessageTemplateParser _parser;
diff --git a/test/Serilog.PerformanceTests/MessageTemplateRenderingBenchmark.cs b/test/Serilog.PerformanceTests/MessageTemplateRenderingBenchmark.cs
index 76023f421..486b79e8d 100644
--- a/test/Serilog.PerformanceTests/MessageTemplateRenderingBenchmark.cs
+++ b/test/Serilog.PerformanceTests/MessageTemplateRenderingBenchmark.cs
@@ -8,6 +8,7 @@ namespace Serilog.PerformanceTests
///
/// Determines the cost of rendering a message template.
///
+ [MemoryDiagnoser]
public class MessageTemplateRenderingBenchmark
{
static readonly LogEvent NoProperties =
@@ -17,14 +18,7 @@ public class MessageTemplateRenderingBenchmark
Some.InformationEvent("Processed {@Position} for {Task} in {Elapsed:000} ms",
new { Latitude = 25, Longitude = 134 }, "Benchmark", 34);
- readonly StringWriter _output = new StringWriter();
-
- [Setup]
- public void Setup()
- {
- _output.GetStringBuilder().Length = 0;
- _output.GetStringBuilder().Capacity = 1024; // Only a few dozen chars actually needed here.
- }
+ readonly TextWriter _output = new NullTextWriter();
[Benchmark]
public void TemplateWithNoProperties()
diff --git a/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs b/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs
index 537a60371..578fd6de3 100644
--- a/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs
+++ b/test/Serilog.PerformanceTests/NestedLoggerLatencyBenchmark.cs
@@ -1,9 +1,5 @@
using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Running;
-using Serilog;
-using System;
using Serilog.PerformanceTests.Support;
-using Xunit;
using Serilog.Events;
namespace Serilog.PerformanceTests
diff --git a/test/Serilog.PerformanceTests/OutputTemplateRenderingBenchmark.cs b/test/Serilog.PerformanceTests/OutputTemplateRenderingBenchmark.cs
index cae6a892d..60310df85 100644
--- a/test/Serilog.PerformanceTests/OutputTemplateRenderingBenchmark.cs
+++ b/test/Serilog.PerformanceTests/OutputTemplateRenderingBenchmark.cs
@@ -11,20 +11,14 @@ namespace Serilog.PerformanceTests
/// Determines the cost of rendering an event out to one of the typical text targets,
/// like the console or a text file.
///
+ [MemoryDiagnoser]
public class OutputTemplateRenderingBenchmark
{
const string DefaultFileOutputTemplate = "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}";
static readonly LogEvent HelloWorldEvent = Some.InformationEvent("Hello, {Name}", "World");
static readonly MessageTemplateTextFormatter Formatter = new MessageTemplateTextFormatter(DefaultFileOutputTemplate, CultureInfo.InvariantCulture);
- readonly StringWriter _output = new StringWriter();
-
- [Setup]
- public void Setup()
- {
- _output.GetStringBuilder().Length = 0;
- _output.GetStringBuilder().Capacity = 1024; // Only a few dozen chars actually needed here.
- }
+ readonly TextWriter _output = new NullTextWriter();
[Benchmark]
public void FormatToOutput()
diff --git a/test/Serilog.PerformanceTests/PipelineBenchmark.cs b/test/Serilog.PerformanceTests/PipelineBenchmark.cs
index 6812f2345..784dd97a8 100644
--- a/test/Serilog.PerformanceTests/PipelineBenchmark.cs
+++ b/test/Serilog.PerformanceTests/PipelineBenchmark.cs
@@ -14,22 +14,15 @@
// limitations under the License.
using BenchmarkDotNet.Attributes;
-using BenchmarkDotNet.Running;
-using Serilog;
-using Serilog.Events;
-using Serilog.Parsing;
using System;
-using System.Linq;
-using System.Collections;
-using System.Collections.Generic;
using Serilog.PerformanceTests.Support;
-using Xunit;
namespace Serilog.PerformanceTests
{
///
/// Tests the cost of writing through the logging pipeline.
///
+ [MemoryDiagnoser]
public class PipelineBenchmark
{
ILogger _log;
diff --git a/test/Serilog.PerformanceTests/Support/NullTextWriter.cs b/test/Serilog.PerformanceTests/Support/NullTextWriter.cs
new file mode 100644
index 000000000..680eac502
--- /dev/null
+++ b/test/Serilog.PerformanceTests/Support/NullTextWriter.cs
@@ -0,0 +1,160 @@
+using System;
+using System.IO;
+using System.Text;
+
+namespace Serilog.PerformanceTests.Support
+{
+ class NullTextWriter : TextWriter
+ {
+ public override void Write(char value)
+ {
+ }
+
+ public override Encoding Encoding { get; } = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
+
+ public override void Write(bool value)
+ {
+ }
+
+ public override void Write(char[] buffer)
+ {
+ }
+
+ public override void Write(char[] buffer, int index, int count)
+ {
+ }
+
+ public override void Write(decimal value)
+ {
+ }
+
+ public override void Write(double value)
+ {
+ }
+
+ public override void Write(int value)
+ {
+ }
+
+ public override void Write(long value)
+ {
+ }
+
+ public override void Write(object value)
+ {
+ }
+
+ public override void Write(float value)
+ {
+ }
+
+ public override void Write(string value)
+ {
+ }
+
+ public override void Write(string format, object arg0)
+ {
+ }
+
+ public override void Write(string format, object arg0, object arg1)
+ {
+ }
+
+ public override void Write(string format, object arg0, object arg1, object arg2)
+ {
+ }
+
+ public override void Write(string format, params object[] arg)
+ {
+ }
+
+ public override void Write(uint value)
+ {
+ }
+
+ public override void Write(ulong value)
+ {
+ }
+
+ public override string ToString()
+ {
+ return String.Empty;
+ }
+
+ public override void Flush()
+ {
+ }
+
+ public override void WriteLine()
+ {
+ }
+
+ public override void WriteLine(bool value)
+ {
+ }
+
+ public override void WriteLine(char value)
+ {
+ }
+
+ public override void WriteLine(char[] buffer)
+ {
+ }
+
+ public override void WriteLine(char[] buffer, int index, int count)
+ {
+ }
+
+ public override void WriteLine(decimal value)
+ {
+ }
+
+ public override void WriteLine(double value)
+ {
+ }
+
+ public override void WriteLine(int value)
+ {
+ }
+
+ public override void WriteLine(long value)
+ {
+ }
+
+ public override void WriteLine(object value)
+ {
+ }
+
+ public override void WriteLine(float value)
+ {
+ }
+
+ public override void WriteLine(string value)
+ {
+ }
+
+ public override void WriteLine(string format, object arg0)
+ {
+ }
+
+ public override void WriteLine(string format, object arg0, object arg1)
+ {
+ }
+
+ public override void WriteLine(string format, object arg0, object arg1, object arg2)
+ {
+ }
+
+ public override void WriteLine(string format, params object[] arg)
+ {
+ }
+
+ public override void WriteLine(uint value)
+ {
+ }
+
+ public override void WriteLine(ulong value)
+ {
+ }
+ }
+}
diff --git a/test/Serilog.PerformanceTests/Support/Some.cs b/test/Serilog.PerformanceTests/Support/Some.cs
index e1284b02c..655eedd7e 100644
--- a/test/Serilog.PerformanceTests/Support/Some.cs
+++ b/test/Serilog.PerformanceTests/Support/Some.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using Serilog.Events;
namespace Serilog.PerformanceTests.Support
diff --git a/test/Serilog.Tests/Parameters/PropertyValueConverterTests.cs b/test/Serilog.Tests/Capturing/PropertyValueConverterTests.cs
similarity index 99%
rename from test/Serilog.Tests/Parameters/PropertyValueConverterTests.cs
rename to test/Serilog.Tests/Capturing/PropertyValueConverterTests.cs
index 732b737ad..6534a35ef 100644
--- a/test/Serilog.Tests/Parameters/PropertyValueConverterTests.cs
+++ b/test/Serilog.Tests/Capturing/PropertyValueConverterTests.cs
@@ -1,20 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using Serilog.Capturing;
using System.Threading.Tasks;
using System.Threading;
-using Xunit;
using Serilog.Core;
using Serilog.Events;
-using Serilog.Parameters;
using Serilog.Parsing;
using Serilog.Tests.Support;
+using Xunit;
// ReSharper disable UnusedAutoPropertyAccessor.Global, UnusedParameter.Local
-namespace Serilog.Tests.Parameters
+namespace Serilog.Tests.Capturing
{
public class PropertyValueConverterTests
{
diff --git a/test/Serilog.Tests/Core/LogEventPropertyCapturingTests.cs b/test/Serilog.Tests/Core/LogEventPropertyCapturingTests.cs
index 07c19f093..8e9f05837 100644
--- a/test/Serilog.Tests/Core/LogEventPropertyCapturingTests.cs
+++ b/test/Serilog.Tests/Core/LogEventPropertyCapturingTests.cs
@@ -1,10 +1,10 @@
using System;
using System.Linq;
using System.Collections.Generic;
+using Serilog.Capturing;
using Serilog.Core;
using Serilog.Debugging;
using Serilog.Events;
-using Serilog.Parameters;
using Serilog.Parsing;
using Serilog.Tests.Support;
using Xunit;
diff --git a/test/Serilog.Tests/Core/MessageTemplateTests.cs b/test/Serilog.Tests/Core/MessageTemplateTests.cs
index b76185d36..8ae5cdb33 100755
--- a/test/Serilog.Tests/Core/MessageTemplateTests.cs
+++ b/test/Serilog.Tests/Core/MessageTemplateTests.cs
@@ -3,9 +3,9 @@
using System.IO;
using System.Linq;
using System.Text;
+using Serilog.Capturing;
using Xunit;
using Serilog.Core;
-using Serilog.Parameters;
using MessageTemplateParser = Serilog.Parsing.MessageTemplateParser;
namespace Serilog.Tests.Core
diff --git a/test/Serilog.Tests/Core/SecondaryLoggerSinkTests.cs b/test/Serilog.Tests/Core/SecondaryLoggerSinkTests.cs
index 0408235ed..c84007bf7 100644
--- a/test/Serilog.Tests/Core/SecondaryLoggerSinkTests.cs
+++ b/test/Serilog.Tests/Core/SecondaryLoggerSinkTests.cs
@@ -1,5 +1,4 @@
-using System;
-using Serilog.Tests.Support;
+using Serilog.Tests.Support;
using Xunit;
using Serilog.Core;
using Serilog.Events;
@@ -37,9 +36,10 @@ public void WhenOwnedByCallerSecondaryLoggerIsNotDisposed()
.WriteTo.Sink(secondary)
.CreateLogger();
- ((IDisposable)new LoggerConfiguration()
+ new LoggerConfiguration()
.WriteTo.Logger(secondaryLogger)
- .CreateLogger()).Dispose();
+ .CreateLogger()
+ .Dispose();
Assert.False(secondary.IsDisposed);
}
@@ -49,9 +49,10 @@ public void WhenOwnedByPrimaryLoggerSecondaryIsDisposed()
{
var secondary = new DisposeTrackingSink();
- ((IDisposable)new LoggerConfiguration()
+ new LoggerConfiguration()
.WriteTo.Logger(lc => lc.WriteTo.Sink(secondary))
- .CreateLogger()).Dispose();
+ .CreateLogger()
+ .Dispose();
Assert.True(secondary.IsDisposed);
}
diff --git a/test/Serilog.Tests/Events/LogEventPropertyValueTests.cs b/test/Serilog.Tests/Events/LogEventPropertyValueTests.cs
index 534351075..76d9dfe9f 100644
--- a/test/Serilog.Tests/Events/LogEventPropertyValueTests.cs
+++ b/test/Serilog.Tests/Events/LogEventPropertyValueTests.cs
@@ -15,10 +15,10 @@
using System;
using System.Globalization;
using System.Linq;
+using Serilog.Capturing;
using Xunit;
using Serilog.Core;
using Serilog.Events;
-using Serilog.Parameters;
using Serilog.Parsing;
using Serilog.Tests.Support;
diff --git a/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs b/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs
index 052ee267c..c5e4a3d82 100644
--- a/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs
+++ b/test/Serilog.Tests/Formatting/Display/MessageTemplateTextFormatterTests.cs
@@ -218,5 +218,34 @@ public void DoNotDuplicatePropertiesAlreadyRenderedInOutputTemplate()
formatter.Format(evt, sw);
Assert.Equal("42 {Bar: 42}", sw.ToString());
}
+
+ [Theory]
+ [InlineData("", "Hello, \"World\"!")]
+ [InlineData(":j", "Hello, \"World\"!")]
+ [InlineData(":l", "Hello, World!")]
+ [InlineData(":lj", "Hello, World!")]
+ [InlineData(":jl", "Hello, World!")]
+ public void AppliesLiteralFormattingToMessageStringsWhenSpecified(string format, string expected)
+ {
+ var formatter = new MessageTemplateTextFormatter("{Message" + format + "}", null);
+ var evt = DelegatingSink.GetLogEvent(l => l.Information("Hello, {Name}!", "World"));
+ var sw = new StringWriter();
+ formatter.Format(evt, sw);
+ Assert.Equal(expected, sw.ToString());
+ }
+
+ [Theory]
+ [InlineData("", "{ Name: \"World\" }")]
+ [InlineData(":j", "{\"Name\":\"World\"}")]
+ [InlineData(":lj", "{\"Name\":\"World\"}")]
+ [InlineData(":jl", "{\"Name\":\"World\"}")]
+ public void AppliesJsonFormattingToMessageStructuresWhenSpecified(string format, string expected)
+ {
+ var formatter = new MessageTemplateTextFormatter("{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());
+ }
}
}
diff --git a/test/Serilog.Tests/Formatting/Json/JsonValueFormatterTests.cs b/test/Serilog.Tests/Formatting/Json/JsonValueFormatterTests.cs
index 45e22324a..84aca1af5 100644
--- a/test/Serilog.Tests/Formatting/Json/JsonValueFormatterTests.cs
+++ b/test/Serilog.Tests/Formatting/Json/JsonValueFormatterTests.cs
@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using Serilog.Events;
using Serilog.Formatting.Json;
-using Serilog.Tests.Events;
-using Serilog.Tests.Support;
using Xunit;
namespace Serilog.Tests.Formatting.Json
diff --git a/test/Serilog.Tests/LoggerConfigurationTests.cs b/test/Serilog.Tests/LoggerConfigurationTests.cs
index 61808a6aa..b94d28570 100644
--- a/test/Serilog.Tests/LoggerConfigurationTests.cs
+++ b/test/Serilog.Tests/LoggerConfigurationTests.cs
@@ -1,11 +1,8 @@
using System;
-using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using System.Runtime.InteropServices.ComTypes;
using Xunit;
-using Serilog.Configuration;
using Serilog.Core;
using Serilog.Core.Filters;
using Serilog.Debugging;
@@ -120,7 +117,7 @@ public void DestructuringSystemTypeGivesScalarByDefault()
.WriteTo.Sink(sink)
.CreateLogger();
- var thisType = this.GetType();
+ var thisType = GetType();
logger.Information("{@thisType}", thisType);
var ev = events.Single();
@@ -171,7 +168,7 @@ public void DestructuringIsPossibleForSystemTypeDerivedProperties()
.WriteTo.Sink(sink)
.CreateLogger();
- var thisType = this.GetType();
+ var thisType = GetType();
logger.Information("{@thisType}", thisType);
var ev = events.Single();
@@ -495,7 +492,7 @@ public void HigherMinimumLevelOverridesArePropagated()
.CreateLogger();
logger.Write(Some.InformationEvent());
- logger.ForContext(Serilog.Core.Constants.SourceContextPropertyName, "Microsoft.AspNet.Something").Write(Some.InformationEvent());
+ logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.AspNet.Something").Write(Some.InformationEvent());
logger.ForContext().Write(Some.InformationEvent());
Assert.Equal(2, sink.Events.Count);
@@ -513,7 +510,7 @@ public void LowerMinimumLevelOverridesArePropagated()
.CreateLogger();
logger.Write(Some.InformationEvent());
- logger.ForContext(Serilog.Core.Constants.SourceContextPropertyName, "Microsoft.AspNet.Something").Write(Some.InformationEvent());
+ logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.AspNet.Something").Write(Some.InformationEvent());
logger.ForContext().Write(Some.InformationEvent());
Assert.Equal(1, sink.Events.Count);
@@ -523,7 +520,7 @@ public void LowerMinimumLevelOverridesArePropagated()
public void ExceptionsThrownBySinksAreNotPropagated()
{
var logger = new LoggerConfiguration()
- .WriteTo.Sink(new DelegatingSink(e => { throw new Exception("Boom!"); }))
+ .WriteTo.Sink(new DelegatingSink(e => throw new Exception("Boom!")))
.CreateLogger();
logger.Write(Some.InformationEvent());
diff --git a/test/Serilog.Tests/MethodOverloadConventionTests.cs b/test/Serilog.Tests/MethodOverloadConventionTests.cs
index c634f46e0..1c03f55f6 100644
--- a/test/Serilog.Tests/MethodOverloadConventionTests.cs
+++ b/test/Serilog.Tests/MethodOverloadConventionTests.cs
@@ -10,6 +10,10 @@
using System.Text.RegularExpressions;
using Xunit;
using Xunit.Sdk;
+// ReSharper disable PossibleMultipleEnumeration
+// ReSharper disable UnusedMember.Local
+// ReSharper disable UnusedParameter.Local
+// ReSharper disable AssignNullToNotNullAttribute
namespace Serilog.Tests
{
@@ -97,10 +101,9 @@ public void ValidateWriteEventLogMethods(Type loggerType)
Assert.True(writeMethod.IsPublic);
Assert.Equal(writeMethod.ReturnType, typeof(void));
- LogEventLevel level = LogEventLevel.Information;
+ var level = LogEventLevel.Information;
CollectingSink sink;
-
var logger = GetLogger(loggerType, out sink);
InvokeMethod(writeMethod, logger, new object[] { Some.LogEvent(DateTimeOffset.Now, level) });
@@ -108,8 +111,8 @@ public void ValidateWriteEventLogMethods(Type loggerType)
//handle silent logger special case i.e. no result validation
if (loggerType == typeof(SilentLogger))
return;
- else
- EvaluateSingleResult(level, sink);
+
+ EvaluateSingleResult(level, sink);
}
[Theory]
@@ -158,12 +161,10 @@ public void ValidateForContextMethods(Type loggerType)
{
report.AppendLine($"{testMethod.Name} Invocation Failure on: {method} with: {xunitException.UserMessage}");
}
-
- continue;
}
}
- Assert.True(signatureMatchAndInvokeSuccess, $"{method} did not match any known method or failed invoke\n" + report.ToString());
+ Assert.True(signatureMatchAndInvokeSuccess, $"{method} did not match any known method or failed invoke\n" + report);
}
}
@@ -185,7 +186,7 @@ public void ValidateBindMessageTemplateMethods(Type loggerType)
Assert.Equal(messageTemplateAttr.MessageTemplateParameterName, MessageTemplate);
var parameters = method.GetParameters();
- int index = 0;
+ var index = 0;
Assert.Equal(parameters[index].Name, "messageTemplate");
Assert.Equal(parameters[index].ParameterType, typeof(string));
@@ -203,7 +204,6 @@ public void ValidateBindMessageTemplateMethods(Type loggerType)
Assert.Equal(parameters[index].Name, "boundProperties");
Assert.Equal(parameters[index].ParameterType, typeof(IEnumerable).MakeByRefType());
Assert.True(parameters[index].IsOut);
- index++;
var logger = GetLogger(loggerType);
@@ -242,7 +242,7 @@ public void ValidateBindPropertyMethods(Type loggerType)
Assert.True(method.IsPublic);
var parameters = method.GetParameters();
- int index = 0;
+ var index = 0;
Assert.Equal(parameters[index].Name, "propertyName");
Assert.Equal(parameters[index].ParameterType, typeof(string));
@@ -343,7 +343,7 @@ void ForContextMethod0(MethodInfo method)
{
e.Data.Add("IsSignatureAssertionFailure", true);
- throw e;
+ throw;
}
var logger = GetLogger(method.DeclaringType);
@@ -375,7 +375,7 @@ void ForContextMethod1(MethodInfo method)
{
e.Data.Add("IsSignatureAssertionFailure", true);
- throw e;
+ throw;
}
var logger = GetLogger(method.DeclaringType);
@@ -396,7 +396,7 @@ void ForContextMethod2(MethodInfo method)
var parameters = method.GetParameters();
Assert.Equal(parameters.Length, 3);
- int index = 0;
+ var index = 0;
Assert.Equal(parameters[index].Name, "propertyName");
Assert.Equal(parameters[index].ParameterType, typeof(string));
@@ -414,7 +414,7 @@ void ForContextMethod2(MethodInfo method)
{
e.Data.Add("IsSignatureAssertionFailure", true);
- throw e;
+ throw;
}
var logger = GetLogger(method.DeclaringType);
@@ -464,12 +464,12 @@ void ForContextMethod3(MethodInfo method)
{
e.Data.Add("IsSignatureAssertionFailure", true);
- throw e;
+ throw;
}
var logger = GetLogger(method.DeclaringType);
- var enrichedLogger = InvokeMethod(method, logger, null, new Type[] { typeof(object) });
+ var enrichedLogger = InvokeMethod(method, logger, null, new[] { typeof(object) });
Assert.NotNull(enrichedLogger);
Assert.True(enrichedLogger is ILogger);
@@ -493,7 +493,7 @@ void ForContextMethod4(MethodInfo method)
{
e.Data.Add("IsSignatureAssertionFailure", true);
- throw e;
+ throw;
}
var logger = GetLogger(method.DeclaringType);
@@ -566,7 +566,7 @@ void ValidateConventionForMethodSet(
{
try
{
- Action invokeTestMethod = null;
+ Action invokeTestMethod;
if (testInvokeResults)
invokeTestMethod = InvokeConventionMethodAndTest;
@@ -592,19 +592,17 @@ void ValidateConventionForMethodSet(
{
report.AppendLine($"{testMethod.Name} Invocation Failure on: {method} with: {xunitException.UserMessage}");
}
-
- continue;
}
}
- Assert.True(signatureMatchAndInvokeSuccess, $"{method} did not match any known convention or failed invoke\n" + report.ToString());
+ Assert.True(signatureMatchAndInvokeSuccess, $"{method} did not match any known convention or failed invoke\n" + report);
}
}
// Method0 (string messageTemplate) : void
void ValidateMethod0(MethodInfo method, Action invokeMethod)
{
- VerifyMethodSignature(method, expectedArgCount: 1);
+ VerifyMethodSignature(method);
var parameters = new object[] { "message" };
@@ -616,7 +614,7 @@ void ValidateMethod1(MethodInfo method, Action inv
{
VerifyMethodSignature(method, isGeneric: true, expectedArgCount: 2);
- var typeArgs = new Type[] { typeof(string) };
+ var typeArgs = new[] { typeof(string) };
var parameters = new object[] { "message", "value0" };
@@ -628,7 +626,7 @@ void ValidateMethod2(MethodInfo method, Action inv
{
VerifyMethodSignature(method, isGeneric: true, expectedArgCount: 3);
- var typeArgs = new Type[] { typeof(string), typeof(string) };
+ var typeArgs = new[] { typeof(string), typeof(string) };
var parameters = new object[]
{
@@ -643,7 +641,7 @@ void ValidateMethod3(MethodInfo method, Action inv
{
VerifyMethodSignature(method, isGeneric: true, expectedArgCount: 4);
- var typeArgs = new Type[] { typeof(string), typeof(string), typeof(string) };
+ var typeArgs = new[] { typeof(string), typeof(string), typeof(string) };
var parameters = new object[]
{
@@ -681,7 +679,7 @@ void ValidateMethod6(MethodInfo method, Action inv
{
VerifyMethodSignature(method, hasExceptionArg: true, isGeneric: true, expectedArgCount: 3);
- var typeArgs = new Type[] { typeof(string) };
+ var typeArgs = new[] { typeof(string) };
var parameters = new object[]
{
@@ -696,7 +694,7 @@ void ValidateMethod7(MethodInfo method, Action inv
{
VerifyMethodSignature(method, hasExceptionArg: true, isGeneric: true, expectedArgCount: 4);
- var typeArgs = new Type[] { typeof(string), typeof(string) };
+ var typeArgs = new[] { typeof(string), typeof(string) };
var parameters = new object[]
{
@@ -711,7 +709,7 @@ void ValidateMethod8(MethodInfo method, Action inv
{
VerifyMethodSignature(method, hasExceptionArg: true, isGeneric: true, expectedArgCount: 5);
- var typeArgs = new Type[] { typeof(string), typeof(string), typeof(string) };
+ var typeArgs = new[] { typeof(string), typeof(string), typeof(string) };
var parameters = new object[]
{
@@ -726,7 +724,7 @@ void ValidateMethod9(MethodInfo method, Action inv
{
VerifyMethodSignature(method, hasExceptionArg: true, expectedArgCount: 3);
- object[] parameters = new object[]
+ var parameters = new object[]
{
new Exception("test"), "Processed {value0}, {value1}, {value2}",
new object[] { "value0", "value1", "value2" }
@@ -786,7 +784,7 @@ static void VerifyMethodSignature(MethodInfo method, bool hasExceptionArg = fals
{
var parameters = method.GetParameters();
- int index = 0;
+ var index = 0;
if (method.Name == Write)
{
@@ -822,7 +820,7 @@ static void VerifyMethodSignature(MethodInfo method, bool hasExceptionArg = fals
//multiple generic argument convention T0...Tx : T0 propertyValue0... Tx propertyValueX
if (genericTypeArgs.Length > 1)
{
- for (int i = 0; i < genericTypeArgs.Length; i++, index++)
+ for (var i = 0; i < genericTypeArgs.Length; i++, index++)
{
Assert.Equal(genericTypeArgs[i].Name, $"T{i}");
@@ -867,7 +865,7 @@ static void VerifyMethodSignature(MethodInfo method, bool hasExceptionArg = fals
// mark xunit assertion failures
e.Data.Add("IsSignatureAssertionFailure", true);
- throw e;
+ throw;
}
}
@@ -881,13 +879,14 @@ static object InvokeMethod(
{
if (method.IsGenericMethod)
return method.MakeGenericMethod(typeArgs).Invoke(null, parameters);
- else
- return method.Invoke(null, parameters);
+
+ return method.Invoke(null, parameters);
}
- else if (method.IsGenericMethod)
+
+ if (method.IsGenericMethod)
return method.MakeGenericMethod(typeArgs).Invoke(instance, parameters);
- else
- return method.Invoke(instance, parameters);
+
+ return method.Invoke(instance, parameters);
}
static void EvaluateSingleResult(LogEventLevel level, CollectingSink results)
@@ -920,7 +919,8 @@ static ILogger GetLogger(Type loggerType, out CollectingSink sink, LogEventLevel
.WriteTo.Sink(sink)
.CreateLogger();
}
- else if (loggerType == typeof(Log))
+
+ if (loggerType == typeof(Log))
{
sink = new CollectingSink();
@@ -933,10 +933,11 @@ static ILogger GetLogger(Type loggerType, out CollectingSink sink, LogEventLevel
return null;
}
- else if (loggerType == typeof(SilentLogger))
+
+ if (loggerType == typeof(SilentLogger))
return new SilentLogger();
- else
- throw new ArgumentException($"Logger Type of {loggerType} is not supported");
+
+ throw new ArgumentException($"Logger Type of {loggerType} is not supported");
}
}
}
\ No newline at end of file
diff --git a/test/Serilog.Tests/Settings/KeyValuePairSettingsTests.cs b/test/Serilog.Tests/Settings/KeyValuePairSettingsTests.cs
index ffb974378..9725f0374 100644
--- a/test/Serilog.Tests/Settings/KeyValuePairSettingsTests.cs
+++ b/test/Serilog.Tests/Settings/KeyValuePairSettingsTests.cs
@@ -6,12 +6,9 @@
using Serilog.Events;
using Serilog.Settings.KeyValuePairs;
using Serilog.Tests.Support;
-using Serilog.Enrichers;
using TestDummies;
using Serilog.Configuration;
using Serilog.Formatting;
-using Serilog.Formatting.Json;
-using Serilog.Tests.Formatting.Json;
namespace Serilog.Tests.Settings
{
@@ -142,7 +139,7 @@ public void TestMinimumLevelOverrides()
.WriteTo.Sink(new DelegatingSink(e => evt = e))
.CreateLogger();
- var systemLogger = log.ForContext();
+ var systemLogger = log.ForContext();
systemLogger.Write(Some.InformationEvent());
Assert.Null(evt);
diff --git a/test/Serilog.Tests/Settings/SettingValueConversionsTests.cs b/test/Serilog.Tests/Settings/SettingValueConversionsTests.cs
index 0fca5ec32..3ee1bc118 100644
--- a/test/Serilog.Tests/Settings/SettingValueConversionsTests.cs
+++ b/test/Serilog.Tests/Settings/SettingValueConversionsTests.cs
@@ -46,7 +46,7 @@ public void ValuesConvertToEnumMembers()
[Fact]
public void StringValuesConvertToDefaultInstancesIfTargetIsInterface()
{
- var result = (object)SettingValueConversions.ConvertToType("Serilog.Formatting.Json.JsonFormatter", typeof(ITextFormatter));
+ var result = SettingValueConversions.ConvertToType("Serilog.Formatting.Json.JsonFormatter", typeof(ITextFormatter));
Assert.IsType(result);
}
}
diff --git a/test/Serilog.Tests/Support/DisposableLogger.cs b/test/Serilog.Tests/Support/DisposableLogger.cs
index 1c46e6132..aa465c1d1 100644
--- a/test/Serilog.Tests/Support/DisposableLogger.cs
+++ b/test/Serilog.Tests/Support/DisposableLogger.cs
@@ -5,7 +5,7 @@
namespace Serilog.Tests.Support
{
- public class DisposableLogger : Serilog.ILogger, IDisposable
+ public class DisposableLogger : ILogger, IDisposable
{
public bool Disposed { get; set; }
diff --git a/test/Serilog.Tests/Support/LogEventPropertyStructuralEqualityComparer.cs b/test/Serilog.Tests/Support/LogEventPropertyStructuralEqualityComparer.cs
index e1162ed8f..8b6135bd6 100644
--- a/test/Serilog.Tests/Support/LogEventPropertyStructuralEqualityComparer.cs
+++ b/test/Serilog.Tests/Support/LogEventPropertyStructuralEqualityComparer.cs
@@ -1,4 +1,3 @@
-using System;
using System.Collections.Generic;
using Serilog.Events;
@@ -11,7 +10,7 @@ class LogEventPropertyStructuralEqualityComparer : IEqualityComparer valueEqualityComparer = null)
{
- this._valueEqualityComparer =
+ _valueEqualityComparer =
valueEqualityComparer ?? new LogEventPropertyValueComparer(EqualityComparer