Мониторинг и телеметрия (создание облачных приложений Real-World с помощью Azure)

Рик Андерсон(Rick Anderson),Том Дайкстра (Tom Dykstra)

Скачать проект Fix It или скачать электронную книгу

Электронная книга "Создание реальных облачных приложений с помощью Azure " основана на презентации, разработанной Скоттом Гатри. В нем объясняется 13 шаблонов и методик, которые помогут вам успешно разрабатывать веб-приложения для облака. Сведения об электронной книге см. в первой главе.

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

Приобретение или аренда решения для телеметрии

Примечание

Эта статья была написана до выпуска Application Insights . Application Insights является предпочтительным подходом для решений телеметрии в Azure. Дополнительные сведения см. в статье Настройка Application Insights для веб-сайта ASP.NET .

Одна из вещей, которые отлично подходят для облачной среды, заключается в том, что вы действительно легко купить или арендовать свой путь к победе. Примером является телеметрия. Без больших усилий вы можете получить действительно хорошую систему телеметрии, очень эффективную. Существует множество отличных партнеров, которые интегрируются с Azure, и некоторые из них имеют бесплатные уровни, поэтому вы можете получить базовые данные телеметрии за бесценок. Ниже приведены лишь некоторые из доступных в настоящее время в Azure.

Microsoft System Center также включает функции мониторинга.

Мы быстро рассмотрим настройку New Relic, чтобы показать, насколько просто использовать систему телеметрии.

На портале управления Azure зарегистрируйтесь в службе. Нажмите кнопку Создать, а затем — Магазин. Откроется диалоговое окно Выбор надстройки . Прокрутите вниз и щелкните Создать реликвию.

Выбор надстройки

Щелкните стрелку вправо и выберите нужный уровень служб. Для этой демонстрации мы будем использовать уровень "Бесплатный".

Персонализация надстройки

Щелкните стрелку вправо, подтвердите "купить", и new Relic теперь отображается как надстройка на портале.

Проверка покупки

Портал управления новой надстройкой Relic

Щелкните Сведения о подключении и скопируйте лицензионный ключ.

Сведения о подключении

Перейдите на вкладку Настройка веб-приложения на портале, установите для параметра Мониторинг производительности значение Надстройка и установите для раскрывающегося списка Выбор надстройки значение New Relic. Затем нажмите кнопку Сохранить.

Создать Relic на вкладке

В Visual Studio установите пакет NuGet New Relic в приложении.

Аналитика для разработчиков на вкладке

Разверните приложение в Azure и начните использовать его. Создайте несколько задач Fix It, чтобы обеспечить некоторые действия для отслеживания New Relic.

Затем вернитесь на страницу New Relic на вкладке Надстройки портала и щелкните Управление. Портал отправляет вас на портал управления New Relic, используя единый вход для проверки подлинности, чтобы вам не нужно было вводить учетные данные снова. На странице Обзор представлены различные статистические данные о производительности. (Щелкните изображение, чтобы увидеть страницу обзора в полном размере.)

Вкладка

Вот лишь некоторые из статистических данных, которые вы можете увидеть:

  • Среднее время отклика в разное время суток.

    Время отклика

  • Пропускная способность (в запросах в минуту) в разное время суток.

    Пропускная способность

  • Время ЦП сервера, затраченное на обработку различных HTTP-запросов.

    Время веб-транзакций

  • Время ЦП, затраченное на различные части кода приложения:

    Сведения о трассировки

  • Статистика производительности за прошлые периоды.

    Производительность за прошлые периоды

  • Вызовы внешних служб, таких как служба BLOB-объектов, и статистические данные о надежности и реагировании службы.

    Внешние службы

    Внешние службы2

    Внешняя служба

  • Сведения о том, откуда в мире и откуда поступил трафик веб-приложения в США.

    Географический регион

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

Отчеты

New Relic — это лишь один пример системы телеметрии; Вы также можете получить все это из других служб. Красота облака заключается в том, что без написания кода и за минимальные затраты или без них вы можете получить гораздо больше информации о том, как используется ваше приложение и что на самом деле испытывают ваши клиенты.

Журнал для получения аналитических сведений

Пакет телеметрии — это хороший первый шаг, но вам все равно придется инструментировать собственный код. Служба телеметрии сообщает вам, когда возникает проблема, и сообщает о том, с чем сталкиваются клиенты, но она может не дать вам большого представления о том, что происходит в коде.

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

