Domanda

Vorrei registrare materiale nelle mie web part Sharepoint, ma voglio che vada nell'ULS. La maggior parte degli esempi che ho trovato accedono al registro eventi o ad altri file, ma in realtà non ne ho ancora trovato uno per accedere all'ULS.

Le classi di diagnostica Microsoft.SharePoint.Diagnostics sono tutte contrassegnate come interne. Ho trovato un esempio di come usarli comunque attraverso la riflessione, ma sembra davvero rischioso e instabile, perché Microsoft può cambiare quella classe con qualsiasi aggiornamento rapido che desiderano.

Anche la documentazione di Sharepoint non è stata davvero utile: molte informazioni dell'amministratore su cosa sia ULS e su come configurarlo, ma devo ancora trovare un esempio di codice supportato per registrare effettivamente i miei eventi.

Qualche suggerimento o suggerimento?

Modifica: Come si può vedere dall'età di questa domanda, questo è per SharePoint 2007. In SharePoint 2010, è possibile utilizzare SPDiagnosticsService.Local e quindi WriteTrace . Vedi la risposta di Jürgen in basso.

È stato utile?

Soluzione

Sì, è possibile, vedi questo articolo MSDN: http : //msdn2.microsoft.com/hi-in/library/aa979595 (it-it) aspx

Ed ecco un codice di esempio 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;
    }
}

}

Altri suggerimenti

Il merito va a: http: // msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
Ho appena pubblicato un post sul mio blog, ma incollando qui il codice.

Definisci il nome della tua soluzione nel codice per la seguente riga:

private const string PRODUCT_NAME = "My Custom Solution";

Di seguito è riportato un codice di esempio su come 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:");  

Di seguito è riportato il codice:

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);
        }

    }
}

Prova sotto il codice: (aggiungi questo riferimento:     utilizzando 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)
        {
        }

Ora apri il visualizzatore uls e filtra per il nome della tua categoria.

Questo DID NON funziona per me e ha interrotto costantemente la mia webpart. L'ho fatto funzionare per un secondo e poi no. E solo, solo quando avessi rimosso le istruzioni Trace register / unregister / etc avrebbe funzionato.

Quindi raccomando questo eccellente articolo che ha funzionato per me: http://sharepoint.namics.com/2008/05/logging_in_webparts.html

In sostanza, dovresti usare:

Librerie di infrastrutture comuni per .NET.

L'ho scaricato da qui: http://netcommon.sourceforge.net/

Ho usato gacutil (o il pannello di controllo / strumenti di amministrazione / .net config tool) per aggiungere 2.0 / release dll a gac.

Ho aggiunto riferimenti al mio codice alle DLL (dal download). Tutto compilato.

Ho dovuto creare una directory e svuotare il file di registro, e bam! nel primo caricamento della web part ha funzionato. Ho provato per ore e ore a ottenere la registrazione per la mia web part e questo ha funzionato meravigliosamente, ed è un buon standard, come log4j.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top