2008-09-25 7 views
6

J'aimerais enregistrer des éléments dans mes composants WebPart Sharepoint, mais je souhaite qu'ils soient intégrés à l'ULS. La plupart des exemples que j'ai trouvé se connecter au journal des événements ou à un autre fichier, mais je n'en ai pas encore trouvé un pour me connecter à l'ULS. Malheureusement, les classes Microsoft.SharePoint.Diagnostics sont toutes marquées Interne. J'ai trouvé one example de comment les utiliser de toute façon par réflexion, mais cela semble vraiment risqué et instable, car Microsoft peut changer cette classe avec n'importe quel correctif qu'ils veulent. La documentation de Sharepoint n'était pas vraiment utile non plus - beaucoup d'informations de l'administrateur sur ce qu'est ULS et comment le configurer, mais je n'ai pas encore trouvé un exemple de code supporté pour enregistrer mes propres événements.Connexion par programme au Sharepoint ULS

Des conseils ou des astuces?

Edit: Comme vous pouvez le voir dès l'âge de cette question, ceci est pour SharePoint 2007. Dans SharePoint 2010, vous pouvez utiliser SPDiagnosticsService.Local puis WriteTrace. Voir la réponse de Jürgen ci-dessous.

Répondre

8

Oui cela est possible, consultez cet article MSDN: http://msdn2.microsoft.com/hi-in/library/aa979595(en-us).aspx

Et voici quelques exemples de code en 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

J'ai utilisé le code de cet article MSDN dans le passé et cela a-t-il fonctionné efficacement pour moi. – barryd

+0

Ne fonctionne pas dans SharePoint 2010 –

+0

Que diriez-vous d'une autre question mais pour Microsoft: Pourquoi cette fonctionnalité n'est-elle pas déjà intégrée? Pourquoi le besoin de notre propre classe d'encapsidation? –

-1

Cela ne fonctionne pour moi, et a raccroché mon webpart toujours. Je l'ai eu travailler pendant une seconde et puis pas. Et seulement, seulement quand j'ai enlevé les instructions de registre de trace/unregister/etc cela fonctionnerait-il.

Je recommande donc cet excellent article qui a fonctionné pour moi: http://sharepoint.namics.com/2008/05/logging_in_webparts.html

Essentiellement, vous devez utiliser:

Bibliothèques communes d'infrastructure pour .NET.

Je l'ai téléchargé à partir d'ici: http://netcommon.sourceforge.net/

I utilisé gacutil (ou le panneau de contrôle/outils d'administration/.net outil de configuration) pour ajouter les dll 2.0/libération du gac.

J'ai ajouté des références à mon code à la DLL (à partir du téléchargement). Tout a été compilé.

J'ai dû créer un répertoire et un fichier journal vide, et bam! sur le premier chargement de la partie Web, cela a fonctionné. J'ai essayé pendant des heures et des heures de me connecter à mon site Web et cela a fonctionné à merveille, et c'est un bon standard, comme log4j.

+0

Le lien est cassé. Pourriez-vous indiquer ce qui n'a pas fonctionné? Vous pourriez vouloir dire la solution rejetée de la question originale ou l'article MSDN suggéré par une autre réponse. –

2

Le crédit va à: http://msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
Je viens de publier un post sur mon blog, mais coller le code ici.

Définir le nom de votre solution dans le code pour la ligne suivante:

private const string PRODUCT_NAME = "My Custom Solution"; 

Après sont des exemples de code sur la façon de l'utiliser:

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

Voici le 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

je l'ai utilisé et cela fonctionne très bien et comme attendre, merci de me sauver d'un mal de tête! –

+0

Je suis heureux de savoir que cela a fonctionné pour vous David. –

1

Essayez ci-dessous Code: (ajoutez cette référence: 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) 
     { 
     } 

Maintenant, ouvrez uls viewer et filtrez par votre nom de catégorie.

Questions connexes