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

Implemented ILogger interface (#6) #7

Merged
merged 4 commits into from
Jul 30, 2024
Merged
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
3 changes: 1 addition & 2 deletions .github/workflows/PR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ on:
pull_request:
branches: [ "main" ]


jobs:
build:

Expand All @@ -27,4 +26,4 @@ jobs:
run: dotnet build TinyInsights/TinyInsights.csproj --no-restore

- name: Pack
run: dotnet pack TinyInsights/TinyInsights.csproj -p:PackageVersion=${{ github.ref_name }}
run: dotnet pack TinyInsights/TinyInsights.csproj
63 changes: 62 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ builder

If you want, you can configure what type of events you want to track.
```csharp
builder.UseMauiInsights("InstrumentationKey=8b51208f-7926-4b7b-9867-16989206b950;IngestionEndpoint=https://swedencentral-0.in.applicationinsights.azure.com/;ApplicationId=0c04d3a0-9ee2-41a5-996e-526552dc730f",
builder.UseMauiInsights("{YOUR_CONNECTION_STRING}",
(provider) =>
{
provider.IsTrackDependencyEnabled = true;
Expand Down Expand Up @@ -104,5 +104,66 @@ var dependency = insights.CreateDependencyTracker("BLOB",blobContainer.Uri.Host,
await blob.DownloadToAsync(stream);
dependency.Dispose();
```
## Use with ILogger
If you want, you can also use TinyInsights with the ILogger interface.

In ***MauiProgram.cs***, you should call ***UseTinyInsights*** like below.
```csharp
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.UseTinyInsightsAsILogger("{YOUR_CONNECTION_STRING}")
```

If you want, you can configure what type of events you want to track.
```csharp
builder.UseTinyInsightsAsILogger("{YOUR_CONNECTION_STRING}",
(provider) =>
{
provider.IsTrackDependencyEnabled = true;
provider.IsTrackEventsEnabled = true;
provider.IsTrackErrorsEnabled = true;
provider.IsTrackPageViewsEnabled = true;
provider.IsTrackCrashesEnabled = true;
});
```

### Use ILogger
To use **ILogger**, just inject the interface in the class you want to use it in.

```csharp
private readonly ILogger logger;

public class MainViewModel(ILogger logger)
{
this.logger = logger;
}
```

#### Track page views
```csharp
logger.LogTrace("MainView");
```

#### Track event
```csharp
logger.LogInformation("EventButton");
```

#### Track error
```csharp
logger.LogError(ex, ex.Message);
```

#### Track debug info

**LogDebug** will only work with the debugger attached because it is using **Debug.WriteLine**.

```csharp
logger.LogDebug("Debug message");
```
7 changes: 5 additions & 2 deletions TinyInsights.TestApp/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TinyInsights.TestApp.MainPage">

<ScrollView>
<ScrollView Padding="20">
<VerticalStackLayout
Padding="30,0"
Spacing="25">
<HorizontalStackLayout Spacing="10">

<Switch IsToggled="{Binding UseILogger, Mode=TwoWay}" />
<Label Text="Use ILogger" />
</HorizontalStackLayout>
<Button x:Name="PageViewButton" Text="Track page view" Clicked="PageViewButton_OnClicked" />

<Button x:Name="EventButton" Text="Track event" Clicked="EventButton_OnClicked" />
Expand Down
46 changes: 42 additions & 4 deletions TinyInsights.TestApp/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,44 @@
namespace TinyInsights.TestApp;
using Microsoft.Extensions.Logging;

namespace TinyInsights.TestApp;

public partial class MainPage : ContentPage
{
private readonly IInsights insights;
private readonly InsightsMessageHandler insightsMessageHandler;
private readonly ILogger logger;

public MainPage(IInsights insights, InsightsMessageHandler insightsMessageHandler)
public MainPage(IInsights insights, InsightsMessageHandler insightsMessageHandler, ILogger logger)
{
this.insights = insights;
this.insightsMessageHandler = insightsMessageHandler;
this.logger = logger;

BindingContext = this;


InitializeComponent();
}

private bool useILogger;
public bool UseILogger
{
get => useILogger;
set
{
useILogger = value;
OnPropertyChanged(nameof(UseILogger));
}
}

private async void PageViewButton_OnClicked(object? sender, EventArgs e)
{
if(UseILogger)
{
logger.LogTrace("MainView");
return;
}

dhindrik marked this conversation as resolved.
Show resolved Hide resolved
var data = new Dictionary<string, string>()
{
{"key", "value"},
Expand All @@ -25,9 +50,16 @@ private async void PageViewButton_OnClicked(object? sender, EventArgs e)


private async void EventButton_OnClicked(object? sender, EventArgs e)
{
{
if(UseILogger)
{
logger.LogInformation("EventButton");
logger.LogDebug("EventButton clicked");
return;
}

await insights.TrackEventAsync("EventButton");
}
}

private async void ExceptionButton_OnClicked(object? sender, EventArgs e)
{
Expand All @@ -37,6 +69,12 @@ private async void ExceptionButton_OnClicked(object? sender, EventArgs e)
}
catch (Exception ex)
{
if(UseILogger)
{
logger.LogError(ex, ex.Message);
return;
}

await insights.TrackErrorAsync(ex);
}
}
Expand Down
3 changes: 2 additions & 1 deletion TinyInsights.TestApp/MauiProgram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public static MauiApp CreateMauiApp()
provider.IsTrackErrorsEnabled = true;
provider.IsTrackPageViewsEnabled = true;
provider.IsTrackCrashesEnabled = true;
});
})
.UseTinyInsightsAsILogger("InstrumentationKey=8b51208f-7926-4b7b-9867-16989206b950;IngestionEndpoint=https://swedencentral-0.in.applicationinsights.azure.com/;ApplicationId=0c04d3a0-9ee2-41a5-996e-526552dc730f");

