Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Android and iOS #49

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ internal class PersistenceTransmitter : IDisposable
/// A list of senders that sends transmissions.
/// </summary>
private List<Sender> senders = new List<Sender>();

/// <summary>
/// The storage that is used to persist all the transmissions.
/// </summary>
Expand Down Expand Up @@ -71,6 +71,11 @@ internal PersistenceTransmitter(StorageBase storage, int sendersCount, bool crea
{
this.mutex = new Mutex(initiallyOwned: false, name: this.storage.FolderName);
}
// named mutex is not supported in Xamarin Android and iOS, it throws NotSupportedException, so we'll use unnamed mutex instead
catch (NotSupportedException)
{
this.mutex = new Mutex(initiallyOwned: false);
}
catch (Exception e)
{
string errorMsg = string.Format(CultureInfo.InvariantCulture, "PersistenceTransmitter: Failed to construct the mutex: {0}", e);
Expand All @@ -94,7 +99,7 @@ internal PersistenceTransmitter(StorageBase storage, int sendersCount, bool crea
/// Gets a unique folder name. This folder will be used to store the transmission files.
/// </summary>
internal string StorageUniqueFolder
{
{
get
{
return this.storage.FolderName;
Expand Down Expand Up @@ -203,7 +208,7 @@ private void AcquireMutex(Action action)
catch (ObjectDisposedException)
{
// if mutex or the auto reset event are disposed, just quit.
return;
return;
}
}
}
Expand Down
36 changes: 23 additions & 13 deletions AppInsights.WindowsDesktop/PersistenceChannel/Sender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace Microsoft.ApplicationInsights.Channel
using System;
using System.Globalization;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights.Extensibility.Implementation.Tracing;
Expand Down Expand Up @@ -144,7 +145,7 @@ internal void ForceSendNow()
/// Stops the sender.
/// </summary>
internal Task StopAsync()
{
{
// After delayHandler is set, a sending iteration will immidiately start.
// Seting <c>stopped</c> to ture, will cause the iteration to skip the actual sending and stop immediately.
this.stopped = true;
Expand All @@ -153,15 +154,15 @@ internal Task StopAsync()
// if delayHandler was set while a transmision was being sent, the return task waill wait for it to finsih, for an additional second,
// before it will mark the task as completed.
return Task.Factory.StartNew(() =>
{
try
{
try
{
this.stoppedHandler.WaitOne(this.drainingTimeout);
}
catch (ObjectDisposedException)
{
}
});
this.stoppedHandler.WaitOne(this.drainingTimeout);
}
catch (ObjectDisposedException)
{
}
});
}

/// <summary>
Expand Down Expand Up @@ -220,17 +221,26 @@ protected void SendLoop()
/// <param name="nextSendInterval">When this value returns it will hold a recommendation for when to start the next sending iteration.</param>
/// <returns>A boolean value that indicates if there was a retriable error.</returns>
protected virtual bool Send(StorageTransmission transmission, ref TimeSpan nextSendInterval)
{
{
try
{
if (transmission != null)
{
transmission.SendAsync().ConfigureAwait(false).GetAwaiter().GetResult();

// After a successful sending, try immeidiately to send another transmission.
nextSendInterval = this.SendingInterval;
}
}
// https://github.com/microsoft/ApplicationInsights-dotnet/blob/70e438848915ec163fd7794221b27be34260d3b4/BASE/src/Microsoft.ApplicationInsights/Channel/Transmission.cs#L158
// HttpClient.SendAsync throws HttpRequestException only on the following scenarios:
// "The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout."
// i.e for Server errors (500 status code), no exception is thrown.
catch (HttpRequestException)
{
nextSendInterval = this.CalculateNextInterval(null, nextSendInterval, this.maxIntervalBetweenRetries);
return true;
}
catch (WebException e)
{
int? statusCode = GetStatusCode(e);
Expand All @@ -252,7 +262,7 @@ protected virtual bool Send(StorageTransmission transmission, ref TimeSpan nextS
/// Logging every interval will just make the log noisy.
/// </summary>
private static void LogInterval(TimeSpan prevSendInterval, TimeSpan nextSendInterval)
{
{
if (Math.Abs(nextSendInterval.TotalSeconds - prevSendInterval.TotalSeconds) > 60)
{
CoreEventSource.Log.LogVerbose("next sending interval: " + nextSendInterval);
Expand All @@ -263,7 +273,7 @@ private static void LogInterval(TimeSpan prevSendInterval, TimeSpan nextSendInte
/// Return the status code from the web exception or null if no such code exists.
/// </summary>
private static int? GetStatusCode(WebException e)
{
{
HttpWebResponse httpWebResponse = e.Response as HttpWebResponse;
if (httpWebResponse != null)
{
Expand Down
20 changes: 12 additions & 8 deletions AppInsights.WindowsDesktop/PersistenceChannel/Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ internal override void Delete(StorageTransmission item)
}

internal override async Task EnqueueAsync(Transmission transmission)
{
{
try
{
if (this.StorageFolder == null)
Expand Down Expand Up @@ -294,7 +294,7 @@ private static string GetApplicationIdentity()
domainDirecotry = AppDomain.CurrentDomain.BaseDirectory;
}
catch (AppDomainUnloadedException e)
{
{
CoreEventSource.Log.LogVerbose(string.Format("GetApplicationIdentity: Failed to read the domain's base directory. Exception: {0}", e));
}

Expand All @@ -314,10 +314,10 @@ private static string GetApplicationIdentity()
}

private static string GetSHA1Hash(string input)
{
{
byte[] inputBits = Encoding.Unicode.GetBytes(input);
try
{
{
byte[] hashBits = new SHA1CryptoServiceProvider().ComputeHash(inputBits);
var hashString = new StringBuilder();
foreach (byte b in hashBits)
Expand All @@ -338,11 +338,15 @@ private DirectoryInfo GetApplicationFolder()
{
IDictionary environment = Environment.GetEnvironmentVariables();

var folderOption1 = new { RootPath = environment["LOCALAPPDATA"] as string, AISubFolder = @"Microsoft\ApplicationInsights" };
var folderOption2 = new { RootPath = environment["TEMP"] as string, AISubFolder = @"Microsoft\ApplicationInsights" };
var folderOption3 = new { RootPath = environment["ProgramData"] as string, AISubFolder = @"Microsoft ApplicationInsights" };
var folderOption1 = new { RootPath = environment["LOCALAPPDATA"] as string, AISubFolder = @"Microsoft\ApplicationInsights" };
var folderOption2 = new { RootPath = environment["TEMP"] as string, AISubFolder = @"Microsoft\ApplicationInsights" };
var folderOption3 = new { RootPath = environment["ProgramData"] as string, AISubFolder = @"Microsoft ApplicationInsights" };
// ANDROID
var folderOption4 = new { RootPath = environment["TMPDIR"] as string, AISubFolder = @"Microsoft ApplicationInsights" };
// iOS
var folderOption5 = new { RootPath = Path.GetTempPath(), AISubFolder = @"Microsoft ApplicationInsights" };

foreach (var folderOption in new[] { folderOption1, folderOption2, folderOption3 })
foreach (var folderOption in new[] { folderOption1, folderOption2, folderOption3, folderOption4, folderOption5 })
{
try
{
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "2.17",
"version": "2.18",
"publicReleaseRefSpec": [
"^refs/heads/main$", // we release out of main
"^refs/heads/dev$", // we release out of develop
Expand Down