Вход в рабочую среду

Многие пользователи включают трассировку в рабочей среде только в том случае, если возникла проблема и они хотят выполнить отладку. Это может привести к значительной задержке между временем, когда вы узнаете о проблеме и когда вы получите полезные сведения об устранении неполадок. А информация, которую вы получаете, может оказаться не полезной для периодических ошибок.

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

Дополнительные расходы на ведение журнала являются тривиальными по сравнению с количеством времени и денег на устранение неполадок, которые вы можете сэкономить, имея все необходимые сведения уже доступны, когда что-то пойдет не так. Затем, когда кто-то говорит вам, что у них была случайная ошибка где-то около 8:00 вчера вечером, но они не помнят ошибку, вы можете легко узнать, в чем была проблема.

Менее чем за 4 долл. США в месяц вы можете хранить 50 гигабайт журналов под рукой, а влияние ведения журнала на производительность является тривиальным, если вы помните об одном. Чтобы избежать узких мест производительности, убедитесь, что библиотека ведения журнала является асинхронной.

Отличить журналы, которые информируют, от журналов, для которых требуется действие

Журналы предназначены для информирования (я хочу, чтобы вы что-то знали) или ACT (я хочу, чтобы вы что-то сделали). Будьте внимательны, записывайте журналы ACT только для проблем, которые действительно требуют от пользователя или автоматизированного процесса действий. Слишком много журналов ACT создаст шум, требуя слишком много работы, чтобы просеять все это, чтобы найти подлинные проблемы. И если журналы ACT автоматически запускают некоторые действия, например отправку электронной почты сотрудникам службы поддержки, не позволяйте тысячам таких действий запускаться одной проблемой.

В трассировке .NET System.Diagnostics журналам можно назначить уровни ошибок, предупреждений, сведений, отладки и детализации. Вы можете отличить журналы ACT от INFORM, зарезервировав уровень ошибки для журналов ACT и используя более низкие уровни для журналов INFORM.

Уровни ведения журнала

Настройка уровней ведения журнала во время выполнения

Хотя ведение журнала в рабочей среде имеет смысл всегда включаться, еще одна рекомендация — реализовать платформу ведения журнала, которая позволяет настраивать во время выполнения уровень детализации, который вы ведите в журнал, без повторного развертывания или перезапуска приложения. Например, при использовании средства трассировки в System.Diagnostics можно создавать журналы ошибок, предупреждений, сведений и отладки и подробных сведений. Мы рекомендуем всегда регистрировать журналы ошибок, предупреждений и сведений в рабочей среде, а также динамически добавлять отладочные или подробные журналы для устранения неполадок в индивидуальном порядке.

веб-приложения в Служба приложений Azure имеют встроенную поддержку записи System.Diagnostics журналов в файловую систему, хранилище таблиц или хранилище BLOB-объектов. Вы можете выбрать разные уровни ведения журнала для каждого места назначения хранилища и изменить уровень ведения журнала в режиме реального времени без перезапуска приложения. Поддержка хранилища BLOB-объектов упрощает выполнение заданий анализа HDInsight в журналах приложений, так как HDInsight знает, как работать с хранилищем BLOB-объектов напрямую.

Запись исключений в журнал

Не просто введите исключение. ToString() в коде ведения журнала. Это оставляет контекстную информацию. В случае ошибок SQL номер ошибки SQL не отображается. Для всех исключений включите сведения о контексте, само исключение и внутренние исключения, чтобы убедиться, что вы предоставляете все, что потребуется для устранения неполадок. Например, контекстная информация может включать имя сервера, идентификатор транзакции и имя пользователя (но не пароль или какие-либо секреты!).

Если вы полагаетесь на того, что каждый разработчик сделает правильные действия с ведением журнала исключений, некоторые из них не будут. Чтобы убедиться, что обработка исключений выполняется правильно каждый раз, выполните сборку обработки исключений прямо в интерфейсе средства ведения журнала: передайте сам объект исключения в класс средства ведения журнала и заносите в журнал данные исключений должным образом в классе средства ведения журнала.

Ведение журнала вызовов служб

