Получение статистики по рассылке Push через Microsoft Azure

Задача состоит в получении статистики о разосланных push уведомлений из Windows Azure. Сам Azure показывает статистику не старше 30 дней, что в долгосрочной перспективе оборачивается потерей информации о более ранних рассылках. Следовательно необходимо хранить всю статистику у себя в базе данных. График успешных уведомлений в Azure выглядит следующим образом:

Windows Azure Notification Hub

В реализованной системе это Windows служба, которая раз в день собирает информацию. Для разработки следует подключить следующие nuget пакеты. Кстати, пакеты можно перенести обычным copy-paste, воспользовавшись заметкой "Как перенести пакеты nuget в другой проект простым переносом packages.config".

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Hyak.Common" version="1.0.1" targetFramework="net45" />
  <package id="Microsoft.Azure.Common" version="2.0.1" targetFramework="net45" />
  <package id="Microsoft.Azure.Common.Dependencies" version="1.0.0" targetFramework="net45" />
  <package id="Microsoft.Bcl" version="1.1.9" targetFramework="net45" />
  <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
  <package id="Microsoft.Bcl.Build" version="1.0.14" targetFramework="net45" />
  <package id="Microsoft.Net.Http" version="2.2.22" targetFramework="net45" />
  <package id="Microsoft.WindowsAzure.Management.Monitoring" version="4.0.0" targetFramework="net45" />
  <package id="Newtonsoft.Json" version="6.0.8" targetFramework="net45" />
  <package id="Oxozle.Utilities" version="1.2.1" targetFramework="net45" />
</packages>

Все операции с Azure из вне подписываются специальным сертификатом. Для этого необходимо создать сертификат. Можно воспользоваться командой ниже или сгенерировать сертификат любым другим известным способом.

makecert -sky exchange -r -n "CN=<CertificateName>" -pe -a sha1 -len 2048 -ss My "<CertificateName>.cer"

Далее выполнить загрузку сертификата для управления соответствующей подпиской в Window Azure Management Portal.

azure management certificate

Для работы в коде нужен будет файл *.pfx. В моем случае это PushMetrics.pfx. Я добавил файл в проект и установил свойство Build Action в Embedded Resource. Чтобы получить объект X509Certificate2 достаточно следующего метода:

public static X509Certificate2 Get()
{
    var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FullAssemblyPath.PushMetrics.pfx");
    var bytes = new byte[stream.Length];
    stream.Read(bytes, 0, bytes.Length);
    var cert = new X509Certificate2(bytes, "CertificatePassword");

    return cert;
}

Стоит отдельно отметить способ выдачи статистики Azure. Это некоторые периоды, сгруппированные по rollup'ам. Всего их 4 вида (Metric Applicable Entities):

На вход функция сбора статистики принимает 2 даты: DateTime fromUtc, DateTime toUtc. Метод несколько урезан, в него необходимо добавить логику по приложениям и платформам.

public void GetQuantityTotalPush()
{
    SubscriptionCloudCredentials credentials = new CertificateCloudCredentials("SUBSCRIPTION_ID", PushStatCertificate.Get());
    MetricsClient client = new MetricsClient(credentials);

    var nameSpace = "SERVICE_BUS_NAMESPACE";
    string platform = "outgoing.apns.success"; // iOS
    string notificationHub = "NOTIFICATION_HUB_ID";
    
    string id0 = ResourceIdBuilder.BuildServiceBusResourceId(nameSpace, Constants.ServiceBusResourceType.NotificationHubs, notificationHub);

    try
    {
        MetricValueListResponse result = client.MetricValues.List(id0, new[] { platform }, string.Empty,
        TimeSpan.FromMinutes(60),
        fromUTC, toUTC);

        if (result != null && result.MetricValueSetCollection.Value.Count > 0)
        {
            foreach (MetricValueSet metricValueSet in result.MetricValueSetCollection.Value)
            {
                foreach (Microsoft.WindowsAzure.Management.Monitoring.Metrics.Models.MetricValue metricValue in metricValueSet.MetricValues)
                {
                    //Statistics here!
                    // (int)metricValue.Total - Total Push Sent
                    // metricValue.Timestamp.ConvertToMoscowDateTime() - Metric Time Stamp
                }
            }
        }


    }
    catch (WebException exception)
    {
        string error = exception.Response != null ? new StreamReader(exception.Response.GetResponseStream()).ReadToEnd() : exception.Message;       
    }       
}

В зависимости от требуемой платформы необходимо передавать соответствующий запрос к Azure. Для этого может быть полезен следующи метод.

private static string GetPlatform(PlatformType platform)
{
    switch (platform)
    {
        case PlatformType.iOS:
            return "outgoing.apns.success";
        case PlatformType.iOSiPad:
            return "outgoing.apns.success";
        case PlatformType.Android:
            return "outgoing.gcm.success";
        case PlatformType.WinPhone:
            return "outgoing.mpns.success";
        case PlatformType.Windows8: 
            return "outgoing.wns.success";
    }

    return null;
}

После этого всего необходимо класс обернуть в Windows службу и настроить на ежедневный сбор статистики.

 

Комментарии

comments powered by Disqus