Ну и почему бы нам для себя подобный сервис не написать?

Зачем, если есть sentry? Всмысле, есть ли у него существенные отличия?

Настолько мощный механизм автоматических игноров, который я описывал в статье, есть только у нас. Без него нам бы пришлось не сладко, ибо очень легко потонуть в потоке ненужных репортов. Это из крупного, далее уже по мелочам.
В случае sentry это делается грамотными сообщениями об ошибке и типами ошибок, что на самом деле, довольно гибко.
У нас внутри были ситуации, когда такое не помогло бы. Мало того, я так понимаю, они их обрабатывают, т.е. они влияют на месячное ограничение количества репортов. Наши же фильтры репорты отбрасывают и они не выедают лимит.
Ну а если смотреть на мелочи, то это и кастомизация темплейтов нотификаций, это CustomFields, это возможность объединить в отдельном блоке самую важную информацию: Favorites. У Sentry нет своего .NET клиента (мелочь, а неприятно), нет автоматической подписки на необработанные эксепшены (написал один раз StartExceptionsHandling и забыл).

Ну и, чисто субъективно, нам наша деталька кажется более удобной :)
это CustomFields,

Кастомные теги в sentry — есть.


это возможность объединить в отдельном блоке самую важную информацию: Favorites

Опять же таки, не уверен, насколько нужна эта фича при походе sentry, потому что у вас просто много тегов, в sentry дополнительные теги нужно добавлять.


У Sentry нет своего .NET клиента (мелочь, а неприятно)

Таки есть.


нет автоматической подписки на необработанные эксепшены

Опять же, есть.


Ну и, чисто субъективно, нам наша деталька кажется более удобной :)

:)

Кастомные теги в sentry — есть.

Это у нас называется CustomData у клиентов. CustomFields это чисто серверная фича, которая позволяет настроить ссылку на абсолютно любое свойство в репорте.

Опять же таки, не уверен, насколько нужна эта фича при походе sentry

Так просто удобнее просматривать репорт, если требуется прежде всего обращать внимание на строго определенные поля, а все остальные уже смотрятся после.

Таки есть.

Это клиент от community, а не от Sentry.

Опять же, есть.

В .NET?
Учишь, учишь PVS-Studio использовать. Так ведь нет… :)

void KeyDown(object sender, KeyEventArgs e) {
  FrameworkElement source = sender as FrameworkElement;
  if(!IsActive || (sender == null))
      return;
  Dictionary<string, string> properties =
    CollectCommonProperties(source, e);
  LogKeyboard(properties, e, false,
              CheckPasswordElement(e.OriginalSource as UIElement));
}

V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'sender', 'source'. BreadcrumbsRecorder.cs 86

Видимо следует проверять на null ссылку source, а не sender.

Аналогично:
  • V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'sender', 'source'. BreadcrumbsRecorder.cs 94
  • V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'sender', 'source'. BreadcrumbsRecorder.cs 102
  • V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'sender', 'source'. BreadcrumbsRecorder.cs 110
  • V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'sender', 'source'. BreadcrumbsRecorder.cs 118
  • V3019 Possibly an incorrect variable is compared to null after type conversion using 'as' keyword. Check variables 'sender', 'source'. BreadcrumbsRecorder.cs 126



bool ValidateConfiguration(SenderConfiguration config) {
  if (String.IsNullOrEmpty(config.Url)) {
      Console.WriteLine("ERROR: service Url not specified");
      return false;
  }
  if (String.IsNullOrEmpty(config.ApiKey)) {
      Console.WriteLine("ERROR: ApiKey not specified");
      return false;
  }
  if (String.IsNullOrEmpty(config.ApiKey)) {
      Console.WriteLine("ERROR: ReportFileName not specified");
      return false;
  }
  ....
}

V3021 There are two 'if' statements with identical conditional expressions. The first 'if' statement contains method return. This means that the second 'if' statement is senseless Program.cs 159

Copy-Paste классический. Два раза проверяется config.ApiKey.

