Repository: logging-log4net Updated Branches: refs/heads/develop [created] f5fdf89fd refs/heads/pr/old/10 [created] b4bc43eed refs/heads/pr/old/22 [created] 675e7cba2 refs/heads/pr/old/7 [created] 3c930d8d9 refs/heads/pr/old/9 [created] f33118151 Updated Tags: refs/tags/1.2.13RC1 [created] 6dc3da926
First version of ProcMonAppender Project: http://git-wip-us.apache.org/repos/asf/logging-log4net/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4net/commit/f3311815 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4net/tree/f3311815 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4net/diff/f3311815 Branch: refs/heads/pr/old/9 Commit: f331181519b36aebf9203bead1cce6e57c58b373 Parents: 610157a Author: Justin Dearing <[email protected]> Authored: Thu Mar 20 19:12:19 2014 -0400 Committer: Dominik Psenner <[email protected]> Committed: Wed May 24 23:25:47 2017 +0200 ---------------------------------------------------------------------- src/log4net/Appender/ProcMonAppender.cs | 170 +++++++++++++++++++++++++++ src/log4net/log4net.vs2010.csproj | 5 +- 2 files changed, 173 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/f3311815/src/log4net/Appender/ProcMonAppender.cs ---------------------------------------------------------------------- diff --git a/src/log4net/Appender/ProcMonAppender.cs b/src/log4net/Appender/ProcMonAppender.cs new file mode 100644 index 0000000..cfd8af6 --- /dev/null +++ b/src/log4net/Appender/ProcMonAppender.cs @@ -0,0 +1,170 @@ +#region Apache License +// +// Licensed to the Apache Software Foundation (ASF) under one or more +// contributor license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright ownership. +// The ASF licenses this file to you 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. +// +#endregion + +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; +using System.Text; +using log4net.Core; +using Microsoft.Win32.SafeHandles; + +namespace log4net.Appender +{ + /// <summary> + /// Appends log events to Sysinternals Process Monitor. + /// </summary> + /// <remarks> + /// <para> + /// The application configuration file can be used to control what listeners + /// are actually used. + /// </para> + /// <para> + /// Events are written using a write only file handle that procmon listens for. Process Monitor will then display these messages amongst the IO data. + /// </para> + /// </remarks> + /// <author>Justin Dearing</author> + /// <seealso cref="http://www.wintellect.com/blogs/jrobbins/see-the-i-o-you-caused-by-getting-your-diagnostic-tracing-into-process-monitor"/> + /// <seealso cref="http://www.wintellect.com/blogs/jrobbins/procmondebugoutput-now-on-github"/> + /// <seealso cref="https://github.com/Wintellect/ProcMonDebugOutput"/> + public class ProcMonAppender : AppenderSkeleton + { + // Constants to represent C preprocessor macros for PInvokes + const uint GENERIC_WRITE = 0x40000000; + const uint OPEN_EXISTING = 3; + const uint FILE_WRITE_ACCESS = 0x0002; + const uint FILE_SHARE_WRITE = 0x00000002; + const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; + const uint METHOD_BUFFERED = 0; + + // Procmon Constants + const uint FILE_DEVICE_PROCMON_LOG = 0x00009535; + const string PROCMON_DEBUGGER_HANDLER = "\\\\.\\Global\\ProcmonDebugLogger"; + + /// <summary> + /// The handle to the procmon log device. + /// </summary> + private static SafeFileHandle hProcMon; + + /// <summary> + /// Get the IO Control code for the ProcMon log. + /// </summary> + private static uint IOCTL_EXTERNAL_LOG_DEBUGOUT { get { return CTL_CODE(); } } + + /// <seealso href="http://msdn.microsoft.com/en-us/library/windows/hardware/ff543023(v=vs.85).aspx"/> + private static uint CTL_CODE( + uint DeviceType = FILE_DEVICE_PROCMON_LOG, + uint Function = 0x81, + uint Method = METHOD_BUFFERED, + uint Access = FILE_WRITE_ACCESS) + { + return ((DeviceType << 16) | (Access << 14) | (Function << 2) | Method); + } + + /// <remarks>This is only used for opening the procmon log handle, hence the default parameters.</remarks> + /// <seealso href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx"/> + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] + private static extern SafeFileHandle CreateFile( + string lpFileName = PROCMON_DEBUGGER_HANDLER, + uint dwDesiredAccess = GENERIC_WRITE, + uint dwShareMode = FILE_SHARE_WRITE, + IntPtr lpSecurityAttributes = default(IntPtr), + uint dwCreationDisposition = OPEN_EXISTING, + uint dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, + IntPtr hTemplateFile = default(IntPtr)); + + [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Auto)] + private static extern bool DeviceIoControl( + SafeFileHandle hDevice, uint dwIoControlCode, + StringBuilder lpInBuffer, uint nInBufferSize, + IntPtr lpOutBuffer, uint nOutBufferSize, + out uint lpBytesReturned, IntPtr lpOverlapped); + + + static ProcMonAppender() + { + AppDomain.CurrentDomain.ProcessExit += (sender, args) => + { + if (!hProcMon.IsInvalid) hProcMon.Close(); + }; + } + + /// <summary> + /// Does the actual tracing to Process Monitor. + /// </summary> + /// <param name="message"> + /// The message to display. + /// </param> + /// <param name="args"> + /// The formatting arguments for the message + /// </param> + /// <returns> + /// True if the trace succeeded, false otherwise. + /// </returns> + private static bool ProcMonDebugOutput(string message, params object[] args) + { + bool returnValue = false; + try + { + StringBuilder renderedMessage = new StringBuilder(); + renderedMessage.AppendFormat(message, args); + uint outLen; + if (hProcMon == null || hProcMon.IsInvalid) + { + hProcMon = CreateFile(); + } + DeviceIoControl( + hProcMon, IOCTL_EXTERNAL_LOG_DEBUGOUT, + renderedMessage, (uint)(message.Length * Marshal.SizeOf(typeof(char))), + IntPtr.Zero, 0, out outLen, IntPtr.Zero); + } + catch (EntryPointNotFoundException notFoundException) + { + // This means the appropriate ProcMonDebugOutput[Win32|x64].DLL + // file could not be found. I'll eat this exception so it does + // not take down the application. + Debug.WriteLine(notFoundException.Message); + } + + return returnValue; + } + + /// <summary> + /// This appender requires a <see cref="AppenderSkeleton.Layout"/> to be set. + /// </summary> + /// <value><c>true</c></value> + override protected bool RequiresLayout + { + get { return true; } + } + + /// <summary> + /// Writes the logging event to Sysinternals Process Monitor. + /// </summary> + /// <param name="loggingEvent">The event to log.</param> + /// <remarks> + /// <para> + /// Writes the logging event to Sysinternals Process Monitor. + /// </para> + /// </remarks> + protected override void Append(LoggingEvent loggingEvent) + { + throw new System.NotImplementedException(); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4net/blob/f3311815/src/log4net/log4net.vs2010.csproj ---------------------------------------------------------------------- diff --git a/src/log4net/log4net.vs2010.csproj b/src/log4net/log4net.vs2010.csproj index 45e2c58..8c6a7a5 100644 --- a/src/log4net/log4net.vs2010.csproj +++ b/src/log4net/log4net.vs2010.csproj @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <!-- Licensed to the Apache Software Foundation (ASF) under one @@ -179,6 +179,7 @@ <Compile Include="Appender\OutputDebugStringAppender.cs"> <SubType>Code</SubType> </Compile> + <Compile Include="Appender\ProcMonAppender.cs" /> <Compile Include="Appender\RemoteSyslogAppender.cs"> <SubType>Code</SubType> </Compile> @@ -793,4 +794,4 @@ <PostBuildEvent> </PostBuildEvent> </PropertyGroup> -</Project> +</Project> \ No newline at end of file
