5
// Alan McGovern <alan@xamarin.com>
7
// Copyright 2011, Xamarin Inc.
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
10
// of this software and associated documentation files (the "Software"), to deal
11
// in the Software without restriction, including without limitation the rights
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
// copies of the Software, and to permit persons to whom the Software is
14
// furnished to do so, subject to the following conditions:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
using System.IO.Compression;
30
using System.Collections.Generic;
31
using System.Xml.Serialization;
34
using MonoDevelop.CrashLog;
36
namespace MonoDevelop.CrashReporting
38
public class CrashReporter
40
// The file which stores the list of reports which have to be uploaded
42
get { return Path.Combine (CacheDirectory, "crashlogs.xml"); }
45
// The directory where we cache all information for reports which
46
// will be uploaded in the future.
47
string CacheDirectory {
59
XmlSerializer Serializer {
63
public CrashReporter (string logDirectory, string email)
65
CacheDirectory = logDirectory;
67
if (!Directory.Exists (CacheDirectory))
68
Directory.CreateDirectory (CacheDirectory);
69
Logger = new StreamWriter (Path.Combine (CacheDirectory, "errors.log"));
70
Logger.AutoFlush = true;
71
Serializer = new XmlSerializer (typeof (List<CrashReport>));
74
public void ProcessCache ()
77
// If log only mode is enabled, don't try to process the cache
78
if (CrashLogOptions.LogOnly)
81
var reports = ReadCachedReports ();
82
File.Delete (CacheFile);
83
foreach (var v in reports)
85
} catch (Exception ex) {
86
Logger.WriteLine ("Exception processing stored cache: {0}", ex);
90
public void UploadOrCache (string crashLog)
92
UploadOrCache (new CrashReport { Email = Email, CrashLogPath = crashLog });
95
void UploadOrCache (CrashReport report)
97
if (!TryUploadReport (report)) {
98
Logger.WriteLine ("Did not upload report, caching");
99
AddReportToCache (report);
103
List<CrashReport> ReadCachedReports ()
106
var fileInfo = new FileInfo (CacheFile);
108
using (var s = fileInfo.OpenRead ())
109
return (List<CrashReport>) Serializer.Deserialize (s);
111
Logger.WriteLine ("Exception deserializing cached reports, ignoring");
113
return new List<CrashReport> ();
116
void AddReportToCache (CrashReport report)
119
// Ensure the log directory exists
120
if (!Directory.Exists (CacheDirectory))
121
Directory.CreateDirectory (CacheDirectory);
123
// Make a copy of the crash log in our own cache and update the crash report info
124
var newPath = Path.Combine (CacheDirectory, Path.GetFileName (report.CrashLogPath));
125
if (report.CrashLogPath != newPath)
126
File.Copy (report.CrashLogPath, newPath, true);
127
report.CrashLogPath = newPath;
129
// Update the list of pending crashes which we want to upload
130
var reports = ReadCachedReports ();
131
reports.Add (report);
132
WriteReportsToCache (reports);
133
} catch (Exception ex) {
134
Logger.WriteLine ("Exception occurred when appending a crash report to the cache: {0}", ex);
138
void WriteReportsToCache (List<CrashReport> reports)
140
using (var s = File.Open (CacheFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
141
Serializer.Serialize (s, reports);
144
bool TryUploadReport (CrashReport report)
147
if (CrashLogOptions.LogOnly) {
148
Logger.WriteLine ("CrashReporter is in log only mode. All crashes will be cached");
152
var server = Environment.GetEnvironmentVariable ("MONODEVELOP_CRASHREPORT_SERVER");
153
if (string.IsNullOrEmpty (server))
154
server = "software.xamarin.com";
156
var url = string.Format ("http://{0}/Service/IssueLogging?m={1}&n={2}", server, HttpUtility.UrlEncode (report.Email), HttpUtility.UrlEncode (Path.GetFileName (report.CrashLogPath)));
157
Logger.WriteLine ("Trying to connect to: {0}", url);
158
var request = WebRequest.Create (url);
159
request.Method = "POST";
160
using (var s = File.OpenRead (report.CrashLogPath)) {
161
request.ContentLength = s.Length;
162
// Write the log file to the request stream
163
using (var requestStream = request.GetRequestStream ())
164
s.CopyTo (requestStream);
166
Logger.WriteLine ("CrashReport sent to server, awaiting response...");
168
// Ensure the server has correctly processed everything.
169
using (var response = request.GetResponse ()) {
170
var responseText = new StreamReader (response.GetResponseStream ()).ReadToEnd ();
171
if (responseText != "OK") {
172
Logger.WriteLine ("Server responded with error: {0}", responseText);
176
} catch (Exception ex) {
177
Logger.WriteLine ("Failed to upload report to the server.");
178
Logger.WriteLine (ex);
181
Logger.WriteLine ("Successfully uploaded");
b'\\ No newline at end of file'