Sharepoint ULSへのプログラムによるログ記録
-
02-07-2019 - |
質問
Sharepoint Webパーツにログを記録したいのですが、ULSに入れたいです。私が見つけたほとんどの例は、イベントログまたはその他のファイルにログインしますが、ULSにログインするための実際の例はまだ見つかりませんでした。
面倒なことに、Microsoft.SharePoint.Diagnosticsクラスはすべて内部としてマークされています。 使用方法の1つの例が見つかりましたとにかくリフレクションを使用しますが、Microsoftは必要な修正プログラムでそのクラスを変更する可能性があるため、それは本当に危険で不安定に見えます。
Sharepointのドキュメントも役に立たなかった-ULSとは何か、その設定方法に関する管理者情報はたくさんありますが、実際に自分のイベントをログに記録するためにサポートされているコードの例はまだ見つかりません。
ヒントやヒントはありますか
編集:この質問の時代からわかるように、これはSharePoint 2007用です。SharePoint2010では、SPDiagnosticsService.Localを使用してから WriteTrace 。以下のJü rgenからの回答を参照してください。
解決
はい、これは可能です。MSDNの記事をご覧ください: http ://msdn2.microsoft.com/hi-in/library/aa979595(en-us).aspx
そして、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;
}
}
}
他のヒント
クレジットは次のとおりです: http:// msdn.microsoft.com/en-us/library/gg512103(v=office.14).aspx
ブログに投稿しましたが、ここにコードを貼り付けました。
次の行のコードでソリューションの名前を定義します。
private const string PRODUCT_NAME = "My Custom Solution";
以下は、使用方法のサンプルコードです。
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:");
次のコードです:
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);
}
}
}
ここでは、SharePointでのログ記録に関する別の優れた記事があります。 http://www.parago.de/2011/01/how-to-implement-a-custom-sharepoint-2010-logging-service-for-uls-and-windows-event-log/
以下のコードを試してください: (この参照を追加: 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)
{
}
ulsビューアを開いて、カテゴリ名でフィルタリングします。
このDIDは私には機能せず、一貫してWebパーツを切断しました。私はそれを数秒間作動させ、その後作動させなかった。そして、Trace register / unregister / etcステートメントを削除した場合にのみ機能します。
だから、私のために働いたこの素晴らしい記事をお勧めします: http://sharepoint.namics.com/2008/05/logging_in_webparts.html
本質的には、次を使用する必要があります:
.NETの共通インフラストラクチャライブラリ。
ここからダウンロードしました: http://netcommon.sourceforge.net/
gacutil(またはコントロールペイン/管理ツール/.net構成ツール)を使用して、2.0 / release dllをgacに追加しました。
(ダウンロードから)dllへのコードへの参照を追加しました。すべてがコンパイルされました。
ディレクトリと空のログファイルを作成し、bam!最初のWebパーツのロードで機能しました。私は自分のWebパーツのログを取得するために何時間も試行しましたが、これは素晴らしく機能し、log4jのような良い標準です。