Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Советы по ведению журналов ULS
Обновление от 04.02.2011: я рекомендую взглянуть на обновленный пример по адресу https://blogs.msdn.com/b/sharepoint_ru/archive/2011/03/21/uls-2.aspx . Он лучше и функциональнее.
Когда я добавил функции ведения журнала ULS в последний проект, я заметил один раздражающий побочный эффект. В журналах ULS область отображается как "Неизвестное". Я понимаю, что некоторые аспекты этой проблемы описаны в других материалах, но я просто хотел написать короткую запись блога с описанием самого простого способа устранения этой проблемы (определенно менее болезненного, чем другие известные мне решения). Следует отметить, что если вы вообще не хотите этим заниматься, в платформе Logging Framework, в которой применяются рекомендации группы разработчиков CodePlex, это проблема решается автоматически. Но обычно я пишу как можно больше собственного кода, поэтому я кратко опишу способ устранения проблемы.
Первое, что я заметил — то, что в большей части документации пакета SDK создается новый объект SPDiagnosticsCategory. Конструктор нового экземпляра класса позволяет указать имя категории, а при этом любое пользовательское имя категории, которое нужно использовать, записывается в журнал ULS в столбце "Категория". В большинстве случаев при написании собственной функции ведения журнала также требуется настраиваемая область для своих категорий. К сожалению, SDK заставляет выполнить гораздо более сложную задачу для реализации такого механизма, так как нельзя использовать простой конструктор для создания новой области и ее применения — необходимо написать собственный класс, производный от SPDiagnosticsServiceBase.
Я решил создать один CS-файл с классом ведения журнала и базовым классом службы диагностики. Я начну с базового класса диагностики — далее я вставил весь класс. После него я опишу самые важные сведения о нем:
public class SteveDiagnosticService : SPDiagnosticsServiceBase
{
private const string LOG_AREA = "Steve Area";
public enum LogCategories
{
SteveCategory
}
public SteveDiagnosticService()
: base("Steve Diagnostics Service", SPFarm.Local)
{
}
public SteveDiagnosticService(string name, SPFarm parent)
: base(name, parent)
{
}
protected override bool HasAdditionalUpdateAccess()
{
return true;
}
public static SteveDiagnosticService Local
{
get
{
return SPDiagnosticsServiceBase.GetLocal<SteveDiagnosticService>();
}
}
public void LogMessage(ushort id, LogCategories LogCategory, TraceSeverity traceSeverity,
string message, params object[] data)
{
if (traceSeverity != TraceSeverity.None)
{
SPDiagnosticsCategory category
= Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];
Local.WriteTrace(id, category, traceSeverity, message, data);
}
}
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsCategory> categories = new List<SPDiagnosticsCategory>();
categories.Add(new SPDiagnosticsCategory(
LogCategories.SteveCategory.ToString(),
TraceSeverity.Medium, EventSeverity.Information));
SPDiagnosticsArea area = new SPDiagnosticsArea(
LOG_AREA, 0, 0, false, categories);
List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>();
areas.Add(area);
return areas;
}
}
Рассмотрим самые интересные части:
private const string LOG_AREA = "Steve Area";
Здесь я определяю имя области, которое я запишу в журнал ULS.
public enum LogCategories
{
SteveCategory
}
Это список категорий, которые я добавлю в настраиваемую область. В этом случае у меня только одна категория, которая будет использована в этой области, но если нужно несколько категорий, просто расширьте это перечисление.
public void LogMessage(ushort id, LogCategories LogCategory, TraceSeverity traceSeverity,
string message, params object[] data)
{
if (traceSeverity != TraceSeverity.None)
{
SPDiagnosticsCategory category
= Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];
Local.WriteTrace(id, category, traceSeverity, message, data);
}
}
Это один из двух важных методов, которые мы реализуем — здесь производится запись в журнал ULS. В первой строке я получаю объект SPDiagnosticCategory и указываю ссылку на область, которой он принадлежит. Во второй строке я просто вызываю метод базового класса в классе SPDiagnosticsServiceBase для записи в журнал ULS и при этом передаю категорию, связанную с областью.
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsCategory> theCategories = new List<SPDiagnosticsCategory>();
theCategories.Add(new SPDiagnosticsCategory(
LogCategories.SteveCategory.ToString(),
TraceSeverity.Medium, EventSeverity.Information));
SPDiagnosticsArea theArea = new SPDiagnosticsArea(
LOG_AREA, 0, 0, false, theCategories);
List<SPDiagnosticsArea> theArea = new List<SPDiagnosticsArea>();
theArea.Add(area);
return theArea;
}
В этой перегрузке я возвращаю в SharePoint все настраиваемые области. В этом случае я использую только одну область, поэтому ее и возвращаю. Кроме того, как я упомянул выше, я использую в области только одну собственную категорию. Если бы требовалось несколько настраиваемых категорий, то я 1) добавил бы их в перечисление, описанное ранее и 2) добавил каждую из них в экземпляр списка theCategories, определенный в этом методе.
Вот, в принципе, и вся суть добавления настраиваемой области и ее отображения в соответствующем столбце в журналах ULS. Реализация класса ведения журнала также довольно простая, я вставлю основную часть здесь и опишу ее чуть дальше.
public class Log
{
private const int LOG_ID = 11100;
public static void WriteLog(string Message, TraceSeverity TraceLogSeverity)
{
try
{
//в этом примере я всегда использую одну и ту же категорию
//ее можно было бы, конечно, передать также в параметр метода
//и использовать при вызове SteveDiagnosticService
SteveDiagnosticService.Local.LogMessage(LOG_ID,
SteveDiagnosticService.LogCategories.SteveCategory,
TraceLogSeverity, Message, null);
}
catch (Exception writeEx)
{
//игнорировать
Debug.WriteLine(writeEx.Message);
}
}
}
Этот код легко реализуется в любом из методов, в которых есть ссылка на него. Так как WriteLog — это статический метод, мой код,например, будет следующим: Log.WriteLog(“This is my error message”, TraceSeverity.Medium); . В этом примере в журнале ULS создается запись в области "Steve Area" и категория "SteveCategory" с сообщением "This is my error message".
Это локализованная запись блога. Исходная статья доступна по адресу Tips for ULS Logging