Skip to content

Commit

Permalink
Merge pull request #310 from DbUp/enh-multipleLoggers286
Browse files Browse the repository at this point in the history
Added the ability to specify multiple loggers.
  • Loading branch information
droyad committed Feb 7, 2018
2 parents a341fcb + 5513543 commit bdb0c1f
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 14 deletions.
4 changes: 3 additions & 1 deletion Breaking changes.md → docs/breaking-changes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# 4.0.0
- If `builder.LogTo..()` is called multiple times, the logs are combined instead of replacing the previous logger
- Default Encoding is now UTF rather than Encoding.Default
- AdHocSqlRunner changed to use Expression<Func<>> rather than Func<>
- AdHocSqlRunner changed to use Expression<Func<>> rather than Func<>

3 changes: 3 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
DbUp is a .NET library that helps you to deploy changes to SQL Server databases. It tracks which SQL scripts have been run already, and runs the change scripts that are needed to get your database up to date.

## Upgrading
If you are upgrading from version 3 to 4, see [breaking changes](./breaking-changes.md). Other release notes are available in [the GitHub releases](https://github.com/DbUp/DbUp/releases).

## Getting started
Start by creating a simple C# console project in Visual Studio, and adding your SQL scripts to it. From the Properties window, mark them as Embedded Resources:

Expand Down
4 changes: 4 additions & 0 deletions docs/more-info/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ DbUp has a simple logging abstraction in place using the `IUpgradeLog` interface
- Use `builder.LogToSqlContext()` to register
* Use `builder.LogTo(new MyCustomLogger())` to provide your own logger

These calls use `builder.Configure((UpgradeConfigureation c) => c.AddLog(log))` under the covers.

If no logger is specified, the `AutodetectUpgradeLog` is used for .NET 4.5+ and .NET Core. `TraceUpgradeLog` is used on earlier .NET frameworks.

The first call to `upgradeConfigureation.AddLog(log)` will replace the default logger. Subsequent calls to `upgradeConfigureation.AddLog(log)` will combine the loggers and result in logs going to all specified loggers. To clear previously configured loggers call `UpgradeConfigureation.Log = null` or `builder.ResetConfiguredLoggers()`.

By default, the output of the scripts run by DbUp do not show up in the logs. To also display the script output (e.g.: text displayed by `PRINT` statements in Sql Server), use `builder.LogScriptOutput()`:

Builder
Expand Down
13 changes: 12 additions & 1 deletion src/dbup-core/Builder/StandardExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static class StandardExtensions
/// </returns>
public static UpgradeEngineBuilder LogTo(this UpgradeEngineBuilder builder, IUpgradeLog log)
{
builder.Configure(c => c.Log = log);
builder.Configure(c => c.AddLog(log));
return builder;
}

Expand Down Expand Up @@ -95,6 +95,17 @@ public static UpgradeEngineBuilder LogToTrace(this UpgradeEngineBuilder builder)
{
return LogTo(builder, new TraceUpgradeLog());
}

/// <summary>
/// Resets any loggers configured with
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static UpgradeEngineBuilder ResetConfiguredLoggers(this UpgradeEngineBuilder builder)
{
builder.Configure(c => c.Log = null);
return builder;
}

/// <summary>
/// Uses a custom journal for recording which scripts were executed.
Expand Down
22 changes: 18 additions & 4 deletions src/dbup-core/Builder/UpgradeConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ public class UpgradeConfiguration
{
private readonly List<IScriptProvider> scriptProviders = new List<IScriptProvider>();
private readonly List<IScriptPreprocessor> preProcessors = new List<IScriptPreprocessor>();
private readonly Dictionary<string, string> variables = new Dictionary<string, string>();
private readonly Dictionary<string, string> variables = new Dictionary<string, string>();

private readonly IUpgradeLog defaultLog;
private IUpgradeLog log;

/// <summary>
/// Initializes a new instance of the <see cref="UpgradeConfiguration"/> class.
/// </summary>
public UpgradeConfiguration()
{
#if SUPPORTS_LIBLOG
Log = new AutodetectUpgradeLog();
defaultLog = new AutodetectUpgradeLog();
#else
Log = new TraceUpgradeLog();
defaultLog = new TraceUpgradeLog();
#endif
VariablesEnabled = true;
}
Expand All @@ -38,7 +41,18 @@ public UpgradeConfiguration()
/// <summary>
/// Gets or sets a log which captures details about the upgrade.
/// </summary>
public IUpgradeLog Log { get; set; }
public IUpgradeLog Log
{
get => log ?? defaultLog;
set => log = value;
}

public void AddLog(IUpgradeLog additionalLog)
{
log = log == null
? additionalLog
: new MultipleUpgradeLog(log, additionalLog);
}

/// <summary>
/// Gets a mutable list of script providers.
Expand Down
38 changes: 38 additions & 0 deletions src/dbup-core/Engine/Output/MultipleUpgradeLog.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Linq;

namespace DbUp.Engine.Output
{
public class MultipleUpgradeLog : IUpgradeLog
{
private readonly IUpgradeLog[] upgradeLogs;

public MultipleUpgradeLog(params IUpgradeLog[] upgradeLogs)
{
var otherMultipleLogs = upgradeLogs.OfType<MultipleUpgradeLog>().ToArray();

this.upgradeLogs = upgradeLogs
.Except(otherMultipleLogs)
.Concat(otherMultipleLogs.SelectMany(l => l.upgradeLogs))
.ToArray();
}

public void WriteInformation(string format, params object[] args)
{
foreach(var log in upgradeLogs)
log.WriteInformation(format, args);
}

public void WriteError(string format, params object[] args)
{
foreach (var log in upgradeLogs)
log.WriteError(format, args);
}

public void WriteWarning(string format, params object[] args)
{
foreach (var log in upgradeLogs)
log.WriteWarning(format, args);
}
}
}
9 changes: 9 additions & 0 deletions src/dbup-tests/ApprovalFiles/dbup-core.approved.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public static class StandardExtensions
public static DbUp.Builder.UpgradeEngineBuilder LogToConsole(this DbUp.Builder.UpgradeEngineBuilder builder) { }
public static DbUp.Builder.UpgradeEngineBuilder LogToNowhere(this DbUp.Builder.UpgradeEngineBuilder builder) { }
public static DbUp.Builder.UpgradeEngineBuilder LogToTrace(this DbUp.Builder.UpgradeEngineBuilder builder) { }
public static DbUp.Builder.UpgradeEngineBuilder ResetConfiguredLoggers(this DbUp.Builder.UpgradeEngineBuilder builder) { }
public static DbUp.Builder.UpgradeEngineBuilder WithExecutionTimeout(this DbUp.Builder.UpgradeEngineBuilder builder, System.Nullable<System.TimeSpan> timeout) { }
public static DbUp.Builder.UpgradeEngineBuilder WithFilter(this DbUp.Builder.UpgradeEngineBuilder builder, DbUp.Engine.IScriptFilter filter) { }
public static DbUp.Builder.UpgradeEngineBuilder WithoutTransaction(this DbUp.Builder.UpgradeEngineBuilder builder) { }
Expand Down Expand Up @@ -88,6 +89,7 @@ public class UpgradeConfiguration
public DbUp.Engine.IScriptSorter ScriptSorter { get; set; }
public System.Collections.Generic.Dictionary<string, string> Variables { get; }
public bool VariablesEnabled { get; set; }
public void AddLog(DbUp.Engine.Output.IUpgradeLog additionalLog) { }
public void AddVariables(System.Collections.Generic.IDictionary<string, string> newVariables) { }
public void Validate() { }
}
Expand Down Expand Up @@ -202,6 +204,13 @@ public interface IUpgradeLog
void WriteInformation(string format, params object[] args);
void WriteWarning(string format, params object[] args);
}
public class MultipleUpgradeLog : DbUp.Engine.Output.IUpgradeLog
{
public MultipleUpgradeLog(params DbUp.Engine.Output.IUpgradeLog[] upgradeLogs) { }
public void WriteError(string format, params object[] args) { }
public void WriteInformation(string format, params object[] args) { }
public void WriteWarning(string format, params object[] args) { }
}
public class NoOpUpgradeLog : DbUp.Engine.Output.IUpgradeLog
{
public NoOpUpgradeLog() { }
Expand Down
77 changes: 77 additions & 0 deletions src/dbup-tests/Builder/UpgradeConfigurationFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using DbUp.Builder;
using DbUp.Engine.Output;
using Shouldly;
using Xunit;

namespace DbUp.Tests.Builder
{
public class UpgradeConfigurationFixture
{
[Fact]
public void WhenNoLoggerIsAddedThenTheDefaultLoggerIsReturned()
{
new UpgradeConfiguration()
.Log.ShouldNotBeNull();
}

[Fact]
public void WhenASingleLoggerIsAddedThenItselfShouldBeReturned()
{
var config = new UpgradeConfiguration();
var addedLog = new NoOpUpgradeLog();
config.AddLog(addedLog);
config.Log.ShouldBe(addedLog);
}

[Fact]
public void WhenMultipleLoggersAreAddedThenAMultipleLoggerShouldBeReturnedAndLogsGoToAllDestinations()
{
var log1 = new TestLog();
var log2 = new TestLog();
var log3 = new TestLog();

var config = new UpgradeConfiguration();
config.AddLog(log1);
config.AddLog(log2);
config.AddLog(log3);
config.Log.WriteInformation("Test");

config.Log.ShouldBeOfType<MultipleUpgradeLog>();
log1.WasWritten.ShouldBe(true);
log2.WasWritten.ShouldBe(true);
log3.WasWritten.ShouldBe(true);
}

[Fact]
public void WhenTheLoggerIsClearedThenTheDefaultLoggerReturns()
{
var config = new UpgradeConfiguration();
var defaultLog = config.Log;
config.AddLog(new NoOpUpgradeLog());
config.Log.ShouldNotBe(defaultLog);

config.Log = null;
config.Log.ShouldBe(defaultLog);

}

class TestLog : IUpgradeLog
{
public bool WasWritten { get; private set; }
public void WriteInformation(string format, params object[] args)
{
WasWritten = true;
}

public void WriteError(string format, params object[] args)
{
WasWritten = true;
}

public void WriteWarning(string format, params object[] args)
{
WasWritten = true;
}
}
}
}
9 changes: 1 addition & 8 deletions src/dbup-tests/dbup-tests.csproj
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net46;netcoreapp2.0</TargetFrameworks>
<AssemblyName>dbup-tests</AssemblyName>
Expand All @@ -11,11 +10,9 @@
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0' ">
<DefineConstants>$(DefineConstants);NETCORE</DefineConstants>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\dbup-core\dbup-core.csproj" />
<ProjectReference Include="..\dbup-sqlserver\dbup-sqlserver.csproj" />
Expand All @@ -29,8 +26,6 @@
<PackageReference Include="TestStack.BDDfy" Version="4.3.1" />
<PackageReference Include="NSubstitute" Version="3.1.0" />
</ItemGroup>


<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
<ProjectReference Include="..\dbup-sqlce\dbup-sqlce.csproj" />
<ProjectReference Include="..\dbup-mysql\dbup-mysql.csproj" />
Expand All @@ -40,7 +35,6 @@
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>

<ItemGroup>
<Compile Remove="**\*.received.cs" />
<EmbeddedResource Include="TestScripts\**\*.sql" Exclude="bin\**;obj\**;**\*.xproj;packages\**;@(EmbeddedResource)" />
Expand All @@ -49,5 +43,4 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
</Project>

0 comments on commit bdb0c1f

Please sign in to comment.