Skip to content

Commit 7dc4f1d

Browse files
committed
Added min log level and some perf changes to logging extensions + added build support
1 parent 8b45acd commit 7dc4f1d

File tree

10 files changed

+197
-179
lines changed

10 files changed

+197
-179
lines changed

Exceptionless.Net.sln

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26730.12
4+
VisualStudioVersion = 15.0.26730.16
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{728C18BC-4085-4492-B0B2-8211CA209A50}"
77
ProjectSection(SolutionItems) = preProject
@@ -88,7 +88,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptionless.SampleAspNetC
8888
EndProject
8989
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptionless.SampleConsole", "samples\Exceptionless.SampleConsole\Exceptionless.SampleConsole.csproj", "{23645F73-57D8-4D70-BE1A-37903A8E4A18}"
9090
EndProject
91-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptionless.Extensions.Logging", "src\Exceptionless.Extensions.Logging\Exceptionless.Extensions.Logging.csproj", "{CA402AB4-D9CE-4053-AE26-94C1B3A4E48E}"
91+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Exceptionless.Extensions.Logging", "src\Platforms\Exceptionless.Extensions.Logging\Exceptionless.Extensions.Logging.csproj", "{9A8BB712-01DE-491C-8E33-E381DDEDDC19}"
9292
EndProject
9393
Global
9494
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -176,10 +176,10 @@ Global
176176
{23645F73-57D8-4D70-BE1A-37903A8E4A18}.Debug|Any CPU.Build.0 = Debug|Any CPU
177177
{23645F73-57D8-4D70-BE1A-37903A8E4A18}.Release|Any CPU.ActiveCfg = Release|Any CPU
178178
{23645F73-57D8-4D70-BE1A-37903A8E4A18}.Release|Any CPU.Build.0 = Release|Any CPU
179-
{CA402AB4-D9CE-4053-AE26-94C1B3A4E48E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
180-
{CA402AB4-D9CE-4053-AE26-94C1B3A4E48E}.Debug|Any CPU.Build.0 = Debug|Any CPU
181-
{CA402AB4-D9CE-4053-AE26-94C1B3A4E48E}.Release|Any CPU.ActiveCfg = Release|Any CPU
182-
{CA402AB4-D9CE-4053-AE26-94C1B3A4E48E}.Release|Any CPU.Build.0 = Release|Any CPU
179+
{9A8BB712-01DE-491C-8E33-E381DDEDDC19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
180+
{9A8BB712-01DE-491C-8E33-E381DDEDDC19}.Debug|Any CPU.Build.0 = Debug|Any CPU
181+
{9A8BB712-01DE-491C-8E33-E381DDEDDC19}.Release|Any CPU.ActiveCfg = Release|Any CPU
182+
{9A8BB712-01DE-491C-8E33-E381DDEDDC19}.Release|Any CPU.Build.0 = Release|Any CPU
183183
EndGlobalSection
184184
GlobalSection(SolutionProperties) = preSolution
185185
HideSolutionNode = FALSE
@@ -203,6 +203,7 @@ Global
203203
{F949CF8F-9D5F-454B-B20A-D8F9C22B70D9} = {D363E15F-621D-40E4-8C96-DEE41A7070FF}
204204
{D7039656-8587-49CC-8657-5C9BDCFC1C80} = {2CEE12C6-3840-4C01-A952-D3026B0A662A}
205205
{23645F73-57D8-4D70-BE1A-37903A8E4A18} = {2CEE12C6-3840-4C01-A952-D3026B0A662A}
206+
{9A8BB712-01DE-491C-8E33-E381DDEDDC19} = {D363E15F-621D-40E4-8C96-DEE41A7070FF}
206207
EndGlobalSection
207208
GlobalSection(ExtensibilityGlobals) = postSolution
208209
SolutionGuid = {EBB2CC85-FF87-431B-865F-2F110B2A10E6}

build/Settings.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ $client_projects = @(
1313
@{ Name = "Exceptionless.Portable.Signed"; SourceDir = "$source_dir\Exceptionless.Portable.Signed"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },
1414
@{ Name = "Exceptionless.AspNetCore"; SourceDir = "$source_dir\Platforms\Exceptionless.AspNetCore"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },
1515
@{ Name = "Exceptionless.AspNetCore.Signed"; SourceDir = "$source_dir\Platforms\Exceptionless.AspNetCore.Signed"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },
16+
@{ Name = "Exceptionless.Extensions.Logging"; SourceDir = "$source_dir\Platforms\Exceptionless.Extensions.Logging"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },
1617
@{ Name = "Exceptionless.Mvc"; SourceDir = "$source_dir\Platforms\Exceptionless.Mvc"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },
1718
@{ Name = "Exceptionless.Mvc.Signed"; SourceDir = "$source_dir\Platforms\Exceptionless.Mvc.Signed"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },
1819
@{ Name = "Exceptionless.Nancy"; SourceDir = "$source_dir\Platforms\Exceptionless.Nancy"; ExternalNuGetDependencies = $null; UseMSBuild = $False; },

samples/Exceptionless.SampleAspNetCore/Exceptionless.SampleAspNetCore.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15-
<ProjectReference Include="..\..\src\Exceptionless.Extensions.Logging\Exceptionless.Extensions.Logging.csproj" />
1615
<ProjectReference Include="..\..\src\Exceptionless\Exceptionless.csproj" />
1716
<ProjectReference Include="..\..\src\Platforms\Exceptionless.AspNetCore\Exceptionless.AspNetCore.csproj" />
17+
<ProjectReference Include="..\..\src\Platforms\Exceptionless.Extensions.Logging\Exceptionless.Extensions.Logging.csproj" />
1818
</ItemGroup>
1919

2020
<ItemGroup>
Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,28 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2+
<Import Project="..\..\..\build\common.props" />
23

34
<PropertyGroup>
4-
<TargetFrameworks>netstandard1.3;netstandard2.0;net46;net461</TargetFrameworks>
5-
<RootNamespace>Exceptionless.Extensions.Logging</RootNamespace>
6-
<Version>4.0.0</Version>
7-
<Copyright>Copyright (c) 2017 Exceptionless. All rights reserved.</Copyright>
8-
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
9-
<PackageProjectUrl>https://github.com/exceptionless/Exceptionless.Net</PackageProjectUrl>
10-
<PackageIconUrl>https://be.exceptionless.io/img/exceptionless-32.png</PackageIconUrl>
11-
<RepositoryUrl>https://github.com/exceptionless/Exceptionless.Net</RepositoryUrl>
12-
<RepositoryType>git</RepositoryType>
13-
<PackageReleaseNotes>https://github.com/exceptionless/Exceptionless.Net/releases</PackageReleaseNotes>
5+
<PackageId>Exceptionless.Extensions.Logging</PackageId>
6+
<AssemblyName>Exceptionless.Extensions.Logging</AssemblyName>
7+
<AssemblyTitle>Exceptionless provider for Microsoft.Extensions.Logging</AssemblyTitle>
8+
<Description>Exceptionless provider for Microsoft.Extensions.Logging. $(Description)</Description>
149
<PackageTags>Exceptionless;Microsoft.Extensions.Logging;log;logging</PackageTags>
15-
<Description>Exceptionless provider for Microsoft.Extensions.Logging.</Description>
10+
<TargetFrameworks>netstandard2.0</TargetFrameworks>
1611
</PropertyGroup>
1712

18-
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard1.3'">
19-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.1.2" />
13+
<ItemGroup Label="Package">
14+
<None Include="readme.txt" />
2015
</ItemGroup>
2116

22-
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
23-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
24-
</ItemGroup>
25-
26-
<ItemGroup Condition="'$(TargetFramework)' == 'net46'">
27-
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="1.1.2" />
17+
<ItemGroup Label="Build">
18+
<Compile Include="..\..\GlobalAssemblyInfo.cs" Link="Properties\GlobalAssemblyInfo.cs" />
2819
</ItemGroup>
2920

30-
<ItemGroup Condition="'$(TargetFramework)' == 'net461'">
21+
<ItemGroup Label="Package References">
3122
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.0.0" />
3223
</ItemGroup>
3324

3425
<ItemGroup>
35-
<ProjectReference Include="..\Exceptionless\Exceptionless.csproj" />
26+
<ProjectReference Include="..\..\Exceptionless\Exceptionless.csproj" />
3627
</ItemGroup>
37-
3828
</Project>
Lines changed: 63 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,31 @@
1-
using Exceptionless.Models;
2-
using Microsoft.Extensions.Logging;
3-
using System;
1+
using System;
42
using System.Collections.Generic;
3+
using ExceptionlessLogLevel = Exceptionless.Logging.LogLevel;
4+
using Microsoft.Extensions.Logging;
55

6-
namespace Exceptionless.Extensions.Logging
7-
{
8-
public class ExceptionlessLogger : ILogger
9-
{
10-
static readonly Dictionary<LogLevel, string> LOG_LEVELS = MapLogLevelsToExceptionlessNames();
11-
12-
static Dictionary<LogLevel, string> MapLogLevelsToExceptionlessNames()
13-
{
14-
Dictionary<LogLevel, string> mappings = new Dictionary<LogLevel, string>(7);
15-
mappings.Add(LogLevel.Critical, global::Exceptionless.Logging.LogLevel.Fatal.ToString());
16-
mappings.Add(LogLevel.Debug, global::Exceptionless.Logging.LogLevel.Debug.ToString());
17-
mappings.Add(LogLevel.Error, global::Exceptionless.Logging.LogLevel.Error.ToString());
18-
mappings.Add(LogLevel.Information, global::Exceptionless.Logging.LogLevel.Info.ToString());
19-
mappings.Add(LogLevel.None, global::Exceptionless.Logging.LogLevel.Off.ToString());
20-
mappings.Add(LogLevel.Trace, global::Exceptionless.Logging.LogLevel.Trace.ToString());
21-
mappings.Add(LogLevel.Warning, global::Exceptionless.Logging.LogLevel.Warn.ToString());
22-
23-
return mappings;
24-
}
25-
26-
ExceptionlessClient _Client;
27-
string _Source;
6+
namespace Exceptionless.Extensions.Logging {
7+
public class ExceptionlessLogger : ILogger {
8+
private readonly ExceptionlessClient _client;
9+
private readonly string _source;
2810

2911
/// <summary>
3012
/// Initializes a new instance of the <see cref="ExceptionlessLogger"/> class.
3113
/// </summary>
3214
/// <param name="client">The <see cref="ExceptionlessClient"/> to be used by the logger.</param>
3315
/// <param name="source">The source to tag events with, typically the category.</param>
34-
public ExceptionlessLogger(ExceptionlessClient client, string source)
35-
{
36-
if (client == null)
37-
throw new ArgumentNullException(nameof(client));
38-
39-
_Client = client;
40-
_Source = source;
16+
public ExceptionlessLogger(ExceptionlessClient client, string source) {
17+
_client = client ?? throw new ArgumentNullException(nameof(client));
18+
_source = source;
4119
}
4220

21+
/// <inheritdoc />
4322
/// <summary>
4423
/// Begins a logical operation scope.
4524
/// </summary>The identifier for the scope.
4625
/// <typeparam name="TState">The type of the state object.</typeparam>
4726
/// <param name="state"></param>
48-
/// <returns>An <see cref="IDisposable"/> that ends the logical operation scope on dispose.</returns>
49-
public IDisposable BeginScope<TState>(TState state)
50-
{
27+
/// <returns>An <see cref="T:System.IDisposable" /> that ends the logical operation scope on dispose.</returns>
28+
public IDisposable BeginScope<TState>(TState state) {
5129
if (state == null)
5230
throw new ArgumentNullException(nameof(state));
5331

@@ -59,24 +37,29 @@ public IDisposable BeginScope<TState>(TState state)
5937
object stateObj = state is string ? null : (object)state;
6038

6139
// Log scope creation as an event so that there is a parent to tie events together
62-
ExceptionlessLoggingScope scope = new ExceptionlessLoggingScope(description);
40+
var scope = new ExceptionlessLoggingScope(description);
6341
LogScope(scope, stateObj);
6442

6543
// Add to stack to support nesting within execution context
6644
ExceptionlessLoggingScope.Push(scope);
6745
return scope;
6846
}
6947

48+
/// <inheritdoc />
7049
/// <summary>
71-
/// Checks if the given <see cref="LogLevel"/> is enabled.
50+
/// Checks if the given <see cref="T:Microsoft.Extensions.Logging.LogLevel" /> is enabled.
7251
/// </summary>
7352
/// <param name="logLevel">The level to be checked.</param>
7453
/// <returns>Returns true if enabled.</returns>
75-
public bool IsEnabled(LogLevel logLevel)
76-
{
77-
return true;
54+
public bool IsEnabled(LogLevel logLevel) {
55+
if (logLevel == LogLevel.None || !_client.Configuration.IsValid)
56+
return false;
57+
58+
var minLogLevel = _client.Configuration.Settings.GetMinLogLevel(_source);
59+
return logLevel.ToLogLevel() >= minLogLevel;
7860
}
7961

62+
/// <inheritdoc />
8063
/// <summary>
8164
/// Writes a log entry.
8265
/// </summary>
@@ -85,84 +68,80 @@ public bool IsEnabled(LogLevel logLevel)
8568
/// <param name="eventId">Id of the event.</param>
8669
/// <param name="state">The entry to be written. Can be also an object.</param>
8770
/// <param name="exception">The exception related to this entry.</param>
88-
/// <param name="formatter">Function to create a <see cref="string"/> message of the <paramref name="state"/> and <paramref name="exception"/>.</param>
89-
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
90-
{
91-
// Create basic event from client
92-
EventBuilder eb = exception == null ? _Client.CreateEvent() : _Client.CreateException(exception);
93-
eb.SetProperty(Event.KnownDataKeys.Level, LOG_LEVELS[logLevel]);
71+
/// <param name="formatter">Function to create a <see cref="T:System.String" /> message of the <paramref name="state" /> and <paramref name="exception" />.</param>
72+
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) {
73+
if (formatter == null)
74+
throw new ArgumentNullException(nameof(formatter));
9475

95-
// Get formatted message
96-
eb.SetMessage(formatter.Invoke(state, exception));
76+
if (!IsEnabled(logLevel))
77+
return;
9778

98-
// Add category as source, if available
99-
if (_Source != null)
100-
eb.SetSource(_Source);
79+
string message = formatter(state, exception);
80+
if (String.IsNullOrEmpty(message) && exception == null)
81+
return;
82+
83+
var builder = exception == null ? _client.CreateLog(_source, message, logLevel.ToLogLevel()) : _client.CreateException(exception);
84+
builder.Target.Date = DateTimeOffset.Now;
85+
86+
if (!String.IsNullOrEmpty(message))
87+
builder.SetMessage(message);
88+
89+
if (exception != null)
90+
builder.SetSource(_source);
10191

10292
// Add event id, if available
10393
if (eventId.Id != 0)
104-
eb.SetProperty("Event Id", eventId.Id);
94+
builder.SetProperty("EventId", eventId.Id);
10595

10696
// If within a scope, add scope's reference id
10797
if (ExceptionlessLoggingScope.Current != null)
108-
eb.SetEventReference("Parent", ExceptionlessLoggingScope.Current.Id);
98+
builder.SetEventReference("Parent", ExceptionlessLoggingScope.Current.Id);
10999

110100
// The logging framework passes in FormattedLogValues, which implements IEnumerable<KeyValuePair<string, object>>;
111101
// add each property and value as individual objects for proper visibility in Exceptionless
112-
IEnumerable<KeyValuePair<string, object>> stateProps = state as IEnumerable<KeyValuePair<string, object>>;
113-
if (stateProps != null)
114-
{
115-
foreach (KeyValuePair<string, object> prop in stateProps)
116-
{
102+
if (state is IEnumerable<KeyValuePair<string, object>> stateProps) {
103+
foreach (KeyValuePair<string, object> prop in stateProps) {
117104
// Logging the message template is superfluous
118105
if (prop.Key != "{OriginalFormat}")
119-
eb.AddObject(prop.Value, prop.Key);
106+
builder.AddObject(prop.Value, prop.Key);
120107
}
121-
}
122-
// Otherwise, attach the entire object, using its type as the name
123-
else
124-
{
125-
eb.AddObject(state);
108+
} else {
109+
// Otherwise, attach the entire object, using its type as the name
110+
builder.AddObject(state);
126111
}
127112

128-
// Add to client's queue
129-
eb.Submit();
113+
builder.Submit();
130114
}
131115

132116
/// <summary>
133117
/// Writes a scope creation entry.
134118
/// </summary>
135119
/// <param name="newScope">The <see cref="ExceptionlessLoggingScope"/> being created.</param>
136-
private void LogScope(ExceptionlessLoggingScope newScope, object state)
137-
{
138-
EventBuilder eb = _Client.CreateLog($"Creating scope: {newScope.Description}.", global::Exceptionless.Logging.LogLevel.Other);
120+
/// <param name="state"></param>
121+
private void LogScope(ExceptionlessLoggingScope newScope, object state) {
122+
var builder = _client.CreateLog($"Creating scope: {newScope.Description}.", ExceptionlessLogLevel.Other);
139123

140124
// Set event reference id to that of scope object
141-
eb.SetReferenceId(newScope.Id);
125+
builder.SetReferenceId(newScope.Id);
142126

143127
// If this is a nested scope, add parent's reference id
144128
if (ExceptionlessLoggingScope.Current != null)
145-
eb.SetEventReference("Parent", ExceptionlessLoggingScope.Current.Id);
129+
builder.SetEventReference("Parent", ExceptionlessLoggingScope.Current.Id);
146130

147-
if (state != null)
148-
{
131+
if (state != null) {
149132
IEnumerable<KeyValuePair<string, object>> stateProps = state as IEnumerable<KeyValuePair<string, object>>;
150-
if (stateProps != null)
151-
{
152-
foreach (KeyValuePair<string, object> prop in stateProps)
153-
{
133+
if (stateProps != null) {
134+
foreach (KeyValuePair<string, object> prop in stateProps) {
154135
// Logging the message template is superfluous
155136
if (prop.Key != "{OriginalFormat}")
156-
eb.AddObject(prop.Value, prop.Key);
137+
builder.AddObject(prop.Value, prop.Key);
157138
}
158-
}
159-
else
160-
{
161-
eb.AddObject(state);
139+
} else {
140+
builder.AddObject(state);
162141
}
163142
}
164143

165-
eb.Submit();
144+
builder.Submit();
166145
}
167146
}
168-
}
147+
}

0 commit comments

Comments
 (0)