TraceSource.TraceEvent () не может войти в систему, если сообщение об исключении содержит непечатные символы - PullRequest
3 голосов
/ 30 сентября 2011

У меня есть звонок на TraceSource.TraceEvent(), который иногда не записывается в журналы диагностики Azure.

public class WorkerRole : RoleEntryPoint
{
    private TraceSource trace = new TraceSource(
        "ImportService", SourceLevels.Information);

    public override void Run()
    {
        ...
        try
        {
            ...
        }
        catch (Exception ex)
        {
            bool hasMsg = !string.IsNullOrEmpty(ex.Message);
            trace.TraceEvent(TraceEventType.Error, 0,
                "ex has message: " + hasMsg.ToString());   // this gets logged
            trace.TraceEvent(TraceEventType.Error, 0,
                "Inner exception message: " + ex.Message); // this does not
        }
    }
}

В некоторых случаях, и я не могу сказать, что, поскольку я не могу прочитать сообщение об исключении, второй вызов не найден в таблице WADLogsTable. Существуют ли определенные символы, которые не разрешены, либо TraceSource, либо DiagnosticMonitor?

Чтобы еще более сузить это, рассматриваемое Исключение фактически является InnerException Исключением: «В документе XML есть ошибка (72, -499)». XML, который вызывает исключение, содержит недопустимые символьные объекты, например . Может ли быть так, что сообщение об исключении содержит некоторые из этих символьных сущностей, а TraceSource не может их зарегистрировать?

Редактировать: Мне удалось наконец-то воспроизвести это в моей среде разработки, и я смог изучить Исключение в отладчике. Исключением, которое не будет регистрироваться, является XmlException:

'', шестнадцатеричное значение 0x11, является недопустимым символом. Линия 72, позиция -499.

Между кавычками находится непечатный символ - он отображается в виде черного треугольника в отладчике. Таким образом, это заставляет меня поверить, что мое подозрение верное - какой-то элемент механизма регистрации не любит непечатный символ. Итак, какой кусок? Или, что более важно, поскольку, похоже, мне нужно начать санацию всех моих строк при трассировке, какие символы я должен искать для удаления?

Есть ли какая-то встроенная функция, которая будет очищать строку, удаляя непечатаемые символы?

Ответы [ 2 ]

1 голос
/ 04 октября 2011

Ответ на другой вопрос помог мне найти решение.Для удобства я добавил пару методов расширения:

public static string RemoveControlChars(this string s)
{
    return Regex.Replace(s, @"(?![\r\n])\p{Cc}", "");
}
public static void TraceEvent(this TraceSource trace, 
    TraceEventType eventType, MyEvtEnum eventId, string message)
{
    trace.TraceEvent(eventType, (int)eventId, message.RemoveControlChars());
}

Мне нравится дополнительное преимущество, заключающееся в том, что нет необходимости приводить MyEvtEnum к int каждый раз, когда я вызываю TraceEvent, и это добавляет естественную перегрузкутак что это похоже на двойную победу.

Меня беспокоит, что я должен сделать это вообще.Одним из основных применений диагностической системы является регистрация исключений.Такая система диагностики должна быть способна обрабатывать любую строку, которая может содержаться в сообщении об исключении. Я также теряю разрывы строк, что разочаровывает. Редактировать: Потеря разрывов строк была побочным эффектом RemoveControlChars().Я не осознавал, что \r и \n включены как «управляющие символы».Я обновил свое регулярное выражение, чтобы оно не заменяло символы \r и \n.

Мне не нравится принимать мой собственный ответ, поэтому, если у вас есть альтернативное решение или улучшение моего, пожалуйста, напишитеи если будет лучше, я приму это.

1 голос
/ 02 октября 2011

Интересно.Похоже, вам нужно HTML кодировать строку исключения.Это преобразует кавычки, например, в ", а непечатаемый символ ASCII - в  или аналогичный.

Итак:

    trace.TraceEvent(TraceEventType.Error, 0,
        "ex has message: " + HttpUtility.HtmlEncode(hasMsg.ToString()));   
    trace.TraceEvent(TraceEventType.Error, 0,
        "Inner exception message: " + HttpUtility.HtmlEncode(ex.Message)); 

должно работать нормально.

Удивительно, но HttpUtility в System.Web, вам нужно добавить ссылку на System.Web.dll, чтобы начать работу.

...