2020-09-01 07:46:07 +02:00
|
|
|
|
namespace Giants.Services.Services
|
|
|
|
|
{
|
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
2020-09-01 20:04:22 +02:00
|
|
|
|
using System.IO.Compression;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Net.Http;
|
2020-09-01 07:46:07 +02:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Azure.Storage.Blobs;
|
|
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
|
|
|
|
public class CrashReportService : ICrashReportService
|
|
|
|
|
{
|
|
|
|
|
private readonly BlobServiceClient blobServiceClient;
|
|
|
|
|
private readonly IConfiguration configuration;
|
|
|
|
|
private readonly ILogger<CrashReportService> logger;
|
2020-09-01 20:04:22 +02:00
|
|
|
|
private readonly IHttpClientFactory clientFactory;
|
|
|
|
|
|
|
|
|
|
private const string SentryMinidumpUploadFileKey = "upload_file_minidump";
|
2020-09-01 07:46:07 +02:00
|
|
|
|
|
|
|
|
|
public CrashReportService(
|
|
|
|
|
IConfiguration configuration,
|
2020-09-01 20:04:22 +02:00
|
|
|
|
ILogger<CrashReportService> logger,
|
|
|
|
|
IHttpClientFactory clientFactory)
|
2020-09-01 07:46:07 +02:00
|
|
|
|
{
|
|
|
|
|
this.configuration = configuration;
|
|
|
|
|
this.logger = logger;
|
2020-09-01 20:04:22 +02:00
|
|
|
|
this.clientFactory = clientFactory;
|
2020-09-01 07:46:07 +02:00
|
|
|
|
|
|
|
|
|
string blobConnectionString = configuration["BlobConnectionString"];
|
|
|
|
|
this.blobServiceClient = new BlobServiceClient(blobConnectionString);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 20:04:22 +02:00
|
|
|
|
public async Task UploadMinidumpToSentry(string fileName, Stream stream)
|
|
|
|
|
{
|
|
|
|
|
string minidumpUri = this.configuration["SentryMinidumpUri"];
|
|
|
|
|
if (string.IsNullOrEmpty(minidumpUri))
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Minidump URI is not defined.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var httpClient = this.clientFactory.CreateClient("Sentry");
|
|
|
|
|
|
|
|
|
|
using var zipArchive = new ZipArchive(stream);
|
|
|
|
|
var zipEntry = zipArchive.Entries.FirstOrDefault(e => e.Name == "crashdump.dmp");
|
|
|
|
|
if (zipEntry == null)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("No crash dump found in archive.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
using var dumpStream = zipEntry.Open();
|
|
|
|
|
using var formData = new MultipartFormDataContent
|
|
|
|
|
{
|
|
|
|
|
{ new StreamContent(dumpStream), SentryMinidumpUploadFileKey, fileName }
|
|
|
|
|
};
|
|
|
|
|
var response = await httpClient.PostAsync(minidumpUri, formData).ConfigureAwait(false);
|
|
|
|
|
|
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 07:46:07 +02:00
|
|
|
|
public async Task ProcessReport(string fileName, string senderIpAddress, Stream stream)
|
|
|
|
|
{
|
|
|
|
|
this.logger.LogInformation("Processing crash report file {FileName} from {IP}", fileName, senderIpAddress);
|
|
|
|
|
|
|
|
|
|
var containerClient = this.blobServiceClient.GetBlobContainerClient(
|
|
|
|
|
this.configuration["CrashBlobContainerName"]);
|
|
|
|
|
|
|
|
|
|
string blobPath = this.GetBlobPath(fileName);
|
|
|
|
|
var blobClient = containerClient.GetBlobClient(blobPath);
|
|
|
|
|
|
|
|
|
|
this.logger.LogInformation("Saving {FileName} to path: {Path}", fileName, blobPath);
|
|
|
|
|
|
|
|
|
|
await blobClient.UploadAsync(stream).ConfigureAwait(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private string GetBlobPath(string fileName)
|
|
|
|
|
{
|
|
|
|
|
DateTime dateTime = DateTime.Now;
|
|
|
|
|
return $"{dateTime.Year}/{dateTime.Month}/{dateTime.Day}/{fileName}";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|