Programmatically logging to the Sharepoint ULS

后端 未结 5 1653
一整个雨季
一整个雨季 2020-12-30 14:08

I\'d like to log stuff in my Sharepoint Web Parts, but I want it to go into the ULS. Most examples that I\'ve found log into the Event Log or some other file, but I did not

相关标签:
5条回答
  • 2020-12-30 14:48

    Try Below Code: (add this reference: using Microsoft.SharePoint.Administration;)

    try
            {
    
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPDiagnosticsService diagSvc = SPDiagnosticsService.Local;
                    diagSvc.WriteTrace(123456, new SPDiagnosticsCategory("Category_Name_Here", TraceSeverity.Monitorable, EventSeverity.Error), TraceSeverity.Monitorable, "{0}:{1}", new object[] { "Method_Name", "Error_Message"});
                });
            }
            catch (Exception ex)
            {
            }
    

    Now open uls viewer and filter by your category name.

    0 讨论(0)
  • 2020-12-30 14:56

    Yes this is possible, see this MSDN article: http://msdn2.microsoft.com/hi-in/library/aa979595(en-us).aspx

    And here is some sample code in C#:

    using System;
    using System.Runtime.InteropServices;
    using Microsoft.SharePoint.Administration;
    
    namespace ManagedTraceProvider
    {
    class Program
    {
        static void Main(string[] args)
        {
            TraceProvider.RegisterTraceProvider();
    
            TraceProvider.WriteTrace(0, TraceProvider.TraceSeverity.High, Guid.Empty, "MyExeName", "Product Name", "Category Name", "Sample Message");
            TraceProvider.WriteTrace(TraceProvider.TagFromString("abcd"), TraceProvider.TraceSeverity.Monitorable, Guid.NewGuid(), "MyExeName", "Product Name", "Category Name", "Sample Message");
    
            TraceProvider.UnregisterTraceProvider();
        }
    }
    
    static class TraceProvider
    {
        static UInt64 hTraceLog;
        static UInt64 hTraceReg;
    
        static class NativeMethods
        {
            internal const int TRACE_VERSION_CURRENT = 1;
            internal const int ERROR_SUCCESS = 0;
            internal const int ERROR_INVALID_PARAMETER = 87;
            internal const int WNODE_FLAG_TRACED_GUID = 0x00020000;
    
            internal enum TraceFlags
            {
                TRACE_FLAG_START = 1,
                TRACE_FLAG_END = 2,
                TRACE_FLAG_MIDDLE = 3,
                TRACE_FLAG_ID_AS_ASCII = 4
            }
    
            // Copied from Win32 APIs
            [StructLayout(LayoutKind.Sequential)]
            internal struct EVENT_TRACE_HEADER_CLASS
            {
                internal byte Type;
                internal byte Level;
                internal ushort Version;
            }
    
            // Copied from Win32 APIs
            [StructLayout(LayoutKind.Sequential)]
            internal struct EVENT_TRACE_HEADER
            {
                internal ushort Size;
                internal ushort FieldTypeFlags;
                internal EVENT_TRACE_HEADER_CLASS Class;
                internal uint ThreadId;
                internal uint ProcessId;
                internal Int64 TimeStamp;
                internal Guid Guid;
                internal uint ClientContext;
                internal uint Flags;
            }
    
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
            internal struct ULSTraceHeader
            {
                internal ushort Size;
                internal uint dwVersion;
                internal uint Id;
                internal Guid correlationID;
                internal TraceFlags dwFlags;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
                internal string wzExeName;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
                internal string wzProduct;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
                internal string wzCategory;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 800)]
                internal string wzMessage;
            }
    
            [StructLayout(LayoutKind.Sequential)]
            internal struct ULSTrace
            {
                internal EVENT_TRACE_HEADER Header;
                internal ULSTraceHeader ULSHeader;
            }
    
            // Copied from Win32 APIs
            internal enum WMIDPREQUESTCODE
            {
                WMI_GET_ALL_DATA = 0,
                WMI_GET_SINGLE_INSTANCE = 1,
                WMI_SET_SINGLE_INSTANCE = 2,
                WMI_SET_SINGLE_ITEM = 3,
                WMI_ENABLE_EVENTS = 4,
                WMI_DISABLE_EVENTS = 5,
                WMI_ENABLE_COLLECTION = 6,
                WMI_DISABLE_COLLECTION = 7,
                WMI_REGINFO = 8,
                WMI_EXECUTE_METHOD = 9
            }
    
            // Copied from Win32 APIs
            internal unsafe delegate uint EtwProc(NativeMethods.WMIDPREQUESTCODE requestCode, IntPtr requestContext, uint* bufferSize, IntPtr buffer);
    
            // Copied from Win32 APIs
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
            internal static extern unsafe uint RegisterTraceGuids([In] EtwProc cbFunc, [In] void* context, [In] ref Guid controlGuid, [In] uint guidCount, IntPtr guidReg, [In] string mofImagePath, [In] string mofResourceName, out ulong regHandle);
    
            // Copied from Win32 APIs
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
            internal static extern uint UnregisterTraceGuids([In]ulong regHandle);
    
            // Copied from Win32 APIs
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode)]
            internal static extern UInt64 GetTraceLoggerHandle([In]IntPtr Buffer);
    
            // Copied from Win32 APIs
            [DllImport("advapi32.dll", SetLastError = true)]
            internal static extern uint TraceEvent([In]UInt64 traceHandle, [In]ref ULSTrace evnt);
        }
    
        public enum TraceSeverity
        {
            Unassigned = 0,
            CriticalEvent = 1,
            WarningEvent = 2,
            InformationEvent = 3,
            Exception = 4,
            Assert = 7,
            Unexpected = 10,
            Monitorable = 15,
            High = 20,
            Medium = 50,
            Verbose = 100,
        }
    
        public static void WriteTrace(uint tag, TraceSeverity level, Guid correlationGuid, string exeName, string productName, string categoryName, string message)
        {
            const ushort sizeOfWCHAR = 2;
            NativeMethods.ULSTrace ulsTrace = new NativeMethods.ULSTrace();
    
            // Pretty standard code needed to make things work
            ulsTrace.Header.Size = (ushort)Marshal.SizeOf(typeof(NativeMethods.ULSTrace));
            ulsTrace.Header.Flags = NativeMethods.WNODE_FLAG_TRACED_GUID;
            ulsTrace.ULSHeader.dwVersion = NativeMethods.TRACE_VERSION_CURRENT;
            ulsTrace.ULSHeader.dwFlags = NativeMethods.TraceFlags.TRACE_FLAG_ID_AS_ASCII;
            ulsTrace.ULSHeader.Size = (ushort)Marshal.SizeOf(typeof(NativeMethods.ULSTraceHeader));
    
            // Variables communicated to SPTrace
            ulsTrace.ULSHeader.Id = tag;
            ulsTrace.Header.Class.Level = (byte)level;
            ulsTrace.ULSHeader.wzExeName = exeName;
            ulsTrace.ULSHeader.wzProduct = productName;
            ulsTrace.ULSHeader.wzCategory = categoryName;
            ulsTrace.ULSHeader.wzMessage = message;
            ulsTrace.ULSHeader.correlationID = correlationGuid;
    
            // Pptionally, to improve performance by reducing the amount of data copied around,
            // the Size parameters can be reduced by the amount of unused buffer in the Message
            if (message.Length < 800)
            {
                ushort unusedBuffer = (ushort) ((800 - (message.Length + 1)) * sizeOfWCHAR);
                ulsTrace.Header.Size -= unusedBuffer;
                ulsTrace.ULSHeader.Size -= unusedBuffer;
            }
    
            if (hTraceLog != 0)
                NativeMethods.TraceEvent(hTraceLog, ref ulsTrace);
        }
    
        public static unsafe void RegisterTraceProvider()
        {
            SPFarm farm = SPFarm.Local;
            Guid traceGuid = farm.TraceSessionGuid;
            uint result = NativeMethods.RegisterTraceGuids(ControlCallback, null, ref traceGuid, 0, IntPtr.Zero, null, null, out hTraceReg);
            System.Diagnostics.Debug.Assert(result == NativeMethods.ERROR_SUCCESS);
        }
    
        public static void UnregisterTraceProvider()
        {
            uint result = NativeMethods.UnregisterTraceGuids(hTraceReg);
            System.Diagnostics.Debug.Assert(result == NativeMethods.ERROR_SUCCESS);
        }
    
        public static uint TagFromString(string wzTag)
        {
            System.Diagnostics.Debug.Assert(wzTag.Length == 4);
            return (uint) (wzTag[0] << 24 | wzTag[1] << 16 | wzTag[2] << 8 | wzTag[3]);
        }
    
        static unsafe uint ControlCallback(NativeMethods.WMIDPREQUESTCODE RequestCode, IntPtr Context, uint* InOutBufferSize, IntPtr Buffer)
        {
            uint Status;
            switch (RequestCode)
            {
                case NativeMethods.WMIDPREQUESTCODE.WMI_ENABLE_EVENTS:
                    hTraceLog = NativeMethods.GetTraceLoggerHandle(Buffer);
                    Status = NativeMethods.ERROR_SUCCESS;
                    break;
                case NativeMethods.WMIDPREQUESTCODE.WMI_DISABLE_EVENTS:
                    hTraceLog = 0;
                    Status = NativeMethods.ERROR_SUCCESS;
                    break;
                default:
                    Status = NativeMethods.ERROR_INVALID_PARAMETER;
                    break;
            }
    
            *InOutBufferSize = 0;
            return Status;
        }
    }
    

    }

    0 讨论(0)
  • 2020-12-30 15:01

    The credit goes to: http://msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
    I have just published a post on my blog, but pasting the code here.

    Define name of your solution in the code for following line:

    private const string PRODUCT_NAME = "My Custom Solution";
    

    Following are sample code on how to use it:

    UlsLogging.LogInformation("This is information message");
    UlsLogging.LogInformation("{0}This is information message","Information:");  
    
    UlsLogging.LogWarning("This is warning message");
    UlsLogging.LogWarning("{0}This is warning message", "Warning:");  
    
    UlsLogging.LogError("This is error message");
    UlsLogging.LogError("{0}This is error message","Error:");  
    

    Following is the code:

    using System;
    using System.Collections.Generic;
    using Microsoft.SharePoint.Administration;
    namespace MyLoggingApp
    {
        public class UlsLogging : SPDiagnosticsServiceBase
        {
            // Product name
            private const string PRODUCT_NAME = "My Custom Solution";
    
            #region private variables
    
            // Current instance
            private static UlsLogging _current;
    
            // area
            private static SPDiagnosticsArea _area;
    
            // category
            private static SPDiagnosticsCategory _catError;
            private static SPDiagnosticsCategory _catWarning;
            private static SPDiagnosticsCategory _catLogging;
    
            #endregion
    
            private static class CategoryName
            {
                public const string Error = "Error";
                public const string Warning = "Warning";
                public const string Logging = "Logging";
            }
    
            private static UlsLogging Current
            {
                get
                {
                    if (_current == null)
                    {
                        _current = new UlsLogging();
                    }
                    return _current;
                }
            }
    
            // Get Area
            private static SPDiagnosticsArea Area
            {
                get
                {
                    if (_area == null)
                    {
                        _area = UlsLogging.Current.Areas[PRODUCT_NAME];
                    }
                    return _area;
                }
            }
    
            // Get error category
            private static SPDiagnosticsCategory CategoryError
            {
                get
                {
                    if (_catError == null)
                    {
                        _catError = Area.Categories[CategoryName.Error];
                    }
                    return _catError;
                }
            }
    
            // Get warning category
            private static SPDiagnosticsCategory CategoryWarning
            {
                get
                {
                    if (_catWarning == null)
                    {
                        _catWarning = Area.Categories[CategoryName.Warning];
                    }
                    return _catWarning;
                }
            }
    
            // Get logging category
            private static SPDiagnosticsCategory CategoryLogging
            {
                get
                {
                    if (_catLogging == null)
                    {
                        _catLogging = Area.Categories[CategoryName.Logging];
                    }
                    return _catLogging;
                }
            }
    
            private UlsLogging()
                : base(PRODUCT_NAME, SPFarm.Local)
            {
            }
    
            protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
            {
                var cat = new List<SPDiagnosticsCategory>{
                    new SPDiagnosticsCategory(CategoryName.Error, TraceSeverity.High,EventSeverity.Error),
                    new SPDiagnosticsCategory(CategoryName.Warning, TraceSeverity.Medium,EventSeverity.Warning),
                    new SPDiagnosticsCategory(CategoryName.Logging,TraceSeverity.Verbose,EventSeverity.Information)
                };
                var areas = new List<SPDiagnosticsArea>();
                areas.Add(new SPDiagnosticsArea(PRODUCT_NAME, cat));
    
                return areas;
            }
    
            // Log Error
            public static void LogError(string msg)
            {
                UlsLogging.Current.WriteTrace(0, CategoryError, TraceSeverity.High, msg);
            }
            public static void LogError(string msg,params object[] args)
            {
                UlsLogging.Current.WriteTrace(0, CategoryError, TraceSeverity.High, msg,args);
            }
    
            // Log Warning
            public static void LogWarning(string msg)
            {
                UlsLogging.Current.WriteTrace(0, CategoryWarning, TraceSeverity.Medium, msg);
            }
            public static void LogWarning(string msg, params object[] args)
            {
                UlsLogging.Current.WriteTrace(0, CategoryWarning, TraceSeverity.Medium, msg,args);
            }
    
            // Log Information
            public static void LogInformation(string msg)
            {
                UlsLogging.Current.WriteTrace(0, CategoryLogging, TraceSeverity.Verbose, msg); 
            }
            public static void LogInformation(string msg,params object[] args)
            {
                UlsLogging.Current.WriteTrace(0, CategoryLogging, TraceSeverity.Verbose, msg,args);
            }
    
        }
    }
    
    0 讨论(0)
  • 2020-12-30 15:08

    This DID NOT work for me, and hung up my webpart consistently. I had it working for a second and then not. And only, only when I removed the Trace register/unregister/etc statements would it work.

    So I recommend this excellent article which worked for me: http://sharepoint.namics.com/2008/05/logging_in_webparts.html

    Essentially, you should use:

    Common Infrastructure Libraries for .NET.

    I downloaded it from here: http://netcommon.sourceforge.net/

    I used gacutil (or the control pane/admin tools/.net config tool) to add the 2.0/release dll's to the gac.

    I added references to my code to the dll's (from the download). Everything compiled.

    I had to create a directory and empty log file, and bam! on the first web part load it worked. I tried for hours and hours to get logging for my web part and this worked wonderfully, and it's a good standard, like log4j.

    0 讨论(0)
  • 2020-12-30 15:10

    Here you find another great article about logging with SharePoint: http://www.parago.de/2011/01/how-to-implement-a-custom-sharepoint-2010-logging-service-for-uls-and-windows-event-log/

    0 讨论(0)
提交回复
热议问题