Pergunta

Eu gostaria de registrar coisas nas minhas partes da Web do SharePoint, mas quero que ela entre nos ULs. A maioria dos exemplos que encontrei logo no log de eventos ou em algum outro arquivo, mas ainda não encontrei um ainda para fazer login nos ULs.

Irritantemente, as classes Microsoft.SharePoint.Diagnostics são todas marcadas internas. Eu encontrei um exemplo De como usá -los de qualquer maneira através da reflexão, mas isso parece realmente arriscado e instável, porque a Microsoft pode mudar essa classe com qualquer hotfix que desejar.

A documentação do SharePoint também não foi realmente útil - muitas informações do administrador sobre o que é o ULS e como configurá -lo, mas ainda não encontrei um exemplo de código suportado para realmente registrar meus próprios eventos.

Alguma dica ou dicas?

Editar: Como você pode ver desde a idade desta pergunta, isso é para o SharePoint 2007. No SharePoint 2010, você pode usar o spdiagnosticsservice.local e depois Writetrace. Veja a resposta de Jürgen abaixo.

Foi útil?

Solução

Sim, isso é possível, consulte este artigo do MSDN: http://msdn2.microsoft.com/hi-in/library/aa979595(en-us).aspx

E aqui está algum código de amostra em 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;
    }
}

}

Outras dicas

O crédito vai para: http://msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
Acabei de publicar um post no meu blog, mas colar o código aqui.

Defina o nome da sua solução no código para a seguinte linha:

private const string PRODUCT_NAME = "My Custom Solution";

A seguir, o código de amostra sobre como usá -lo:

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 seguir, o 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);
        }

    }
}

Experimente o código abaixo: (Adicione esta referência: Usando 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)
        {
        }

Agora abra o Visualizador do ULS e o filtro pelo nome da sua categoria.

Isso não funcionou para mim e pendurei minha Webpart de forma consistente. Eu tinha funcionando por um segundo e não. E somente, somente quando eu removi o registro de rastreamento/declarações de registro/etc. funcionaria.

Então, eu recomendo este excelente artigo que funcionou para mim:http://sharepoint.namics.com/2008/05/logging_in_webparts.html

Essencialmente, você deve usar:

Bibliotecas de infraestrutura comuns para .NET.

Eu baixei aqui:http://netcommon.sourceforge.net/

Eu usei Gacutil (ou a ferramenta de configuração de painel de controle/admin/.NET) para adicionar as DLLs 2.0/liberação ao GAC.

Adicionei referências ao meu código às DLLs (do download). Tudo compilado.

Eu tive que criar um diretório e um arquivo de log vazio, e Bam! Na primeira carga da Web Part, funcionou. Tentei por horas e horas para obter o registro da minha Web Part e isso funcionou maravilhosamente, e é um bom padrão, como o Log4J.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top