#if DEBUG
builder.Logging.AddDebug();
Expand Down
1 change: 1 addition & 0 deletions TinyInsights.Web/Components/Menu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<RadzenPanelMenuItem Text="Page views" Icon="visibility" Path="/analytics/page" />
<RadzenPanelMenuItem Text="Events" Icon="touch_app" Path="/analytics/events" />
<RadzenPanelMenuItem Text="Users" Icon="people" Path="/analytics/users" />
<RadzenPanelMenuItem Text="Devices" Icon="smartphone" Path="/analytics/devices" />
}

@* <RadzenPanelMenuItem Text="Source code" Icon="data_object" Path="https://github.com/dhindrik" Target="_blank" /> *@
Expand Down
28 changes: 28 additions & 0 deletions TinyInsights.Web/Pages/DeviceAnalytics.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@page "/analytics/devices"

@using TinyInsights.Web.Services

@inherits TinyInsightsComponentBase

@inject IInsightsService Service
<RadzenStack Gap="20">
<RadzenRow JustifyContent="JustifyContent.End">
<GlobalFilters />
</RadzenRow>
<RadzenCard>
<RadzenStack>
<h2>Idioms</h2>
@if (isLoadingIdiom)
{
<RadzenProgressBarCircular Value="100" ShowValue="false" Mode="ProgressBarMode.Indeterminate"/>
}
else
{

}
</RadzenStack>
</RadzenCard>
</RadzenStack>
@code {
private bool isLoadingIdiom = true;
}
Empty file.
1 change: 0 additions & 1 deletion TinyInsights.Web/Pages/ErrorDetails.razor
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
</a>
<GlobalFilters />


</RadzenRow>
<RadzenCard>

Expand Down
77 changes: 75 additions & 2 deletions TinyInsights/ApplicationInsightsProvider.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using System.Diagnostics;
using System.Globalization;
using System.Text.Json;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.Logging;

namespace TinyInsights;

