2008-09-25 8 views
6

Ich möchte in meinen SharePoint-Webparts etwas protokollieren, aber ich möchte, dass es in das ULS geht. Die meisten Beispiele, die ich gefunden habe, loggen sich in das Ereignisprotokoll oder eine andere Datei ein, aber ich habe noch keine wirklich gefunden, um sich am ULS anzumelden.Programmgesteuertes Protokollieren auf dem Sharepoint ULS

Ärgerlich, Microsoft.SharePoint.Diagnostics Klassen sind alle markiert Intern. Ich fand one example, wie man sie sowieso durch Reflexion verwendet, aber das sieht wirklich riskant und instabil aus, weil Microsoft diese Klasse mit jedem gewünschten Hotfix ändern kann. Die Sharepoint-Dokumentation war auch nicht wirklich hilfreich - viele Administrator-Informationen darüber, was ULS ist und wie man es konfiguriert, aber ich muss noch ein Beispiel für unterstützten Code finden, um meine eigenen Ereignisse tatsächlich zu protokollieren.

Hinweise oder Tipps?

Edit: Wie Sie aus dem Alter dieser Frage sehen kann, ist dies für Sharepoint 2007 Sharepoint 2010 ist, können Sie SPDiagnosticsService.Local verwenden und dann WriteTrace. Siehe die Antwort von Jürgen unten.

Antwort

8

Ja, das möglich ist, finden Sie in diesem MSDN-Artikel: http://msdn2.microsoft.com/hi-in/library/aa979595(en-us).aspx

Und hier ist ein Beispielcode 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; 
    } 
} 

}

+1

Ich habe den Code aus diesem MSDN Artikel in der Vergangenheit verwendet und kann es effektiv für mich gearbeitet haben. – barryd

+0

Funktioniert nicht in SharePoint 2010 –

+0

Wie wäre es mit einer anderen Frage, aber für Microsoft: Warum ist diese Funktionalität nicht bereits integriert? Warum brauchen wir eine eigene Klasse für die Kapselung? –

-1

Das ist für mich nicht funktioniert hat, und hängte mein Webpart konsequent. Ich hatte es für eine Sekunde arbeiten und dann nicht. Und nur, wenn ich die Trace-Register/Unregister/etc-Anweisungen entfernte, würde es funktionieren.

So empfehle ich diesen ausgezeichneten Artikel, die für mich gearbeitet: http://sharepoint.namics.com/2008/05/logging_in_webparts.html

Im Wesentlichen sollten Sie verwenden:

gemeinsame Infrastruktur Bibliotheken für .NET.

ich heruntergeladen es von hier: http://netcommon.sourceforge.net/

I verwendet gacutil (oder Kontrollfenster/Admin-Tools/.net Config-Tool), um den 2.0/release DLL im GAC hinzuzufügen.

Ich habe Referenzen zu meinem Code zu den DLLs (aus dem Download) hinzugefügt. Alles kompiliert.

Ich musste ein Verzeichnis erstellen und leere Protokolldatei und Bam! Auf der ersten Web-Teillast funktionierte es. Ich habe stundenlang versucht, Logging für meinen Webpart zu bekommen, und das hat wunderbar funktioniert, und es ist ein guter Standard, wie log4j.

+0

Die Verbindung ist unterbrochen. Können Sie angeben, was nicht funktioniert hat? Sie könnten die ursprüngliche Lösung der ursprünglichen Frage oder den von einer anderen Antwort vorgeschlagenen MSDN-Artikel meinen. –

2

Der Kredit geht an: http://msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
Ich habe nur einen Beitrag auf meinem Blog veröffentlicht, sondern den Code hier einfügen.

definieren Namen Ihrer Lösung im Code für folgende Zeile:

private const string PRODUCT_NAME = "My Custom Solution"; 

Im Folgenden sind Beispielcode, wie es zu benutzen:

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

Es folgt der 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

ich benutze dies und es funktioniert gut und wie erwartet, danke für die Rettung von Kopfschmerzen! –

+0

Ich bin froh zu wissen, dass es für dich gearbeitet hat David. –

1

Versuchen Sie unter Code: (diese Referenz hinzufügen: usi ng 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) 
     { 
     } 

jetzt offen uls Viewer und Filter von Ihrem Kategorienamen.

Verwandte Themen