¿Cuál es la mejor manera de enviar errores de aplicación y los registros de Internet para los desarrolladores?

StackOverflow https://stackoverflow.com/questions/902975

Pregunta

A medida que el autor de una aplicación C #, he encontrado que la solución de problemas reportados por los usuarios sería mucho más fácil si tuviera acceso a los registros de excepción o de depuración.

He incluido un mecanismo de registro de cosecha que el usuario puede activar o desactivar. Quiero que el usuario sea capaz de presentar los registros a través de Internet para que pueda revisar los registros para el error.

He pensado en utilizar SMTPClient o servicio web para enviar la información. SMTPClient podría no funcionar debido a los cortafuegos pueden bloquear el acceso SMTP saliente. Haría un servicio web tiene problema con el envío de una gran cantidad de datos (potencialmente 1+ MB)?

¿Qué le recomendaría como la mejor manera de tener una aplicación de informes de errores de transmisión directamente a los desarrolladores para su revisión?

EDIT: Aclaración: Esta es una aplicación de Windows y cuando se produce un error Quiero que aparezca un cuadro de diálogo preguntando a presentar el error. Mi pregunta es sobre el mecanismo para transmitir el registro de errores de la aplicación a mí (desarrollador) a través de Internet.

¿Fue útil?

Solución

3 Utilizamos métodos donde trabajo

  • SMTP a un buzón dedicado. Esto requiere un mucho de la configuración y el baile alrededor con "grandes empresas" departamentos de TI a trabajar en lo que su servidor de correo y cómo autenticar contra ella y enviar a través de él. Entonces hay programas como Norton Internet Security que pueden bloquear el tráfico SMTP saliente en la máquina cliente que arrojan llaves adicionales en las obras.
  • La sumisión a un asmx en nuestro servidor. Este es nuestro método preferido, pero un montón de cosas puede ponerse en el camino. Es principalmente proxies, pero Norton también puede intervenir y swat abajo. Si hay un proxy involucrados, huir huir: -)
  • POST HTTP utilizando HttpWebRequest y typ mime de multipart / form-codificado. También tiene problemas de proxy y cortafuegos, pero a veces puede trabajar donde no presentación asmx.

Buena suerte. Tienes razón en que es más fácil de depurar si tienes el seguimiento de la pila y tal vez incluso un screenie de lo que el usuario anterior estaba haciendo mal.

Otros consejos

Algunos forma en que vamos a indicar al usuario qué quiere decir para hacerlo. Pedirles un proxy, pedirles un servidor de correo electrónico, o algo así.

El dispuestos a la seguridad obtendrá muy nervioso si descubren que usted está abriendo un enchufe o algo por el estilo y el envío de datos a cabo sin notificación.

Y con razón.

Yo sugeriría no enviar todo (toda la auditoría de su aplicación).
Pero sólo si el usuario lo desee (botón de "Feedback") o si hay una excepción explícita, error fatal, estado del problema en la aplicación.

Se utilizó ambos servicios web y correo electrónico (SMTPClient). Mis pensamientos sobre estos

servicio web
BUENO

  • No configuración especial por usuario
  • El límite de tamaño, más de 5 MB-8 MB de correo electrónico son posibles

BAD

  • Pública visible (hackers les gusta jugar con estas cosas)
  • desarrollo adicional para crear el servicio web con el extremo posterior db
  • Creación de campos adicionales más adelante es malo
  • Los cambios en el servicio web no son buenas!

SMTPClient
BUENO

  • No configuración especial por usuario
  • Acceso a la carpeta pública hace que la búsqueda / filtro fácil (agrupación, ...)
  • Todos los datos posibles para enviar, capturas de pantalla, StackTrace, de usuario, ...
    -> HTML
  • Los cambios en el formato de registro y la información es fácil, porque utilizamos correos electrónicos HTML

BAD

  • Configuración especial por usuario (servidor SMTP, el usuario de correo electrónico, ...)
  • El límite de tamaño de correo electrónico (5 MB-8 MB ??)
  • Registrar en dB de mensajes de correo electrónico requiere mucho desarrollo

Se puede escribir usted mismo, o puede usar algo como log4net , que se encarga del registro de excepción para usted ...

Me gustaría recibir este tipo de cosas como el correo electrónico a un buzón dedicado. De esa manera puedo archivar fácilmente, buscarla, o ignorarla.

En el cliente / remitente, creo que una oferta emergente para enviar los registros es una buena idea. Si las ventanas, se puede utilizar MAPI para enviar el correo electrónico. En un sistema UNIX "correo" problema funciona en la mayoría de los sistemas.

Puede solicitar al usuario una dirección de correo electrónico en el mensaje de confirmación, y tal vez ofrecer algunas opciones sobre la forma de enviarlo (incluyendo copiar / pegar en el cliente de correo de su elección).

Una cosa que debe no hacer es enviar la información sin el permiso del usuario.

Si usted no está esperando que muchos informes que se enviarán en un solo día ... se puede crear una cuenta de Gmail y usarlo para enviar los correos electrónicos de moverse por tener que forzar al usuario a configurar un servidor SMTP. términos y condiciones no está seguro de lo que son de Gmail para hacer esto.

Esta es una clase que he escrito que envía un correo electrónico con una cuenta de gmail ...

Es obvio que hay algunos problemas de seguridad aquí como alguien podría potencialmente obtener acceso a su cuenta de Gmail. Por lo tanto, tomar esto en consideración.

Existen métodos de esta clase para enviar el correo electrónico de forma sincrónica o asincrónica.

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;
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top