diff --git a/docs/spec/logging.md b/docs/spec/logging.md
new file mode 100644
index 0000000000..91d35023e4
--- /dev/null
+++ b/docs/spec/logging.md
@@ -0,0 +1,54 @@
+# Perspex Logging
+
+Perspex uses [Serilog](https://github.com/serilog/serilog) for logging via
+the Perspex.Logging.Serilog assembly.
+
+The following method should be present in your App.xaml.cs file:
+
+```C#
+private void InitializeLogging()
+{
+#if DEBUG
+ SerilogLogger.Initialize(new LoggerConfiguration()
+ .MinimumLevel.Warning()
+ .WriteTo.Trace(outputTemplate: "{Area}: {Message}")
+ .CreateLogger());
+#endif
+}
+```
+
+By default, this logging setup will write log messages with a severity of
+`Warning` or higher to `System.Diagnostics.Trace`. See the [Serilog
+documentation](https://github.com/serilog/serilog/wiki/Configuration-Basics)
+for more information on the options here.
+
+## Areas
+
+Each Perspex log message has an "Area" that can be used to filter the log to
+include only the type of events that you are interested in. These are currently:
+
+- Property
+- Binding
+- Visual
+- Layout
+- Control
+
+To limit the log output to a specific area you can add a filter; for example
+to enable verbose logging but only about layout:
+
+```C#
+SerilogLogger.Initialize(new LoggerConfiguration()
+ .Filter.ByIncludingOnly(Matching.WithProperty("Area", LogArea.Layout))
+ .MinimumLevel.Verbose()
+ .WriteTo.Trace(outputTemplate: "{Area}: {Message}")
+ .CreateLogger());
+```
+
+## Removing Serilog
+
+If you don't want a dependency on Serilog in your application, simply remove
+the reference to Perspex.Logging.Serilog and the code that initializes it. If
+you do however still want some kinda of logging, there are two steps:
+
+- Implement `Perspex.Logging.ILogSink`
+- Assign your implementation to `Logger.Sink`
diff --git a/docs/spec/toc.yml b/docs/spec/toc.yml
index e5c40d7544..3075a03619 100644
--- a/docs/spec/toc.yml
+++ b/docs/spec/toc.yml
@@ -5,4 +5,6 @@
- name: Defining Properties
href: defining-properties.md
- name: Working with Properties
- href: working-with-properties.md
\ No newline at end of file
+ href: working-with-properties.md
+- name: Logging
+ href: logging.md
diff --git a/samples/BindingTest/App.xaml.cs b/samples/BindingTest/App.xaml.cs
index ff0fe8e65a..837e17839d 100644
--- a/samples/BindingTest/App.xaml.cs
+++ b/samples/BindingTest/App.xaml.cs
@@ -2,6 +2,7 @@
using Perspex;
using Perspex.Controls;
using Perspex.Diagnostics;
+using Perspex.Logging;
using Perspex.Logging.Serilog;
using Perspex.Markup.Xaml;
using Serilog;
@@ -41,7 +42,8 @@ namespace BindingTest
{
#if DEBUG
SerilogLogger.Initialize(new LoggerConfiguration()
- .MinimumLevel.Warning()
+ .Filter.ByIncludingOnly(Matching.WithProperty("Area", LogArea.Layout))
+ .MinimumLevel.Verbose()
.WriteTo.Trace(outputTemplate: "{Area}: {Message}")
.CreateLogger());
#endif
diff --git a/src/Perspex.Base/Logging/ILogSink.cs b/src/Perspex.Base/Logging/ILogSink.cs
index b8d1540981..d2b6b62b4f 100644
--- a/src/Perspex.Base/Logging/ILogSink.cs
+++ b/src/Perspex.Base/Logging/ILogSink.cs
@@ -3,8 +3,19 @@
namespace Perspex.Logging
{
+ ///
+ /// Defines a sink for Perspex logging messages.
+ ///
public interface ILogSink
{
+ ///
+ /// Logs a new event.
+ ///
+ /// The log event level.
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
void Log(
LogEventLevel level,
string area,
diff --git a/src/Perspex.Base/Logging/Logger.cs b/src/Perspex.Base/Logging/Logger.cs
index 311dc55fc0..f21915a332 100644
--- a/src/Perspex.Base/Logging/Logger.cs
+++ b/src/Perspex.Base/Logging/Logger.cs
@@ -1,15 +1,28 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
-using System;
using System.Runtime.CompilerServices;
namespace Perspex.Logging
{
+ ///
+ /// Logs perspex messages.
+ ///
public static class Logger
{
+ ///
+ /// Gets or sets the application-defined sink that recieves the messages.
+ ///
public static ILogSink Sink { get; set; }
+ ///
+ /// Logs an event.
+ ///
+ /// The log event level.
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Log(
LogEventLevel level,
@@ -21,6 +34,13 @@ namespace Perspex.Logging
Sink?.Log(level, area, source, messageTemplate, propertyValues);
}
+ ///
+ /// Logs an event with the level.
+ ///
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Verbose(
string area,
@@ -31,6 +51,13 @@ namespace Perspex.Logging
Log(LogEventLevel.Verbose, area, source, messageTemplate, propertyValues);
}
+ ///
+ /// Logs an event with the level.
+ ///
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Debug(
string area,
@@ -41,6 +68,13 @@ namespace Perspex.Logging
Log(LogEventLevel.Debug, area, source, messageTemplate, propertyValues);
}
+ ///
+ /// Logs an event with the level.
+ ///
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Information(
string area,
@@ -51,6 +85,13 @@ namespace Perspex.Logging
Log(LogEventLevel.Information, area, source, messageTemplate, propertyValues);
}
+ ///
+ /// Logs an event with the level.
+ ///
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Warning(
string area,
@@ -61,6 +102,13 @@ namespace Perspex.Logging
Log(LogEventLevel.Warning, area, source, messageTemplate, propertyValues);
}
+ ///
+ /// Logs an event with the level.
+ ///
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Error(
string area,
@@ -71,6 +119,13 @@ namespace Perspex.Logging
Log(LogEventLevel.Error, area, source, messageTemplate, propertyValues);
}
+ ///
+ /// Logs an event with the level.
+ ///
+ /// The area that the event originates.
+ /// The object from which the event originates.
+ /// The message template.
+ /// The message property values.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Fatal(
string area,