Program registration in Sharepoint ULS

I would like to write material to my Sharepoint web parts, but I want it to go to ULS. Most of the examples I found are logged in the Event Log or in some other file, but I really haven't found it yet to log into ULS.

It is annoying that Microsoft.SharePoint.Diagnostics classes are marked as internal. I found one example on how to use them anyway through reflection, but it looks very risky and unstable, since Microsoft can change this class with any fix they want.

The Sharepoint documentation is also not very useful - a lot of information about the administrator, what ULS is and how to configure it, but I have not yet been able to find an example of supported code to actually record my own events.

Any clues or hints?

Edit: As you can see from the age of this question, this is for SharePoint 2007. In SharePoint 2010 you can use SPDiagnosticsService.Local and then WriteTrace . See Reply from Jürgen below.

+6
sharepoint sharepoint-2007
source share
5 answers

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

And here is an example 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; } } 

}

+8
source share

Credit: http://msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
I just posted a post on my blog, but am pasting the code here.

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

 private const string PRODUCT_NAME = "My Custom Solution"; 

The following is 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:"); 

Below 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); } } } 
+2
source share
+1
source share

Try the code below: (add link: 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 the uls viewer and filter by the name of your category.

+1
source share

This DID does NOT work for me, and has hung up my web page sequentially. I worked for a second, and then not. And only, only when I deleted the register Trace / unregister / etc statements, it will work.

So I recommend this wonderful article that 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 panel / admin tools / .net config tool) to add dll 2.0 / release to gac.

I added links to my code in the dll (from download). All compiled.

I had to create a directory and an empty log file, as well as bam! on the first download of the web part, it worked. I tried for hours and hours to access my web part, and it worked great, and it's a good standard, like log4j for example.

-one
source share

All Articles