├── .editorconfig ├── .github └── workflows │ └── dotnetcore.yml ├── .gitignore ├── LICENSE ├── README.md ├── ZNetCS.AspNetCore.Logging.EntityFrameworkCore.sln ├── src ├── Directory.Build.props ├── StrongNameKey.snk └── ZNetCS.AspNetCore.Logging.EntityFrameworkCore │ ├── EntityFrameworkLogger.cs │ ├── EntityFrameworkLoggerBuilderExtensions.cs │ ├── EntityFrameworkLoggerOptions.cs │ ├── EntityFrameworkLoggerProvider.cs │ ├── EntityFrameworkLoggerProviderBase.cs │ ├── Log.cs │ ├── LogModelBuilderHelper.cs │ ├── Properties │ └── AssemblyInfo.cs │ └── ZNetCS.AspNetCore.Logging.EntityFrameworkCore.csproj ├── stylecop.json └── test └── ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest ├── ContextExtended.cs ├── ContextSimple.cs ├── ExtendedLog.cs ├── Startup.cs ├── StartupBuilderExtended.cs ├── StartupBuilderExtendedSettings.cs ├── StartupBuilderSimple.cs ├── StartupBuilderSimpleCreator.cs ├── StartupBuilderSimpleException.cs ├── StartupBuilderSimpleNoFilter.cs ├── StartupBuilderSimpleSettings.cs ├── TestLoggerBuilderExtended.cs ├── TestLoggerBuilderExtendedSettings.cs ├── TestLoggerBuilderSimple.cs ├── TestLoggerBuilderSimpleCreator.cs ├── TestLoggerBuilderSimpleException.cs ├── TestLoggerBuilderSimpleNoFilter.cs ├── TestLoggerBuilderSimpleSettings.cs ├── TestVersion.cs ├── TestWebApplicationFactory.cs ├── ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest.csproj └── appsettings.json /.editorconfig: -------------------------------------------------------------------------------- 1 | [*.{asax,ascx,aspx,axaml,c,c++,cc,cginc,compute,cp,cpp,cs,cshtml,css,cu,cuh,cxx,h,hh,hlsl,hlsli,hlslinc,hpp,htm,html,hxx,inc,inl,ino,ipp,js,jsx,master,mpp,mq4,mq5,mqh,paml,razor,skin,tpp,ts,tsx,usf,ush,vb,xaml,xamlx,xoml}] 2 | indent_style = space 3 | indent_size = 4 4 | tab_width = 4 5 | 6 | [*.{appxmanifest,axml,build,config,csproj,dbml,discomap,dtd,json,jsproj,lsproj,njsproj,nuspec,proj,props,resjson,resw,resx,StyleCop,targets,tasks,vbproj,xml,xsd}] 7 | indent_style = space 8 | indent_size = 2 9 | tab_width = 2 10 | 11 | # Code files 12 | [*.{cs,vb}] 13 | dotnet_diagnostic.CA1001.severity = warning 14 | dotnet_diagnostic.CA1009.severity = warning 15 | dotnet_diagnostic.CA1016.severity = warning 16 | dotnet_diagnostic.CA1033.severity = warning 17 | dotnet_diagnostic.CA1049.severity = warning 18 | dotnet_diagnostic.CA1060.severity = warning 19 | dotnet_diagnostic.CA1061.severity = warning 20 | dotnet_diagnostic.CA1063.severity = warning 21 | dotnet_diagnostic.CA1065.severity = warning 22 | dotnet_diagnostic.CA1301.severity = warning 23 | dotnet_diagnostic.CA1303.severity = none 24 | dotnet_diagnostic.CA1400.severity = warning 25 | dotnet_diagnostic.CA1401.severity = warning 26 | dotnet_diagnostic.CA1403.severity = warning 27 | dotnet_diagnostic.CA1404.severity = warning 28 | dotnet_diagnostic.CA1405.severity = warning 29 | dotnet_diagnostic.CA1410.severity = warning 30 | dotnet_diagnostic.CA1415.severity = warning 31 | dotnet_diagnostic.CA1821.severity = warning 32 | dotnet_diagnostic.CA1900.severity = warning 33 | dotnet_diagnostic.CA1901.severity = warning 34 | dotnet_diagnostic.CA2002.severity = warning 35 | dotnet_diagnostic.CA2006.severity = warning 36 | dotnet_diagnostic.CA2007.severity = none 37 | dotnet_diagnostic.CA2100.severity = warning 38 | dotnet_diagnostic.CA2101.severity = warning 39 | dotnet_diagnostic.CA2108.severity = warning 40 | dotnet_diagnostic.CA2111.severity = warning 41 | dotnet_diagnostic.CA2112.severity = warning 42 | dotnet_diagnostic.CA2114.severity = warning 43 | dotnet_diagnostic.CA2116.severity = warning 44 | dotnet_diagnostic.CA2117.severity = warning 45 | dotnet_diagnostic.CA2122.severity = warning 46 | dotnet_diagnostic.CA2123.severity = warning 47 | dotnet_diagnostic.CA2124.severity = warning 48 | dotnet_diagnostic.CA2126.severity = warning 49 | dotnet_diagnostic.CA2131.severity = warning 50 | dotnet_diagnostic.CA2132.severity = warning 51 | dotnet_diagnostic.CA2133.severity = warning 52 | dotnet_diagnostic.CA2134.severity = warning 53 | dotnet_diagnostic.CA2137.severity = warning 54 | dotnet_diagnostic.CA2138.severity = warning 55 | dotnet_diagnostic.CA2140.severity = warning 56 | dotnet_diagnostic.CA2141.severity = warning 57 | dotnet_diagnostic.CA2146.severity = warning 58 | dotnet_diagnostic.CA2147.severity = warning 59 | dotnet_diagnostic.CA2149.severity = warning 60 | dotnet_diagnostic.CA2200.severity = warning 61 | dotnet_diagnostic.CA2202.severity = warning 62 | dotnet_diagnostic.CA2207.severity = warning 63 | dotnet_diagnostic.CA2212.severity = warning 64 | dotnet_diagnostic.CA2213.severity = warning 65 | dotnet_diagnostic.CA2214.severity = warning 66 | dotnet_diagnostic.CA2216.severity = warning 67 | dotnet_diagnostic.CA2220.severity = warning 68 | dotnet_diagnostic.CA2229.severity = warning 69 | dotnet_diagnostic.CA2231.severity = warning 70 | dotnet_diagnostic.CA2232.severity = warning 71 | dotnet_diagnostic.CA2235.severity = warning 72 | dotnet_diagnostic.CA2236.severity = warning 73 | dotnet_diagnostic.CA2237.severity = warning 74 | dotnet_diagnostic.CA2238.severity = warning 75 | dotnet_diagnostic.CA2240.severity = warning 76 | dotnet_diagnostic.CA2241.severity = warning 77 | dotnet_diagnostic.CA2242.severity = warning 78 | 79 | dotnet_diagnostic.IDE0001.severity = none 80 | dotnet_diagnostic.IDE0003.severity = none 81 | 82 | dotnet_diagnostic.SA1117.severity = none 83 | dotnet_diagnostic.SA1118.severity = none 84 | dotnet_diagnostic.SA1124.severity = none 85 | dotnet_diagnostic.SA1127.severity = none 86 | dotnet_diagnostic.SA1128.severity = none 87 | dotnet_diagnostic.SA1413.severity = none 88 | dotnet_diagnostic.SA1615.severity = none 89 | dotnet_diagnostic.SA1616.severity = none 90 | dotnet_diagnostic.SA1649.severity = none 91 | dotnet_diagnostic.SA1652.severity = none 92 | 93 | [*] 94 | # Microsoft .NET properties 95 | csharp_new_line_before_members_in_object_initializers = false 96 | csharp_preferred_modifier_order = public, protected, internal, private, static, new, abstract, virtual, override, sealed, readonly, extern, unsafe, volatile, async:suggestion 97 | csharp_style_var_for_built_in_types = false:suggestion 98 | csharp_using_directive_placement = inside_namespace:silent 99 | 100 | dotnet_naming_rule.private_constants_rule.severity = warning 101 | dotnet_naming_rule.private_constants_rule.style = upper_camel_case_style 102 | dotnet_naming_rule.private_constants_rule.symbols = private_constants_symbols 103 | dotnet_naming_rule.private_instance_fields_rule.severity = warning 104 | dotnet_naming_rule.private_instance_fields_rule.style = lower_camel_case_style 105 | dotnet_naming_rule.private_instance_fields_rule.symbols = private_instance_fields_symbols 106 | dotnet_naming_rule.private_static_fields_rule.severity = warning 107 | dotnet_naming_rule.private_static_fields_rule.style = lower_camel_case_style 108 | dotnet_naming_rule.private_static_fields_rule.symbols = private_static_fields_symbols 109 | dotnet_naming_rule.private_static_readonly_rule.severity = warning 110 | dotnet_naming_rule.private_static_readonly_rule.style = upper_camel_case_style 111 | dotnet_naming_rule.private_static_readonly_rule.symbols = private_static_readonly_symbols 112 | dotnet_naming_style.lower_camel_case_style.capitalization = camel_case 113 | dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case 114 | dotnet_naming_symbols.private_constants_symbols.applicable_accessibilities = private 115 | dotnet_naming_symbols.private_constants_symbols.applicable_kinds = field 116 | dotnet_naming_symbols.private_constants_symbols.required_modifiers = const 117 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_accessibilities = private 118 | dotnet_naming_symbols.private_instance_fields_symbols.applicable_kinds = field 119 | dotnet_naming_symbols.private_static_fields_symbols.applicable_accessibilities = private 120 | dotnet_naming_symbols.private_static_fields_symbols.applicable_kinds = field 121 | dotnet_naming_symbols.private_static_fields_symbols.required_modifiers = static 122 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_accessibilities = private 123 | dotnet_naming_symbols.private_static_readonly_symbols.applicable_kinds = field 124 | dotnet_naming_symbols.private_static_readonly_symbols.required_modifiers = static, readonly 125 | dotnet_separate_import_directive_groups = true 126 | dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:suggestion 127 | dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:suggestion 128 | dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:suggestion 129 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion 130 | dotnet_style_predefined_type_for_member_access = true:suggestion 131 | dotnet_style_qualification_for_event = true:suggestion 132 | dotnet_style_qualification_for_field = true:suggestion 133 | dotnet_style_qualification_for_method = true:suggestion 134 | dotnet_style_qualification_for_property = true:suggestion 135 | dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion 136 | 137 | 138 | -------------------------------------------------------------------------------- /.github/workflows/dotnetcore.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ${{ matrix.os }} 9 | 10 | strategy: 11 | matrix: 12 | os: [ubuntu-latest, windows-latest] 13 | steps: 14 | - name: Setup .NET Core 3.1 15 | uses: actions/setup-dotnet@v4 16 | with: 17 | dotnet-version: | 18 | 3.1.x 19 | 5.0.x 20 | 6.0.x 21 | 7.0.x 22 | 8.0.x 23 | 9.0.x 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | - name: Build 27 | run: dotnet build ./src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/ZNetCS.AspNetCore.Logging.EntityFrameworkCore.csproj --configuration Release 28 | - name: Test with dotnet for .NET 6.0 29 | run: dotnet test ./test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest.csproj --configuration Release 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | *.snupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.pfx 193 | *.publishsettings 194 | node_modules/ 195 | orleans.codegen.cs 196 | 197 | # Since there are multiple workflows, uncomment next line to ignore bower_components 198 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 199 | #bower_components/ 200 | 201 | # RIA/Silverlight projects 202 | Generated_Code/ 203 | 204 | # Backup & report files from converting an old project file 205 | # to a newer Visual Studio version. Backup files are not needed, 206 | # because we have git ;-) 207 | _UpgradeReport_Files/ 208 | Backup*/ 209 | UpgradeLog*.XML 210 | UpgradeLog*.htm 211 | 212 | # SQL Server files 213 | *.mdf 214 | *.ldf 215 | 216 | # Business Intelligence projects 217 | *.rdl.data 218 | *.bim.layout 219 | *.bim_*.settings 220 | 221 | # Microsoft Fakes 222 | FakesAssemblies/ 223 | 224 | # GhostDoc plugin setting file 225 | *.GhostDoc.xml 226 | 227 | # Node.js Tools for Visual Studio 228 | .ntvs_analysis.dat 229 | 230 | # Visual Studio 6 build log 231 | *.plg 232 | 233 | # Visual Studio 6 workspace options file 234 | *.opt 235 | 236 | # Visual Studio LightSwitch build output 237 | **/*.HTMLClient/GeneratedArtifacts 238 | **/*.DesktopClient/GeneratedArtifacts 239 | **/*.DesktopClient/ModelManifest.xml 240 | **/*.Server/GeneratedArtifacts 241 | **/*.Server/ModelManifest.xml 242 | _Pvt_Extensions 243 | 244 | # Paket dependency manager 245 | .paket/paket.exe 246 | paket-files/ 247 | 248 | # FAKE - F# Make 249 | .fake/ 250 | 251 | # JetBrains Rider 252 | .idea/ 253 | *.sln.iml 254 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 - 2022 Marcin Smółka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ZNetCS.AspNetCore.Logging.EntityFrameworkCore 2 | 3 | [![NuGet](https://img.shields.io/nuget/v/ZNetCS.AspNetCore.Logging.EntityFrameworkCore.svg)](https://www.nuget.org/packages/ZNetCS.AspNetCore.Logging.EntityFrameworkCore) 4 | [![Build](https://github.com/msmolka/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/workflows/build/badge.svg)](https://github.com/msmolka/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/actions) 5 | 6 | This is Entity Framework Core logger and logger provider. A small package to allow store logs in any data store using Entity Framework Core. It was prepared to use in ASP 7 | NET Core application, but it does not contain any references that prevents to use it in plain .NET Core application. 8 | 9 | As from version 2.0.2 there is silent error handling on logger SaveChanges(). To avoid Db error having impact on application. 10 | 11 | ## Installing 12 | 13 | Install using the [ZNetCS.AspNetCore.Logging.EntityFrameworkCore NuGet package](https://www.nuget.org/packages/ZNetCS.AspNetCore.Logging.EntityFrameworkCore) 14 | 15 | ``` 16 | PM> Install-Package ZNetCS.AspNetCore.Logging.EntityFrameworkCore 17 | ``` 18 | 19 | ## Usage 20 | 21 | When you install the package, it should be added to your `.csproj`. Alternatively, you can add it directly by adding: 22 | 23 | ```xml 24 | 25 | 26 | 27 | ``` 28 | 29 | ### .NET 6 30 | In order to use the IP filtering middleware, you must configure the services in the `Program.cs` file. 31 | 32 | ```c# 33 | // Add services to the container. 34 | builder.Logging.AddEntityFramework(); 35 | ``` 36 | 37 | 38 | ### .NET 5 and Below 39 | 40 | ```c# 41 | public static void Main(string[] args) 42 | { 43 | var webHost = new WebHostBuilder() 44 | // other code ommited to focus on logging settings 45 | .ConfigureLogging((hostingContext, logging) => 46 | { 47 | // other log providers 48 | // ... 49 | // 50 | logging.AddEntityFramework(); 51 | 52 | }) 53 | .UseStartup() 54 | .Build(); 55 | 56 | webHost.Run(); 57 | } 58 | 59 | ``` 60 | 61 | ### Important Notes 62 | 63 | In most case scenario you would not like add all logs from application to database. A lot of of them is jut debug/trace ones. In that case is better use filter before 64 | add `Logger`. This will also prevent some `StackOverflowException` when using this logger to log `EntityFrameworkCore` logs. 65 | 66 | ### .NET 6 67 | 68 | ```c# 69 | builder.Logging..AddFilter>("Microsoft", LogLevel.None); 70 | builder.Logging..AddFilter>("System", LogLevel.None); 71 | builder.Logging..AddEntityFramework(); 72 | ``` 73 | 74 | ### .NET 5 and Below 75 | 76 | ```c# 77 | public static void Main(string[] args) 78 | { 79 | var webHost = new WebHostBuilder() 80 | // other code ommited to focus on logging settings 81 | .ConfigureLogging((hostingContext, logging) => 82 | { 83 | // other log providers 84 | // ... 85 | // 86 | 87 | // because setting up filter inside code requires exact provider class, and EntityFrameworkLoggerProvider is generic class with multiple overrides 88 | // filters needs to applied properly to chosen provider 89 | logging.AddFilter>("Microsoft", LogLevel.None); 90 | logging.AddFilter>("System", LogLevel.None); 91 | logging.AddEntityFramework(); 92 | 93 | }) 94 | .UseStartup() 95 | .Build(); 96 | 97 | webHost.Run(); 98 | } 99 | ``` 100 | 101 | It is also possible to setting filters inside `appsettings.json` file. This provider is using `EntityFramework` alias. This way is recommended because there is no need to 102 | care about proper provider definition. 103 | 104 | ```json 105 | { 106 | "Logging": { 107 | "EntityFramework": { 108 | "LogLevel": { 109 | "Microsoft": "None", 110 | "System": "None" 111 | } 112 | } 113 | } 114 | } 115 | ``` 116 | 117 | ```c# 118 | public static void Main(string[] args) 119 | { 120 | var webHost = new WebHostBuilder() 121 | // other code ommited to focus on logging settings 122 | .ConfigureLogging((hostingContext, logging) => 123 | { 124 | logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); 125 | 126 | // other log providers 127 | // ... 128 | // 129 | 130 | logging.AddEntityFramework(); 131 | 132 | }) 133 | .UseStartup() 134 | .Build(); 135 | 136 | webHost.Run(); 137 | } 138 | ``` 139 | 140 | Then you need to setup your context to have access to log table e.g. 141 | 142 | ```c# 143 | using ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 144 | 145 | public class MyDbContext : DbContext 146 | { 147 | public MyDbContext(DbContextOptions options) : base(options) 148 | { 149 | } 150 | 151 | public DbSet Logs { get; set; } 152 | 153 | protected override void OnModelCreating(ModelBuilder modelBuilder) 154 | { 155 | base.OnModelCreating(modelBuilder); 156 | 157 | // build default model. 158 | LogModelBuilderHelper.Build(modelBuilder.Entity()); 159 | 160 | // real relation database can map table: 161 | modelBuilder.Entity().ToTable("Log"); 162 | } 163 | } 164 | ``` 165 | 166 | There is also possibility to extend base `Log` class. 167 | 168 | ```c# 169 | 170 | public class ExtendedLog : Log 171 | { 172 | public ExtendedLog(IHttpContextAccessor accessor) 173 | { 174 | string browser = accessor.HttpContext.Request.Headers["User-Agent"]; 175 | if (!string.IsNullOrEmpty(browser) && (browser.Length > 255)) 176 | { 177 | browser = browser.Substring(0, 255); 178 | } 179 | 180 | this.Browser = browser; 181 | this.Host = accessor.HttpContext.Connection?.RemoteIpAddress?.ToString(); 182 | this.User = accessor.HttpContext.User?.Identity?.Name; 183 | this.Path = accessor.HttpContext.Request.Path; 184 | } 185 | 186 | protected ExtendedLog() 187 | { 188 | } 189 | 190 | public string Browser { get; set; } 191 | public string Host { get; set; } 192 | public string Path { get; set; } 193 | public string User { get; set; } 194 | } 195 | ``` 196 | 197 | Change `MyDbContext` to use new extended log model 198 | 199 | ```c# 200 | public DbSet Logs => this.Set; 201 | ``` 202 | 203 | You can extend `ModelBuilder` as well: 204 | 205 | ```c# 206 | 207 | protected override void OnModelCreating(ModelBuilder modelBuilder) 208 | { 209 | base.OnModelCreating(modelBuilder); 210 | 211 | // build default model. 212 | LogModelBuilderHelper.Build(modelBuilder.Entity()); 213 | 214 | // real relation database can map table: 215 | modelBuilder.Entity().ToTable("Log"); 216 | 217 | modelBuilder.Entity().Property(r => r.Id).ValueGeneratedOnAdd(); 218 | 219 | modelBuilder.Entity().HasIndex(r => r.TimeStamp).HasName("IX_Log_TimeStamp"); 220 | modelBuilder.Entity().HasIndex(r => r.EventId).HasName("IX_Log_EventId"); 221 | modelBuilder.Entity().HasIndex(r => r.Level).HasName("IX_Log_Level"); 222 | 223 | modelBuilder.Entity().Property(u => u.Name).HasMaxLength(255); 224 | modelBuilder.Entity().Property(u => u.Browser).HasMaxLength(255); 225 | modelBuilder.Entity().Property(u => u.User).HasMaxLength(255); 226 | modelBuilder.Entity().Property(u => u.Host).HasMaxLength(255); 227 | modelBuilder.Entity().Property(u => u.Path).HasMaxLength(255); 228 | } 229 | 230 | ``` 231 | 232 | To use `IHttpContextAccessor` there is need to register it inside `ConfigureServices` call of `Startup`: 233 | 234 | ```c# 235 | 236 | public void ConfigureServices(IServiceCollection services) 237 | { 238 | // requires for http context access. 239 | services.AddSingleton(); 240 | } 241 | 242 | ``` 243 | 244 | Add extended log registration 245 | 246 | ```c# 247 | public static void Main(string[] args) 248 | { 249 | var webHost = new WebHostBuilder() 250 | // other code ommited to focus on logging settings 251 | .ConfigureLogging((hostingContext, logging) => 252 | { 253 | logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); 254 | 255 | // other log providers 256 | // ... 257 | // 258 | 259 | logging.AddEntityFramework(); 260 | 261 | }) 262 | .UseStartup() 263 | .Build(); 264 | 265 | webHost.Run(); 266 | } 267 | ``` 268 | 269 | There is also possibility to create new log model using custom creator method. This can be done by providing options during configuration. 270 | 271 | ```c# 272 | public static void Main(string[] args) 273 | { 274 | var webHost = new WebHostBuilder() 275 | // other code ommited to focus on logging settings 276 | .ConfigureLogging((hostingContext, logging) => 277 | { 278 | logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); 279 | 280 | // other log providers 281 | // ... 282 | // 283 | 284 | logging.AddEntityFramework( 285 | opts => 286 | { 287 | opts.Creator = (logLevel, eventId, name, message) => new Log 288 | { 289 | TimeStamp = DateTimeOffset.Now, 290 | Level = logLevel, 291 | EventId = eventId, 292 | Name = "This is my custom log", 293 | Message = message 294 | }; 295 | }); 296 | 297 | }) 298 | .UseStartup() 299 | .Build(); 300 | 301 | webHost.Run(); 302 | } 303 | ``` 304 | 305 | 306 | -------------------------------------------------------------------------------- /ZNetCS.AspNetCore.Logging.EntityFrameworkCore.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26228.4 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B87D0349-F666-4A78-B185-FD1FE1DFC3E6}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C85D4F1C-B540-489A-9ADB-D673C6C26F1D}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest", "test\ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest\ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest.csproj", "{FF8AC07F-C72F-41C9-9242-613B60FF7780}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZNetCS.AspNetCore.Logging.EntityFrameworkCore", "src\ZNetCS.AspNetCore.Logging.EntityFrameworkCore\ZNetCS.AspNetCore.Logging.EntityFrameworkCore.csproj", "{B7286E9E-E953-4D24-AE60-20AF4BD0BAEA}" 13 | EndProject 14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{D91CE32C-152A-4846-B25C-F8DF14AE3C6F}" 15 | ProjectSection(SolutionItems) = preProject 16 | src\Directory.Build.props = src\Directory.Build.props 17 | src\StrongNameKey.snk = src\StrongNameKey.snk 18 | EndProjectSection 19 | EndProject 20 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "config", "config", "{AF9B7179-5EBC-4B24-A209-E8E65738DDC7}" 21 | ProjectSection(SolutionItems) = preProject 22 | .editorconfig = .editorconfig 23 | .gitignore = .gitignore 24 | LICENSE = LICENSE 25 | README.md = README.md 26 | stylecop.json = stylecop.json 27 | EndProjectSection 28 | EndProject 29 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "pipelines", "pipelines", "{C8D4A1FB-8EC8-4367-8DFD-301523638B26}" 30 | ProjectSection(SolutionItems) = preProject 31 | .github\workflows\dotnetcore.yml = .github\workflows\dotnetcore.yml 32 | EndProjectSection 33 | EndProject 34 | Global 35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 36 | Debug|Any CPU = Debug|Any CPU 37 | Release|Any CPU = Release|Any CPU 38 | EndGlobalSection 39 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 40 | {FF8AC07F-C72F-41C9-9242-613B60FF7780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {FF8AC07F-C72F-41C9-9242-613B60FF7780}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {FF8AC07F-C72F-41C9-9242-613B60FF7780}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {FF8AC07F-C72F-41C9-9242-613B60FF7780}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {B7286E9E-E953-4D24-AE60-20AF4BD0BAEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {B7286E9E-E953-4D24-AE60-20AF4BD0BAEA}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {B7286E9E-E953-4D24-AE60-20AF4BD0BAEA}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {B7286E9E-E953-4D24-AE60-20AF4BD0BAEA}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(NestedProjects) = preSolution 53 | {FF8AC07F-C72F-41C9-9242-613B60FF7780} = {C85D4F1C-B540-489A-9ADB-D673C6C26F1D} 54 | {B7286E9E-E953-4D24-AE60-20AF4BD0BAEA} = {B87D0349-F666-4A78-B185-FD1FE1DFC3E6} 55 | EndGlobalSection 56 | EndGlobal 57 | -------------------------------------------------------------------------------- /src/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9.0.0 4 | Added support for .net core 7, 8, and 9 5 | 6 | 7 | 8 | ZNetCS.AspNetCore.Authentication.Basic 9 | ZNetCS.AspNetCore.Authentication.Basic 10 | This is Entity Framework Core logger and logger provider. A small package to allow store logs in any data store using Entity Framework Core. 11 | Marcin Smółka 12 | Marcin Smółka 13 | Copyright © Marcin Smółka 2016 - 2022 14 | Marcin Smółka zNET Computer Solutions 15 | 16 | 17 | 18 | ZNetCS.AspNetCore.Logging.EntityFrameworkCore 19 | aspnetcore;aspnetcoremvc;logging;loggerprovider;logger;asp.net;mvc;ef;entity-framework-core;entity framework core;netcore 20 | https://github.com/msmolka/ZNetCS.AspNetCore.Logging.EntityFrameworkCore 21 | LICENSE 22 | README.md 23 | git 24 | https://github.com/msmolka/ZNetCS.AspNetCore.Logging.EntityFrameworkCore 25 | true 26 | 27 | 28 | 29 | true 30 | ..\StrongNameKey.snk 31 | 32 | 33 | 34 | true 35 | enable 36 | latest 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | all 49 | runtime; build; native; contentfiles; analyzers; buildtransitive 50 | 51 | 52 | all 53 | runtime; build; native; contentfiles; analyzers; buildtransitive 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /src/StrongNameKey.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msmolka/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/5b986e82ef47826fa5d6870116c90ae6727b3f43/src/StrongNameKey.snk -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/EntityFrameworkLogger.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // Represents a new instance of an entity framework logger for the specified log. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 11 | 12 | #region Usings 13 | 14 | using System; 15 | using System.Diagnostics.CodeAnalysis; 16 | 17 | using Microsoft.EntityFrameworkCore; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// Represents a new instance of an entity framework logger for the specified log. 25 | /// 26 | /// 27 | /// The type of the data context class used to access the store. 28 | /// 29 | public class EntityFrameworkLogger : EntityFrameworkLogger 30 | where TContext : DbContext 31 | { 32 | #region Constructors and Destructors 33 | 34 | /// 35 | /// Initializes a new instance of the class. 36 | /// 37 | /// 38 | /// The service provider to resolve dependency. 39 | /// 40 | /// 41 | /// The name of the logger. 42 | /// 43 | /// 44 | /// The function used to filter events based on the log level. 45 | /// 46 | /// 47 | /// The creator used to create new instance of log. 48 | /// 49 | public EntityFrameworkLogger( 50 | IServiceProvider serviceProvider, 51 | string name, 52 | Func filter, 53 | Func? creator = null) 54 | : base(serviceProvider, name, filter, creator) 55 | { 56 | } 57 | 58 | #endregion 59 | } 60 | 61 | /// 62 | /// Represents a new instance of an entity framework logger for the specified log. 63 | /// 64 | /// 65 | /// The type of the data context class used to access the store. 66 | /// 67 | /// 68 | /// The type representing a log. 69 | /// 70 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 71 | [SuppressMessage("ReSharper", "MemberCanBeProtected.Global", Justification = "Public API")] 72 | public class EntityFrameworkLogger : EntityFrameworkLogger 73 | where TContext : DbContext 74 | where TLog : Log 75 | { 76 | #region Constructors and Destructors 77 | 78 | /// 79 | /// Initializes a new instance of the class. 80 | /// 81 | /// 82 | /// The service provider to resolve dependency. 83 | /// 84 | /// 85 | /// The name of the logger. 86 | /// 87 | /// 88 | /// The function used to filter events based on the log level. 89 | /// 90 | /// 91 | /// The creator used to create new instance of log. 92 | /// 93 | public EntityFrameworkLogger( 94 | IServiceProvider serviceProvider, 95 | string name, 96 | Func filter, 97 | Func? creator = null) 98 | : base(serviceProvider, name, filter, creator) 99 | { 100 | } 101 | 102 | #endregion 103 | } 104 | 105 | /// 106 | /// Represents a new instance of an entity framework logger for the specified log. 107 | /// 108 | /// 109 | /// The type of the data context class used to access the store. 110 | /// 111 | /// 112 | /// The type representing a log. 113 | /// 114 | /// 115 | /// The type of the primary key for a log. 116 | /// 117 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 118 | public class EntityFrameworkLogger : ILogger 119 | where TContext : DbContext 120 | where TLog : Log 121 | where TKey : IEquatable 122 | { 123 | #region Fields 124 | 125 | /// 126 | /// The function used to filter events based on the log level. 127 | /// 128 | private readonly Func filter; 129 | 130 | /// 131 | /// The service provider to resolve dependency. 132 | /// 133 | private readonly IServiceProvider serviceProvider; 134 | 135 | #endregion 136 | 137 | #region Constructors and Destructors 138 | 139 | /// 140 | /// Initializes a new instance of the class. 141 | /// 142 | /// 143 | /// The service provider to resolve dependency. 144 | /// 145 | /// 146 | /// The name of the logger. 147 | /// 148 | /// 149 | /// The function used to filter events based on the log level. 150 | /// 151 | /// 152 | /// The creator used to create new instance of log. 153 | /// 154 | [SuppressMessage("ReSharper", "MemberCanBeProtected.Global", Justification = "Public API")] 155 | public EntityFrameworkLogger( 156 | IServiceProvider? serviceProvider, 157 | string? name, 158 | Func? filter, 159 | Func? creator = null) 160 | { 161 | this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); 162 | this.filter = filter ?? throw new ArgumentNullException(nameof(filter)); 163 | 164 | this.Name = name ?? string.Empty; 165 | this.Creator = creator ?? this.DefaultCreator; 166 | } 167 | 168 | #endregion 169 | 170 | #region Properties 171 | 172 | /// 173 | /// Gets the function used to create new model instance for a log. 174 | /// 175 | protected virtual Func Creator { get; } 176 | 177 | /// 178 | /// Gets the name of the logger. 179 | /// 180 | protected virtual string Name { get; } 181 | 182 | #endregion 183 | 184 | #region Implemented Interfaces 185 | 186 | #region ILogger 187 | 188 | /// 189 | public virtual bool IsEnabled(LogLevel logLevel) 190 | { 191 | // internal check to not log any Microsoft.EntityFrameworkCore. It won't work any way and cause StackOverflowException 192 | if (this.Name.StartsWith("Microsoft.EntityFrameworkCore", StringComparison.OrdinalIgnoreCase)) 193 | { 194 | return false; 195 | } 196 | 197 | return (logLevel != LogLevel.None) && this.filter(this.Name, logLevel); 198 | } 199 | 200 | /// 201 | #pragma warning disable CS8633 202 | public IDisposable BeginScope(TState state) where TState : notnull => NoopDisposable.Instance; 203 | #pragma warning restore CS8633 204 | 205 | /// 206 | public virtual void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) 207 | { 208 | if (!this.IsEnabled(logLevel)) 209 | { 210 | return; 211 | } 212 | 213 | if (formatter == null) 214 | { 215 | throw new ArgumentNullException(nameof(formatter)); 216 | } 217 | 218 | string message = formatter(state, exception); 219 | 220 | if (string.IsNullOrEmpty(message)) 221 | { 222 | return; 223 | } 224 | 225 | message = $"{message}"; 226 | 227 | if (exception != null) 228 | { 229 | message += $"{Environment.NewLine}{Environment.NewLine}{exception}"; 230 | } 231 | 232 | this.WriteMessage(message, logLevel, eventId.Id); 233 | } 234 | 235 | #endregion 236 | 237 | #endregion 238 | 239 | #region Methods 240 | 241 | /// 242 | /// Writes message to database. 243 | /// 244 | /// 245 | /// The message to write. 246 | /// 247 | /// 248 | /// The log level to write. 249 | /// 250 | /// 251 | /// The event id to write. 252 | /// 253 | [SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Saving log should never throw error.")] 254 | protected virtual void WriteMessage(string message, LogLevel logLevel, int eventId) 255 | { 256 | // create separate scope for DbContextOptions and DbContext 257 | using IServiceScope scope = this.serviceProvider.CreateScope(); 258 | 259 | // create separate DbContext for adding log 260 | // normally we should rely on scope context, but in rare scenarios when DbContext is 261 | // registered as singleton, we should avoid this. 262 | using var context = ActivatorUtilities.CreateInstance(scope.ServiceProvider); 263 | 264 | // create new log with resolving dependency injection 265 | TLog log = this.Creator((int)logLevel, eventId, this.Name, message); 266 | 267 | context.Set().Add(log); 268 | 269 | try 270 | { 271 | context.SaveChanges(); 272 | } 273 | catch 274 | { 275 | // if db cannot save error we should ignore it. To not cause additional connection errors. 276 | } 277 | } 278 | 279 | /// 280 | /// The default log creator method. 281 | /// 282 | /// 283 | /// The log level. 284 | /// 285 | /// 286 | /// The event id. 287 | /// 288 | /// 289 | /// The log name. 290 | /// 291 | /// 292 | /// The message. 293 | /// 294 | private TLog DefaultCreator(int logLevel, int eventId, string logName, string message) 295 | { 296 | // create separate scope for Scope registered dependencies. 297 | using IServiceScope scope = this.serviceProvider.CreateScope(); 298 | var log = ActivatorUtilities.CreateInstance(scope.ServiceProvider); 299 | 300 | log.TimeStamp = DateTimeOffset.Now; 301 | log.Level = logLevel; 302 | log.EventId = eventId; 303 | log.Name = logName.Length > 255 ? logName[..255] : logName; 304 | log.Message = message; 305 | 306 | return log; 307 | } 308 | 309 | #endregion 310 | 311 | #region Nested Classes 312 | 313 | #region NoopDisposable 314 | 315 | /// 316 | /// The noop disposable. 317 | /// 318 | [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "OK")] 319 | private class NoopDisposable : IDisposable 320 | { 321 | #region Static Fields 322 | 323 | /// 324 | /// The instance. 325 | /// 326 | public static readonly NoopDisposable Instance = new(); 327 | 328 | #endregion 329 | 330 | #region Implemented Interfaces 331 | 332 | #region IDisposable 333 | 334 | /// 335 | /// The dispose. 336 | /// 337 | public void Dispose() 338 | { 339 | } 340 | 341 | #endregion 342 | 343 | #endregion 344 | } 345 | 346 | #endregion 347 | 348 | #endregion 349 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/EntityFrameworkLoggerBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The entity framework logger builder extensions. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | // ReSharper disable once CheckNamespace 11 | namespace Microsoft.Extensions.Logging; 12 | 13 | #region Usings 14 | 15 | using System; 16 | using System.Diagnostics.CodeAnalysis; 17 | 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.Extensions.DependencyInjection; 20 | using Microsoft.Extensions.DependencyInjection.Extensions; 21 | using Microsoft.Extensions.Logging; 22 | 23 | using ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 24 | 25 | #endregion 26 | 27 | /// 28 | /// The entity framework logger builder extensions. 29 | /// 30 | [SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Public API")] 31 | public static class EntityFrameworkLoggerBuilderExtensions 32 | { 33 | #region Public Methods 34 | 35 | /// 36 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 37 | /// 38 | /// 39 | /// The to use. 40 | /// 41 | /// 42 | /// The type of the data context class used to access the store. 43 | /// 44 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder) where TContext : DbContext 45 | { 46 | if (builder == null) 47 | { 48 | throw new ArgumentNullException(nameof(builder)); 49 | } 50 | 51 | builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>()); 52 | 53 | return builder; 54 | } 55 | 56 | /// 57 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 58 | /// 59 | /// 60 | /// The to use. 61 | /// 62 | /// 63 | /// The configuration delegate. 64 | /// 65 | /// 66 | /// The type of the data context class used to access the store. 67 | /// 68 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder, Action configure) 69 | where TContext : DbContext 70 | { 71 | if (configure == null) 72 | { 73 | throw new ArgumentNullException(nameof(configure)); 74 | } 75 | 76 | builder.AddEntityFramework(); 77 | builder.Services.Configure(configure); 78 | 79 | return builder; 80 | } 81 | 82 | /// 83 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 84 | /// 85 | /// 86 | /// The to use. 87 | /// 88 | /// 89 | /// The type of the data context class used to access the store. 90 | /// 91 | /// 92 | /// The type representing a log. 93 | /// 94 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder) 95 | where TContext : DbContext 96 | where TLog : Log 97 | { 98 | if (builder == null) 99 | { 100 | throw new ArgumentNullException(nameof(builder)); 101 | } 102 | 103 | builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>()); 104 | 105 | return builder; 106 | } 107 | 108 | /// 109 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 110 | /// 111 | /// 112 | /// The to use. 113 | /// 114 | /// 115 | /// The configuration delegate. 116 | /// 117 | /// 118 | /// The type of the data context class used to access the store. 119 | /// 120 | /// 121 | /// The type representing a log. 122 | /// 123 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder, Action> configure) 124 | where TContext : DbContext 125 | where TLog : Log 126 | { 127 | if (configure == null) 128 | { 129 | throw new ArgumentNullException(nameof(configure)); 130 | } 131 | 132 | builder.AddEntityFramework(); 133 | builder.Services.Configure(configure); 134 | 135 | return builder; 136 | } 137 | 138 | /// 139 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 140 | /// 141 | /// 142 | /// The to use. 143 | /// 144 | /// 145 | /// The type of the data context class used to access the store. 146 | /// 147 | /// 148 | /// The type representing a log. 149 | /// 150 | /// 151 | /// The type of the entity framework logger class used to log. 152 | /// 153 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder) 154 | where TContext : DbContext 155 | where TLog : Log 156 | where TLogger : EntityFrameworkLogger 157 | { 158 | if (builder == null) 159 | { 160 | throw new ArgumentNullException(nameof(builder)); 161 | } 162 | 163 | builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>()); 164 | 165 | return builder; 166 | } 167 | 168 | /// 169 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 170 | /// 171 | /// 172 | /// The to use. 173 | /// 174 | /// 175 | /// The configuration delegate. 176 | /// 177 | /// 178 | /// The type of the data context class used to access the store. 179 | /// 180 | /// 181 | /// The type representing a log. 182 | /// 183 | /// 184 | /// The type of the entity framework logger class used to log. 185 | /// 186 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder, Action> configure) 187 | where TContext : DbContext 188 | where TLog : Log 189 | where TLogger : EntityFrameworkLogger 190 | { 191 | if (configure == null) 192 | { 193 | throw new ArgumentNullException(nameof(configure)); 194 | } 195 | 196 | builder.AddEntityFramework(); 197 | builder.Services.Configure(configure); 198 | 199 | return builder; 200 | } 201 | 202 | /// 203 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 204 | /// 205 | /// 206 | /// The to use. 207 | /// 208 | /// 209 | /// The type of the data context class used to access the store. 210 | /// 211 | /// 212 | /// The type representing a log. 213 | /// 214 | /// 215 | /// The type of the entity framework logger class used to log. 216 | /// 217 | /// 218 | /// The type of the primary key for a log. 219 | /// 220 | public static ILoggingBuilder AddEntityFramework(this ILoggingBuilder builder) 221 | where TContext : DbContext 222 | where TLog : Log 223 | where TLogger : EntityFrameworkLogger 224 | where TKey : IEquatable 225 | { 226 | if (builder == null) 227 | { 228 | throw new ArgumentNullException(nameof(builder)); 229 | } 230 | 231 | builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton>()); 232 | 233 | return builder; 234 | } 235 | 236 | /// 237 | /// Adds a entity framework logger named 'EntityFramework' to the factory. 238 | /// 239 | /// 240 | /// The to use. 241 | /// 242 | /// 243 | /// The configuration delegate. 244 | /// 245 | /// 246 | /// The type of the data context class used to access the store. 247 | /// 248 | /// 249 | /// The type representing a log. 250 | /// 251 | /// 252 | /// The type of the entity framework logger class used to log. 253 | /// 254 | /// 255 | /// The type of the primary key for a log. 256 | /// 257 | public static ILoggingBuilder AddEntityFramework( 258 | this ILoggingBuilder builder, 259 | Action> configure) 260 | where TContext : DbContext 261 | where TLog : Log 262 | where TLogger : EntityFrameworkLogger 263 | where TKey : IEquatable 264 | { 265 | if (configure == null) 266 | { 267 | throw new ArgumentNullException(nameof(configure)); 268 | } 269 | 270 | builder.AddEntityFramework(); 271 | builder.Services.Configure(configure); 272 | 273 | return builder; 274 | } 275 | 276 | #endregion 277 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/EntityFrameworkLoggerOptions.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The entity framework logger options. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 11 | 12 | #region Usings 13 | 14 | using System; 15 | using System.Diagnostics.CodeAnalysis; 16 | 17 | #endregion 18 | 19 | /// 20 | /// The entity framework logger options. 21 | /// 22 | public class EntityFrameworkLoggerOptions : EntityFrameworkLoggerOptions 23 | { 24 | } 25 | 26 | /// 27 | /// The entity framework logger options. 28 | /// 29 | /// 30 | /// The log model type. 31 | /// 32 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 33 | [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Public API")] 34 | public class EntityFrameworkLoggerOptions 35 | { 36 | #region Public Properties 37 | 38 | /// 39 | /// Gets or sets the creator. 40 | /// 41 | public Func? Creator { get; set; } 42 | 43 | #endregion 44 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/EntityFrameworkLoggerProvider.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // Defines the EntityFrameworkLoggerProvider type. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 11 | 12 | #region Usings 13 | 14 | using System; 15 | using System.Diagnostics.CodeAnalysis; 16 | 17 | using Microsoft.EntityFrameworkCore; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | using Microsoft.Extensions.Options; 21 | 22 | #endregion 23 | 24 | /// 25 | [ProviderAlias("EntityFramework")] 26 | [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Public API")] 27 | public class EntityFrameworkLoggerProvider : EntityFrameworkLoggerProvider 28 | where TContext : DbContext 29 | { 30 | #region Constructors and Destructors 31 | 32 | /// 33 | /// Initializes a new instance of the class. 34 | /// 35 | /// 36 | /// The service provider to resolve dependency. 37 | /// 38 | /// 39 | /// The filter used to filter log messages. 40 | /// 41 | /// 42 | /// The creator used to create new instance of log. 43 | /// 44 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, Func filter, Func? creator = null) 45 | : base(serviceProvider, filter, creator) 46 | { 47 | } 48 | 49 | /// 50 | /// Initializes a new instance of the class. 51 | /// 52 | /// 53 | /// The service provider. 54 | /// 55 | /// 56 | /// The options. 57 | /// 58 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, IOptions options) : base(serviceProvider, options) 59 | { 60 | } 61 | 62 | #endregion 63 | } 64 | 65 | /// 66 | [ProviderAlias("EntityFramework")] 67 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 68 | [SuppressMessage("ReSharper", "MemberCanBeProtected.Global", Justification = "Public API")] 69 | public class EntityFrameworkLoggerProvider : EntityFrameworkLoggerProvider> 70 | where TLog : Log 71 | where TContext : DbContext 72 | { 73 | #region Constructors and Destructors 74 | 75 | /// 76 | /// Initializes a new instance of the class. 77 | /// 78 | /// 79 | /// The service provider to resolve dependency. 80 | /// 81 | /// 82 | /// The filter used to filter log messages. 83 | /// 84 | /// 85 | /// The creator used to create new instance of log. 86 | /// 87 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, Func filter, Func? creator = null) 88 | : base(serviceProvider, filter, creator) 89 | { 90 | } 91 | 92 | /// 93 | /// Initializes a new instance of the class. 94 | /// 95 | /// 96 | /// The service provider. 97 | /// 98 | /// 99 | /// The options. 100 | /// 101 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, IOptions> options) : base(serviceProvider, options) 102 | { 103 | } 104 | 105 | #endregion 106 | } 107 | 108 | /// 109 | [ProviderAlias("EntityFramework")] 110 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 111 | [SuppressMessage("ReSharper", "MemberCanBeProtected.Global", Justification = "Public API")] 112 | public class EntityFrameworkLoggerProvider : EntityFrameworkLoggerProvider 113 | where TLogger : EntityFrameworkLogger 114 | where TContext : DbContext 115 | where TLog : Log 116 | { 117 | #region Constructors and Destructors 118 | 119 | /// 120 | /// Initializes a new instance of the class. 121 | /// 122 | /// 123 | /// The service provider to resolve dependency. 124 | /// 125 | /// 126 | /// The filter used to filter log messages. 127 | /// 128 | /// 129 | /// The creator used to create new instance of log. 130 | /// 131 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, Func filter, Func? creator = null) 132 | : base(serviceProvider, filter, creator) 133 | { 134 | } 135 | 136 | /// 137 | /// Initializes a new instance of the class. 138 | /// 139 | /// 140 | /// The service provider. 141 | /// 142 | /// 143 | /// The options. 144 | /// 145 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, IOptions> options) : base(serviceProvider, options) 146 | { 147 | } 148 | 149 | #endregion 150 | } 151 | 152 | /// 153 | /// Represents a new instance of an entity framework logger provider for the specified log. 154 | /// 155 | /// 156 | /// The type of the data context class used to access the store. 157 | /// 158 | /// 159 | /// The type representing a log. 160 | /// 161 | /// 162 | /// The type of the entity framework logger class used to log. 163 | /// 164 | /// 165 | /// The type of the primary key for a log. 166 | /// 167 | [ProviderAlias("EntityFramework")] 168 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 169 | [SuppressMessage("ReSharper", "MemberCanBeProtected.Global", Justification = "Public API")] 170 | public class EntityFrameworkLoggerProvider : EntityFrameworkLoggerProviderBase 171 | where TContext : DbContext 172 | where TLog : Log 173 | where TLogger : EntityFrameworkLogger 174 | where TKey : IEquatable 175 | { 176 | #region Fields 177 | 178 | /// 179 | /// The function used to create new model instance for a log. 180 | /// 181 | private readonly Func? creator; 182 | 183 | /// 184 | /// The object factory to create new logger used defined types. 185 | /// 186 | private readonly ObjectFactory factory; 187 | 188 | /// 189 | /// The function used to filter events based on the log level. 190 | /// 191 | private readonly Func filter; 192 | 193 | /// 194 | /// The service provider to resolve dependency. 195 | /// 196 | private readonly IServiceProvider serviceProvider; 197 | 198 | #endregion 199 | 200 | #region Constructors and Destructors 201 | 202 | /// 203 | /// Initializes a new instance of the class. 204 | /// 205 | /// 206 | /// The service provider to resolve dependency. 207 | /// 208 | /// 209 | /// The filter used to filter log messages. 210 | /// 211 | /// 212 | /// The creator used to create new instance of log. 213 | /// 214 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, Func filter, Func? creator = null) 215 | { 216 | this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); 217 | this.filter = filter ?? throw new ArgumentNullException(nameof(filter)); 218 | this.creator = creator; 219 | this.factory = ActivatorUtilities.CreateFactory( 220 | typeof(TLogger), 221 | new[] { typeof(string), typeof(Func), typeof(Func) }); 222 | } 223 | 224 | /// 225 | /// Initializes a new instance of the class. 226 | /// 227 | /// 228 | /// The service provider. 229 | /// 230 | /// 231 | /// The options. 232 | /// 233 | public EntityFrameworkLoggerProvider(IServiceProvider serviceProvider, IOptions> options) 234 | { 235 | if (options == null) 236 | { 237 | throw new ArgumentNullException(nameof(options)); 238 | } 239 | 240 | this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); 241 | 242 | // Filter would be applied on LoggerFactory level 243 | this.filter = TrueFilter; 244 | this.creator = options.Value.Creator; 245 | this.factory = ActivatorUtilities.CreateFactory( 246 | typeof(TLogger), 247 | new[] { typeof(string), typeof(Func), typeof(Func) }); 248 | } 249 | 250 | #endregion 251 | 252 | #region Public Methods 253 | 254 | /// 255 | public override ILogger CreateLogger(string categoryName) 256 | { 257 | this.ThrowIfDisposed(); 258 | return (ILogger)this.factory(this.serviceProvider, new object?[] { categoryName, this.filter, this.creator }); 259 | } 260 | 261 | #endregion 262 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/EntityFrameworkLoggerProviderBase.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The entity framework logger provider base. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 11 | 12 | #region Usings 13 | 14 | using System; 15 | 16 | using Microsoft.Extensions.Logging; 17 | 18 | #endregion 19 | 20 | /// 21 | /// The entity framework logger provider base. 22 | /// 23 | public abstract class EntityFrameworkLoggerProviderBase : ILoggerProvider 24 | { 25 | #region Static Fields 26 | 27 | /// 28 | /// The true filter. 29 | /// 30 | protected static readonly Func TrueFilter = (_, _) => true; 31 | 32 | #endregion 33 | 34 | #region Fields 35 | 36 | /// 37 | /// The disposed flag. 38 | /// 39 | private bool disposed; 40 | 41 | #endregion 42 | 43 | #region Implemented Interfaces 44 | 45 | #region IDisposable 46 | 47 | /// 48 | public void Dispose() 49 | { 50 | this.Dispose(true); 51 | GC.SuppressFinalize(this); 52 | } 53 | 54 | #endregion 55 | 56 | #region ILoggerProvider 57 | 58 | /// 59 | public abstract ILogger CreateLogger(string categoryName); 60 | 61 | #endregion 62 | 63 | #endregion 64 | 65 | #region Methods 66 | 67 | /// 68 | /// Clean up any resources being used. 69 | /// 70 | /// 71 | /// True if managed resources should be disposed; otherwise, false. 72 | /// 73 | protected virtual void Dispose(bool disposing) 74 | { 75 | this.disposed = true; 76 | } 77 | 78 | /// 79 | /// Throws if this class has been disposed. 80 | /// 81 | protected void ThrowIfDisposed() 82 | { 83 | if (this.disposed) 84 | { 85 | throw new ObjectDisposedException(this.GetType().Name); 86 | } 87 | } 88 | 89 | #endregion 90 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/Log.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // ----------------------------------------------------------------------- 6 | 7 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 8 | 9 | #region Usings 10 | 11 | using System; 12 | using System.Diagnostics.CodeAnalysis; 13 | 14 | #endregion 15 | 16 | /// 17 | /// The default implementation of which uses a integer as a primary key. 18 | /// 19 | [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Public API")] 20 | public class Log : Log 21 | { 22 | } 23 | 24 | /// 25 | /// Represents a log in the logging database. 26 | /// 27 | /// 28 | /// The type used for the primary key for the log. 29 | /// 30 | [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "OK")] 31 | [SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global", Justification = "Public API")] 32 | public class Log where TKey : IEquatable 33 | { 34 | #region Public Properties 35 | 36 | /// 37 | /// Gets or sets the event id. 38 | /// 39 | public virtual int EventId { get; set; } 40 | 41 | /// 42 | /// Gets or sets the primary key for this log. 43 | /// 44 | public virtual TKey Id { get; set; } = default!; 45 | 46 | /// 47 | /// Gets or sets the level. 48 | /// 49 | public virtual int Level { get; set; } 50 | 51 | /// 52 | /// Gets or sets the message. 53 | /// 54 | public virtual string Message { get; set; } = default!; 55 | 56 | /// 57 | /// Gets or sets the name. 58 | /// 59 | public virtual string Name { get; set; } = default!; 60 | 61 | /// 62 | /// Gets or sets the time stamp. 63 | /// 64 | public virtual DateTimeOffset TimeStamp { get; set; } 65 | 66 | #endregion 67 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/LogModelBuilderHelper.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The model builder helper. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 11 | 12 | #region Usings 13 | 14 | using System; 15 | using System.Diagnostics.CodeAnalysis; 16 | 17 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 18 | 19 | #endregion 20 | 21 | /// 22 | /// The model builder helper. 23 | /// 24 | [SuppressMessage("ReSharper", "MemberCanBePrivate.Global", Justification = "Public API")] 25 | public static class LogModelBuilderHelper 26 | { 27 | #region Public Methods 28 | 29 | /// 30 | /// The build helper method. 31 | /// 32 | /// 33 | /// The builder. 34 | /// 35 | public static void Build(EntityTypeBuilder builder) 36 | { 37 | Build(builder); 38 | } 39 | 40 | /// 41 | /// The build helper method. 42 | /// 43 | /// 44 | /// The builder. 45 | /// 46 | /// 47 | /// The type representing a log. 48 | /// 49 | public static void Build(EntityTypeBuilder builder) 50 | where TLog : Log 51 | { 52 | Build(builder); 53 | } 54 | 55 | /// 56 | /// The build helper method. 57 | /// 58 | /// 59 | /// The builder. 60 | /// 61 | /// 62 | /// The type representing a log. 63 | /// 64 | /// 65 | /// The type of the primary key for a log. 66 | /// 67 | public static void Build(EntityTypeBuilder builder) 68 | where TLog : Log 69 | where TKey : IEquatable 70 | { 71 | if (builder == null) 72 | { 73 | throw new ArgumentNullException(nameof(builder)); 74 | } 75 | 76 | builder.HasKey(r => r.Id); 77 | 78 | builder.Property(r => r.Name).HasMaxLength(255); 79 | } 80 | 81 | #endregion 82 | } -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // AssemblyInfo.cs 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | #region Usings 11 | 12 | using System.Runtime.InteropServices; 13 | 14 | #endregion 15 | 16 | [assembly: Guid("f56f98eb-7a88-4f81-ac08-e06f8265b142")] -------------------------------------------------------------------------------- /src/ZNetCS.AspNetCore.Logging.EntityFrameworkCore/ZNetCS.AspNetCore.Logging.EntityFrameworkCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ZNetCS.AspNetCore.Logging.EntityFrameworkCore 5 | netcoreapp3.1;net6.0;net7.0;net8.0;net9.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /stylecop.json: -------------------------------------------------------------------------------- 1 | { 2 | // ACTION REQUIRED: This file was automatically added to your project, but it 3 | // will not take effect until additional steps are taken to enable it. See the 4 | // following page for additional information: 5 | // 6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md 7 | 8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", 9 | "settings": { 10 | "documentationRules": { 11 | "companyName": "Marcin Smółka", 12 | "copyrightText": "Copyright (c) {companyName}. All rights reserved.", 13 | "headerDecoration": "-----------------------------------------------------------------------" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/ContextExtended.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The context. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | using Microsoft.EntityFrameworkCore; 17 | 18 | using ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 19 | 20 | #endregion 21 | 22 | /// 23 | /// The context. 24 | /// 25 | public class ContextExtended : DbContext 26 | { 27 | #region Constructors and Destructors 28 | 29 | /// 30 | /// Initializes a new instance of the class. 31 | /// 32 | /// 33 | /// The options. 34 | /// 35 | public ContextExtended(DbContextOptions options) : base(options) 36 | { 37 | } 38 | 39 | #endregion 40 | 41 | #region Public Properties 42 | 43 | /// 44 | /// Gets the logs. 45 | /// 46 | public DbSet Logs => this.Set(); 47 | 48 | #endregion 49 | 50 | #region Methods 51 | 52 | /// 53 | /// The on model creating. 54 | /// 55 | /// 56 | /// The model builder. 57 | /// 58 | protected override void OnModelCreating(ModelBuilder modelBuilder) 59 | { 60 | base.OnModelCreating(modelBuilder); 61 | 62 | // build default model. 63 | LogModelBuilderHelper.Build(modelBuilder.Entity()); 64 | 65 | // real relation database can map table: 66 | // modelBuilder.Entity().ToTable("Log"); 67 | } 68 | 69 | #endregion 70 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/ContextSimple.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The context. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using Microsoft.EntityFrameworkCore; 15 | 16 | using ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 17 | 18 | #endregion 19 | 20 | /// 21 | /// The context. 22 | /// 23 | public class ContextSimple : DbContext 24 | { 25 | #region Constructors and Destructors 26 | 27 | /// 28 | /// Initializes a new instance of the class. 29 | /// 30 | /// 31 | /// The options. 32 | /// 33 | public ContextSimple(DbContextOptions options) : base(options) 34 | { 35 | } 36 | 37 | #endregion 38 | 39 | #region Public Properties 40 | 41 | /// 42 | /// Gets the logs. 43 | /// 44 | public DbSet Logs => this.Set(); 45 | 46 | #endregion 47 | 48 | #region Methods 49 | 50 | /// 51 | /// The on model creating. 52 | /// 53 | /// 54 | /// The model builder. 55 | /// 56 | protected override void OnModelCreating(ModelBuilder modelBuilder) 57 | { 58 | base.OnModelCreating(modelBuilder); 59 | 60 | // build default model. 61 | LogModelBuilderHelper.Build(modelBuilder.Entity()); 62 | 63 | // real relation database can map table: 64 | // modelBuilder.Entity().ToTable("Log"); 65 | } 66 | 67 | #endregion 68 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/ExtendedLog.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The extended log. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Diagnostics.CodeAnalysis; 15 | 16 | using Microsoft.AspNetCore.Http; 17 | 18 | using ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 19 | 20 | #endregion 21 | 22 | /// 23 | /// The extended log. 24 | /// 25 | [SuppressMessage("ReSharper", "ClassNeverInstantiated.Global", Justification = "Test")] 26 | public class ExtendedLog : Log 27 | { 28 | #region Constructors and Destructors 29 | 30 | /// 31 | /// Initializes a new instance of the class. 32 | /// 33 | /// 34 | /// The accessor. 35 | /// 36 | public ExtendedLog(IHttpContextAccessor accessor) 37 | { 38 | this.Browser = "Test Browser"; 39 | this.Host = "localhost"; 40 | this.User = "Test User"; 41 | this.Path = accessor.HttpContext?.Request.Path; 42 | } 43 | 44 | /// 45 | /// Initializes a new instance of the class. 46 | /// 47 | protected ExtendedLog() 48 | { 49 | } 50 | 51 | #endregion 52 | 53 | #region Public Properties 54 | 55 | /// 56 | /// Gets or sets the browser. 57 | /// 58 | public string? Browser { get; set; } 59 | 60 | /// 61 | /// Gets or sets the host. 62 | /// 63 | public string? Host { get; set; } 64 | 65 | /// 66 | /// Gets or sets the path. 67 | /// 68 | public string? Path { get; set; } 69 | 70 | /// 71 | /// Gets or sets the user. 72 | /// 73 | public string? User { get; set; } 74 | 75 | #endregion 76 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/Startup.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // ----------------------------------------------------------------------- 6 | 7 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 8 | 9 | #region Usings 10 | 11 | using System; 12 | 13 | using Microsoft.AspNetCore.Builder; 14 | using Microsoft.AspNetCore.Hosting; 15 | using Microsoft.AspNetCore.Http; 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// The startup. 25 | /// 26 | public class Startup 27 | { 28 | #region Public Methods 29 | 30 | /// 31 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 32 | /// 33 | /// 34 | /// The application builder. 35 | /// 36 | /// 37 | /// The logger factory. 38 | /// 39 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 40 | { 41 | } 42 | 43 | /// 44 | /// This method gets called by the runtime. Use this method to add services to the container. 45 | /// 46 | /// 47 | /// The service collection. 48 | /// 49 | public void ConfigureServices(IServiceCollection services) 50 | { 51 | } 52 | 53 | #endregion 54 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderExtended.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using Microsoft.AspNetCore.Builder; 15 | using Microsoft.AspNetCore.Http; 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// The startup. 25 | /// 26 | public class StartupBuilderExtended 27 | { 28 | #region Static Fields 29 | 30 | /// 31 | /// The memory root. 32 | /// 33 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 34 | 35 | #endregion 36 | 37 | #region Public Methods 38 | 39 | /// 40 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | /// 42 | /// 43 | /// The application builder. 44 | /// 45 | /// 46 | /// The logger factory. 47 | /// 48 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 49 | { 50 | ILogger logger = loggerFactory.CreateLogger("Configure"); 51 | app.Use( 52 | async (_, next) => 53 | { 54 | logger.LogInformation(1, "Handling request"); 55 | await next.Invoke(); 56 | logger.LogInformation(2, "Finished handling request"); 57 | }); 58 | 59 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 60 | } 61 | 62 | /// 63 | /// This method gets called by the runtime. Use this method to add services to the container. 64 | /// 65 | /// 66 | /// The service collection. 67 | /// 68 | public void ConfigureServices(IServiceCollection services) 69 | { 70 | // Add framework services. 71 | services.AddDbContext(options => options.UseInMemoryDatabase("ExtendedLogDatabase", MemoryRoot)); 72 | 73 | // requires for http context access. 74 | services.AddSingleton(); 75 | } 76 | 77 | #endregion 78 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderExtendedSettings.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System; 15 | 16 | using Microsoft.AspNetCore.Builder; 17 | using Microsoft.AspNetCore.Http; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Storage; 20 | using Microsoft.Extensions.DependencyInjection; 21 | using Microsoft.Extensions.Logging; 22 | 23 | #endregion 24 | 25 | /// 26 | /// The startup. 27 | /// 28 | public class StartupBuilderExtendedSettings 29 | { 30 | #region Static Fields 31 | 32 | /// 33 | /// The memory root. 34 | /// 35 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 36 | 37 | #endregion 38 | 39 | #region Public Methods 40 | 41 | /// 42 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 43 | /// 44 | /// 45 | /// The application builder. 46 | /// 47 | /// 48 | /// The logger factory. 49 | /// 50 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 51 | { 52 | ILogger logger = loggerFactory.CreateLogger("Configure"); 53 | app.Use( 54 | async (_, next) => 55 | { 56 | logger.LogInformation(1, "Handling request"); 57 | await next.Invoke(); 58 | logger.LogInformation(2, "Finished handling request"); 59 | }); 60 | 61 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 62 | } 63 | 64 | /// 65 | /// This method gets called by the runtime. Use this method to add services to the container. 66 | /// 67 | /// 68 | /// The service collection. 69 | /// 70 | public void ConfigureServices(IServiceCollection services) 71 | { 72 | // Add framework services. 73 | services.AddDbContext(options => options.UseInMemoryDatabase("ExtendedLogDatabase", MemoryRoot)); 74 | 75 | // requires for http context access. 76 | services.AddSingleton(); 77 | } 78 | 79 | #endregion 80 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderSimple.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using Microsoft.AspNetCore.Builder; 15 | using Microsoft.AspNetCore.Http; 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// The startup. 25 | /// 26 | public class StartupBuilderSimple 27 | { 28 | #region Static Fields 29 | 30 | /// 31 | /// The memory root. 32 | /// 33 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 34 | 35 | #endregion 36 | 37 | #region Public Methods 38 | 39 | /// 40 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | /// 42 | /// 43 | /// The application builder. 44 | /// 45 | /// 46 | /// The logger factory. 47 | /// 48 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 49 | { 50 | ILogger logger = loggerFactory.CreateLogger("Configure"); 51 | app.Use( 52 | async (_, next) => 53 | { 54 | logger.LogInformation(1, "Handling request"); 55 | await next.Invoke(); 56 | logger.LogInformation(2, "Finished handling request"); 57 | }); 58 | 59 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 60 | } 61 | 62 | /// 63 | /// This method gets called by the runtime. Use this method to add services to the container. 64 | /// 65 | /// 66 | /// The service collection. 67 | /// 68 | public void ConfigureServices(IServiceCollection services) 69 | { 70 | // Add framework services. 71 | services.AddDbContext(options => options.UseInMemoryDatabase("SimpleLogDatabase", MemoryRoot)); 72 | } 73 | 74 | #endregion 75 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderSimpleCreator.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using Microsoft.AspNetCore.Builder; 15 | using Microsoft.AspNetCore.Http; 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// The startup. 25 | /// 26 | public class StartupBuilderSimpleCreator 27 | { 28 | #region Static Fields 29 | 30 | /// 31 | /// The memory root. 32 | /// 33 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 34 | 35 | #endregion 36 | 37 | #region Public Methods 38 | 39 | /// 40 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | /// 42 | /// 43 | /// The application builder. 44 | /// 45 | /// 46 | /// The logger factory. 47 | /// 48 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 49 | { 50 | ILogger logger = loggerFactory.CreateLogger("Configure"); 51 | app.Use( 52 | async (_, next) => 53 | { 54 | logger.LogInformation(1, "Handling request {Test}", "Test2"); 55 | await next.Invoke(); 56 | logger.LogInformation(2, "Finished handling request {Param}", "param 1"); 57 | }); 58 | 59 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 60 | } 61 | 62 | /// 63 | /// This method gets called by the runtime. Use this method to add services to the container. 64 | /// 65 | /// 66 | /// The service collection. 67 | /// 68 | public void ConfigureServices(IServiceCollection services) 69 | { 70 | // Add framework services. 71 | services.AddDbContext(options => options.UseInMemoryDatabase("SimpleLogCreatorDatabase", MemoryRoot)); 72 | } 73 | 74 | #endregion 75 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderSimpleException.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System; 15 | 16 | using Microsoft.AspNetCore.Builder; 17 | using Microsoft.AspNetCore.Http; 18 | using Microsoft.EntityFrameworkCore; 19 | using Microsoft.EntityFrameworkCore.Storage; 20 | using Microsoft.Extensions.DependencyInjection; 21 | using Microsoft.Extensions.Logging; 22 | 23 | #endregion 24 | 25 | /// 26 | /// The startup. 27 | /// 28 | public class StartupBuilderSimpleException 29 | { 30 | #region Static Fields 31 | 32 | /// 33 | /// The memory root. 34 | /// 35 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 36 | 37 | #endregion 38 | 39 | #region Public Methods 40 | 41 | /// 42 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 43 | /// 44 | /// 45 | /// The application builder. 46 | /// 47 | /// 48 | /// The logger factory. 49 | /// 50 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 51 | { 52 | ILogger logger = loggerFactory.CreateLogger("Configure"); 53 | 54 | app.Use( 55 | async (_, next) => 56 | { 57 | try 58 | { 59 | throw new Exception("By purpose"); 60 | } 61 | catch (Exception ex) 62 | { 63 | logger.LogError(1, ex, "Exception message"); 64 | } 65 | 66 | await next.Invoke(); 67 | }); 68 | 69 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 70 | } 71 | 72 | /// 73 | /// This method gets called by the runtime. Use this method to add services to the container. 74 | /// 75 | /// 76 | /// The service collection. 77 | /// 78 | public void ConfigureServices(IServiceCollection services) 79 | { 80 | // Add framework services. 81 | services.AddDbContext(options => options.UseInMemoryDatabase("SimpleLogExceptionDatabase", MemoryRoot)); 82 | } 83 | 84 | #endregion 85 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderSimpleNoFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using Microsoft.AspNetCore.Builder; 15 | using Microsoft.AspNetCore.Http; 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// The startup. 25 | /// 26 | public class StartupBuilderSimpleNoFilter 27 | { 28 | #region Static Fields 29 | 30 | /// 31 | /// The memory root. 32 | /// 33 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 34 | 35 | #endregion 36 | 37 | #region Public Methods 38 | 39 | /// 40 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | /// 42 | /// 43 | /// The application builder. 44 | /// 45 | /// 46 | /// The logger factory. 47 | /// 48 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 49 | { 50 | ILogger logger = loggerFactory.CreateLogger("Configure"); 51 | app.Use( 52 | async (_, next) => 53 | { 54 | logger.LogInformation(1, "Handling request"); 55 | await next.Invoke(); 56 | logger.LogInformation(2, "Finished handling request"); 57 | }); 58 | 59 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 60 | } 61 | 62 | /// 63 | /// This method gets called by the runtime. Use this method to add services to the container. 64 | /// 65 | /// 66 | /// The service collection. 67 | /// 68 | public void ConfigureServices(IServiceCollection services) 69 | { 70 | // Add framework services. 71 | services.AddDbContext(options => options.UseInMemoryDatabase("SimpleLogNoFilterDatabase", MemoryRoot)); 72 | } 73 | 74 | #endregion 75 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/StartupBuilderSimpleSettings.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The startup. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using Microsoft.AspNetCore.Builder; 15 | using Microsoft.AspNetCore.Http; 16 | using Microsoft.EntityFrameworkCore; 17 | using Microsoft.EntityFrameworkCore.Storage; 18 | using Microsoft.Extensions.DependencyInjection; 19 | using Microsoft.Extensions.Logging; 20 | 21 | #endregion 22 | 23 | /// 24 | /// The startup. 25 | /// 26 | public class StartupBuilderSimpleSettings 27 | { 28 | #region Static Fields 29 | 30 | /// 31 | /// The memory root. 32 | /// 33 | public static readonly InMemoryDatabaseRoot MemoryRoot = new InMemoryDatabaseRoot(); 34 | 35 | #endregion 36 | 37 | #region Public Methods 38 | 39 | /// 40 | /// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | /// 42 | /// 43 | /// The application builder. 44 | /// 45 | /// 46 | /// The logger factory. 47 | /// 48 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) 49 | { 50 | ILogger logger = loggerFactory.CreateLogger("Configure"); 51 | app.Use( 52 | async (_, next) => 53 | { 54 | logger.LogDebug(10, "Debug information should be ignored"); 55 | logger.LogInformation(1, "Handling request"); 56 | await next.Invoke(); 57 | logger.LogInformation(2, "Finished handling request"); 58 | }); 59 | 60 | app.Run(async context => { await context.Response.WriteAsync("Hello World"); }); 61 | } 62 | 63 | /// 64 | /// This method gets called by the runtime. Use this method to add services to the container. 65 | /// 66 | /// 67 | /// The service collection. 68 | /// 69 | public void ConfigureServices(IServiceCollection services) 70 | { 71 | // Add framework services. 72 | services.AddDbContext(options => options.UseInMemoryDatabase("SimpleLogDatabase", MemoryRoot)); 73 | } 74 | 75 | #endregion 76 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderExtended.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger extended. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger extended. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderExtended 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderExtendedLog() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.BuilderExtended); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("ExtendedLogDatabase", StartupBuilderExtended.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextExtended(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual(2, logs.Count); 56 | Assert.AreEqual("Handling request", logs.First().Message); 57 | Assert.AreEqual(1, logs.First().EventId); 58 | Assert.AreEqual("Test User", logs.First().User); 59 | Assert.AreEqual("Test Browser", logs.First().Browser); 60 | Assert.AreEqual("localhost", logs.First().Host); 61 | Assert.AreEqual("/", logs.First().Path); 62 | Assert.AreEqual("Finished handling request", logs.Last().Message); 63 | Assert.AreEqual(2, logs.Last().EventId); 64 | } 65 | 66 | #endregion 67 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderExtendedSettings.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger extended. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger extended. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderExtendedSettings 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderExtendedSettingsLog() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.BuilderExtendedSettings); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("ExtendedLogDatabase", StartupBuilderExtendedSettings.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextExtended(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual(2, logs.Count); 56 | Assert.AreEqual("Handling request", logs.First().Message); 57 | Assert.AreEqual(1, logs.First().EventId); 58 | Assert.AreEqual("Test User", logs.First().User); 59 | Assert.AreEqual("Test Browser", logs.First().Browser); 60 | Assert.AreEqual("localhost", logs.First().Host); 61 | Assert.AreEqual("/", logs.First().Path); 62 | Assert.AreEqual("Finished handling request", logs.Last().Message); 63 | Assert.AreEqual(2, logs.Last().EventId); 64 | } 65 | 66 | #endregion 67 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderSimple.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger simple. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger simple. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderSimple 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderSimpleLog() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.Simple); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("SimpleLogDatabase", StartupBuilderSimple.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextSimple(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual(2, logs.Count); 56 | Assert.AreEqual("Handling request", logs.First().Message); 57 | Assert.AreEqual(1, logs.First().EventId); 58 | Assert.AreEqual("Finished handling request", logs.Last().Message); 59 | Assert.AreEqual(2, logs.Last().EventId); 60 | } 61 | 62 | #endregion 63 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderSimpleCreator.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger simple. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger simple. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderSimpleCreator 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderSimpleCreatorLog() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.BuilderSimpleCreator); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("SimpleLogCreatorDatabase", StartupBuilderSimpleCreator.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextSimple(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual(2, logs.Count); 56 | Assert.AreEqual("Handling request Test2", logs.First().Message); 57 | Assert.AreEqual("This is my custom log", logs.First().Name); 58 | Assert.AreEqual(1, logs.First().EventId); 59 | Assert.AreEqual("Finished handling request param 1", logs.Last().Message); 60 | Assert.AreEqual(2, logs.Last().EventId); 61 | } 62 | 63 | #endregion 64 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderSimpleException.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger simple exception. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger simple exception. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderSimpleException 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderSimpleLogException() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.SimpleException); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("SimpleLogExceptionDatabase", StartupBuilderSimpleException.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextSimple(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual(1, logs.Count); 56 | Assert.AreEqual(true, logs.First().Message.StartsWith("Exception message")); 57 | Assert.AreEqual(1, logs.First().EventId); 58 | } 59 | 60 | #endregion 61 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderSimpleNoFilter.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger simple. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger simple. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderSimpleNoFilter 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderSimpleNoFilterLog() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.BuilderSimpleNoFilter); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("SimpleLogNoFilterDatabase", StartupBuilderSimpleNoFilter.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextSimple(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual("Handling request", logs[0].Message); 56 | Assert.AreEqual(1, logs[0].EventId); 57 | Assert.AreEqual("Finished handling request", logs[1].Message); 58 | Assert.AreEqual(2, logs[1].EventId); 59 | } 60 | 61 | #endregion 62 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestLoggerBuilderSimpleSettings.cs: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // 6 | // The test logger simple. 7 | // 8 | // -------------------------------------------------------------------------------------------------------------------- 9 | 10 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 11 | 12 | #region Usings 13 | 14 | using System.Linq; 15 | using System.Net.Http; 16 | using System.Threading.Tasks; 17 | 18 | using Microsoft.AspNetCore.TestHost; 19 | using Microsoft.EntityFrameworkCore; 20 | using Microsoft.VisualStudio.TestTools.UnitTesting; 21 | 22 | #endregion 23 | 24 | /// 25 | /// The test logger simple. 26 | /// 27 | [TestClass] 28 | public class TestLoggerBuilderSimpleSettings 29 | { 30 | #region Public Methods 31 | 32 | /// 33 | /// The write log. 34 | /// 35 | [TestMethod] 36 | public async Task WriteBuilderSimpleSettingsLog() 37 | { 38 | using var factory = new TestWebApplicationFactory(TestVersion.BuilderSimpleSettings); 39 | 40 | var options = new DbContextOptionsBuilder() 41 | .UseInMemoryDatabase("SimpleLogDatabase", StartupBuilderSimpleSettings.MemoryRoot) 42 | .Options; 43 | 44 | // Act 45 | RequestBuilder request = factory.Server.CreateRequest("/"); 46 | HttpResponseMessage response = await request.SendAsync("PUT"); 47 | 48 | // Assert 49 | response.EnsureSuccessStatusCode(); 50 | 51 | // Use a separate instance of the context to verify correct data was saved to database 52 | await using var context = new ContextSimple(options); 53 | var logs = context.Logs.ToList(); 54 | 55 | Assert.AreEqual(2, logs.Count); 56 | Assert.AreEqual("Handling request", logs.First().Message); 57 | Assert.AreEqual(1, logs.First().EventId); 58 | Assert.AreEqual("Finished handling request", logs.Last().Message); 59 | Assert.AreEqual(2, logs.Last().EventId); 60 | } 61 | 62 | #endregion 63 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestVersion.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // ----------------------------------------------------------------------- 6 | 7 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 8 | 9 | /// 10 | /// The test version logging. 11 | /// 12 | internal enum TestVersion 13 | { 14 | /// 15 | /// Simple logging. 16 | /// 17 | Simple = 0, 18 | 19 | /// 20 | /// Simple logging with exception. 21 | /// 22 | SimpleException = 1, 23 | 24 | /// 25 | /// Builder logging. 26 | /// 27 | BuilderExtended = 2, 28 | 29 | /// 30 | /// Builder logging with creator. 31 | /// 32 | BuilderSimpleCreator = 3, 33 | 34 | /// 35 | /// Builder simple logging with no filer. 36 | /// 37 | BuilderSimpleNoFilter = 4, 38 | 39 | /// 40 | /// Builder simple logging using settings. 41 | /// 42 | BuilderSimpleSettings = 5, 43 | 44 | /// 45 | /// Builder extended logging using settings. 46 | /// 47 | BuilderExtendedSettings = 6 48 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/TestWebApplicationFactory.cs: -------------------------------------------------------------------------------- 1 | // ----------------------------------------------------------------------- 2 | // 3 | // Copyright (c) Marcin Smółka. All rights reserved. 4 | // 5 | // ----------------------------------------------------------------------- 6 | 7 | namespace ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest; 8 | 9 | #region Usings 10 | 11 | using System; 12 | using System.IO; 13 | using System.Reflection; 14 | 15 | using Microsoft.AspNetCore.Hosting; 16 | using Microsoft.AspNetCore.Mvc.Testing; 17 | using Microsoft.Extensions.Configuration; 18 | using Microsoft.Extensions.Hosting; 19 | using Microsoft.Extensions.Logging; 20 | 21 | using ZNetCS.AspNetCore.Logging.EntityFrameworkCore; 22 | 23 | #endregion 24 | 25 | /// 26 | internal class TestWebApplicationFactory : WebApplicationFactory 27 | { 28 | #region Fields 29 | 30 | private readonly TestVersion testVersion; 31 | 32 | #endregion 33 | 34 | #region Constructors and Destructors 35 | 36 | /// 37 | /// Initializes a new instance of the class. 38 | /// 39 | /// Teh testing version. 40 | public TestWebApplicationFactory(TestVersion testVersion) => this.testVersion = testVersion; 41 | 42 | #endregion 43 | 44 | #region Methods 45 | 46 | /// 47 | protected override void ConfigureWebHost(IWebHostBuilder builder) 48 | { 49 | builder.UseContentRoot(GetPath() ?? string.Empty); 50 | builder.ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("appsettings.json", false, true); }); 51 | 52 | switch (this.testVersion) 53 | { 54 | case TestVersion.Simple: 55 | 56 | builder.UseStartup(); 57 | builder.ConfigureLogging( 58 | (_, logging) => 59 | { 60 | logging.AddConsole(); 61 | logging.AddDebug(); 62 | 63 | logging.AddFilter>("Microsoft", LogLevel.None); 64 | logging.AddFilter>("System", LogLevel.None); 65 | logging.AddFilter>("ZNetCS", LogLevel.Information); 66 | 67 | logging.AddEntityFramework(); 68 | }); 69 | 70 | break; 71 | case TestVersion.SimpleException: 72 | 73 | builder.UseStartup(); 74 | builder.ConfigureLogging( 75 | (_, logging) => 76 | { 77 | logging.AddConsole(); 78 | logging.AddDebug(); 79 | 80 | logging.AddFilter>("Microsoft", LogLevel.None); 81 | logging.AddFilter>("System", LogLevel.None); 82 | logging.AddFilter>("ZNetCS", LogLevel.Information); 83 | 84 | logging.AddEntityFramework(); 85 | }); 86 | 87 | break; 88 | case TestVersion.BuilderExtended: 89 | 90 | builder.UseStartup(); 91 | builder.ConfigureLogging( 92 | (_, logging) => 93 | { 94 | logging.AddConsole(); 95 | logging.AddDebug(); 96 | 97 | logging.AddFilter>("Microsoft", LogLevel.None); 98 | logging.AddFilter>("System", LogLevel.None); 99 | logging.AddFilter>("ZNetCS", LogLevel.Information); 100 | 101 | logging.AddEntityFramework(); 102 | }); 103 | 104 | break; 105 | case TestVersion.BuilderSimpleCreator: 106 | 107 | builder.UseStartup(); 108 | builder.ConfigureLogging( 109 | (_, logging) => 110 | { 111 | logging.AddConsole(); 112 | logging.AddDebug(); 113 | 114 | logging.AddFilter>("Microsoft", LogLevel.None); 115 | logging.AddFilter>("System", LogLevel.None); 116 | logging.AddFilter>("ZNetCS", LogLevel.Information); 117 | 118 | logging.AddEntityFramework( 119 | opts => 120 | { 121 | opts.Creator = (logLevel, eventId, _, message) 122 | => new Log 123 | { 124 | TimeStamp = DateTimeOffset.Now, 125 | Level = logLevel, 126 | EventId = eventId, 127 | Name = "This is my custom log", 128 | Message = message 129 | }; 130 | }); 131 | }); 132 | 133 | break; 134 | case TestVersion.BuilderSimpleNoFilter: 135 | 136 | builder.UseStartup(); 137 | builder.ConfigureLogging( 138 | (_, logging) => 139 | { 140 | logging.AddConsole(); 141 | logging.AddDebug(); 142 | 143 | logging.AddEntityFramework(); 144 | }); 145 | 146 | break; 147 | case TestVersion.BuilderSimpleSettings: 148 | 149 | builder.UseStartup(); 150 | builder.ConfigureLogging( 151 | (hostingContext, logging) => 152 | { 153 | logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); 154 | logging.AddConsole(); 155 | logging.AddDebug(); 156 | 157 | logging.AddEntityFramework(); 158 | }); 159 | 160 | break; 161 | case TestVersion.BuilderExtendedSettings: 162 | 163 | builder.UseStartup(); 164 | builder.ConfigureLogging( 165 | (hostingContext, logging) => 166 | { 167 | logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); 168 | logging.AddConsole(); 169 | logging.AddDebug(); 170 | 171 | logging.AddEntityFramework(); 172 | }); 173 | 174 | break; 175 | } 176 | } 177 | 178 | /// 179 | protected override IHostBuilder CreateHostBuilder() => Host.CreateDefaultBuilder().ConfigureWebHostDefaults(_ => { }); 180 | 181 | /// 182 | /// Get root path for test web server. 183 | /// 184 | private static string? GetPath() 185 | { 186 | string path = Path.GetDirectoryName(typeof(Startup).GetTypeInfo().Assembly.Location)!; 187 | 188 | // ReSharper disable PossibleNullReferenceException 189 | DirectoryInfo? di = new DirectoryInfo(path).Parent?.Parent?.Parent; 190 | 191 | return di?.FullName; 192 | } 193 | 194 | #endregion 195 | } -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Marcin Smółka 5 | Marcin Smółka 6 | netcoreapp3.1;net6.0;net7.0;net8.0;net9.0 7 | false 8 | latest 9 | enable 10 | true 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | all 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | 25 | 26 | all 27 | runtime; build; native; contentfiles; analyzers; buildtransitive 28 | 29 | 30 | all 31 | runtime; build; native; contentfiles; analyzers; buildtransitive 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /test/ZNetCS.AspNetCore.Logging.EntityFrameworkCoreTest/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Information" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning", 12 | "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug", 13 | "Microsoft.AspNetCore.Mvc.Razor": "Error", 14 | "Default": "Information" 15 | } 16 | }, 17 | "EntityFramework": { 18 | "LogLevel": { 19 | "Microsoft": "None", 20 | "System": "None", 21 | "ZNetCS": "Information" 22 | } 23 | } 24 | } 25 | } --------------------------------------------------------------------------------