Мы настоятельно рекомендуем записывать журнал каждый раз, когда приложение обращается к службе, будь то база данных, REST API или любая внешняя служба. Включите в журналы не только сведения об успешном или неудачном выполнении, но и о том, сколько времени занимает каждый запрос. В облачной среде часто возникают проблемы, связанные с замедлением, а не полными простоями. То, что обычно занимает 10 миллисекунд, может внезапно начать занимать секунду. Когда кто-то сообщает, что ваше приложение работает медленно, вы хотите иметь возможность просмотреть New Relic или любую службу телеметрии, которую у вас есть, и проверить их работу, а затем вы хотите иметь возможность просмотреть собственные журналы, чтобы узнать, почему это медленно.

Использование интерфейса ILogger

При создании рабочего приложения рекомендуется создать простой интерфейс ILogger и использовать в нем некоторые методы. Это позволяет легко изменить реализацию ведения журнала позже и не придется проходить весь код, чтобы сделать это. Мы можем использовать System.Diagnostics.Trace класс в приложении Fix It, но вместо этого мы используем его под крышкой в классе ведения журнала, который реализует ILogger, и мы вызываем метод ILogger во всем приложении.

Таким образом, если вы хотите сделать ведение журнала более богатым, вы можете заменить System.Diagnostics.Trace любым механизмом ведения журнала. Например, по мере роста приложения вы можете решить, что хотите использовать более полный пакет ведения журнала, такой как NLog или Блок приложения для ведения журнала корпоративной библиотеки. (Log4Net — это еще одна популярная платформа ведения журнала, но она не выполняет асинхронное ведение журнала.)

Одна из возможных причин использования такой платформы, как NLog, заключается в том, чтобы упростить разделение выходных данных журнала на отдельные хранилища данных с большим объемом и высокой ценностью. Это помогает эффективно хранить большие объемы данных INFORM, к которым не нужно выполнять быстрые запросы, сохраняя при этом быстрый доступ к данным ACT.

Семантическое ведение журнала

Относительно новый способ ведения журнала, который может создавать более полезные диагностические сведения, см. в разделе Блок приложения семантического ведения корпоративной библиотеки (SLAB). SLAB использует трассировку событий Windows (ETW) и поддержку EventSource в .NET 4.5 для создания более структурированных и запрашиваемых журналов. Для каждого типа событий, регистрируемых в журнале, определяется отдельный метод, который позволяет настраивать записываемые сведения. Например, чтобы записать в журнал ошибку База данных SQL, можно вызвать LogSQLDatabaseError метод . Для такого исключения известно, что ключевым элементом является номер ошибки, поэтому можно включить параметр номера ошибки в сигнатуру метода и записать номер ошибки в отдельное поле в записях журнала, которые вы записываете. Так как число находится в отдельном поле, вы можете легко и надежно получать отчеты на основе номеров ошибок SQL, чем если бы вы просто сцепляли номер ошибки в строку сообщения.

Ведение журнала в приложении Fix It

Интерфейс ILogger

Ниже приведен интерфейс ILogger в приложении Fix It.

public interface ILogger
{
    void Information(string message);
    void Information(string fmt, params object[] vars);
    void Information(Exception exception, string fmt, params object[] vars);

    void Warning(string message);
    void Warning(string fmt, params object[] vars);
    void Warning(Exception exception, string fmt, params object[] vars);

    void Error(string message);
    void Error(string fmt, params object[] vars);
    void Error(Exception exception, string fmt, params object[] vars);

    void TraceApi(string componentName, string method, TimeSpan timespan);
    void TraceApi(string componentName, string method, TimeSpan timespan, string properties);
    void TraceApi(string componentName, string method, TimeSpan timespan, string fmt, params object[] vars);
}

Эти методы позволяют записывать журналы на четырех уровнях, поддерживаемых System.Diagnostics. Методы TraceApi предназначены для ведения журнала вызовов внешних служб с информацией о задержке. Можно также добавить набор методов для уровня отладки или детализации.

Реализация средства ведения журнала для интерфейса ILogger

Реализация интерфейса очень проста. В основном он просто вызывает стандартные методы System.Diagnostics . В следующем фрагменте кода показаны все три метода Information и каждый из них.

public class Logger : ILogger
{
    public void Information(string message)
    {
        Trace.TraceInformation(message);
    }

    public void Information(string fmt, params object[] vars)
    {
        Trace.TraceInformation(fmt, vars);
    }

    public void Information(Exception exception, string fmt, params object[] vars)
    {
        var msg = String.Format(fmt, vars);
        Trace.TraceInformation(string.Format(fmt, vars) + ";Exception Details={0}", exception.ToString());
    }

