2008-09-25 13 views
6

Me gustaría registrar cosas en mis elementos web de Sharepoint, pero quiero que entren en el ULS. La mayoría de los ejemplos que he encontrado se registran en el Registro de eventos o en algún otro archivo, pero realmente no encontré ninguno para iniciar sesión en el ULS.Iniciar sesión programáticamente en Sharepoint ULS

Anormalmente, las clases de Microsoft.SharePoint.Diagnostics están marcadas como Internas. Encontré one example de cómo usarlos de todos modos a través de la reflexión, pero parece realmente arriesgado e inestable, porque Microsoft puede cambiar esa clase con cualquier revisión que deseen.

La Documentación de Sharepoint tampoco fue de mucha ayuda; hay mucha información de administrador sobre qué es ULS y cómo configurarla, pero aún no he encontrado un ejemplo de código compatible para realmente registrar mis propios eventos.

¿Algún consejo o sugerencia?

Editar: Como se puede ver a partir de la edad de esta cuestión, esto es para SharePoint 2007. En SharePoint 2010, puede utilizar SPDiagnosticsService.Local y luego WriteTrace. Vea la respuesta de Jürgen a continuación.

Respuesta

8

Si esto es posible, consulte este artículo de MSDN: http://msdn2.microsoft.com/hi-in/library/aa979595(en-us).aspx

Y aquí está algunos ejemplos de código 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

He utilizado el código de este artículo de MSDN en el pasado y puede haber funcionado de manera efectiva para mí. – barryd

+0

No funciona en SharePoint 2010 –

+0

¿Qué le parece otra pregunta, pero para Microsoft: por qué esta funcionalidad ya no está incorporada? ¿Por qué la necesidad de nuestra propia clase de encapsilación? –

-1

esto no funcionó para mí, y colgó mi webpart consistentemente. Lo tuve trabajando por un segundo y luego no. Y solo, solo cuando eliminé las declaraciones Trace register/unregister/etc funcionaría.

por lo que recomiendo este excelente artículo que funcionó para mí: http://sharepoint.namics.com/2008/05/logging_in_webparts.html

Esencialmente, usted debe utilizar:

Bibliotecas infraestructura común para .NET.

he descargado desde aquí: http://netcommon.sourceforge.net/

que utilizan gacutil (o el/herramientas de administración/.net herramienta de configuración de panel de control) para añadir los 2,0/liberación de DLL en el GAC.

Agregué referencias a mi código a dll (desde la descarga). Todo compilado.

Tuve que crear un directorio y un archivo de registro vacío, y ¡bam! en la primera carga de la pieza web funcionó. Intenté durante horas y horas obtener el registro para mi parte web y esto funcionó maravillosamente, y es un buen estándar, como log4j.

+0

El enlace está roto. ¿Podrías indicar lo que no funcionó? Podría referirse a la solución descartada de la pregunta original o al artículo de MSDN sugerido por otra respuesta. –

2

El mérito es de: http://msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
Acabo de publicar un post en mi blog, pero pegar el código aquí.

definir el nombre de su solución en el código para la siguiente línea:

private const string PRODUCT_NAME = "My Custom Solution"; 

Los siguientes son ejemplos de código sobre cómo usarlo:

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

A continuación se presenta el código:

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

Lo usé y funciona muy bien y como esperaba, ¡gracias por salvarme de un dolor de cabeza! –

+0

Me alegra saber que funcionó para ti, David. –

1

Probar Abajo Código: (agrega esta referencia: 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) 
     { 
     } 

Ahora ULS abrir el Visor y filtrar por el nombre de la categoría.

Cuestiones relacionadas