diff --git a/Scripts/Build.ps1 b/Scripts/Build.ps1 index fcc0fc1..5afe620 100644 --- a/Scripts/Build.ps1 +++ b/Scripts/Build.ps1 @@ -25,11 +25,15 @@ properties { @{"Framework" = "net45"; "TestingFramework" = "net-4.5"; "Utility" = "NUnit";}, @{"Framework" = "net451"; "TestingFramework" = "net-4.0"; "Utility" = "NUnit";}, @{"Framework" = "net452"; "TestingFramework" = "net-4.5"; "Utility" = "NUnit";}, - @{"Framework" = "net46"; "TestingFramework" = "net46"; "Utility" = "DotnetTest";} + @{"Framework" = "net46"; "TestingFramework" = "net46"; "Utility" = "DotnetTest";}, + @{"Framework" = "net47"; "TestingFramework" = "net47"; "Utility" = "DotnetTest";} ) $ProjectsToPublish=@( - "$SourceDirectory\Vima.LoggingAbstractor.Core\Vima.LoggingAbstractor.Core.csproj" + "$SourceDirectory\Vima.LoggingAbstractor.Core\Vima.LoggingAbstractor.Core.csproj", + "$SourceDirectory\Vima.LoggingAbstractor.AppInsights\Vima.LoggingAbstractor.AppInsights.csproj", + "$SourceDirectory\Vima.LoggingAbstractor.Raygun\Vima.LoggingAbstractor.Raygun.csproj", + "$SourceDirectory\Vima.LoggingAbstractor.Sentry\Vima.LoggingAbstractor.Sentry.csproj" ) } diff --git a/Source/Vima.LoggingAbstractor.AppInsights.Tests/UnitTest1.cs b/Source/Vima.LoggingAbstractor.AppInsights.Tests/UnitTest1.cs new file mode 100644 index 0000000..2620ebe --- /dev/null +++ b/Source/Vima.LoggingAbstractor.AppInsights.Tests/UnitTest1.cs @@ -0,0 +1,12 @@ +using Xunit; + +namespace Vima.LoggingAbstractor.AppInsights.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + } + } +} diff --git a/Source/Vima.LoggingAbstractor.AppInsights.Tests/Vima.LoggingAbstractor.AppInsights.Tests.csproj b/Source/Vima.LoggingAbstractor.AppInsights.Tests/Vima.LoggingAbstractor.AppInsights.Tests.csproj new file mode 100644 index 0000000..756ce98 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.AppInsights.Tests/Vima.LoggingAbstractor.AppInsights.Tests.csproj @@ -0,0 +1,28 @@ + + + + netcoreapp2.0 + Vima.LoggingAbstractor.AppInsights.Tests + Vima.LoggingAbstractor.AppInsights.Tests + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.AppInsights.Tests.xml + ..\ca-tests.ruleset + true + + false + + + + + + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.AppInsights/AppInsightsLogger.cs b/Source/Vima.LoggingAbstractor.AppInsights/AppInsightsLogger.cs new file mode 100644 index 0000000..d976d1d --- /dev/null +++ b/Source/Vima.LoggingAbstractor.AppInsights/AppInsightsLogger.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.DataContracts; +using Vima.LoggingAbstractor.Core; +using Vima.LoggingAbstractor.Core.Extensions; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.AppInsights +{ + /// + /// Represents an instance of an Application Insights logger. + /// + public class AppInsightsLogger : LoggerBase, IAppInsightsLogger + { + private readonly TelemetryClient _telemetryClient; + + /// + /// Initializes a new instance of the class. + /// + /// The Application Insights client. + /// The minimal logging level. + public AppInsightsLogger(TelemetryClient telemetryClient, LoggingLevel minimalLoggingLevel = LoggingLevel.Verbose) + : base(minimalLoggingLevel) + { + _telemetryClient = telemetryClient ?? throw new ArgumentNullException(nameof(telemetryClient)); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + /// The logging parameters. + public override void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters) + { + if (!ShouldBeTraced(loggingLevel)) + { + return; + } + + var traceTelemetry = new TraceTelemetry(message); + AddParametersToProperties(traceTelemetry, parameters); + _telemetryClient.Track(traceTelemetry); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + /// The logging parameters. + public override void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters) + { + if (!ShouldBeTraced(loggingLevel)) + { + return; + } + + var exceptionTelemetry = new ExceptionTelemetry(exception); + AddParametersToProperties(exceptionTelemetry, parameters); + _telemetryClient.Track(exceptionTelemetry); + } + + private static void AddParametersToProperties(ISupportProperties telemetry, IEnumerable parameters) + { + IEnumerable loggingParameters = parameters.ToList(); + + foreach (string tag in loggingParameters.ExtractTags()) + { + telemetry.Properties.Add(tag, tag); + } + + var dataCount = 0; + foreach (string data in loggingParameters.ExtractData()) + { + telemetry.Properties.Add($"Data #{dataCount++}", data); + } + } + } +} diff --git a/Source/Vima.LoggingAbstractor.AppInsights/IAppInsightsLogger.cs b/Source/Vima.LoggingAbstractor.AppInsights/IAppInsightsLogger.cs new file mode 100644 index 0000000..8dd3970 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.AppInsights/IAppInsightsLogger.cs @@ -0,0 +1,12 @@ +using Vima.LoggingAbstractor.Core; + +namespace Vima.LoggingAbstractor.AppInsights +{ + /// + /// Represents an instance of an Application Insights logger. + /// + /// + public interface IAppInsightsLogger : ILogger + { + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.AppInsights/Vima.LoggingAbstractor.AppInsights.csproj b/Source/Vima.LoggingAbstractor.AppInsights/Vima.LoggingAbstractor.AppInsights.csproj new file mode 100644 index 0000000..f0c3782 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.AppInsights/Vima.LoggingAbstractor.AppInsights.csproj @@ -0,0 +1,41 @@ + + + + 0.1.0 + 0.1.0 + Victor Usoltsev + Logging Abstractor is a library for .NET that allows you to swap out logging providers with ease. + Copyright © Victor Usoltsev 2018 + https://github.com/bernarden/LoggingAbstractor/blob/master/LICENSE + https://raw.githubusercontent.com/bernarden/LoggingAbstractor/master/Resources/NugetIcon.png + https://github.com/bernarden/LoggingAbstractor + git + logging abstractor abstraction logger + https://github.com/bernarden/LoggingAbstractor + Vima + en-US + False + LoggingAbstractor.AppInsights + LoggingAbstractor.AppInsights + + + + net47;net46;net45;netstandard1.3;netstandard2.0 + Vima.LoggingAbstractor.AppInsights + Vima.LoggingAbstractor.AppInsights + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.AppInsights.xml + ..\ca.ruleset + true + + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.Core.Tests/LoggerBaseTest.cs b/Source/Vima.LoggingAbstractor.Core.Tests/LoggerBaseTest.cs new file mode 100644 index 0000000..a407939 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core.Tests/LoggerBaseTest.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Xunit; + +namespace Vima.LoggingAbstractor.Core.Tests +{ + public sealed class LoggerBaseTest + { + public sealed class ShouldBeTraced + { + [Fact] + public void ShouldReturnCorrectValueInAllCombinationsOfInputs() + { + var loggingLevels = Enum.GetValues(typeof(LoggingLevel)).Cast().ToList(); + + foreach (var minimalLoggingLevel in loggingLevels) + { + foreach (var currentLoggingLevel in loggingLevels) + { + // Arrange + TestLoggerBase loggerBase = new TestLoggerBase(minimalLoggingLevel); + var expectedResult = ShouldClientLogTrace(minimalLoggingLevel, currentLoggingLevel); + + // Act + var result = loggerBase.ShouldBeTraced(currentLoggingLevel); + + // Assert + result.Should().Be(expectedResult, $"current logging level is '{currentLoggingLevel:G}' and minimal logging level is '{minimalLoggingLevel.ToString()}'"); + } + } + } + + private static bool ShouldClientLogTrace(LoggingLevel currentLoggingLevel, LoggingLevel minimumLoggingLevel) + { + Dictionary> allowedLoggingLevelsForMinimumLoggingLevel = + new Dictionary> + { + { LoggingLevel.Verbose, new List { LoggingLevel.Verbose } }, + { LoggingLevel.Information, new List { LoggingLevel.Verbose, LoggingLevel.Information } }, + { LoggingLevel.Warning, new List { LoggingLevel.Verbose, LoggingLevel.Information, LoggingLevel.Warning } }, + { LoggingLevel.Error, new List { LoggingLevel.Verbose, LoggingLevel.Information, LoggingLevel.Warning, LoggingLevel.Error } }, + { LoggingLevel.Critical, new List { LoggingLevel.Verbose, LoggingLevel.Information, LoggingLevel.Warning, LoggingLevel.Error, LoggingLevel.Critical } }, + { LoggingLevel.None, new List() } + }; + + return allowedLoggingLevelsForMinimumLoggingLevel[minimumLoggingLevel].Contains(currentLoggingLevel); + } + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Core.Tests/LoggingParameterExtensionsTest.cs b/Source/Vima.LoggingAbstractor.Core.Tests/LoggingParameterExtensionsTest.cs new file mode 100644 index 0000000..e6c569a --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core.Tests/LoggingParameterExtensionsTest.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FluentAssertions; +using Vima.LoggingAbstractor.Core.Extensions; +using Vima.LoggingAbstractor.Core.Parameters; +using Xunit; + +namespace Vima.LoggingAbstractor.Core.Tests +{ + public sealed class LoggingParameterExtensionsTest + { + public sealed class ExtractTags + { + [Fact(Skip = "Need other logging parameters to exist.")] + public void ShouldHandleNoParameters() + { + // Arrange + // TODO: Create different logging parameter and add here for tests. + + // Act + var tags = new List { }.ExtractTags().ToList(); + + // Assert + tags.Should().BeEmpty(); + } + + [Fact] + public void ShouldHandleNoTagsParameters() + { + // Act + var tags = new List().ExtractTags().ToList(); + + // Assert + tags.Should().BeEmpty(); + } + + [Fact] + public void ShouldHandleOneTagsParameter() + { + // Arrange + string tag = "CustomTag"; + var loggingTagsParameter = new LoggingTagsParameter(new List { tag }); + + // Act + var tags = new List { loggingTagsParameter }.ExtractTags().ToList(); + + // Assert + tags.Count.Should().Be(1); + tags.Should().Contain(tag); + } + + [Fact] + public void ShouldHandleMultipleTagsParameter() + { + // Arrange + var loggingTagsParameter1 = new LoggingTagsParameter(new List { LoggingLevel.Critical }); + var loggingTagsParameter2 = new LoggingTagsParameter(new List { LoggingLevel.None }); + + // Act + var tags = new List { loggingTagsParameter1, loggingTagsParameter2 }.ExtractTags().ToList(); + + // Assert + tags.Count.Should().Be(2); + tags.Should().Contain(LoggingLevel.Critical.ToString("G")); + tags.Should().Contain(LoggingLevel.None.ToString("G")); + } + } + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core.Tests/TestLoggerBase.cs b/Source/Vima.LoggingAbstractor.Core.Tests/TestLoggerBase.cs new file mode 100644 index 0000000..e9bffd7 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core.Tests/TestLoggerBase.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.Core.Tests +{ + public class TestLoggerBase : LoggerBase + { + public TestLoggerBase(LoggingLevel minimalLoggingLevel = LoggingLevel.Verbose) + : base(minimalLoggingLevel) + { + } + + public override void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters) + { + } + + public override void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters) + { + } + + public new bool ShouldBeTraced(LoggingLevel loggingLevel) + { + return base.ShouldBeTraced(loggingLevel); + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Core.Tests/Vima.LoggingAbstractor.Core.Tests.csproj b/Source/Vima.LoggingAbstractor.Core.Tests/Vima.LoggingAbstractor.Core.Tests.csproj new file mode 100644 index 0000000..d72cd9d --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core.Tests/Vima.LoggingAbstractor.Core.Tests.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp2.0 + Vima.LoggingAbstractor.Core.Tests + Vima.LoggingAbstractor.Core.Tests + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.Core.Tests.xml + true + ..\ca-tests.ruleset + + false + + + + + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.Core/Extensions/LoggingParameterExtensions.cs b/Source/Vima.LoggingAbstractor.Core/Extensions/LoggingParameterExtensions.cs new file mode 100644 index 0000000..4467e1e --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/Extensions/LoggingParameterExtensions.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.Core.Extensions +{ + /// + /// Responsible for containing all of the extensions for logging parameters. + /// + public static class LoggingParameterExtensions + { + /// + /// Extracts the tags. + /// + /// The logging parameters. + /// Tag values + public static IEnumerable ExtractTags(this IEnumerable parameters) + { + List loggingParameters = parameters + .Where(x => x.LoggingParameterType == LoggingParameterType.Tags) + .ToList(); + + if (!loggingParameters.Any()) + { + return new List(); + } + + List result = new List(); + foreach (var loggingParameter in loggingParameters) + { + if (loggingParameter is ILoggingParameter> tags) + { + result.AddRange(tags.Value); + } + } + + return result.Distinct(); + } + + /// + /// Extracts the data values. + /// + /// The logging parameters. + /// Data values + public static IEnumerable ExtractData(this IEnumerable parameters) + { + List loggingParameters = parameters + .Where(x => x.LoggingParameterType == LoggingParameterType.Data) + .ToList(); + + if (!loggingParameters.Any()) + { + return new List(); + } + + List result = new List(); + foreach (var loggingParameter in loggingParameters) + { + if (loggingParameter is ILoggingParameter data) + { + string value = JsonConvert.SerializeObject(data.Value); + result.Add(value); + } + } + + return result; + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Core/ILogger.cs b/Source/Vima.LoggingAbstractor.Core/ILogger.cs index 9fd1f99..4ca9f39 100644 --- a/Source/Vima.LoggingAbstractor.Core/ILogger.cs +++ b/Source/Vima.LoggingAbstractor.Core/ILogger.cs @@ -1,36 +1,54 @@ using System; +using System.Collections.Generic; +using Vima.LoggingAbstractor.Core.Parameters; namespace Vima.LoggingAbstractor.Core { /// - /// Represents an instance of a logger. + /// Represents an instance of a logger. /// public interface ILogger { /// /// Traces the message. /// - /// The message. + /// The message to be logged. void TraceMessage(string message); /// /// Traces the message. /// /// The message to be logged. - /// The logging severity level. - void TraceMessage(string message, LoggingSeverityLevel loggingSeverityLevel); + /// The logging level. + void TraceMessage(string message, LoggingLevel loggingLevel); + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + /// The logging parameters. + void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters); /// /// Traces the exception. /// - /// The exception. + /// The exception to be logged. void TraceException(Exception exception); /// /// Traces the exception. /// - /// The exception. - /// The logging severity level. - void TraceException(Exception exception, LoggingSeverityLevel loggingSeverityLevel); + /// The exception to be logged. + /// The logging level. + void TraceException(Exception exception, LoggingLevel loggingLevel); + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + /// The logging parameters. + void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters); } } diff --git a/Source/Vima.LoggingAbstractor.Core/IMultiLogger.cs b/Source/Vima.LoggingAbstractor.Core/IMultiLogger.cs new file mode 100644 index 0000000..459bf91 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/IMultiLogger.cs @@ -0,0 +1,9 @@ +namespace Vima.LoggingAbstractor.Core +{ + /// + /// Responsible for combining multiple loggers at the same time. + /// + public interface IMultiLogger : ILogger + { + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/LoggerBase.cs b/Source/Vima.LoggingAbstractor.Core/LoggerBase.cs new file mode 100644 index 0000000..e4f941f --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/LoggerBase.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.Core +{ + /// + /// Represents an instance of a logger. + /// + public abstract class LoggerBase : ILogger + { + private readonly LoggingLevel _minimalLoggingLevel; + + /// + /// Initializes a new instance of the class. + /// + /// The minimal logging level. + protected LoggerBase(LoggingLevel minimalLoggingLevel) + { + _minimalLoggingLevel = minimalLoggingLevel; + } + + /// + /// Traces the message. + /// + /// The message to be logged. + public virtual void TraceMessage(string message) + { + TraceMessage(message, LoggingLevel.Verbose); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + public virtual void TraceMessage(string message, LoggingLevel loggingLevel) + { + TraceMessage(message, loggingLevel, Enumerable.Empty()); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + /// The logging parameters. + public abstract void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters); + + /// + /// Traces the exception. + /// + /// The exception to be logged. + public virtual void TraceException(Exception exception) + { + TraceException(exception, LoggingLevel.Critical); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + public virtual void TraceException(Exception exception, LoggingLevel loggingLevel) + { + TraceException(exception, loggingLevel, Enumerable.Empty()); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + /// The logging parameters. + public abstract void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters); + + /// + /// Determines whether tracing should be performed. + /// + /// The logging level. + /// Value indicating whether tracing should be performed + protected bool ShouldBeTraced(LoggingLevel loggingLevel) + { + if (loggingLevel == LoggingLevel.None) + { + return false; + } + + return loggingLevel >= _minimalLoggingLevel; + } + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/LoggingSeverityLevel.cs b/Source/Vima.LoggingAbstractor.Core/LoggingLevel.cs similarity index 95% rename from Source/Vima.LoggingAbstractor.Core/LoggingSeverityLevel.cs rename to Source/Vima.LoggingAbstractor.Core/LoggingLevel.cs index 8df1a49..88b6dc5 100644 --- a/Source/Vima.LoggingAbstractor.Core/LoggingSeverityLevel.cs +++ b/Source/Vima.LoggingAbstractor.Core/LoggingLevel.cs @@ -6,7 +6,7 @@ namespace Vima.LoggingAbstractor.Core /// Represents the severity of the logged message or exception. /// [Flags] - public enum LoggingSeverityLevel + public enum LoggingLevel { /// /// Verbose. diff --git a/Source/Vima.LoggingAbstractor.Core/MultiLogger.cs b/Source/Vima.LoggingAbstractor.Core/MultiLogger.cs new file mode 100644 index 0000000..7815014 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/MultiLogger.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.Core +{ + /// + /// Responsible for combining multiple loggers at the same time. + /// + public class MultiLogger : IMultiLogger + { + private readonly IEnumerable _loggers; + + /// + /// Initializes a new instance of the class. + /// + /// The loggers used to trace events. + protected MultiLogger(IEnumerable loggers) + { + _loggers = loggers ?? throw new ArgumentNullException(nameof(loggers)); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + public void TraceMessage(string message) + { + TraceMessage(message, LoggingLevel.Verbose); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + public void TraceMessage(string message, LoggingLevel loggingLevel) + { + TraceMessage(message, loggingLevel, Enumerable.Empty()); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + /// The logging parameters. + public void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters) + { + IEnumerable loggingParameters = parameters.ToList(); + foreach (var logger in _loggers) + { + logger.TraceMessage(message, loggingLevel, loggingParameters); + } + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + public void TraceException(Exception exception) + { + TraceException(exception, LoggingLevel.Critical); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + public void TraceException(Exception exception, LoggingLevel loggingLevel) + { + TraceException(exception, loggingLevel, Enumerable.Empty()); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + /// The logging parameters. + public void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters) + { + IEnumerable loggingParameters = parameters.ToList(); + foreach (var logger in _loggers) + { + logger.TraceException(exception, loggingLevel, loggingParameters); + } + } + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/Parameters/ILoggingParameter.cs b/Source/Vima.LoggingAbstractor.Core/Parameters/ILoggingParameter.cs new file mode 100644 index 0000000..66cb11c --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/Parameters/ILoggingParameter.cs @@ -0,0 +1,31 @@ +namespace Vima.LoggingAbstractor.Core.Parameters +{ + /// + /// Represents logging parameter. + /// + /// Parameter's value type. + public interface ILoggingParameter : ILoggingParameter + { + /// + /// Gets the parameter's value. + /// + /// + /// The parameter's value. + /// + T Value { get; } + } + + /// + /// Represents logging parameter. + /// + public interface ILoggingParameter + { + /// + /// Gets the type of the logging parameter. + /// + /// + /// The type of the logging parameter. + /// + LoggingParameterType LoggingParameterType { get; } + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingDataParameter.cs b/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingDataParameter.cs new file mode 100644 index 0000000..2e9d819 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingDataParameter.cs @@ -0,0 +1,35 @@ +using System; + +namespace Vima.LoggingAbstractor.Core.Parameters +{ + /// + /// Represents logging data parameter. + /// + public class LoggingDataParameter : ILoggingParameter + { + /// + /// Initializes a new instance of the class. + /// + /// The data. + public LoggingDataParameter(object data) + { + Value = data ?? throw new ArgumentNullException(nameof(data)); + } + + /// + /// Gets the parameter's value. + /// + /// + /// The parameter's value. + /// + public object Value { get; } + + /// + /// Gets the type of the logging parameter. + /// + /// + /// The type of the logging parameter. + /// + public LoggingParameterType LoggingParameterType => LoggingParameterType.Data; + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingParameterType.cs b/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingParameterType.cs new file mode 100644 index 0000000..4fb4d9b --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingParameterType.cs @@ -0,0 +1,18 @@ +namespace Vima.LoggingAbstractor.Core.Parameters +{ + /// + /// Represents logging parameter type. + /// + public enum LoggingParameterType + { + /// + /// The tags parameter. + /// + Tags, + + /// + /// The data parameter + /// + Data + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingTagsParameter.cs b/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingTagsParameter.cs new file mode 100644 index 0000000..7fcfe81 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Core/Parameters/LoggingTagsParameter.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Vima.LoggingAbstractor.Core.Parameters +{ + /// + /// Represents logging tags parameter. + /// + public class LoggingTagsParameter : ILoggingParameter> + { + /// + /// Initializes a new instance of the class. + /// + /// The tags. + public LoggingTagsParameter(IEnumerable tags) + { + Value = tags ?? throw new ArgumentNullException(nameof(tags)); + } + + /// + /// Initializes a new instance of the class. + /// + /// The tags. + public LoggingTagsParameter(IEnumerable tags) + { + IEnumerable enumTags = tags ?? throw new ArgumentNullException(nameof(tags)); + Value = enumTags.Select(x => x.ToString("G")); + } + + /// + /// Gets the parameter's value. + /// + /// + /// The parameter's value. + /// + public IEnumerable Value { get; } + + /// + /// Gets the type of the logging parameter. + /// + /// + /// The type of the logging parameter. + /// + public LoggingParameterType LoggingParameterType => LoggingParameterType.Tags; + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Core/Vima.LoggingAbstractor.Core.csproj b/Source/Vima.LoggingAbstractor.Core/Vima.LoggingAbstractor.Core.csproj index f091082..1210f15 100644 --- a/Source/Vima.LoggingAbstractor.Core/Vima.LoggingAbstractor.Core.csproj +++ b/Source/Vima.LoggingAbstractor.Core/Vima.LoggingAbstractor.Core.csproj @@ -1,8 +1,8 @@ - - 1.0.0 - 1.0.0 + + 0.1.0 + 0.1.0 Victor Usoltsev Logging Abstractor is a library for .NET that allows you to swap out logging providers with ease. Copyright © Victor Usoltsev 2018 @@ -18,13 +18,22 @@ LoggingAbstractor.Core LoggingAbstractor.Core - + - net46;net45;net40;net35;net20;netstandard1.0;netstandard2.0;portable-net40+sl5+win8+wpa81+wp8;portable-net45+win8+wpa81+wp8 + net47;net46;net45;net40;net35;netstandard1.0;netstandard2.0 Vima.LoggingAbstractor.Core Vima.LoggingAbstractor.Core + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.Core.xml + ..\ca.ruleset + true + - + + + + + + NET46 @@ -33,38 +42,10 @@ NET45 - - PORTABLE45 - .NETPortable - v4.5 - Profile259 - .NETPortable,Version=v0.0,Profile=Profile259 - $(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets - false - - - - NET40 - - - - PORTABLE40 - .NETPortable - v4.0 - Profile328 - .NETPortable,Version=v0.0,Profile=Profile328 - $(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets - false - - NET35 - - NET20 - - NETSTANDARD1_0 @@ -72,5 +53,4 @@ NETSTANDARD2_0 - diff --git a/Source/Vima.LoggingAbstractor.Raygun.Tests/UnitTest1.cs b/Source/Vima.LoggingAbstractor.Raygun.Tests/UnitTest1.cs new file mode 100644 index 0000000..e0c183a --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Raygun.Tests/UnitTest1.cs @@ -0,0 +1,12 @@ +using Xunit; + +namespace Vima.LoggingAbstractor.Raygun.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Raygun.Tests/Vima.LoggingAbstractor.Raygun.Tests.csproj b/Source/Vima.LoggingAbstractor.Raygun.Tests/Vima.LoggingAbstractor.Raygun.Tests.csproj new file mode 100644 index 0000000..e3d11bf --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Raygun.Tests/Vima.LoggingAbstractor.Raygun.Tests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp2.0 + Vima.LoggingAbstractor.Raygun.Tests + Vima.LoggingAbstractor.Raygun.Tests + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.Raygun.Tests.xml + ..\ca-tests.ruleset + true + + false + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.Raygun/IRaygunLogger.cs b/Source/Vima.LoggingAbstractor.Raygun/IRaygunLogger.cs new file mode 100644 index 0000000..f4ff6ba --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Raygun/IRaygunLogger.cs @@ -0,0 +1,11 @@ +using Vima.LoggingAbstractor.Core; + +namespace Vima.LoggingAbstractor.Raygun +{ + /// + /// Represents an instance of a Raygun logger. + /// + public interface IRaygunLogger : ILogger + { + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Raygun/RaygunLogger.cs b/Source/Vima.LoggingAbstractor.Raygun/RaygunLogger.cs new file mode 100644 index 0000000..5c26794 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Raygun/RaygunLogger.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Mindscape.Raygun4Net; +using Vima.LoggingAbstractor.Core; +using Vima.LoggingAbstractor.Core.Extensions; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.Raygun +{ + /// + /// Represents an instance of a Raygun logger. + /// + public class RaygunLogger : LoggerBase, IRaygunLogger + { + private readonly RaygunClient _raygunClient; + + /// + /// Initializes a new instance of the class. + /// + /// The raygun client. + /// The minimal logging level. + public RaygunLogger(RaygunClient raygunClient, LoggingLevel minimalLoggingLevel = LoggingLevel.Verbose) + : base(minimalLoggingLevel) + { + _raygunClient = raygunClient ?? throw new ArgumentNullException(nameof(raygunClient)); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + /// The logging parameters. + public override void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters) + { + if (!ShouldBeTraced(loggingLevel)) + { + return; + } + + IEnumerable loggingParameters = parameters.ToList(); + var messageException = new RaygunMessageException(message); + var data = ExtractDataValues(loggingParameters); + _raygunClient.Send(messageException, loggingParameters.ExtractTags().ToList(), data); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + /// The logging parameters. + public override void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters) + { + if (!ShouldBeTraced(loggingLevel)) + { + return; + } + + IEnumerable loggingParameters = parameters.ToList(); + var data = ExtractDataValues(loggingParameters); + _raygunClient.Send(exception, loggingParameters.ExtractTags().ToList(), data); + } + + private Dictionary ExtractDataValues(IEnumerable parameters) + { + var dataCount = 0; + var dataDictionary = new Dictionary(); + foreach (string data in parameters.ExtractData()) + { + dataDictionary.Add($"Data #{dataCount++}", data); + } + + return dataDictionary; + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Raygun/RaygunMessageException.cs b/Source/Vima.LoggingAbstractor.Raygun/RaygunMessageException.cs new file mode 100644 index 0000000..6824633 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Raygun/RaygunMessageException.cs @@ -0,0 +1,37 @@ +using System; + +namespace Vima.LoggingAbstractor.Raygun +{ + /// + /// Represents a wrapper for logging messages to Raygun in the form of exception. + /// + /// + public class RaygunMessageException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public RaygunMessageException() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public RaygunMessageException(string message) + : base(message) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public RaygunMessageException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Raygun/Vima.LoggingAbstractor.Raygun.csproj b/Source/Vima.LoggingAbstractor.Raygun/Vima.LoggingAbstractor.Raygun.csproj new file mode 100644 index 0000000..f60790c --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Raygun/Vima.LoggingAbstractor.Raygun.csproj @@ -0,0 +1,49 @@ + + + + 0.1.0 + 0.1.0 + Victor Usoltsev + Logging Abstractor is a library for .NET that allows you to swap out logging providers with ease. + Copyright © Victor Usoltsev 2018 + https://github.com/bernarden/LoggingAbstractor/blob/master/LICENSE + https://raw.githubusercontent.com/bernarden/LoggingAbstractor/master/Resources/NugetIcon.png + https://github.com/bernarden/LoggingAbstractor + git + logging abstractor abstraction logger + https://github.com/bernarden/LoggingAbstractor + Vima + en-US + False + LoggingAbstractor.Raygun + LoggingAbstractor.Raygun + + + + net451;netstandard1.6 + Vima.LoggingAbstractor.Raygun + Vima.LoggingAbstractor.Raygun + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.Raygun.xml + ..\ca.ruleset + true + + + + + + + + + + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.Sentry.Tests/UnitTest1.cs b/Source/Vima.LoggingAbstractor.Sentry.Tests/UnitTest1.cs new file mode 100644 index 0000000..480e4dc --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Sentry.Tests/UnitTest1.cs @@ -0,0 +1,12 @@ +using Xunit; + +namespace Vima.LoggingAbstractor.Sentry.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Sentry.Tests/Vima.LoggingAbstractor.Sentry.Tests.csproj b/Source/Vima.LoggingAbstractor.Sentry.Tests/Vima.LoggingAbstractor.Sentry.Tests.csproj new file mode 100644 index 0000000..6250070 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Sentry.Tests/Vima.LoggingAbstractor.Sentry.Tests.csproj @@ -0,0 +1,23 @@ + + + + net47 + Vima.LoggingAbstractor.Sentry.Tests + Vima.LoggingAbstractor.Sentry.Tests + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.Sentry.Tests.xml + true + ..\ca-tests.ruleset + + false + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.Sentry/ISentryLogger.cs b/Source/Vima.LoggingAbstractor.Sentry/ISentryLogger.cs new file mode 100644 index 0000000..a8eb548 --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Sentry/ISentryLogger.cs @@ -0,0 +1,11 @@ +using Vima.LoggingAbstractor.Core; + +namespace Vima.LoggingAbstractor.Sentry +{ + /// + /// Represents an instance of a Sentry logger. + /// + public interface ISentryLogger : ILogger + { + } +} \ No newline at end of file diff --git a/Source/Vima.LoggingAbstractor.Sentry/SentryLogger.cs b/Source/Vima.LoggingAbstractor.Sentry/SentryLogger.cs new file mode 100644 index 0000000..603887d --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Sentry/SentryLogger.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SharpRaven; +using SharpRaven.Data; +using Vima.LoggingAbstractor.Core; +using Vima.LoggingAbstractor.Core.Extensions; +using Vima.LoggingAbstractor.Core.Parameters; + +namespace Vima.LoggingAbstractor.Sentry +{ + /// + /// Represents an instance of a Sentry logger. + /// + public class SentryLogger : LoggerBase, ISentryLogger + { + private readonly RavenClient _ravenClient; + + /// + /// Initializes a new instance of the class. + /// + /// The raven client. + /// The minimal logging level. + public SentryLogger(RavenClient ravenClient, LoggingLevel minimalLoggingLevel = LoggingLevel.Verbose) + : base(minimalLoggingLevel) + { + _ravenClient = ravenClient ?? throw new ArgumentNullException(nameof(ravenClient)); + } + + /// + /// Traces the message. + /// + /// The message to be logged. + /// The logging level. + /// The logging parameters. + public override void TraceMessage(string message, LoggingLevel loggingLevel, IEnumerable parameters) + { + if (!ShouldBeTraced(loggingLevel)) + { + return; + } + + IEnumerable loggingParameters = parameters.ToList(); + Dictionary tags = GenerateTags(loggingParameters); + _ravenClient.Capture(new SentryEvent(message) { Tags = tags, Extra = loggingParameters.ExtractData() }); + } + + /// + /// Traces the exception. + /// + /// The exception to be logged. + /// The logging level. + /// The logging parameters. + public override void TraceException(Exception exception, LoggingLevel loggingLevel, IEnumerable parameters) + { + if (!ShouldBeTraced(loggingLevel)) + { + return; + } + + IEnumerable loggingParameters = parameters.ToList(); + Dictionary tags = GenerateTags(loggingParameters); + _ravenClient.Capture(new SentryEvent(exception) { Tags = tags, Extra = loggingParameters.ExtractData() }); + } + + private static Dictionary GenerateTags(IEnumerable parameters) + { + return parameters.ExtractTags().ToDictionary(tag => tag); + } + } +} diff --git a/Source/Vima.LoggingAbstractor.Sentry/Vima.LoggingAbstractor.Sentry.csproj b/Source/Vima.LoggingAbstractor.Sentry/Vima.LoggingAbstractor.Sentry.csproj new file mode 100644 index 0000000..4a19a1a --- /dev/null +++ b/Source/Vima.LoggingAbstractor.Sentry/Vima.LoggingAbstractor.Sentry.csproj @@ -0,0 +1,41 @@ + + + + 0.1.0 + 0.1.0 + Victor Usoltsev + Logging Abstractor is a library for .NET that allows you to swap out logging providers with ease. + Copyright © Victor Usoltsev 2018 + https://github.com/bernarden/LoggingAbstractor/blob/master/LICENSE + https://raw.githubusercontent.com/bernarden/LoggingAbstractor/master/Resources/NugetIcon.png + https://github.com/bernarden/LoggingAbstractor + git + logging abstractor abstraction logger + https://github.com/bernarden/LoggingAbstractor + Vima + en-US + False + LoggingAbstractor.Sentry + LoggingAbstractor.Sentry + + + + net47;net46;net45;net40;net35;netstandard2.0 + Vima.LoggingAbstractor.Sentry + Vima.LoggingAbstractor.Sentry + bin\$(Configuration)\$(TargetFramework)\Vima.LoggingAbstractor.Sentry.xml + ..\ca.ruleset + true + + + + + + + + + + + + + diff --git a/Source/Vima.LoggingAbstractor.sln b/Source/Vima.LoggingAbstractor.sln index a2537f2..504d4d6 100644 --- a/Source/Vima.LoggingAbstractor.sln +++ b/Source/Vima.LoggingAbstractor.sln @@ -5,6 +5,26 @@ VisualStudioVersion = 15.0.27130.2027 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.Core", "Vima.LoggingAbstractor.Core\Vima.LoggingAbstractor.Core.csproj", "{3FB0E95B-327C-4679-8DB4-4769813BED6B}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.Raygun", "Vima.LoggingAbstractor.Raygun\Vima.LoggingAbstractor.Raygun.csproj", "{5CADCE35-9157-4644-A9C2-058D8E8AE8BB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.Sentry", "Vima.LoggingAbstractor.Sentry\Vima.LoggingAbstractor.Sentry.csproj", "{CD2797B3-0861-435A-9B36-ADB457E9242A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.AppInsights", "Vima.LoggingAbstractor.AppInsights\Vima.LoggingAbstractor.AppInsights.csproj", "{5F507DDE-69FC-464F-AC7E-069E2D16D05D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{3C17934E-6CA1-4F9B-BBB5-40405D4489E2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Clients", "Clients", "{9F33D991-BD90-406B-9A62-4D1C7D184368}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{ECC3568E-2B5D-4CD9-90E3-8727BA55E179}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.AppInsights.Tests", "Vima.LoggingAbstractor.AppInsights.Tests\Vima.LoggingAbstractor.AppInsights.Tests.csproj", "{E3D4BE5B-E487-40D0-A2A5-CADC98D6EAC4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.Raygun.Tests", "Vima.LoggingAbstractor.Raygun.Tests\Vima.LoggingAbstractor.Raygun.Tests.csproj", "{BE9E1277-540B-43AF-B2B0-39C4D54EB4C5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.Sentry.Tests", "Vima.LoggingAbstractor.Sentry.Tests\Vima.LoggingAbstractor.Sentry.Tests.csproj", "{B67216FC-D4EB-4E71-AF39-5A5C84C03505}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vima.LoggingAbstractor.Core.Tests", "Vima.LoggingAbstractor.Core.Tests\Vima.LoggingAbstractor.Core.Tests.csproj", "{1FE06ABE-1840-48FC-B897-86467D804171}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,10 +35,48 @@ Global {3FB0E95B-327C-4679-8DB4-4769813BED6B}.Debug|Any CPU.Build.0 = Debug|Any CPU {3FB0E95B-327C-4679-8DB4-4769813BED6B}.Release|Any CPU.ActiveCfg = Release|Any CPU {3FB0E95B-327C-4679-8DB4-4769813BED6B}.Release|Any CPU.Build.0 = Release|Any CPU + {5CADCE35-9157-4644-A9C2-058D8E8AE8BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5CADCE35-9157-4644-A9C2-058D8E8AE8BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5CADCE35-9157-4644-A9C2-058D8E8AE8BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5CADCE35-9157-4644-A9C2-058D8E8AE8BB}.Release|Any CPU.Build.0 = Release|Any CPU + {CD2797B3-0861-435A-9B36-ADB457E9242A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD2797B3-0861-435A-9B36-ADB457E9242A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD2797B3-0861-435A-9B36-ADB457E9242A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD2797B3-0861-435A-9B36-ADB457E9242A}.Release|Any CPU.Build.0 = Release|Any CPU + {5F507DDE-69FC-464F-AC7E-069E2D16D05D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5F507DDE-69FC-464F-AC7E-069E2D16D05D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5F507DDE-69FC-464F-AC7E-069E2D16D05D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5F507DDE-69FC-464F-AC7E-069E2D16D05D}.Release|Any CPU.Build.0 = Release|Any CPU + {E3D4BE5B-E487-40D0-A2A5-CADC98D6EAC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E3D4BE5B-E487-40D0-A2A5-CADC98D6EAC4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E3D4BE5B-E487-40D0-A2A5-CADC98D6EAC4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E3D4BE5B-E487-40D0-A2A5-CADC98D6EAC4}.Release|Any CPU.Build.0 = Release|Any CPU + {BE9E1277-540B-43AF-B2B0-39C4D54EB4C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE9E1277-540B-43AF-B2B0-39C4D54EB4C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE9E1277-540B-43AF-B2B0-39C4D54EB4C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE9E1277-540B-43AF-B2B0-39C4D54EB4C5}.Release|Any CPU.Build.0 = Release|Any CPU + {B67216FC-D4EB-4E71-AF39-5A5C84C03505}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B67216FC-D4EB-4E71-AF39-5A5C84C03505}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B67216FC-D4EB-4E71-AF39-5A5C84C03505}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B67216FC-D4EB-4E71-AF39-5A5C84C03505}.Release|Any CPU.Build.0 = Release|Any CPU + {1FE06ABE-1840-48FC-B897-86467D804171}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FE06ABE-1840-48FC-B897-86467D804171}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FE06ABE-1840-48FC-B897-86467D804171}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FE06ABE-1840-48FC-B897-86467D804171}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {3FB0E95B-327C-4679-8DB4-4769813BED6B} = {3C17934E-6CA1-4F9B-BBB5-40405D4489E2} + {5CADCE35-9157-4644-A9C2-058D8E8AE8BB} = {9F33D991-BD90-406B-9A62-4D1C7D184368} + {CD2797B3-0861-435A-9B36-ADB457E9242A} = {9F33D991-BD90-406B-9A62-4D1C7D184368} + {5F507DDE-69FC-464F-AC7E-069E2D16D05D} = {9F33D991-BD90-406B-9A62-4D1C7D184368} + {E3D4BE5B-E487-40D0-A2A5-CADC98D6EAC4} = {ECC3568E-2B5D-4CD9-90E3-8727BA55E179} + {BE9E1277-540B-43AF-B2B0-39C4D54EB4C5} = {ECC3568E-2B5D-4CD9-90E3-8727BA55E179} + {B67216FC-D4EB-4E71-AF39-5A5C84C03505} = {ECC3568E-2B5D-4CD9-90E3-8727BA55E179} + {1FE06ABE-1840-48FC-B897-86467D804171} = {ECC3568E-2B5D-4CD9-90E3-8727BA55E179} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {81C432BA-8657-42A6-BC44-C0D267D70BF8} EndGlobalSection diff --git a/Source/ca-tests.ruleset b/Source/ca-tests.ruleset new file mode 100644 index 0000000..139474d --- /dev/null +++ b/Source/ca-tests.ruleset @@ -0,0 +1,666 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/ca.ruleset b/Source/ca.ruleset new file mode 100644 index 0000000..92ca674 --- /dev/null +++ b/Source/ca.ruleset @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file