public class ApplicationInsightsProvider : IInsightsProvider
public class ApplicationInsightsProvider : IInsightsProvider, ILogger
{
private const string userIdKey = nameof(userIdKey);

Expand All @@ -23,10 +25,10 @@
public bool IsTrackDependencyEnabled { get; set; } = true;

#if IOS || MACCATALYST || ANDROID
public ApplicationInsightsProvider(string connectionString)

Check warning on line 28 in TinyInsights/ApplicationInsightsProvider.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable field 'client' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

Check warning on line 31 in TinyInsights/ApplicationInsightsProvider.cs

View workflow job for this annotation

GitHub Actions / build

Nullability of reference types in type of parameter 'sender' of 'void ApplicationInsightsProvider.TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)' doesn't match the target delegate 'EventHandler<UnobservedTaskExceptionEventArgs>' (possibly because of nullability attributes).

var configuration = new TelemetryConfiguration()
{
Expand Down Expand Up @@ -135,7 +137,7 @@

if (crashes != null)
{

Debug.WriteLine($"TinyInsights: Sending {crashes.Count} crashes");

foreach (var crash in crashes)
{
Expand Down Expand Up @@ -216,6 +218,8 @@
{
try
{
Debug.WriteLine($"TinyInsights: Tracking error {ex.Message}");

if (properties == null)
{
properties = new Dictionary<string, string>();
Expand All @@ -237,6 +241,8 @@
{
try
{
Debug.WriteLine($"TinyInsights: Tracking event {eventName}");

client.TrackEvent(eventName, properties);
client.Flush();
}
Expand All @@ -252,6 +258,8 @@
{
try
{
Debug.WriteLine($"TinyInsights: Tracking page view {viewName}");

client.TrackPageView(viewName);
client.Flush();
}
Expand All @@ -267,6 +275,8 @@
{
try
{
Debug.WriteLine($"TinyInsights: Tracking dependency {dependencyName}");

var fullUrl = data;

if (data.Contains("?"))
Expand Down Expand Up @@ -309,4 +319,67 @@

return Task.CompletedTask;
}

#region ILogger
public async void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if(!IsEnabled(logLevel))
{
return;
}

var logTask = logLevel switch {
LogLevel.Trace => TrackPageViewAsync(GetEventName(eventId), GetLoggerData(logLevel, eventId, state, exception, formatter)),
LogLevel.Debug => TrackDebugAsync(eventId, state, exception),
LogLevel.Information => TrackEventAsync(GetEventName(eventId), GetLoggerData(logLevel, eventId, state, exception, formatter)),
LogLevel.Warning => TrackErrorAsync(exception!, GetLoggerData(logLevel, eventId, state, exception, formatter)),
LogLevel.Error => TrackErrorAsync(exception!, GetLoggerData(logLevel, eventId, state, exception, formatter)),
LogLevel.Critical => TrackErrorAsync(exception!, GetLoggerData(logLevel, eventId, state, exception, formatter)),
LogLevel.None => Task.CompletedTask,
_ => Task.CompletedTask
};

await logTask;
}

private Task TrackDebugAsync<TState>(EventId eventId, TState state, Exception? exception)
{
Debug.WriteLine($"TinyInsights: DebugLogging, Event: {GetEventName(eventId)}, State: {state}, Exception: {exception?.Message}");
return Task.CompletedTask;
}

private string GetEventName(EventId eventId)
{
return eventId.Name ?? eventId.Id.ToString();
}

private Dictionary<string, string> GetLoggerData<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
return new Dictionary<string, string>()
{
{ "LogLevel", logLevel.ToString() },
{ "EventId", eventId.ToString() },
{ "EventName", eventId.Name?.ToString() ?? string.Empty },
{ "State", state?.ToString() ?? string.Empty },
{ "Message", formatter(state, exception) }
};
}

public bool IsEnabled(LogLevel logLevel)
{
return logLevel switch {
LogLevel.Trace => IsTrackPageViewsEnabled,
LogLevel.Debug => Debugger.IsAttached,
LogLevel.Information => IsTrackEventsEnabled,
LogLevel.Warning => IsTrackErrorsEnabled,
LogLevel.Error => IsTrackErrorsEnabled,
LogLevel.Critical => IsTrackCrashesEnabled,
LogLevel.None => false,
_ => false
};
}

public IDisposable? BeginScope<TState>(TState state) where TState : notnull => default!;

#endregion
}
Loading
Loading