인터넷별로 응용 프로그램 오류 및 로그를 개발자에게 보내는 가장 좋은 방법은 무엇입니까?

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

문제

C# 응용 프로그램의 저자로서, 예외 또는 디버그 로그에 액세스 할 수 있다면 사용자가보고 한 문제 해결 문제가 훨씬 쉬울 것입니다.

사용자가 켜거나 끌 수있는 집에서 재배 한 벌목 메커니즘을 포함 시켰습니다. 사용자가 인터넷을 통해 로그를 제출하여 오류에 대한 로그를 검토 할 수 있기를 원합니다.

나는 어느 쪽도 사용한다고 생각했다 smtpclient 또는 a 웹 서비스 정보를 보내려면. 방화벽이 나가는 SMTP 액세스를 차단할 수 있으므로 SMTPClient가 작동하지 않을 수 있습니다. 웹 서비스가 많은 양의 데이터를 보내는 데 문제가 있습니까 (잠재적으로 1 개 이상)?

응용 프로그램이 검토를 위해 개발자에게 직접 오류 보고서를 직접 전송하는 가장 좋은 방법은 무엇입니까?

편집하다: 설명 : 이것은 Windows 응용 프로그램이며 오류가 발생하면 오류를 제출하도록 묻는 대화 상자를 가져오고 싶습니다. 내 질문은 인터넷을 통해 응용 프로그램에서 나 (개발자)로 오류 로그를 전송하는 메커니즘에 관한 것입니다.

도움이 되었습니까?

해결책

우리는 내가 일하는 곳에서 3 가지 방법을 사용합니다

  • 전용 사서함에 SMTP. 이것은 필요합니다 많은 "대기업"IT 부서와의 구성 및 춤으로 메일 서버가 무엇인지, 그리고 이에 대한 인증 및이를 통해 보내는 방법을 알아냅니다. 그런 다음 클라이언트 시스템의 아웃 바운드 SMTP 트래픽을 차단할 수있는 Norton Internet Security와 같은 프로그램이있어 작품에 추가 스패너를 던져 버립니다.
  • 서버의 ASMX에 제출. 이것은 우리가 선호하는 방법이지만 많은 것들이 방해 할 수 있습니다. 주로 프록시이지만 Norton은 들어 와서 당신을 무너 뜨릴 수 있습니다. 프록시가 관련되어 있다면, 도망자는 도망칩니다 :-)
  • httpwebrequest 및 mimpart/form-encoded의 마임 유형을 사용한 HTTP 게시물. 또한 프록시 및 방화벽 문제가 있지만 때로는 ASMX 제출이 실패한 곳에서 작동 할 수 있습니다.

행운을 빕니다. 당신이 옳습니다 많이 스택 추적이있는 경우 디버깅하기가 더 쉽고 가난한 오래된 사용자가하는 일에 대한 선별관 일 수도 있습니다.

다른 팁

사용자가 당신이 그것을 의미한다는 것을 알게하는 방법. 그들에게 프록시를 요청하고, 이메일 서버를 요청하십시오.

보안 신분은 소켓이나 그와 비슷한 것을 열고 알림없이 데이터를 보내는 것을 발견하면 정말 긴장하게됩니다.

그리고 맞습니다.

내가 제안 할게 모든 것을 보내지 마십시오 (신청서의 전체 감사).
그러나 사용자가 원하는 경우 ( "피드백"버튼) 또는 명시 적 예외, 치명적인 오류, 응용 프로그램의 문제 상태가있는 경우.

우리는 웹 서비스와 이메일 (smtpclient)을 모두 사용했습니다. 이것에 대한 나의 생각

웹 서비스
좋은

  • 사용자 당 특별한 구성이 없습니다
  • 크기 제한, 5MB-8MB 이상의 이메일이 가능합니다.

나쁜

  • 대중의 가시적 (해커는 이런 것들을 가지고 놀고 싶어)
  • DB 백엔드로 웹 서비스를 만들기위한 추가 개발
  • 나중에 추가 필드를 만드는 것은 나쁘다
  • 웹 서비스의 변화는 좋지 않습니다!

smtpclient
좋은

  • 사용자 당 특별한 구성이 없습니다
  • 공개 폴더에 로그인하면 검색/필터가 쉽게 만들 수 있습니다 (그룹화, ...)
  • 보낼 수있는 모든 데이터, 스크린 샷, 스택 트레이스, 사용자 설정 ...
    -> html
  • HTML 이메일을 사용했기 때문에 로깅 형식 및 정보 변경이 쉽습니다.

나쁜

  • 사용자 당 특수 구성 (SMTP 서버, 이메일 사용자, ...)
  • 이메일의 크기 제한 (5MB-8MB ??)
  • DB의 이메일에 로그인하려면 많은 개발이 필요합니다

직접 쓸 수 있거나 같은 것을 사용할 수 있습니다. log4net, 그것은 당신을 위해 예외 로깅을 처리합니다 ...

전용 사서함의 이메일로 이와 같은 물건을받는 것을 좋아합니다. 그렇게하면 쉽게 보관하거나 검색하거나 무시할 수 있습니다.

클라이언트/발신자 측면에서 로그를 보내기위한 팝업 제안은 좋은 생각이라고 생각합니다. Windows 인 경우 Mapi를 사용하여 이메일을 보낼 수 있습니다. UNIX 시스템에서 "메일"문제는 대부분의 시스템에서 작동합니다.

확인 메시지에서 이메일 주소를 사용자에게 프롬프트 할 수 있으며, 선택한 메일 클라이언트에 복사/붙여 넣기를 포함하는 방법에 대한 몇 가지 옵션을 제공 할 수 있습니다.

한 가지 아니다 Do는 사용자의 허가없이 정보를 보내는 것입니다.

많은 보고서가 하루 안에 전송 될 것으로 예상하지 않는 경우 ... 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;
            }
        }
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top