protected override bool SendExceptionReportCore(....) {
  ....
  lock (typeof(OfflineDirectoryExceptionReportSender)) {
  ....
}

V3090 Unsafe locking on a type. All instances of a type will have the same 'Type' object. TempDirectoryExceptionReportSender.cs 33

Плохо делать lock, используя тип. Подробности в документации. И таких lock-ов ещё 7 штук.

И т.д.
Спасибо, поправили (кроме лока на тип — оно так надёжнее будет, чем на статическую переменную полагаться в многопоточной среде).
<зануда on> Хочу напомнить всем присутствующим, что продуктивнее не разово что-то проверить и поправить, а использовать статически анализ регулярно. Тогда многие ошибки можно было выявить не в процессе внутреннего тестирования (и последующему фидбека от пользователей), а сразу в ходе написания кода. <зануда off>
А что по поводу V3083? Например, здесь:
public bool CopyHandler(int bytesCopied) {
    ....
    if (NotifyProgress != null)
        NotifyProgress(this, EventArgs.Empty);
    return !isStopped;
}

V3083 Unsafe invocation of event 'NotifyProgress', NullReferenceException is possible. Consider assigning event to a local variable before invoking it. Zip.cs 1035

Или:
protected override bool
RaiseConfirmationDialogShowing(ReportConfirmationModel model) {
  if(ConfirmationDialogShowing != null) {
    ConfirmationDialogModel actualModel = model as ConfirmationDialogModel;
    if(actualModel == null)
        return false;
    ConfirmationDialogEventArgs args = new ConfirmationDialogEventArgs(actualModel);
    ConfirmationDialogShowing(this, args);
    return args.Handled;
  }
  return false;
}

V3083 Unsafe invocation of event, NullReferenceException is possible. Consider assigning event to a local variable before invoking it. LogifyClient.cs 169
Здесь больше шанс возникновения NullReferenceException, так как проверка и использование разнесены дальше.

Далее
  • V3083 Unsafe invocation of event, NullReferenceException is possible. Consider assigning event to a local variable before invoking it. LogifyClient.cs 156
  • V3083 Unsafe invocation of event 'FocusChanged', NullReferenceException is possible. Consider assigning event to a local variable before invoking it. BreadcrumbsRecorder.cs 391
  • V3083 Unsafe invocation of event 'PropertyChanged', NullReferenceException is possible. Consider assigning event to a local variable before invoking it. ReportConfirmationModel.cs 55
  • V3083 Unsafe invocation of event, NullReferenceException is possible. Consider assigning event to a local variable before invoking it. LogifyClientBase.cs 171
  • V3083 Unsafe invocation of event, NullReferenceException is possible. Consider assigning event to a local variable before invoking it. LogifyClientBase.cs 183
  • V3083 Unsafe invocation of event, NullReferenceException is possible. Consider assigning event to a local variable before invoking it. LogifyClientBase.cs 192

P.S. Я не из вредности, а чтобы наглядно демонстрировать, как цена исправления растёт.
Андрей, ИМХО, подобная проверка уже на грани абсурда. Следующий шаг — запретить напрямую обращаться к свойствам объекта, а разрешить только брать значения в локальную переменную — вдруг свойство из соседней нитки кто-нить занулит между обращениями. Принцип разумной достаточности никто не отменял.

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

А в дальнейшем планируется расширение функционала или будет работать узкопрофильно?
Да, конечно планируется. Продукт активно развивается. А какой функционал требуется?
Мне кажется, было бы полезно внедрить напоминание о необходимости просканировать на наличие ошибок с определённой периодичностью. Но это для примера, что первое в голову пришло.
Logify это не анализатор, который надо запускать. Logify работает в рантайме в самом приложении и ловит происходящие в нем ошибки.
Ясно, спасибо!
Не планируете сделать оффлайн версию, для использования в интранетах?
В ближайших планах нет, но мы эту задачу в голове держим, так как иногда запросы приходят.
Пишу как простой пользователь.
Дело не в отсутствии какой-то обратной связи. Дело в том, что разработчикам наплевать, я так думаю. Не было бы наплевать — просто делали бы простые и понятные формы обратной связи. Потом автоматический отсев, потом, полуавтоматический. И уже отсеянное читали бы живые люди. И исправляли.
Я не верю, что разработчиков по-настоящему интересуют проблемы пользователей. Да и собственные программы тоже. Ну, перестанут покупать эту говно-программу, напишем другую, поскольку мы всё равно знаем лучше, что ИМ (презрительно) нужно. Яркий пример отношение мозиллы к своему браузеру. Как до них не доходит, что в эти маленькие крестики, закрывающие вкладки просто трудно попасть мышкой — я не понимаю. Почему они не дают пользователю изменить размеры значков, шрифт интерфейса — я не понимаю.
Самое плодотворное общение у меня было с разработчиком mkvtoolnix. Вменяемый человек, что тут скажешь.
Почему media player classic не могут научить понимать, что если человек делает скриншот в плеере, и скриншот этот приходится на ту же секунду, что и предыдущий, то не загружай тупые окошки и не задавай тупых вопросов о перезаписи уже существующего файла, а просто присвой новый номер (через дефис, например), если уж не понимаешь, что есть десятые и сотые и тысячные доли секунды.
Акронис. Если уж человека угораздило один раз сделать копию в другую папку, на другой диск, то не надо всякий раз ее опять там создавать в случае, если ты создаешь новую копию после восстановления предыдущей.
O&O Defrag. Ваша программа не умеет дефрагментировать MFT. Не умеет! И никогда не умела. Хотя вы годами заявляете обратное.
Privazer. Где ты хранишь настройки, чтобы не ставить всякий раз нужные галки??
RegOrganizer. Почему ты спрашиваешь дважды после завершения очистки реестра закрыть это окно или нет? У меня, что есть варианты? Они там что, вообще ещё какие-то возможны, другие варианты?
и т.д.
Яркий пример отношение мозиллы к своему браузеру. Как до них не доходит, что в эти маленькие крестики, закрывающие вкладки просто трудно попасть мышкой — я не понимаю.
Между прочим в новом Firefox Quantum с крестиками все нормально, да и еще много чего
Согласен. Отсутствие позитивной обратной связи с пользователями приводит к тому, что разработчики игнорируют гораздо более критичные ошибки, нежели просто падения приложения. После падения программу действительно несложно запустить снова — и если в ней в момент падения не редактировалось что-то важное, а само падение было результатом стечения маловероятных обстоятельств, а не какого-то серьёзного бага, который почему-то просочился через тестировщиков — пользователь забудет об этом досадном инциденте и будет продолжать пользоваться приложением дальше. А вот если функционал приложения реализован неудобно, нелогично, поведение приложения попросту раздражает/бесит пользователя систематически — вы ничего не получите своим Logify, но если для приложения отсутствует удобная система обратной связи, позволяющая пользователю понять, что его обращение действительно важно для разработчиков (а не ушло в /dev/null), то вы должны быть как минимум Microsoft'ом, чтобы иметь полное моральное право просто «забить на тупых хомячков» и сосредоточиться исключительно на эксплуатации оных в качестве бесплатных бета-тестеров с использованием Logify…
Так никто же и не спорит, мы тут тоже за все хорошее и против всего плохого. Только работать надо в комплексе. И стабильность важна и юзабилити важно. Очень удобная, но постаянно глючащая программа тоже мало радости приносит. И если повлиять на UI и обратную связь у сторонних приложений мы никак не можем, то предоставить инструмент, позволяющий улучшить стабильность уже в наших силах.
Яркий пример отношение мозиллы к своему браузеру. Как до них не доходит, что в эти маленькие крестики, закрывающие вкладки просто трудно попасть мышкой
Я уже наверно лет 100 не целюсь в крестик, используйте для закрытия вкладок среднюю кнопку мыши и меньше ворчите… жизнь прекрасна :)
Ctrl+W, ещё меньше телодвижений)

Используется ли Logify для мониторинга ошибок внутри Logify?

Разработчики PVS-Studio одобряют этот вопрос.
Используется, конечно, микросервисов много, если глазками за каждым из них приглядывать, то у разработчиков ручки отвалятся :) Одно из внутренних внедрений как раз к себе в проект и было.
Только полноправные пользователи могут оставлять комментарии.
Войдите, пожалуйста.