Как лучше всего отправлять разработчикам сообщения об ошибках приложений и журналы через Интернет? - PullRequest
8 голосов
/ 24 мая 2009

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

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

Я думал об использовании SMTPClient или веб-службы для отправки информации. SMTPClient может не работать, поскольку брандмауэры могут блокировать исходящий SMTP-доступ. Будет ли у веб-службы проблема с отправкой большого объема данных (возможно, 1+ МБ)?

Что бы вы посоветовали как лучший способ, чтобы приложение передавало отчеты об ошибках непосредственно разработчикам для проверки?

РЕДАКТИРОВАТЬ: Пояснение: Это приложение для Windows, и когда возникает ошибка, я хочу вызвать диалоговое окно с просьбой отправить ошибку. Мой вопрос касается механизма передачи журнала ошибок из приложения мне (разработчику) через Интернет.

Ответы [ 6 ]

3 голосов
/ 24 мая 2009

Я бы предложил НЕ отправлять все (весь аудит вашей заявки).
Но только если пользователь хочет это (кнопка «Обратная связь») или если есть явное исключение, фатальная ошибка, состояние проблемы в приложении.

Мы использовали как веб-сервисы, так и электронную почту (SMTPClient). Мои мысли по этим

Веб-сервис
ХОРОШО

  • Нет специальных настроек для пользователя
  • Ограничение размера, возможно более 5–8 МБ электронной почты

ПЛОХО

  • публично видно (хакеру нравится играть с этими вещами)
  • Дополнительные разработки для создания веб-сервиса с базой данных db
  • Создание дополнительных полей позже - это плохо
  • Изменения в веб-сервисе НЕ ХОРОШИЕ!

SmtpClient
ХОРОШО

  • Нет специальной конфигурации для пользователя
  • Вход в общую папку облегчает поиск / фильтрацию (группировка, ...)
  • Все данные можно отправлять, скриншоты, трассировка стека, пользовательские настройки, ...
    -> HTML
  • Изменение формата регистрации и информации легко, потому что мы использовали электронные письма HTML

ПЛОХО

  • Специальная конфигурация для пользователя (сервер smtp, пользователь электронной почты, ...)
  • Предел размера электронной почты (5MB-8MB ??)
  • Запись в дБ электронных писем требует большой разработки
3 голосов
/ 24 мая 2009

Каким-то образом, чтобы пользователь знал, что вы хотите это сделать. Попросите у них прокси, попросите у них почтовый сервер, что-то в этом роде.

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

И это правильно.

2 голосов
/ 24 мая 2009

Мы используем 3 метода, где я работаю

  • SMTP к выделенному почтовому ящику. Для этого требуется много конфигурации и совместная работа с «крупными корпоративными» ИТ-отделами, чтобы выяснить, что представляет собой их почтовый сервер и как пройти проверку подлинности на нем и отправить его через него. Кроме того, есть такие программы, как Norton Internet Security, которые могут блокировать исходящий SMTP-трафик на клиентском компьютере, который добавляет дополнительные ключи в работу.
  • Подача asmx на наш сервер. Это наш предпочтительный метод, но многое может помешать. В основном это прокси, но Нортон также может вмешаться и убить вас. Если задействован прокси, убегайте, убегайте: -)
  • HTTP POST с использованием HttpWebRequest и MIME-типа multipart / form-encoded. У него также есть проблемы с прокси и брандмауэром, но иногда он может работать при сбое отправки asmx.

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

2 голосов
/ 24 мая 2009

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

0 голосов
/ 19 июня 2009

Если вы не ожидаете, что за один день будет отправлено так много отчетов ... вы можете создать учетную запись Gmail и использовать ее для отправки электронных писем, чтобы заставить пользователя настроить SMTP-сервер. Не знаете, каковы условия использования Gmail.

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

Очевидно, что здесь есть некоторые проблемы с безопасностью, например, кто-то может получить доступ к вашей учетной записи Gmail. Итак, примите это во внимание.

В этом классе есть методы для отправки электронной почты синхронно или асинхронно.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections;
using System.Text;
using System.Net;
using System.Net.Mail;
using System.Net.Mime; 
//Mime is Not necerrary if you dont change the msgview and 
//if you dont add custom/extra headers 
using System.Threading;
using System.IO;
using System.Windows.Forms; // needed for MessageBox only.



namespace BR.Util
{
    public class Gmailer
    {

        SmtpClient client = new SmtpClient();
        static String mDefaultToAddress = "yourToAddress@yourdomain.com";
        static String mDefaultFromAddress = "anonymous@gmail.com";
        static String mDefaultFromDisplayName = "Anonymous";

        String mGmailLogin = "someaccount@gmail.com";
        String mGmailPassword = "yourpassword";