    public void Warning(string message)
    {
        Trace.TraceWarning(message);
    }

    public void Error(string message)
    {
        Trace.TraceError(message);
    }

    public void TraceApi(string componentName, string method, TimeSpan timespan, string properties)
    {
        string message = String.Concat("component:", componentName, ";method:", method, ";timespan:", timespan.ToString(), ";properties:", properties);
        Trace.TraceInformation(message);
    }
}

Вызов методов ILogger

Каждый раз, когда код в приложении Fix It перехватывает исключение, он вызывает метод ILogger для регистрации сведений об исключении. Каждый раз, когда выполняется вызов к базе данных, службе BLOB-объектов или REST API, он запускает секундомер перед вызовом, останавливает секундомер при возвращении службы и регистрирует затраченное время вместе со сведениями об успешном или неудачном выполнении.

Обратите внимание, что сообщение журнала содержит имя класса и имя метода. Рекомендуется убедиться, что сообщения журнала определяют, какая часть кода приложения их написала.

public class FixItTaskRepository : IFixItTaskRepository
{
    private MyFixItContext db = new MyFixItContext();
    private ILogger log = null;

    public FixItTaskRepository(ILogger logger)
    {
        log = logger;
    }

    public async Task<FixItTask> FindTaskByIdAsync(int id)
    {
        FixItTask fixItTask = null;
        Stopwatch timespan = Stopwatch.StartNew();

        try
        {
            fixItTask = await db.FixItTasks.FindAsync(id);
            
            timespan.Stop();
            log.TraceApi("SQL Database", "FixItTaskRepository.FindTaskByIdAsync", timespan.Elapsed, "id={0}", id);
        }
        catch(Exception e)
        {
            log.Error(e, "Error in FixItTaskRepository.FindTaskByIdAsynx(id={0})", id);
        }

        return fixItTask;
    }

Таким образом, теперь каждый раз, когда приложение Fix It делало вызов База данных SQL, вы можете увидеть вызов, метод, который его вызвал, и точное количество времени, которое потребовалось.

запрос База данных SQL в журналах

Снимок экрана: изменение свойств сущности и то, как должно выглядеть каждое свойство для успешного обновления и сколько времени потребовалось.

Если вы просматриваете журналы, вы увидите, что время вызовов базы данных является переменным. Эта информация может оказаться полезной: так как приложение регистрирует все это, вы можете анализировать исторические тенденции работы службы базы данных с течением времени. Например, служба может быть быстрой большую часть времени, но запросы могут завершиться сбоем или ответы могут замедляться в определенное время суток.

Вы можете сделать то же самое для службы BLOB-объектов — каждый раз, когда приложение отправляет новый файл, есть журнал, и вы можете точно узнать, сколько времени потребовалось для отправки каждого файла.

Журнал отправки BLOB-объектов

Это всего лишь несколько дополнительных строк кода для написания каждый раз, когда вы вызываете службу, и теперь, когда кто-то говорит, что у него возникла проблема, вы точно знаете, что это была за ошибка, или даже если она выполнялась медленно. Вы можете точно определить источник проблемы без удаленного доступа к серверу или включить ведение журнала после возникновения ошибки и надеяться создать ее повторно.

Внедрение зависимостей в приложении Fix It

Вы можете задаться вопросом, как конструктор репозитория в приведенном выше примере получает реализацию интерфейса средства ведения журнала:

public class FixItTaskRepository : IFixItTaskRepository
{
    private MyFixItContext db = new MyFixItContext();
    private ILogger log = null;

    public FixItTaskRepository(ILogger logger)
    {
        log = logger;
    }

Чтобы подключить интерфейс к реализации, приложение использует внедрение зависимостей (DI) с помощью AutoFac. ВНЕДРЕНИЕ позволяет использовать объект, основанный на интерфейсе, во многих местах в коде и только в одном месте указывать реализацию, которая используется при создании экземпляра интерфейса. Это упрощает изменение реализации. Например, можно заменить средство ведения журнала System.Diagnostics на средство ведения журнала NLog. Или для автоматического тестирования может потребоваться заменить макетную версию средства ведения журнала.

Приложение Fix It использует di во всех репозиториях и всех контроллерах. Конструкторы классов контроллеров получают интерфейс ITaskRepository так же, как репозиторий получает интерфейс средства ведения журнала:

public class DashboardController : Controller
{
    private IFixItTaskRepository fixItRepository = null;

