diff --git a/.gitignore b/.gitignore index 2329206..c499cb0 100644 --- a/.gitignore +++ b/.gitignore @@ -95,6 +95,15 @@ ipch/ # Guidance Automation Toolkit *.gpState +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper diff --git a/ApplicationInsightsOutputSubscriber.cs b/ApplicationInsightsOutputSubscriber.cs new file mode 100644 index 0000000..cef827e --- /dev/null +++ b/ApplicationInsightsOutputSubscriber.cs @@ -0,0 +1,96 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using Microsoft.ApplicationInsights; +using Microsoft.ApplicationInsights.DataContracts; + +namespace PSLogging +{ + using System; + using System.IO; + using System.Management.Automation; + + public class ApplicationInsightsOutputSubscriber : HostIOSubscriberBase + { + private readonly TelemetryClient client; + + public ApplicationInsightsOutputSubscriber(string key, // Azure Application Insights "InstrumentationKey" + string dateTimeFormat = "r") + { + client = new TelemetryClient(); + client.InstrumentationKey = key; + DateTimeFormat = dateTimeFormat; + } + + + #region Properties + + public string DateTimeFormat { get; set; } + + #endregion + + + public override void WriteDebug(string message) + { + if (string.IsNullOrEmpty(message)) + { + return; + } + + if (message.Trim() != String.Empty) + { + message = String.Format("{0,-29} - [D] {1}", DateTime.UtcNow.ToString(DateTimeFormat), message); + } + + client.TrackTrace(message, SeverityLevel.Verbose); + } + + public override void WriteError(string message) + { + if (string.IsNullOrEmpty(message)) + { + return; + } + + if (message.Trim() != String.Empty) + { + message = String.Format("{0,-29} - [E] {1}", DateTime.UtcNow.ToString(DateTimeFormat), message); + } + + client.TrackTrace(message, SeverityLevel.Error); + } + + public override void WriteVerbose(string message) + { + if (string.IsNullOrEmpty(message)) + { + return; + } + + if (message.Trim() != String.Empty) + { + message = String.Format("{0,-29} - [V] {1}", DateTime.UtcNow.ToString(DateTimeFormat), message); + } + + client.TrackTrace(message, SeverityLevel.Verbose); + } + + public override void WriteWarning(string message) + { + if (string.IsNullOrEmpty(message)) + { + return; + } + + if (message.Trim() != String.Empty) + { + message = String.Format("{0,-29} - [W] {1}", DateTime.UtcNow.ToString(DateTimeFormat), message); + } + + client.TrackTrace(message, SeverityLevel.Warning); + } + } +} + +// ReSharper restore MemberCanBePrivate.Global +// ReSharper restore UnusedMember.Global \ No newline at end of file diff --git a/Commands/DisableApplicationInsightsCommand.cs b/Commands/DisableApplicationInsightsCommand.cs new file mode 100644 index 0000000..7f9bace --- /dev/null +++ b/Commands/DisableApplicationInsightsCommand.cs @@ -0,0 +1,26 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable UnusedMember.Global + +namespace PSLogging.Commands +{ + using System.Management.Automation; + + [Cmdlet(VerbsLifecycle.Disable, "ApplicationInsights")] + public class DisableApplicationInsightsCommand : PSCmdlet + { + [Parameter(Mandatory = true, + ValueFromPipeline = true, + Position = 0)] + public ApplicationInsightsOutputSubscriber InputObject { get; set; } + + protected override void EndProcessing() + { + HostIOInterceptor.Instance.RemoveSubscriber(InputObject); + } + } +} + +// ReSharper restore MemberCanBePrivate.Global +// ReSharper restore UnusedAutoPropertyAccessor.Global +// ReSharper restore UnusedMember.Global \ No newline at end of file diff --git a/Commands/EnableApplicationInsightsCommand.cs b/Commands/EnableApplicationInsightsCommand.cs new file mode 100644 index 0000000..6c7c2f5 --- /dev/null +++ b/Commands/EnableApplicationInsightsCommand.cs @@ -0,0 +1,68 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global +// ReSharper disable UnusedMember.Global + +namespace PSLogging.Commands +{ + using System.Management.Automation; + + [Cmdlet(VerbsLifecycle.Enable, "ApplicationInsights")] + public class EnableApplicationInsightsCommand : PSCmdlet + { + private ApplicationInsightsOutputSubscriber inputObject; + private string key; + private string dateTimeFormat = "r"; + + #region Parameters + + [Parameter(ParameterSetName = "AttachExisting", + Mandatory = true, + Position = 0, + ValueFromPipeline = true)] + public ApplicationInsightsOutputSubscriber InputObject + { + get { return inputObject; } + set { inputObject = value; } + } + + [Parameter(Mandatory = true, + Position = 0, + ParameterSetName = "New")] + public string Key + { + get { return key; } + set { key = value; } + } + + [Parameter(ParameterSetName = "New")] + public string DateTimeFormat + { + get { return dateTimeFormat; } + set { dateTimeFormat = value; } + } + + #endregion + + protected override void EndProcessing() + { + ApplicationInsightsOutputSubscriber subscriber; + + if (ParameterSetName == "New") + { + subscriber = new ApplicationInsightsOutputSubscriber(key, dateTimeFormat); + WriteObject(subscriber); + } + else + { + subscriber = inputObject; + } + + HostIOInterceptor.Instance.AttachToHost(Host); + HostIOInterceptor.Instance.AddSubscriber(subscriber); + } + } +} + +// ReSharper restore MemberCanBePrivate.Global +// ReSharper restore UnusedAutoPropertyAccessor.Global +// ReSharper restore UnusedMember.Global \ No newline at end of file diff --git a/PSLogging.csproj b/PSLogging.csproj index 6dd6501..cc99b10 100644 --- a/PSLogging.csproj +++ b/PSLogging.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,7 +9,7 @@ Properties PSLogging PowerShellLoggingModule - v2.0 + v4.6.1 512 @@ -22,6 +22,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -30,15 +31,26 @@ TRACE prompt 4 + false + + packages\Microsoft.ApplicationInsights.2.6.4\lib\net46\Microsoft.ApplicationInsights.dll + + + packages\System.Diagnostics.DiagnosticSource.4.4.0\lib\net46\System.Diagnostics.DiagnosticSource.dll + False ..\..\..\..\..\..\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll + + + + @@ -60,12 +72,17 @@ Designer + + + + + - --> \ No newline at end of file diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..a5879f2 --- /dev/null +++ b/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/targets/PowerShellLoggingModule.targets b/targets/PowerShellLoggingModule.targets new file mode 100644 index 0000000..83e7a12 --- /dev/null +++ b/targets/PowerShellLoggingModule.targets @@ -0,0 +1,23 @@ + + + + $(SolutionDir)Module\PowerShellLogging\ + $(SolutionDir)bin\$(Configuration)\ + + + + + + + + + + + + + + + + \ No newline at end of file