        public Gmailer()
        {
            client.Credentials = new System.Net.NetworkCredential(mGmailLogin, mGmailPassword);
            client.Port = 587;           
            client.Host = "smtp.gmail.com";
            client.EnableSsl = true;
            client.SendCompleted += new SendCompletedEventHandler(Gmailer_DefaultAsyncSendCompletedHandler);
        }

        public void setSendCompletedHandler(SendCompletedEventHandler pHandler)
        {
            client.SendCompleted -= Gmailer_DefaultAsyncSendCompletedHandler;
            client.SendCompleted += pHandler;
        }

        /// <summary>
        /// Static method which sends an email synchronously.
        /// It uses a hardcoded from email.
        /// </summary>
        /// <returns></returns>
        public static bool quickSend(String toEmailAddress, String subject, String body)
        {
            return Gmailer.quickSend(toEmailAddress, mDefaultFromAddress, mDefaultFromDisplayName, subject, body);
        }

        /// <summary>
        /// Static method which sends an email synchronously.
        /// It uses the hardcoded email address.
        /// </summary>
        /// <returns>true if successful, false if an error occurred.</returns>
        public static bool quickSend(String toEmailAddress, String fromEmailAddress,
                                     String fromDisplayName, String subject, String body)
        {
            try
            {
                Gmailer gmailer = new Gmailer();
                System.Net.Mail.MailMessage mailMsg = gmailer.createMailMessage(toEmailAddress, fromEmailAddress, fromDisplayName, subject, body);
                gmailer.send(mailMsg);
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        // <summary> creates a MailMessage object initialized with the default values.</summary>
        public System.Net.Mail.MailMessage createMailMessage()
        {
            return createMailMessage(mDefaultToAddress, mDefaultFromAddress, mDefaultFromDisplayName, mDefaultEmailSubject, mDefaultEmailBody);
        }

        public System.Net.Mail.MailMessage createMailMessage(String toEmailAddress, String fromEmailAddress, 
                                                             String fromDisplayName, String subject, String body)
        {
            //Build The MSG
            System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
            msg.To.Add(toEmailAddress);
            msg.From = new MailAddress(fromEmailAddress, fromDisplayName, System.Text.Encoding.UTF8);
            msg.Subject = subject;
            msg.SubjectEncoding = System.Text.Encoding.UTF8;
            msg.Body = body;
            msg.BodyEncoding = System.Text.Encoding.UTF8;
            msg.IsBodyHtml = false;
            msg.Priority = MailPriority.High;
            return msg;
        }

        public System.Net.Mail.MailMessage addAttachmentToMailMessage(System.Net.Mail.MailMessage msg, String attachmentPath)
        {
            msg.Attachments.Add(new Attachment(attachmentPath));
            return msg;
        }

        // <summary> method which blocks until the MailMessage has been sent.  Throws
        // System.Net.Mail.SmtpException if error occurs.</summary>
        public void send(System.Net.Mail.MailMessage pMailMessage)
        {
            //try {
                client.Send(pMailMessage);
            //}
            //catch (System.Net.Mail.SmtpException ex)
            //{
            //    MessageBox.Show(ex.Message, "Send Mail Error");
            //}
        }

        // 
        public void sendAsync(System.Net.Mail.MailMessage pMailMessage)
        {
            object userState = pMailMessage;
            try
            {
                MailSent = false;
                client.SendAsync(pMailMessage, userState);
            }
            catch (System.Net.Mail.SmtpException ex)
            {
                MessageBox.Show(ex.Message, "Send Mail Error");
            }
        }

        // <summary> 
        // Provides a default SendComplete handler which is activated when an AsyncCompletedEvent 
        // is triggered by the private client variable.  This is useful for debugging etc.
        // Use the method setSendCompletedHandler to define your own application specific handler.
        // That method also turns this handler off.
        // </summary>
        public void Gmailer_DefaultAsyncSendCompletedHandler(object sender, AsyncCompletedEventArgs e)
        {
            MailMessage mail = (MailMessage)e.UserState;
            string subject = mail.Subject;

            if (e.Cancelled)
            {
                string cancelled = string.Format("[{0}] Send canceled.", subject);
                MessageBox.Show(cancelled);                
            }
            if (e.Error != null)
            {
                string error = String.Format("[{0}] {1}", subject, e.Error.ToString());
                MessageBox.Show(error);                
            }
            else
            {
                MessageBox.Show("Message sent.");
            }
            MailSent = true;
        }


        private bool _MailSent = false;
        /// <summary>
        /// Set to false when an async send operation is started and is set to true when finished.
        /// </summary>
        public bool MailSent
        {
            set
            {
                _MailSent = value;
            }
            get
            {
                return _MailSent;
            }
        }
    }
}
0 голосов
/ 24 мая 2009

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

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

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

Одна вещь, которую вы должны НЕ сделать, это отправить информацию без разрешения пользователя.

...