Стратегии / методы для отчетов о сбоях в Java - PullRequest
4 голосов
/ 21 августа 2009

Я занимаюсь разработкой нового Java-приложения для настольных компьютеров и хотел бы включить функцию отчетов о сбоях - вы знаете, что такого рода - происходит сбой программы, появляется окно с просьбой нажать «ОК» для отправки и т. Д.

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

Ответы [ 6 ]

7 голосов
/ 22 августа 2009

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

-XX:-HeapDumpOnOutOfMemoryError -XX:OnError="<cmd args>;<cmd args>"
5 голосов
/ 22 августа 2009

Используйте Thread.setUncaughtExceptionHandler и статический Thread.setDefaultUncaughtExceptionHandler, чтобы (пытаться) сообщить об исключениях в вашу систему ведения журнала.

2 голосов
/ 14 ноября 2012

Использовать ведение журнала. Общий шаблон работает так:

  • Создание приложения, которое отправляет сообщение об ошибке на сервер (большинство сред ведения журналов поддерживают приложения, которые передают сообщения журнала по почте или даже через JDBC). Если аппендиата нет, у них есть примеры, как это сделать.
  • Добавьте этот appender в корневой логгер и установите его порог на ERROR
  • Записать ошибку, когда вы заметили исключение. Тогда каркас каротажа сделает всю работу за вас.
2 голосов
/ 21 августа 2009

Я вижу три случая:

  1. катастрофы. Сама JVM либо мертва, либо умирает. Вы не можете предполагать, что любой ваш код сможет работать - например, вы не можете выделить какую-либо память. Следовательно, в этом случае вы не можете разумно надеяться на возможность отправки какой-либо диагностики. Лучшее, на что вы можете надеяться, это иметь некоторую диагностику, такую ​​как дампы ядра, оставленные в пепле мертвой программы.

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

  2. Код приложения низкого уровня не перехватывает исключение, возможно, исключение RunTime, такое как исключение NullPointer. В этом случае вы могли бы в своей основной (если она есть) вы можете поймать Exception и надеяться, что ваш код Crash Reporter будет работать. Передайте исключение и его трассировку стека в Crash Reporter.

  3. Ваш код низкого уровня ловит что-то действительно нездоровое. Не достаточно, чтобы завершить процесс, но стоит сообщить. Здесь у вас есть не только исключение, но и другая контекстная информация. Нам нужно отправить еще кое-что в Crash Reporter.

0 голосов
/ 14 ноября 2012

Одним из вариантов будет использование BugSense. Он нацелен на создание отчетов о сбоях мобильных приложений, но API заявляет, что его можно использовать для любых отчетов о сбоях. Это очень просто из того, что я прочитал, и все, что нужно сделать, это создать простой запрос POST со всеми значениями.

{
   "client": {
      "name": "bugsense-android", // Obligatory
      "version": "0.6"
   },
   "request": {
      "remote_ip": "10.0.0.1",
      "custom_data": {
         "key1": "value1",
         "key2": "value2"
      }
   },
   "exception": {
      "message": "java.lang.RuntimeException: exception requested", // Obligatory
      "where": "MainActivity.java:47", // Obligatory
      "klass": "java.lang.RuntimeException", // Type of exception
      "backtrace": "java.lang.RuntimeException: exception requested\r\nat com.sfalma.trace.example.MainActivity$1.onClick(MainActivity.java:47)\r\nat android.view.View.performClick(View.java:2408)\r\nat android.view.View$PerformClick.run(View.java:8816)\r\nat android.os.Handler.handleCallback(Handler.java:587)\r\nat android.os.Handler.dispatchMessage(Handler.java:92)\r\nat android.os.Looper.loop(Looper.java:123)\r\nat android.app.ActivityThread.main(ActivityThread.java:4627)\r\nat java.lang.reflect.Method.invokeNative(Native Method)\r\nat java.lang.reflect.Method.invoke(Method.java:521)\r\nat com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)\r\nat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)\r\nat dalvik.system.NativeStart.main(Native Method)\\n" // Obligatory
   },
   "application_environment": {
      "phone": "android", // Device model (could be PC or Max) Obligatory
      "appver": "1.2", // Obligatory
      "appname": "com.sfalma", // Obligatory
      "osver": "2.3", // Obligatory
      "wifi_on": "true",
      "mobile_net_on": "true",
      "gps_on": "true",
      "screen_dpi(x:y)": "120.0:120.0",
      "screen:width": "240",
      "screen:height": "400",
      "screen:orientation": "normal"
   }
}

Вы можете узнать больше об этом здесь .

0 голосов
/ 21 августа 2009

Я не знаю, является ли это лучшим из того, что сейчас предлагает Java, но это то, что я делал некоторое время назад.

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

Во-вторых, пользовательская очередь событий использовалась в Swing для перехвата любых исключений, которые происходят в потоке событий. Я хотел бы надеяться, что в настоящее время у Java есть лучшее решение, но в основном, когда произошло исключение, вам пришлось проверить, не был ли задействован ваш код, в противном случае некоторые ошибки Swing могут привести к сбою в вашем приложении, что неприятно. И, конечно, рекурсия должна быть проверена (сбой повторяется снова и снова, когда вы пытаетесь отобразить сообщение пользователю).

Кстати, большинство любых сбоев будут поддерживать работу вашей JVM, включая ошибки нехватки памяти, в большинстве случаев достаточные для отправки электронной почты, так как после ошибки нехватки памяти обычно ошибка освобождает достаточно стека (и следовательно, куча) для дальнейшей сборки мусора и запуска вашего кода. Но в таком случае вы все равно должны быстро выйти. IDEA продолжает работать после ошибки нехватки памяти, но часто не работает должным образом. Им лучше выйти, ИМО.

Вы выдвигаете новую очередь со следующим и создаете подкласс EventQueue для связи в своем поведении.

 Toolkit.getDefaultToolkit().getSystemEventQueue().push(newQueue);
...