    public DashboardController(IFixItTaskRepository repository)
    {
        fixItRepository = repository;
    }

Приложение использует библиотеку AutoFac DI для автоматического предоставления экземпляров TaskRepository и Logger для этих конструкторов.

public class DependenciesConfig
{
    public static void RegisterDependencies()
    {
        var builder = new ContainerBuilder();

        builder.RegisterControllers(typeof(MvcApplication).Assembly);
        builder.RegisterType<Logger>().As<ILogger>().SingleInstance();

        builder.RegisterType<FixItTaskRepository>().As<IFixItTaskRepository>();
        builder.RegisterType<PhotoService>().As<IPhotoService>().SingleInstance();
        builder.RegisterType<FixItQueueManager>().As<IFixItQueueManager>();

        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }
}

Этот код в основном говорит о том, что в любом месте конструктору требуется интерфейс ILogger , передайте экземпляр класса Logger и всякий раз, когда ему нужен интерфейс IFixItTaskRepository , передайте экземпляр класса FixItTaskRepository .

AutoFac — это одна из многих платформ внедрения зависимостей, которые можно использовать. Еще один популярный — Unity, который рекомендуется и поддерживается в шаблонах и методиках Майкрософт.

Встроенная поддержка ведения журнала в Azure

Azure поддерживает следующие виды ведения журнала для веб-приложения в Служба приложений Azure:

  • Трассировка System.Diagnostics (вы можете включать и выключать и устанавливать уровни в режиме реального времени без перезапуска сайта).
  • События Windows.
  • Журналы IIS (HTTP/FREB).

Azure поддерживает следующие виды ведения журнала в Облачные службы:

  • Трассировка System.Diagnostics.
  • Счетчики производительности.
  • События Windows.
  • Журналы IIS (HTTP/FREB).
  • Мониторинг пользовательских каталогов.

Приложение Fix It использует трассировку System.Diagnostics. Все, что нужно сделать, чтобы включить ведение журнала System.Diagnostics в веб-приложении, — это переключить переключатель на портале или вызвать REST API. На портале щелкните вкладку Конфигурация сайта и прокрутите вниз, чтобы увидеть раздел Диагностика приложений . Вы можете включить или отключить ведение журнала и выбрать нужный уровень ведения журнала. Вы можете заставить Azure записывать журналы в файловую систему или в учетную запись хранения.

Диагностика приложений и диагностика сайта на вкладке

После включения ведения журнала в Azure вы сможете просматривать журналы в окне Выходные данные Visual Studio по мере их создания.

Меню журналов потоковой передачи

Меню потоковой передачи журналов2

Вы также можете записывать журналы в учетную запись хранения и просматривать их с помощью любого средства, доступного к службе таблиц службы хранилища Azure, например server Обозреватель в Visual Studio или Обозреватель службы хранилища Azure.

Журналы в Обозреватель сервера

Сводка

Очень просто реализовать встроенную систему телеметрии, инструментировать ведение журнала в собственном коде и настроить ведение журнала в Azure. А при возникновении проблем в рабочей среде сочетание системы телеметрии и пользовательских журналов поможет быстро устранить проблемы, прежде чем они станут основными для клиентов.

В следующей главе мы рассмотрим, как обрабатывать временные ошибки, чтобы они не стали рабочими проблемами, которые необходимо исследовать.

Ресурсы

Для получения дополнительных сведений см. следующие ресурсы.

Документация в основном о телеметрии:

Документация, главным образом, о ведении журнала:

Документация по устранению неполадок:

Видеоролики:

  • FailSafe: создание масштабируемых, устойчивых Облачные службы. Серия из девяти частей Ульрих Хоманн, Марк Меркури и Марк Симмс. Представляет высокоуровневые концепции и принципы архитектуры очень доступным и интересным способом, на основе историй, взятых из опыта группы технической поддержки Майкрософт (CAT) с реальными клиентами. Эпизоды 4 и 9 посвящены мониторингу и телеметрии. Эпизод 9 содержит обзор служб мониторинга MetricsHub, AppDynamics, New Relic и PagerDuty.
  • Большое здание: уроки, извлеченные от клиентов Azure— часть II. Марк Симмс рассказывает о проектировании на основе сбоев и инструментировании всего. Похожа на серию Failsafe, но в ней подробно описаны инструкции.

Пример кода: