├── .editorconfig ├── .gitattributes ├── .gitignore ├── Build.ps1 ├── LICENSE ├── README.md ├── assets ├── Serilog.snk └── pre-docs.md ├── docs └── README.md ├── serilog-settings-comparison.sln ├── serilog-settings-comparison.sln.DotSettings ├── src └── Serilog.Settings.Code │ ├── CodeSettings.cs │ ├── CodeSettingsExtensions.cs │ └── Serilog.Settings.Code.csproj └── test ├── Serilog.Settings.Comparison.Tests ├── 1-Basics │ ├── 100_Basics.cs │ ├── 101-Empty-EmptySection.config │ ├── 101-Empty-EmptySection.json │ ├── 101-Empty.config │ ├── 101-Empty.csx │ ├── 101-Empty.json │ ├── 101_EmptySettings.cs │ ├── 110-MinimumLevel-Default.json │ ├── 110-MinimumLevel-is.csx │ ├── 110-MinimumLevel.config │ ├── 110-MinimumLevel.csx │ ├── 110-MinimumLevel.json │ ├── 110_MinimumLevel.cs │ ├── 120-WriteToWithNoParams-LongForm.json │ ├── 120-WriteToWithNoParams.config │ ├── 120-WriteToWithNoParams.csx │ ├── 120-WriteToWithNoParams.json │ ├── 120_WriteToSink.cs │ ├── 125-WriteToRestrictedToMinimumLevel.config │ ├── 125-WriteToRestrictedToMinimumLevel.csx │ ├── 125-WriteToRestrictedToMinimumLevel.json │ ├── 125_WriteToRestrictedToMinimumLevel.cs │ ├── 128-WriteToWithSimpleParams.config │ ├── 128-WriteToWithSimpleParams.csx │ ├── 128-WriteToWithSimpleParams.json │ ├── 128_WriteToWithSimpleParams.cs │ ├── 130-EnrichWithProperty.config │ ├── 130-EnrichWithProperty.csx │ ├── 130-EnrichWithProperty.json │ └── 130_PropertyEnrichment.cs ├── 2-Advanced scenarios │ ├── 200_AdvancedScenarios.cs │ ├── 210-MinimumLevelOverrides.config │ ├── 210-MinimumLevelOverrides.csx │ ├── 210-MinimumLevelOverrides.json │ ├── 210_MinimumLevelOverrides.cs │ ├── 221-AuditToWithSimpleParams.config │ ├── 221-AuditToWithSimpleParams.csx │ ├── 221-AuditToWithSimpleParams.json │ ├── 221_AuditToSink.cs │ ├── 222-LoggingLevelSwitch.config │ ├── 222-LoggingLevelSwitch.csx │ ├── 222-LoggingLevelSwitch.json │ ├── 222_LoggingLevelSwitch.cs │ ├── 230-EnrichFromLogContext.config │ ├── 230-EnrichFromLogContext.csx │ ├── 230-EnrichFromLogContext.json │ ├── 230_EnrichFromLogContext.cs │ ├── 235-Destructure.config │ ├── 235-Destructure.csx │ ├── 235-Destructure.json │ ├── 235_Destructure.cs │ ├── 240-FilterExpressions.config │ ├── 240-FilterExpressions.csx │ ├── 240-FilterExpressions.json │ ├── 240_FilterExpressions.cs │ ├── 250-SubLoggers.config │ ├── 250-SubLoggers.csx │ ├── 250-SubLoggers.json │ └── 250_SubLoggers.cs ├── 3-Advanced settings formats │ ├── 300_AdvancedSettings.cs │ ├── 310-MethodDiscovery.config │ ├── 310-MethodDiscovery.csx │ ├── 310-MethodDiscovery.json │ ├── 310_MethodDiscovery.cs │ ├── 320-SettingsValueConversions.config │ ├── 320-SettingsValueConversions.csx │ ├── 320-SettingsValueConversions.json │ ├── 320_SettingsValueConversions.cs │ ├── 321-ComplexValues.config │ ├── 321-ComplexValues.csx │ ├── 321-ComplexValues.json │ ├── 321_ComplexValues.cs │ ├── 330_InterfacesAndAbstractClasses.cs │ ├── 331-ImplementationDefaultConstructor.config │ ├── 331-ImplementationDefaultConstructor.csx │ ├── 331-ImplementationDefaultConstructor.json │ ├── 331_ImplementationDefaultConstructor.cs │ ├── 332-ImplementationViaStaticProperty.config │ ├── 332-ImplementationViaStaticProperty.csx │ ├── 332-ImplementationViaStaticProperty.json │ ├── 332_StaticProperty.cs │ ├── 390-EnvironmentVariableExpansion.config │ ├── 390-EnvironmentVariableExpansion.csx │ ├── 390-EnvironmentVariableExpansion.json │ └── 390_EnvironmentVariableExpansion.cs ├── BaseSettingsSupportComparisonTests.cs ├── Serilog.Settings.Comparison.Tests.csproj ├── Support │ ├── DelegatingSink.cs │ ├── Extensions.cs │ └── Formatting │ │ ├── CustomFormatters.cs │ │ └── MyFormatter.cs ├── TODO.cs └── xunit.runner.json └── TestDummies ├── Console ├── CustomConsoleTheme.cs ├── DummyConsoleSink.cs └── Themes │ ├── ConcreteConsoleTheme.cs │ ├── ConsoleTheme.cs │ ├── ConsoleThemes.cs │ └── EmptyConsoleTheme.cs ├── DummyAuditSink.cs ├── DummyEnricher.cs ├── DummyEventLevelFilter.cs ├── DummyLoggerConfigurationExtensions.cs ├── DummyRollingFileAuditSink.cs ├── DummyRollingFileSink.cs ├── DummySink.cs ├── DummySinkWithComplexParams.cs ├── DummySinkWithParams.cs ├── DummyWithLevelSwitchSink.cs ├── MyEnum.cs ├── Policies └── CustomPolicy.cs ├── Properties └── AssemblyInfo.cs └── TestDummies.csproj /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | trim_trailing_whitespace = true 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 4 8 | 9 | [*.{csproj,json,config,yml}] 10 | indent_size = 2 11 | 12 | [*.sh] 13 | end_of_line = lf 14 | 15 | [*.{cmd, bat}] 16 | end_of_line = crlf 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | 3 | * text=auto 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | 290 | artefacts/ 291 | -------------------------------------------------------------------------------- /Build.ps1: -------------------------------------------------------------------------------- 1 | function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } } 2 | 3 | echo "build: Build started" 4 | 5 | Push-Location $PSScriptRoot 6 | 7 | if(Test-Path .\artifacts) { 8 | echo "build: Cleaning .\artifacts" 9 | Remove-Item .\artifacts -Force -Recurse 10 | } 11 | 12 | Push-Location "test\Serilog.Settings.Comparison.Tests" 13 | 14 | & dotnet xunit -xml ../../artifacts/testOutput.xml 15 | 16 | Pop-Location 17 | 18 | Copy-Item .\assets\pre-docs.md .\artifacts\README.md -Force 19 | 20 | Push-Location "artifacts" 21 | 22 | [xml]$xml = Get-Content testOutput.xml 23 | $xml.SelectNodes('/assemblies/assembly/collection') | Sort-Object name | ForEach-Object { 24 | New-Object -Type PSObject -Property @{ 25 | Description = $_.name.Substring(3).Replace("\r\n", "`n") 26 | Tests = $_.SelectNodes('test') | ForEach-Object { 27 | if ($_.result -eq "Skip") { ":warning: $($_.reason.InnerText)`n" } 28 | elseif ($_.result -eq "Fail") { "$($_.output.InnerText)`n:heavy_exclamation_mark: **Test Failed** : `n``````$($_.failure.message.InnerText.Replace("\r\n", "`n"))`n``````" } 29 | else { $_.output.InnerText } 30 | } 31 | } 32 | } | % {@($_.Description) + "`n" + $_.Tests} | Out-File README.md -Encoding utf8 -Append 33 | Pop-Location 34 | 35 | Copy-Item artifacts/*.md docs 36 | 37 | Push-Location "docs" 38 | Get-ChildItem * -Include *.md | ForEach-Object { 39 | ## If contains UNIX line endings, replace with Windows line endings 40 | if (Get-Content $_.FullName -Delimiter "`0" | Select-String "[^`r]`n") 41 | { 42 | $content = Get-Content $_.FullName 43 | $content | Set-Content $_.FullName 44 | } 45 | } 46 | Pop-Location 47 | 48 | Pop-Location 49 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # serilog-settings-comparison 2 | 3 | _The code in this repo tests and documents the different configuration formats understood by Serilog._ 4 | 5 | You are probably more interested in the output than in the code itself, so here it is : 6 | 7 | **:blue_book:[Serilog settings documentation](./docs/README.md)** 8 | -------------------------------------------------------------------------------- /assets/Serilog.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tsimbalar/serilog-settings-comparison/309f034fa448002d2e9e986a78ff51f6db59b9d1/assets/Serilog.snk -------------------------------------------------------------------------------- /assets/pre-docs.md: -------------------------------------------------------------------------------- 1 | # Serilog Settings documentation 2 | Serilog is typically configured via code though its *configuration APIs*, but it is quite common to specify the settings also from some sort of configuration file. 3 | 4 | For that purpose, several *Settings providers* exist, that mimic the *code-based* API and allow supplying values from external sources : 5 | - *Serilog.Settings.AppSettings* allows to read configuration from the `` section of an `App.config` or `Web.config` file, 6 | - *Serilog.Settings.Configuration* relies on *Microsoft.Logging.Configuration* to read settings from sources in *JSON*, *XML* or anything that can be plugged in the *ConfigurationProvider* APIs 7 | 8 | To use *Serilog.Settings.AppSettings*, install the Nuget package, and configure you logger like : 9 | ```csharp 10 | new LoggerConfiguration().ReadFrom.AppSettings() 11 | // snip ... 12 | .CreateLogger(); 13 | ``` 14 | 15 | To use *Serilog.Settings.Configuration*, install the Nuget package, and configure you logger like : 16 | ```csharp 17 | var config = new ConfigurationBuilder() 18 | .AddJsonFile(fileName, optional: false) // or possibly other sources 19 | .Build(); 20 | 21 | new LoggerConfiguration().ReadFrom.Configuration(config) 22 | // snip ... 23 | .CreateLogger(); 24 | ``` 25 | 26 | 27 | You will find below some snippets of common configuration code in *C#* with the equivalent settings in *JSON* and *XML*. 28 | 29 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Serilog Settings documentation 2 | Serilog is typically configured via code though its *configuration APIs*, but it is quite common to specify the settings also from some sort of configuration file. 3 | 4 | For that purpose, several *Settings providers* exist, that mimic the *code-based* API and allow supplying values from external sources : 5 | - *Serilog.Settings.AppSettings* allows to read configuration from the `` section of an `App.config` or `Web.config` file, 6 | - *Serilog.Settings.Configuration* relies on *Microsoft.Logging.Configuration* to read settings from sources in *JSON*, *XML* or anything that can be plugged in the *ConfigurationProvider* APIs 7 | 8 | To use *Serilog.Settings.AppSettings*, install the Nuget package, and configure you logger like : 9 | ```csharp 10 | new LoggerConfiguration().ReadFrom.AppSettings() 11 | // snip ... 12 | .CreateLogger(); 13 | ``` 14 | 15 | To use *Serilog.Settings.Configuration*, install the Nuget package, and configure you logger like : 16 | ```csharp 17 | var config = new ConfigurationBuilder() 18 | .AddJsonFile(fileName, optional: false) // or possibly other sources 19 | .Build(); 20 | 21 | new LoggerConfiguration().ReadFrom.Configuration(config) 22 | // snip ... 23 | .CreateLogger(); 24 | ``` 25 | 26 | 27 | You will find below some snippets of common configuration code in *C#* with the equivalent settings in *JSON* and *XML*. 28 | 29 | ## Basics 30 | 31 | 32 | ### Empty settings 33 | Loading an empty config file behaves the same as the default `CreateLogger()`. Minimum Level is *Information*. 34 | 35 | 36 | 44 | 45 | 54 | 55 | - in **JSON** (ex : `101-Empty-EmptySection.json`) 56 | 57 | ```json 58 | { 59 | "Serilog": {} 60 | } 61 | ``` 62 | 63 | 64 | 74 | 75 | - in **XML** (ex : `101-Empty-EmptySection.config`) 76 | 77 | ```xml 78 | 79 | 80 | 81 | 82 | 83 | ``` 84 | 85 | 86 | ### Minimum Level 87 | Global Minimum level can be defined. 88 | 89 | 90 | - in **C#** (ex : `110-MinimumLevel.csx`) 91 | 92 | ```csharp 93 | LoggerConfiguration 94 | .MinimumLevel.Warning(); 95 | ``` 96 | 97 | 98 | 109 | 110 | - in **JSON** (ex : `110-MinimumLevel.json`) 111 | 112 | ```json 113 | { 114 | "Serilog": { 115 | "MinimumLevel": "Warning" 116 | } 117 | } 118 | ``` 119 | 120 | 121 | 135 | 136 | - in **XML** (ex : `110-MinimumLevel.config`) 137 | 138 | ```xml 139 | 140 | 141 | 142 | 143 | 144 | 145 | ``` 146 | 147 | 148 | ### Sinks - Basics 149 | You can configure usage of a given *Sink* by specifying the name of the method or extension method that you would usually use after `WriteTo.*`. 150 | You may need to explicitly add a `using` directive to look for extension methods in a separate assembly or Nuget package. 151 | 152 | 153 | - in **C#** (ex : `120-WriteToWithNoParams.csx`) 154 | 155 | ```csharp 156 | #r ".\TestDummies.dll" 157 | using System; 158 | using TestDummies; 159 | 160 | LoggerConfiguration 161 | .WriteTo.Dummy(); 162 | ``` 163 | 164 | 165 | - in **JSON** (ex : `120-WriteToWithNoParams.json`) 166 | 167 | ```json 168 | { 169 | "Serilog": { 170 | "Using": [ "TestDummies" ], 171 | "WriteTo": [ "Dummy" ] 172 | } 173 | } 174 | ``` 175 | 176 | 177 | 192 | 193 | - in **XML** (ex : `120-WriteToWithNoParams.config`) 194 | 195 | ```xml 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | ``` 204 | 205 | 206 | ### Sinks - `restrictedToMinimumLevel` 207 | Parameters of type `LogEventLevel` such as `restrictedToMinimumLevel` can be provided from the level's name. 208 | 209 | 210 | - in **C#** (ex : `125-WriteToRestrictedToMinimumLevel.csx`) 211 | 212 | ```csharp 213 | #r ".\TestDummies.dll" 214 | using Serilog.Events; 215 | using TestDummies; 216 | 217 | LoggerConfiguration 218 | .WriteTo.Dummy(restrictedToMinimumLevel: LogEventLevel.Error); 219 | ``` 220 | 221 | 222 | - in **JSON** (ex : `125-WriteToRestrictedToMinimumLevel.json`) 223 | 224 | ```json 225 | { 226 | "Serilog": { 227 | "Using": [ "TestDummies" ], 228 | "WriteTo": [ 229 | { 230 | "Name": "Dummy", 231 | "Args": { 232 | "restrictedToMinimumLevel": "Error" 233 | } 234 | } 235 | ] 236 | } 237 | } 238 | ``` 239 | 240 | 241 | - in **XML** (ex : `125-WriteToRestrictedToMinimumLevel.config`) 242 | 243 | ```xml 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | ``` 252 | 253 | 254 | ### Sinks - Simple parameter types 255 | Simple types that are *convertible* from string can be passed. Empty string can be provided to specify null for nullable parameters. Parameters with a default value can be omitted. 256 | 257 | 258 | - in **C#** (ex : `128-WriteToWithSimpleParams.csx`) 259 | 260 | ```csharp 261 | #r ".\TestDummies.dll" 262 | using TestDummies; 263 | 264 | LoggerConfiguration 265 | .WriteTo.Dummy(stringParam: "A string param", intParam: 666, nullableIntParam: null); 266 | ``` 267 | 268 | 269 | - in **JSON** (ex : `128-WriteToWithSimpleParams.json`) 270 | 271 | ```json 272 | { 273 | "Serilog": { 274 | "Using": [ "TestDummies" ], 275 | "WriteTo": [ 276 | { 277 | "Name": "Dummy", 278 | "Args": { 279 | "stringParam": "A string param", 280 | "intParam": 666, 281 | "nullableIntParam": "" 282 | } 283 | } 284 | ] 285 | } 286 | } 287 | ``` 288 | 289 | 290 | - in **XML** (ex : `128-WriteToWithSimpleParams.config`) 291 | 292 | ```xml 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | ``` 303 | 304 | 305 | ### Property-Enrichment 306 | Log events can be enriched with arbitrary properties. 307 | 308 | 309 | - in **C#** (ex : `130-EnrichWithProperty.csx`) 310 | 311 | ```csharp 312 | LoggerConfiguration 313 | .Enrich.WithProperty("AppName", "MyApp") 314 | .Enrich.WithProperty("ServerName", "MyServer"); 315 | ``` 316 | 317 | 318 | - in **JSON** (ex : `130-EnrichWithProperty.json`) 319 | 320 | ```json 321 | { 322 | "Serilog": { 323 | "Properties": { 324 | "AppName": "MyApp", 325 | "ServerName": "MyServer" 326 | } 327 | } 328 | } 329 | ``` 330 | 331 | 332 | - in **XML** (ex : `130-EnrichWithProperty.config`) 333 | 334 | ```xml 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | ``` 343 | 344 | 345 | # Advanced scenarios 346 | The following scenarios are also supported. 347 | 348 | 349 | ### Minimum level overrides 350 | Minimum level can be overriden (up or down) for specific `SourceContext`s. 351 | 352 | 353 | - in **C#** (ex : `210-MinimumLevelOverrides.csx`) 354 | 355 | ```csharp 356 | using Serilog.Events; 357 | 358 | LoggerConfiguration 359 | .MinimumLevel.Verbose() 360 | .MinimumLevel.Override("Microsoft", LogEventLevel.Error) 361 | .MinimumLevel.Override("Microsoft.Extensions", LogEventLevel.Information) 362 | .MinimumLevel.Override("System", LogEventLevel.Debug) 363 | ; 364 | ``` 365 | 366 | 367 | - in **JSON** (ex : `210-MinimumLevelOverrides.json`) 368 | 369 | ```json 370 | { 371 | "Serilog": { 372 | "MinimumLevel": { 373 | "Default": "Verbose", 374 | "Override": { 375 | "Microsoft": "Error", 376 | "Microsoft.Extensions": "Information", 377 | "System": "Debug" 378 | } 379 | } 380 | } 381 | } 382 | ``` 383 | 384 | 385 | - in **XML** (ex : `210-MinimumLevelOverrides.config`) 386 | 387 | ```xml 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | ``` 398 | 399 | 400 | ### Sinks - `AuditTo` 401 | Some sinks provide *Audit* functionality via the configuration method `.AuditTo.MySink()`. This is also supported via configuration. 402 | 403 | 404 | - in **C#** (ex : `221-AuditToWithSimpleParams.csx`) 405 | 406 | ```csharp 407 | #r ".\TestDummies.dll" 408 | using TestDummies; 409 | 410 | LoggerConfiguration 411 | .AuditTo.Dummy(stringParam: "A string param", intParam: 666, nullableIntParam: null); 412 | ``` 413 | 414 | 415 | - in **JSON** (ex : `221-AuditToWithSimpleParams.json`) 416 | 417 | ```json 418 | { 419 | "Serilog": { 420 | "Using": [ "TestDummies" ], 421 | "AuditTo": [ 422 | { 423 | "Name": "Dummy", 424 | "Args": { 425 | "stringParam": "A string param", 426 | "intParam": 666, 427 | "nullableIntParam": "" 428 | } 429 | } 430 | ] 431 | } 432 | } 433 | ``` 434 | 435 | 436 | - in **XML** (ex : `221-AuditToWithSimpleParams.config`) 437 | 438 | ```xml 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | ``` 449 | 450 | 451 | ### Sinks - `LoggingLevelSwitch` 452 | Some sinks such as the *Seq* sink accept a `LoggingLevelSwitch` that can be remote-controlled. In those case, the same `LoggingLevelSwitch` instance that is used to control the global minimum level must be used. 453 | The *reference* to the switch is noted with the symbol `$`. 454 | 455 | 456 | - in **C#** (ex : `222-LoggingLevelSwitch.csx`) 457 | 458 | ```csharp 459 | #r ".\TestDummies.dll" 460 | using Serilog.Core; 461 | using Serilog.Events; 462 | using TestDummies; 463 | 464 | var mySwitch = new LoggingLevelSwitch(LogEventLevel.Warning); 465 | 466 | LoggerConfiguration 467 | .MinimumLevel.ControlledBy(mySwitch) 468 | .WriteTo.DummyWithLevelSwitch(controlLevelSwitch: mySwitch); 469 | ``` 470 | 471 | 472 | - in **JSON** (ex : `222-LoggingLevelSwitch.json`) 473 | 474 | ```json 475 | { 476 | "Serilog": { 477 | "Using": [ "TestDummies" ], 478 | "LevelSwitches": { "$mySwitch": "Warning" }, 479 | "MinimumLevel": { 480 | "ControlledBy": "$mySwitch" 481 | }, 482 | "WriteTo": [ 483 | { 484 | "Name": "DummyWithLevelSwitch", 485 | "Args": { 486 | "controlLevelSwitch": "$mySwitch" 487 | } 488 | } 489 | ] 490 | } 491 | } 492 | ``` 493 | 494 | 495 | - in **XML** (ex : `222-LoggingLevelSwitch.config`) 496 | 497 | ```xml 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | ``` 508 | 509 | 510 | ### Enrichment from `LogContext` 511 | Log events can be enriched with `LogContext`. 512 | 513 | 514 | - in **C#** (ex : `230-EnrichFromLogContext.csx`) 515 | 516 | ```csharp 517 | LoggerConfiguration.Enrich.FromLogContext(); 518 | ``` 519 | 520 | 521 | - in **JSON** (ex : `230-EnrichFromLogContext.json`) 522 | 523 | ```json 524 | { 525 | "Serilog": { 526 | "Enrich": [ "FromLogContext" ] 527 | } 528 | } 529 | ``` 530 | 531 | 532 | - in **XML** (ex : `230-EnrichFromLogContext.config`) 533 | 534 | ```xml 535 | 536 | 537 | 538 | 539 | 540 | 541 | ``` 542 | 543 | 544 | ### Custom Destructuring 545 | Specific *Destructuring* rules can be specified. 546 | 547 | 548 | - in **C#** (ex : `235-Destructure.csx`) 549 | 550 | ```csharp 551 | #r ".\TestDummies.dll" 552 | using TestDummies; 553 | using TestDummies.Policies; 554 | 555 | LoggerConfiguration 556 | .Destructure.ToMaximumDepth(maximumDestructuringDepth: 3) 557 | .Destructure.ToMaximumStringLength(maximumStringLength: 3) 558 | .Destructure.ToMaximumCollectionCount(maximumCollectionCount: 3) 559 | .Destructure.AsScalar(typeof(System.Version)) 560 | .Destructure.With(new CustomPolicy()); 561 | ``` 562 | 563 | 564 | - in **JSON** (ex : `235-Destructure.json`) 565 | 566 | ```json 567 | { 568 | "Serilog": { 569 | "Using": [ "TestDummies" ], 570 | "Destructure": [ 571 | { 572 | "Name": "ToMaximumDepth", 573 | "Args": { "maximumDestructuringDepth": 3 } 574 | }, 575 | { 576 | "Name": "ToMaximumStringLength", 577 | "Args": { "maximumStringLength": 3 } 578 | }, 579 | { 580 | "Name": "ToMaximumCollectionCount", 581 | "Args": { "maximumCollectionCount": 3 } 582 | }, 583 | { 584 | "Name": "AsScalar", 585 | "Args": { "scalarType": "System.Version" } 586 | }, 587 | { 588 | "Name": "With", 589 | "Args": { "policy": "TestDummies.Policies.CustomPolicy, TestDummies" } 590 | } 591 | ] 592 | } 593 | } 594 | ``` 595 | 596 | 597 | - in **XML** (ex : `235-Destructure.config`) 598 | 599 | ```xml 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | ``` 612 | 613 | 614 | ### Filtering - Expressions 615 | Filtering can be specified using *filter expressions* thanks to the package *Serilog.Filters.Expressions*. 616 | 617 | 618 | - in **C#** (ex : `240-FilterExpressions.csx`) 619 | 620 | ```csharp 621 | #r ".\Serilog.Filters.Expressions.dll" 622 | 623 | LoggerConfiguration 624 | .Filter.ByExcluding("filter = 'exclude'"); 625 | ``` 626 | 627 | 628 | - in **JSON** (ex : `240-FilterExpressions.json`) 629 | 630 | ```json 631 | { 632 | "Serilog": { 633 | "Using": [ "Serilog.Filters.Expressions" ], 634 | "Filter": [ 635 | { 636 | "Name": "ByExcluding", 637 | "Args": { 638 | "expression": "filter = 'exclude'" 639 | } 640 | } 641 | ] 642 | } 643 | } 644 | ``` 645 | 646 | 647 | - in **XML** (ex : `240-FilterExpressions.config`) 648 | 649 | ```xml 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | ``` 658 | 659 | 660 | ### Sub-loggers / child loggers 661 | When conditional configuration is needed depending on the sinks, sub-loggers can be used. [More about sub-loggers](https://nblumhardt.com/2016/07/serilog-2-write-to-logger/) 662 | 663 | 664 | - in **C#** (ex : `250-SubLoggers.csx`) 665 | 666 | ```csharp 667 | #r ".\TestDummies.dll" 668 | using TestDummies; 669 | 670 | LoggerConfiguration 671 | .WriteTo.Logger(lc => lc 672 | .Enrich.WithProperty("Prop1", "PropValue1") 673 | .WriteTo.DummyConsole() 674 | ) 675 | .WriteTo.Logger(lc => lc 676 | .Enrich.WithProperty("Prop2", "PropValue2") 677 | .WriteTo.Dummy() 678 | ); 679 | ``` 680 | 681 | 682 | - in **JSON** (ex : `250-SubLoggers.json`) 683 | 684 | ```json 685 | { 686 | "Serilog": { 687 | "Using": [ "TestDummies" ], 688 | "WriteTo:SubLogger1": { 689 | "Name": "Logger", 690 | "Args": { 691 | "configureLogger": { 692 | "Properties": { 693 | "Prop1": "PropValue1" 694 | }, 695 | "WriteTo": [ "DummyConsole" ] 696 | } 697 | } 698 | }, 699 | "WriteTo:SubLogger2": { 700 | "Name": "Logger", 701 | "Args": { 702 | "configureLogger": { 703 | "Properties": { 704 | "Prop2": "PropValue2" 705 | }, 706 | "WriteTo": [ "Dummy" ] 707 | } 708 | } 709 | } 710 | } 711 | } 712 | ``` 713 | 714 | 715 | :warning: Not supported yet in the appSettings XML format. [![GitHub issue state](https://img.shields.io/github/issues/detail/s/serilog/serilog/1072.svg)](https://github.com/serilog/serilog/issues/1072) 716 | 717 | # Advanced settings formats 718 | Below are the general rules for setting values. 719 | 720 | 721 | ## Method Discovery 722 | Settings providers will discover extension methods for configuration. Remember to add `using` directives if those extension methods leave in an assembly other than *Serilog*. 723 | 724 | Extension methods to the following types are supported : 725 | 726 | | Type | C# API | xml prefix | json section 727 | | ---- | ------ | ---------- | ------------ 728 | | `LoggerSinkConfiguration` | `config.WriteTo.*` | `serilog:write-to:` | `WriteTo` 729 | | `LoggerAuditSinkConfiguration` | `config.AuditTo.*` | `serilog:audit-to:` | `AuditTo` 730 | | `LoggerEnrichmentConfiguration` | `config.Enrich.*` | `serilog:enrich:` | `Enrich` 731 | | `LoggerFilterConfiguration` | `config.Filter.*` | `serilog:filter:` | `Filter` 732 | 733 | 734 | 735 | 736 | - in **C#** (ex : `310-MethodDiscovery.csx`) 737 | 738 | ```csharp 739 | #r ".\TestDummies.dll" 740 | using Serilog.Events; 741 | using TestDummies; 742 | 743 | LoggerConfiguration 744 | .Filter.ByExcludingLevel(LogEventLevel.Warning) 745 | .Enrich.WithDummyUserName("UserExtraParam") 746 | .AuditTo.Dummy(stringParam: "A string param", intParam: 666) 747 | .WriteTo.Dummy() 748 | ; 749 | ``` 750 | 751 | 752 | - in **JSON** (ex : `310-MethodDiscovery.json`) 753 | 754 | ```json 755 | { 756 | "Serilog": { 757 | "Using": [ "TestDummies" ], 758 | "Filter": [ 759 | { 760 | "Name": "ByExcludingLevel", 761 | "Args": { 762 | "excludedLevel": "Warning" 763 | } 764 | } 765 | ], 766 | "Enrich": [ 767 | { 768 | "Name": "WithDummyUserName", 769 | "Args": { 770 | "extraParam": "UserExtraParam" 771 | } 772 | } 773 | ], 774 | "AuditTo": [ 775 | { 776 | "Name": "Dummy", 777 | "Args": { 778 | "stringParam": "A string param", 779 | "intParam": 666 780 | } 781 | } 782 | ], 783 | "WriteTo": [ "Dummy" ] 784 | } 785 | } 786 | ``` 787 | 788 | 789 | - in **XML** (ex : `310-MethodDiscovery.config`) 790 | 791 | ```xml 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | ``` 804 | 805 | 806 | ## Setting values conversions 807 | ### Simple values 808 | Values for settings can be simple value types (`string`, `int`, `bool` etc), nullable versions of the previous. `Enum`s can also be parsed by name. Some specific types like `Uri` and `TimeSpan` are also supported. 809 | 810 | 811 | - in **C#** (ex : `320-SettingsValueConversions.csx`) 812 | 813 | ```csharp 814 | #r ".\TestDummies.dll" 815 | using System; 816 | using TestDummies; 817 | 818 | LoggerConfiguration 819 | .WriteTo.DummyWithManyParams( 820 | enumParam: MyEnum.Qux, 821 | timespanParam: new TimeSpan(2, 3, 4, 5), 822 | uriParam: new Uri("https://www.serilog.net")); 823 | ``` 824 | 825 | 826 | - in **JSON** (ex : `320-SettingsValueConversions.json`) 827 | 828 | ```json 829 | { 830 | "Serilog": { 831 | "Using": [ "TestDummies" ], 832 | "WriteTo": [ 833 | { 834 | "Name": "DummyWithManyParams", 835 | "Args": { 836 | "enumParam": "Qux", 837 | "timespanParam": "2.03:04:05", 838 | "uriParam": "https://www.serilog.net" 839 | } 840 | } 841 | ] 842 | } 843 | } 844 | ``` 845 | 846 | 847 | - in **XML** (ex : `320-SettingsValueConversions.config`) 848 | 849 | ```xml 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | ``` 860 | 861 | 862 | ### Complex values 863 | Arrays or complex type can also be passed to configuration methods. 864 | 865 | 866 | - in **C#** (ex : `321-ComplexValues.csx`) 867 | 868 | ```csharp 869 | #r ".\TestDummies.dll" 870 | using TestDummies; 871 | 872 | LoggerConfiguration 873 | .WriteTo.DummyWithComplexParams( 874 | poco: new Poco() 875 | { 876 | StringProperty = "myString", 877 | IntProperty = 42, 878 | Nested = new SubPoco() 879 | { 880 | SubProperty = "Sub" 881 | } 882 | }, 883 | intArray: new[] { 2, 4, 6 }, 884 | stringArray: new[] { "one", "two", "three" }, 885 | objArray: new SubPoco[] 886 | { 887 | new SubPoco() 888 | { 889 | SubProperty = "Sub1" 890 | }, 891 | new SubPoco() 892 | { 893 | SubProperty = "Sub2" 894 | } 895 | } 896 | ); 897 | ``` 898 | 899 | 900 | - in **JSON** (ex : `321-ComplexValues.json`) 901 | 902 | ```json 903 | { 904 | "Serilog": { 905 | "Using": [ "TestDummies" ], 906 | "WriteTo": [ 907 | { 908 | "Name": "DummyWithComplexParams", 909 | "Args": { 910 | "poco": { 911 | "stringProperty": "myString", 912 | "intProperty": 42, 913 | "nested": { 914 | "subProperty": "Sub" 915 | } 916 | }, 917 | "intArray": [ 2, 4, 6 ], 918 | "stringArray": [ "one", "two", "three" ], 919 | "objArray": [ 920 | { "subProperty": "Sub1" }, 921 | { "subProperty": "Sub2" } 922 | ] 923 | } 924 | } 925 | ] 926 | } 927 | } 928 | ``` 929 | 930 | 931 | :warning: Not supported yet in the appSettings XML format. 932 | 933 | ## Interfaces and abstract classes 934 | 935 | 936 | ### Full type name of implementation with default constructor 937 | For parameters whose type is an `interface` or an `abstract class`, the full type name of an implementation can be provided. If the type is not in the `Serilog` assembly, remember to include `using` directives. 938 | 939 | 940 | - in **C#** (ex : `331-ImplementationDefaultConstructor.csx`) 941 | 942 | ```csharp 943 | #r ".\TestDummies.dll" 944 | using System; 945 | using Serilog.Formatting.Json; 946 | using TestDummies; 947 | using TestDummies.Console; 948 | 949 | LoggerConfiguration 950 | .WriteTo.DummyWithFormatter(formatter: new JsonFormatter()) 951 | .WriteTo.DummyConsole(theme: new CustomConsoleTheme()); 952 | ``` 953 | 954 | 955 | - in **JSON** (ex : `331-ImplementationDefaultConstructor.json`) 956 | 957 | ```json 958 | { 959 | "Serilog": { 960 | "Using": [ "TestDummies" ], 961 | "WriteTo": [ 962 | { 963 | "Name": "DummyWithFormatter", 964 | "Args": { 965 | "formatter": "Serilog.Formatting.Json.JsonFormatter" 966 | } 967 | }, 968 | { 969 | "Name": "DummyConsole", 970 | "Args": { 971 | "theme": "TestDummies.Console.CustomConsoleTheme, TestDummies" 972 | } 973 | } 974 | ] 975 | } 976 | } 977 | ``` 978 | 979 | 980 | - in **XML** (ex : `331-ImplementationDefaultConstructor.config`) 981 | 982 | ```xml 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | ``` 992 | 993 | 994 | ### Public static properties 995 | For parameters whose type is an `interface` or an `abstract class`, you can reference a static property that exposes an instance of that interface. Use the full containing type name followed by `::` and the `public static` property name. 996 | 997 | 998 | - in **C#** (ex : `332-ImplementationViaStaticProperty.csx`) 999 | 1000 | ```csharp 1001 | #r ".\TestDummies.dll" 1002 | #r ".\Serilog.Settings.Comparison.Tests.dll" 1003 | using System; 1004 | using Serilog.Formatting.Json; 1005 | using TestDummies; 1006 | using TestDummies.Console; 1007 | using TestDummies.Console.Themes; 1008 | using Serilog.SettingsComparisonTests.Support.Formatting; 1009 | 1010 | LoggerConfiguration 1011 | .WriteTo.DummyWithFormatter(formatter: CustomFormatters.Formatter) 1012 | .WriteTo.DummyConsole(theme: ConsoleThemes.Theme1); 1013 | ``` 1014 | 1015 | 1016 | - in **JSON** (ex : `332-ImplementationViaStaticProperty.json`) 1017 | 1018 | ```json 1019 | { 1020 | "Serilog": { 1021 | "Using": [ "TestDummies" ], 1022 | "WriteTo": [ 1023 | { 1024 | "Name": "DummyWithFormatter", 1025 | "Args": { 1026 | "formatter": "Serilog.SettingsComparisonTests.Support.Formatting.CustomFormatters::Formatter, Serilog.Settings.Comparison.Tests" 1027 | } 1028 | }, 1029 | { 1030 | "Name": "DummyConsole", 1031 | "Args": { 1032 | "theme": "TestDummies.Console.Themes.ConsoleThemes::Theme1, TestDummies" 1033 | } 1034 | } 1035 | ] 1036 | } 1037 | } 1038 | ``` 1039 | 1040 | 1041 | - in **XML** (ex : `332-ImplementationViaStaticProperty.config`) 1042 | 1043 | ```xml 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | ``` 1053 | 1054 | 1055 | ## Environment variable expansion 1056 | Values like `%ENV_VARIABLE%` are replaced by the value of the environment variable `ENV_VARIABLE`. 1057 | This can be used, for instance, to provide environment-dependent property-enrichment (ex: `%COMPUTERNAME%`) or paths (ex: %TEMP%). 1058 | 1059 | 1060 | - in **C#** (ex : `390-EnvironmentVariableExpansion.csx`) 1061 | 1062 | ```csharp 1063 | #r ".\TestDummies.dll" 1064 | using System; 1065 | using TestDummies; 1066 | 1067 | 1068 | LoggerConfiguration 1069 | .WriteTo.Dummy( 1070 | stringParam: Environment.ExpandEnvironmentVariables("%PATH%"), 1071 | intParam: Int32.Parse(Environment.ExpandEnvironmentVariables("%NUMBER_OF_PROCESSORS%"))); 1072 | ``` 1073 | 1074 | 1075 | - in **JSON** (ex : `390-EnvironmentVariableExpansion.json`) 1076 | 1077 | ```json 1078 | { 1079 | "Serilog": { 1080 | "Using": [ "TestDummies" ], 1081 | "WriteTo": [ 1082 | { 1083 | "Name": "Dummy", 1084 | "Args": { 1085 | "stringParam": "%PATH%", 1086 | "intParam": "%NUMBER_OF_PROCESSORS%" 1087 | } 1088 | } 1089 | ] 1090 | } 1091 | } 1092 | ``` 1093 | 1094 | 1095 | - in **XML** (ex : `390-EnvironmentVariableExpansion.config`) 1096 | 1097 | ```xml 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | ``` 1107 | 1108 | 1109 | -------------------------------------------------------------------------------- /serilog-settings-comparison.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Settings.Comparison.Tests", "test\Serilog.Settings.Comparison.Tests\Serilog.Settings.Comparison.Tests.csproj", "{00BF7178-64EF-42A7-AFFB-D6F9A1A4E2BF}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestDummies", "test\TestDummies\TestDummies.csproj", "{220BB2B2-FB03-48B5-8B8E-C21DE683164B}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "assets", "assets", "{B88E60D4-DB93-4BA8-BE04-535125613B6E}" 11 | ProjectSection(SolutionItems) = preProject 12 | Build.ps1 = Build.ps1 13 | assets\pre-docs.md = assets\pre-docs.md 14 | README.md = README.md 15 | serilog-settings-comparison.sln.DotSettings = serilog-settings-comparison.sln.DotSettings 16 | assets\Serilog.snk = assets\Serilog.snk 17 | EndProjectSection 18 | EndProject 19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{BBDE608C-6826-4ED1-BD6F-08B278D0873C}" 20 | ProjectSection(SolutionItems) = preProject 21 | docs\README.md = docs\README.md 22 | EndProjectSection 23 | EndProject 24 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{4932AABF-0472-4DFD-A4C8-7FA5291A7522}" 25 | EndProject 26 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Serilog.Settings.Code", "src\Serilog.Settings.Code\Serilog.Settings.Code.csproj", "{12DC7FF3-7305-489D-8E73-9F8E0F7FD899}" 27 | EndProject 28 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{DF9F62A1-F98D-481A-8B6D-1782B1A20C4B}" 29 | EndProject 30 | Global 31 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 32 | Debug|Any CPU = Debug|Any CPU 33 | Release|Any CPU = Release|Any CPU 34 | EndGlobalSection 35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 36 | {00BF7178-64EF-42A7-AFFB-D6F9A1A4E2BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {00BF7178-64EF-42A7-AFFB-D6F9A1A4E2BF}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {00BF7178-64EF-42A7-AFFB-D6F9A1A4E2BF}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {00BF7178-64EF-42A7-AFFB-D6F9A1A4E2BF}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {220BB2B2-FB03-48B5-8B8E-C21DE683164B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {220BB2B2-FB03-48B5-8B8E-C21DE683164B}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {220BB2B2-FB03-48B5-8B8E-C21DE683164B}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {220BB2B2-FB03-48B5-8B8E-C21DE683164B}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {12DC7FF3-7305-489D-8E73-9F8E0F7FD899}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {12DC7FF3-7305-489D-8E73-9F8E0F7FD899}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {12DC7FF3-7305-489D-8E73-9F8E0F7FD899}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {12DC7FF3-7305-489D-8E73-9F8E0F7FD899}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(NestedProjects) = preSolution 53 | {00BF7178-64EF-42A7-AFFB-D6F9A1A4E2BF} = {DF9F62A1-F98D-481A-8B6D-1782B1A20C4B} 54 | {12DC7FF3-7305-489D-8E73-9F8E0F7FD899} = {4932AABF-0472-4DFD-A4C8-7FA5291A7522} 55 | EndGlobalSection 56 | GlobalSection(ExtensibilityGlobals) = postSolution 57 | SolutionGuid = {5CAF905A-68BA-485F-8E67-37C8D2063FCA} 58 | EndGlobalSection 59 | EndGlobal 60 | -------------------------------------------------------------------------------- /serilog-settings-comparison.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | True 5 | True 6 | True 7 | True 8 | False 9 | SOLUTION 10 | DO_NOT_SHOW 11 | DO_NOT_SHOW 12 | DO_NOT_SHOW 13 | ERROR 14 | DO_NOT_SHOW 15 | DO_NOT_SHOW 16 | DO_NOT_SHOW 17 | DO_NOT_SHOW 18 | ERROR 19 | ERROR 20 | WARNING 21 | ERROR 22 | HINT 23 | ERROR 24 | ERROR 25 | ERROR 26 | ERROR 27 | ERROR 28 | ERROR 29 | ERROR 30 | ERROR 31 | ERROR 32 | DO_NOT_SHOW 33 | DO_NOT_SHOW 34 | DO_NOT_SHOW 35 | DO_NOT_SHOW 36 | HINT 37 | DO_NOT_SHOW 38 | HINT 39 | ERROR 40 | WARNING 41 | ERROR 42 | ERROR 43 | ERROR 44 | HINT 45 | ERROR 46 | ERROR 47 | ERROR 48 | ERROR 49 | ERROR 50 | WARNING 51 | HINT 52 | ERROR 53 | SUGGESTION 54 | ERROR 55 | ERROR 56 | ERROR 57 | ERROR 58 | SUGGESTION 59 | DO_NOT_SHOW 60 | ERROR 61 | ERROR 62 | ERROR 63 | ERROR 64 | ERROR 65 | ERROR 66 | ERROR 67 | SUGGESTION 68 | ERROR 69 | ERROR 70 | ERROR 71 | ERROR 72 | ERROR 73 | ERROR 74 | ERROR 75 | ERROR 76 | ERROR 77 | WARNING 78 | ERROR 79 | ERROR 80 | ERROR 81 | DoHide 82 | DoHide 83 | DoHide 84 | DoHide 85 | DoHide 86 | DoHide 87 | DoHide 88 | DoHide 89 | DoHide 90 | DoHide 91 | DoHide 92 | DoHide 93 | DoHide 94 | DoHide 95 | DoHide 96 | DoHide 97 | DoHide 98 | DoHide 99 | DoHide 100 | ERROR 101 | ERROR 102 | ERROR 103 | ERROR 104 | ERROR 105 | ERROR 106 | ERROR 107 | ERROR 108 | ERROR 109 | DO_NOT_SHOW 110 | SUGGESTION 111 | ERROR 112 | HINT 113 | ERROR 114 | ERROR 115 | ERROR 116 | ERROR 117 | HINT 118 | <?xml version="1.0" encoding="utf-16"?><Profile name="Format My Code Using &quot;Particular&quot; conventions"><CSMakeFieldReadonly>True</CSMakeFieldReadonly><CSUseVar><BehavourStyle>CAN_CHANGE_TO_IMPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_IMPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_IMPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSReorderTypeMembers>True</CSReorderTypeMembers><JsInsertSemicolon>True</JsInsertSemicolon><JsReformatCode>True</JsReformatCode><CssReformatCode>True</CssReformatCode><CSArrangeThisQualifier>True</CSArrangeThisQualifier><RemoveCodeRedundancies>True</RemoveCodeRedundancies><CSUseAutoProperty>True</CSUseAutoProperty><HtmlReformatCode>True</HtmlReformatCode><CSShortenReferences>True</CSShortenReferences><CSharpFormatDocComments>True</CSharpFormatDocComments><CssAlphabetizeProperties>True</CssAlphabetizeProperties></Profile> 119 | Default: Reformat Code 120 | Format My Code Using "Particular" conventions 121 | Implicit 122 | Implicit 123 | False 124 | DO_NOT_CHANGE 125 | DO_NOT_CHANGE 126 | DO_NOT_CHANGE 127 | DO_NOT_CHANGE 128 | DO_NOT_CHANGE 129 | NEVER 130 | False 131 | False 132 | False 133 | CHOP_ALWAYS 134 | False 135 | CHOP_ALWAYS 136 | CHOP_ALWAYS 137 | True 138 | True 139 | <?xml version="1.0" encoding="utf-16"?> 140 | <Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"> 141 | <TypePattern DisplayName="COM interfaces or structs"> 142 | <TypePattern.Match> 143 | <Or> 144 | <And> 145 | <Kind Is="Interface" /> 146 | <Or> 147 | <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /> 148 | <HasAttribute Name="System.Runtime.InteropServices.ComImport" /> 149 | </Or> 150 | </And> 151 | <Kind Is="Struct" /> 152 | </Or> 153 | </TypePattern.Match> 154 | </TypePattern> 155 | <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"> 156 | <TypePattern.Match> 157 | <And> 158 | <Kind Is="Class" /> 159 | <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" /> 160 | <HasAttribute Name="NUnit.Framework.TestCaseFixtureAttribute" Inherited="True" /> 161 | </And> 162 | </TypePattern.Match> 163 | <Entry DisplayName="Setup/Teardown Methods"> 164 | <Entry.Match> 165 | <And> 166 | <Kind Is="Method" /> 167 | <Or> 168 | <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" /> 169 | <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" /> 170 | <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" /> 171 | <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" /> 172 | </Or> 173 | </And> 174 | </Entry.Match> 175 | </Entry> 176 | <Entry DisplayName="All other members" /> 177 | <Entry Priority="100" DisplayName="Test Methods"> 178 | <Entry.Match> 179 | <And> 180 | <Kind Is="Method" /> 181 | <HasAttribute Name="NUnit.Framework.TestAttribute" /> 182 | </And> 183 | </Entry.Match> 184 | <Entry.SortBy> 185 | <Name /> 186 | </Entry.SortBy> 187 | </Entry> 188 | </TypePattern> 189 | <TypePattern DisplayName="Default Pattern"> 190 | <Entry Priority="100" DisplayName="Public Delegates"> 191 | <Entry.Match> 192 | <And> 193 | <Access Is="Public" /> 194 | <Kind Is="Delegate" /> 195 | </And> 196 | </Entry.Match> 197 | <Entry.SortBy> 198 | <Name /> 199 | </Entry.SortBy> 200 | </Entry> 201 | <Entry Priority="100" DisplayName="Public Enums"> 202 | <Entry.Match> 203 | <And> 204 | <Access Is="Public" /> 205 | <Kind Is="Enum" /> 206 | </And> 207 | </Entry.Match> 208 | <Entry.SortBy> 209 | <Name /> 210 | </Entry.SortBy> 211 | </Entry> 212 | <Entry DisplayName="Static Fields and Constants"> 213 | <Entry.Match> 214 | <Or> 215 | <Kind Is="Constant" /> 216 | <And> 217 | <Kind Is="Field" /> 218 | <Static /> 219 | </And> 220 | </Or> 221 | </Entry.Match> 222 | <Entry.SortBy> 223 | <Kind Order="Constant Field" /> 224 | </Entry.SortBy> 225 | </Entry> 226 | <Entry DisplayName="Fields"> 227 | <Entry.Match> 228 | <And> 229 | <Kind Is="Field" /> 230 | <Not> 231 | <Static /> 232 | </Not> 233 | </And> 234 | </Entry.Match> 235 | <Entry.SortBy> 236 | <Readonly /> 237 | <Name /> 238 | </Entry.SortBy> 239 | </Entry> 240 | <Entry DisplayName="Constructors"> 241 | <Entry.Match> 242 | <Kind Is="Constructor" /> 243 | </Entry.Match> 244 | <Entry.SortBy> 245 | <Static /> 246 | </Entry.SortBy> 247 | </Entry> 248 | <Entry DisplayName="Properties, Indexers"> 249 | <Entry.Match> 250 | <Or> 251 | <Kind Is="Property" /> 252 | <Kind Is="Indexer" /> 253 | </Or> 254 | </Entry.Match> 255 | </Entry> 256 | <Entry Priority="100" DisplayName="Interface Implementations"> 257 | <Entry.Match> 258 | <And> 259 | <Kind Is="Member" /> 260 | <ImplementsInterface /> 261 | </And> 262 | </Entry.Match> 263 | <Entry.SortBy> 264 | <ImplementsInterface Immediate="True" /> 265 | </Entry.SortBy> 266 | </Entry> 267 | <Entry DisplayName="All other members" /> 268 | <Entry DisplayName="Nested Types"> 269 | <Entry.Match> 270 | <Kind Is="Type" /> 271 | </Entry.Match> 272 | </Entry> 273 | </TypePattern> 274 | </Patterns> 275 | <?xml version="1.0" encoding="utf-8" ?> 276 | 277 | <!-- 278 | I. Overall 279 | 280 | I.1 Each pattern can have <Match>....</Match> element. For the given type declaration, the pattern with the match, evaluated to 'true' with the largest weight, will be used 281 | I.2 Each pattern consists of the sequence of <Entry>...</Entry> elements. Type member declarations are distributed between entries 282 | I.3 If pattern has RemoveAllRegions="true" attribute, then all regions will be cleared prior to reordering. Otherwise, only auto-generated regions will be cleared 283 | I.4 The contents of each entry is sorted by given keys (First key is primary, next key is secondary, etc). Then the declarations are grouped and en-regioned by given property 284 | 285 | II. Available match operands 286 | 287 | Each operand may have Weight="..." attribute. This weight will be added to the match weight if the operand is evaluated to 'true'. 288 | The default weight is 1 289 | 290 | II.1 Boolean functions: 291 | II.1.1 <And>....</And> 292 | II.1.2 <Or>....</Or> 293 | II.1.3 <Not>....</Not> 294 | 295 | II.2 Operands 296 | II.2.1 <Kind Is="..."/>. Kinds are: class, struct, interface, enum, delegate, type, constructor, destructor, property, indexer, method, operator, field, constant, event, member 297 | II.2.2 <Name Is="..." [IgnoreCase="true/false"] />. The 'Is' attribute contains regular expression 298 | II.2.3 <HasAttribute CLRName="..." [Inherit="true/false"] />. The 'CLRName' attribute contains regular expression 299 | II.2.4 <Access Is="..."/>. The 'Is' values are: public, protected, internal, protected internal, private 300 | II.2.5 <Static/> 301 | II.2.6 <Abstract/> 302 | II.2.7 <Virtual/> 303 | II.2.8 <Override/> 304 | II.2.9 <Sealed/> 305 | II.2.10 <Readonly/> 306 | II.2.11 <ImplementsInterface CLRName="..."/>. The 'CLRName' attribute contains regular expression 307 | II.2.12 <HandlesEvent /> 308 | --> 309 | 310 | <Patterns xmlns="urn:shemas-jetbrains-com:member-reordering-patterns"> 311 | 312 | <!--Do not reorder COM interfaces and structs marked by StructLayout attribute--> 313 | <Pattern> 314 | <Match> 315 | <Or Weight="100"> 316 | <And> 317 | <Kind Is="interface"/> 318 | <Or> 319 | <HasAttribute CLRName="System.Runtime.InteropServices.InterfaceTypeAttribute"/> 320 | <HasAttribute CLRName="System.Runtime.InteropServices.ComImport"/> 321 | </Or> 322 | </And> 323 | <HasAttribute CLRName="System.Runtime.InteropServices.StructLayoutAttribute"/> 324 | </Or> 325 | </Match> 326 | </Pattern> 327 | 328 | <!--Special formatting of NUnit test fixture--> 329 | <Pattern RemoveAllRegions="true"> 330 | <Match> 331 | <And Weight="100"> 332 | <Kind Is="class"/> 333 | <HasAttribute CLRName="NUnit.Framework.TestFixtureAttribute" Inherit="true"/> 334 | </And> 335 | </Match> 336 | 337 | <!--Setup/Teardow--> 338 | <Entry> 339 | <Match> 340 | <And> 341 | <Kind Is="method"/> 342 | <Or> 343 | <HasAttribute CLRName="NUnit.Framework.SetUpAttribute" Inherit="true"/> 344 | <HasAttribute CLRName="NUnit.Framework.TearDownAttribute" Inherit="true"/> 345 | <HasAttribute CLRName="NUnit.Framework.FixtureSetUpAttribute" Inherit="true"/> 346 | <HasAttribute CLRName="NUnit.Framework.FixtureTearDownAttribute" Inherit="true"/> 347 | </Or> 348 | </And> 349 | </Match> 350 | </Entry> 351 | 352 | <!--All other members--> 353 | <Entry/> 354 | 355 | <!--Test methods--> 356 | <Entry> 357 | <Match> 358 | <And Weight="100"> 359 | <Kind Is="method"/> 360 | <HasAttribute CLRName="NUnit.Framework.TestAttribute" Inherit="false"/> 361 | </And> 362 | </Match> 363 | <Sort> 364 | <Name/> 365 | </Sort> 366 | </Entry> 367 | </Pattern> 368 | 369 | <!--Default pattern--> 370 | <Pattern> 371 | 372 | <!--public delegate--> 373 | <Entry> 374 | <Match> 375 | <And Weight="100"> 376 | <Access Is="public"/> 377 | <Kind Is="delegate"/> 378 | </And> 379 | </Match> 380 | <Sort> 381 | <Name/> 382 | </Sort> 383 | </Entry> 384 | 385 | <!--public enum--> 386 | <Entry> 387 | <Match> 388 | <And Weight="100"> 389 | <Access Is="public"/> 390 | <Kind Is="enum"/> 391 | </And> 392 | </Match> 393 | <Sort> 394 | <Name/> 395 | </Sort> 396 | </Entry> 397 | 398 | <!--Constructors. Place static one first--> 399 | <Entry> 400 | <Match> 401 | <Kind Is="constructor"/> 402 | </Match> 403 | <Sort> 404 | <Static/> 405 | </Sort> 406 | </Entry> 407 | 408 | <!--properties, indexers--> 409 | <Entry> 410 | <Match> 411 | <Or> 412 | <Kind Is="property"/> 413 | <Kind Is="indexer"/> 414 | </Or> 415 | </Match> 416 | </Entry> 417 | 418 | <!--interface implementations--> 419 | <Entry> 420 | <Match> 421 | <And Weight="100"> 422 | <Kind Is="member"/> 423 | <ImplementsInterface/> 424 | </And> 425 | </Match> 426 | <Sort> 427 | <ImplementsInterface Immediate="true"/> 428 | </Sort> 429 | </Entry> 430 | 431 | <!--all other members--> 432 | <Entry/> 433 | 434 | <!--static fields and constants--> 435 | <Entry> 436 | <Match> 437 | <Or> 438 | <Kind Is="constant"/> 439 | <And> 440 | <Kind Is="field"/> 441 | <Static/> 442 | </And> 443 | </Or> 444 | </Match> 445 | <Sort> 446 | <Kind Order="constant field"/> 447 | </Sort> 448 | </Entry> 449 | 450 | <!--instance fields--> 451 | <Entry> 452 | <Match> 453 | <And> 454 | <Kind Is="field"/> 455 | <Not> 456 | <Static/> 457 | </Not> 458 | </And> 459 | </Match> 460 | <Sort> 461 | <Readonly/> 462 | <Name/> 463 | </Sort> 464 | </Entry> 465 | 466 | <!--nested types--> 467 | <Entry> 468 | <Match> 469 | <Kind Is="type"/> 470 | </Match> 471 | <Sort> 472 | <Name/> 473 | </Sort> 474 | </Entry> 475 | </Pattern> 476 | 477 | </Patterns> 478 | 479 | CustomLayout 480 | 481 | True 482 | False 483 | True 484 | False 485 | False 486 | False 487 | True 488 | Automatic property 489 | True 490 | False 491 | False 492 | False 493 | AD 494 | DB 495 | DTC 496 | GT 497 | ID 498 | NSB 499 | SLA 500 | $object$_On$event$ 501 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 502 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 503 | <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> 504 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 505 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 506 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 507 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 508 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 509 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 510 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> 511 | <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> 512 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 513 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 514 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 515 | <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> 516 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 517 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 518 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 519 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 520 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 521 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 522 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 523 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 524 | $object$_On$event$ 525 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 526 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 527 | <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /> 528 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 529 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 530 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 531 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 532 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 533 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 534 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 535 | <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> 536 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 537 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 538 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 539 | <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /> 540 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 541 | True 542 | True 543 | True 544 | True 545 | True 546 | True 547 | True 548 | True 549 | True 550 | True 551 | True 552 | True 553 | True 554 | 555 | 556 | 557 | 558 | <data /> 559 | <data><IncludeFilters /><ExcludeFilters /></data> -------------------------------------------------------------------------------- /src/Serilog.Settings.Code/CodeSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Microsoft.CodeAnalysis.CSharp.Scripting; 6 | using Microsoft.CodeAnalysis.Scripting; 7 | using Serilog.Configuration; 8 | 9 | namespace Serilog.Settings.Code 10 | { 11 | public class CodeSettings : ILoggerSettings 12 | { 13 | readonly string _cSharpCode; 14 | readonly List _referencedAssemblies; 15 | 16 | public CodeSettings(string cSharpCode, Assembly[] referencedAssemblies = null) 17 | { 18 | _cSharpCode = cSharpCode ?? throw new ArgumentNullException(nameof(cSharpCode)); 19 | _referencedAssemblies = referencedAssemblies?.ToList() ?? new List(); 20 | } 21 | 22 | public void Configure(LoggerConfiguration loggerConfiguration) 23 | { 24 | var scriptOptions = ScriptOptions.Default 25 | .WithReferences(typeof(ILogger).Assembly) 26 | .WithImports(typeof(ILogger).Namespace) 27 | .AddReferences(_referencedAssemblies); 28 | 29 | var runTask = CSharpScript.RunAsync(_cSharpCode, 30 | globals: new Globals() 31 | { 32 | LoggerConfiguration = loggerConfiguration 33 | }, 34 | options: scriptOptions); 35 | runTask.Wait(); 36 | } 37 | 38 | public class Globals 39 | { 40 | public LoggerConfiguration LoggerConfiguration; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Serilog.Settings.Code/CodeSettingsExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Serilog.Configuration; 3 | 4 | namespace Serilog.Settings.Code 5 | { 6 | public static class CodeSettingsExtensions 7 | { 8 | public static LoggerConfiguration CodeString(this LoggerSettingsConfiguration lsc, string csharpCode, Assembly[] referencedAssemblies = null) 9 | { 10 | return lsc.Settings(new CodeSettings(csharpCode, referencedAssemblies)); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Serilog.Settings.Code/Serilog.Settings.Code.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net46 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/100_Basics.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace Serilog.SettingsComparisonTests 5 | { 6 | [Collection(docs)] 7 | public class Basics : BaseSettingsSupportComparisonTests 8 | { 9 | public const string docs = @"100## Basics"; 10 | 11 | public Basics(ITestOutputHelper outputHelper) 12 | : base(outputHelper) 13 | { 14 | } 15 | 16 | [Fact] 17 | public void Whatever() 18 | { 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/101-Empty-EmptySection.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/101-Empty-EmptySection.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": {} 3 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/101-Empty.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/101-Empty.csx: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/101-Empty.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/101_EmptySettings.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | using Serilog.SettingsComparisonTests.Support; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class EmptySettings : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"101### Empty settings 12 | Loading an empty config file behaves the same as the default `CreateLogger()`. " + 13 | "Minimum Level is *Information*."; 14 | 15 | public EmptySettings(ITestOutputHelper outputHelper) 16 | : base(outputHelper) 17 | { 18 | } 19 | 20 | [Theory] 21 | [InlineData("101-Empty.csx", false)] 22 | [InlineData("101-Empty.json", false)] 23 | [InlineData("101-Empty-EmptySection.json", true)] 24 | [InlineData("101-Empty.config", false)] 25 | [InlineData("101-Empty-EmptySection.config", true)] 26 | public void TestCase(string fileName, bool includeInOutput) 27 | { 28 | WriteDocumentation(fileName, includeInOutput); 29 | 30 | var loggerConfig = LoadConfig(fileName); 31 | 32 | LogEvent e = null; 33 | var logger = loggerConfig 34 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 35 | 36 | e = null; 37 | logger.Debug("Should not be written (default min level is Information)"); 38 | Assert.Null(e); 39 | logger.Information("Should be written"); 40 | Assert.NotNull(e); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/110-MinimumLevel-Default.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "MinimumLevel": { 4 | "Default": "Warning" 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/110-MinimumLevel-is.csx: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | 3 | LoggerConfiguration 4 | .MinimumLevel.Is(LogEventLevel.Warning); 5 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/110-MinimumLevel.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/110-MinimumLevel.csx: -------------------------------------------------------------------------------- 1 | LoggerConfiguration 2 | .MinimumLevel.Warning(); 3 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/110-MinimumLevel.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "MinimumLevel": "Warning" 4 | } 5 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/110_MinimumLevel.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | using Serilog.SettingsComparisonTests.Support; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class MinimumLevel : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"110### Minimum Level 12 | Global Minimum level can be defined."; 13 | 14 | public MinimumLevel(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | } 18 | 19 | [Theory] 20 | [InlineData("110-MinimumLevel.csx", true)] 21 | [InlineData("110-MinimumLevel-is.csx", false)] 22 | [InlineData("110-MinimumLevel.json", true)] 23 | [InlineData("110-MinimumLevel-Default.json", false)] 24 | [InlineData("110-MinimumLevel.config", true)] 25 | public void TestCase(string fileName, bool includeInOutput) 26 | { 27 | WriteDocumentation(fileName, includeInOutput); 28 | 29 | var loggerConfig = LoadConfig(fileName); 30 | 31 | LogEvent e = null; 32 | var logger = loggerConfig 33 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 34 | 35 | e = null; 36 | logger.Information("Should not be written"); 37 | Assert.Null(e); 38 | logger.Warning("Should be written"); 39 | Assert.NotNull(e); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/120-WriteToWithNoParams-LongForm.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { "Name": "Dummy" } 6 | ] 7 | } 8 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/120-WriteToWithNoParams.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/120-WriteToWithNoParams.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using System; 3 | using TestDummies; 4 | 5 | LoggerConfiguration 6 | .WriteTo.Dummy(); 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/120-WriteToWithNoParams.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ "Dummy" ] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/120_WriteToSink.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace Serilog.SettingsComparisonTests 6 | { 7 | [Collection(docs)] 8 | public class WriteToSink : BaseSettingsSupportComparisonTests 9 | { 10 | public const string docs = @"120### Sinks - Basics 11 | You can configure usage of a given *Sink* by specifying the name of the method or extension method that you would usually use after `WriteTo.*`. 12 | You may need to explicitly add a `using` directive to look for extension methods in a separate assembly or Nuget package."; 13 | 14 | public WriteToSink(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | } 18 | 19 | [Theory] 20 | [InlineData("120-WriteToWithNoParams.csx", true)] 21 | [InlineData("120-WriteToWithNoParams.json", true)] 22 | [InlineData("120-WriteToWithNoParams-LongForm.json", false)] 23 | [InlineData("120-WriteToWithNoParams.config", true)] 24 | public void TestCase(string fileName, bool includeInOutput) 25 | { 26 | WriteDocumentation(fileName, includeInOutput); 27 | 28 | var loggerConfig = LoadConfig(fileName); 29 | 30 | var logger = loggerConfig.CreateLogger(); 31 | logger.Error("This should be written to Dummy"); 32 | var e = TestDummies.DummySink.Emitted.FirstOrDefault(); 33 | Assert.NotNull(e); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/125-WriteToRestrictedToMinimumLevel.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/125-WriteToRestrictedToMinimumLevel.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using Serilog.Events; 3 | using TestDummies; 4 | 5 | LoggerConfiguration 6 | .WriteTo.Dummy(restrictedToMinimumLevel: LogEventLevel.Error); 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/125-WriteToRestrictedToMinimumLevel.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "Dummy", 7 | "Args": { 8 | "restrictedToMinimumLevel": "Error" 9 | } 10 | } 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/125_WriteToRestrictedToMinimumLevel.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace Serilog.SettingsComparisonTests 6 | { 7 | [Collection(docs)] 8 | public class WriteToRestrictedToMinimumLevel : BaseSettingsSupportComparisonTests 9 | { 10 | public const string docs = @"125### Sinks - `restrictedToMinimumLevel` 11 | Parameters of type `LogEventLevel` such as `restrictedToMinimumLevel` can be provided from the level's name."; 12 | 13 | public WriteToRestrictedToMinimumLevel(ITestOutputHelper outputHelper) 14 | : base(outputHelper) 15 | { 16 | } 17 | 18 | [Theory] 19 | [InlineData("125-WriteToRestrictedToMinimumLevel.csx")] 20 | [InlineData("125-WriteToRestrictedToMinimumLevel.json")] 21 | [InlineData("125-WriteToRestrictedToMinimumLevel.config")] 22 | public void TestCase(string fileName) 23 | { 24 | WriteDocumentation(fileName); 25 | 26 | var loggerConfig = LoadConfig(fileName); 27 | 28 | var logger = loggerConfig.CreateLogger(); 29 | logger.Warning("This should not be written because `restrictedToMinimumLevel` = `Error`"); 30 | Assert.Null(TestDummies.DummySink.Emitted.FirstOrDefault()); 31 | 32 | logger.Error("This should be written because `restrictedToMinimumLevel` = `Error`"); 33 | Assert.NotNull(TestDummies.DummySink.Emitted.FirstOrDefault()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/128-WriteToWithSimpleParams.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/128-WriteToWithSimpleParams.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using TestDummies; 3 | 4 | LoggerConfiguration 5 | .WriteTo.Dummy(stringParam: "A string param", intParam: 666, nullableIntParam: null); 6 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/128-WriteToWithSimpleParams.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "Dummy", 7 | "Args": { 8 | "stringParam": "A string param", 9 | "intParam": 666, 10 | "nullableIntParam": "" 11 | } 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/128_WriteToWithSimpleParams.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace Serilog.SettingsComparisonTests 5 | { 6 | [Collection(docs)] 7 | public class WriteToWithSimpleParams : BaseSettingsSupportComparisonTests 8 | { 9 | public const string docs = @"128### Sinks - Simple parameter types 10 | Simple types that are *convertible* from string can be passed. " + 11 | "Empty string can be provided to specify null for nullable parameters. " + 12 | "Parameters with a default value can be omitted."; 13 | 14 | public WriteToWithSimpleParams(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | } 18 | 19 | [Theory] 20 | [InlineData("128-WriteToWithSimpleParams.csx")] 21 | [InlineData("128-WriteToWithSimpleParams.json")] 22 | [InlineData("128-WriteToWithSimpleParams.config")] 23 | public void TestCase(string fileName) 24 | { 25 | WriteDocumentation(fileName); 26 | 27 | var loggerConfig = LoadConfig(fileName); 28 | 29 | loggerConfig.CreateLogger(); 30 | Assert.Equal("A string param", TestDummies.DummySink.StringParam); 31 | Assert.Equal(666, TestDummies.DummySink.IntParam); 32 | Assert.Null(TestDummies.DummySink.NullableIntParam); 33 | Assert.Equal("default", TestDummies.DummySink.StringParamWithDefault); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/130-EnrichWithProperty.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/130-EnrichWithProperty.csx: -------------------------------------------------------------------------------- 1 | LoggerConfiguration 2 | .Enrich.WithProperty("AppName", "MyApp") 3 | .Enrich.WithProperty("ServerName", "MyServer"); 4 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/130-EnrichWithProperty.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Properties": { 4 | "AppName": "MyApp", 5 | "ServerName": "MyServer" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/1-Basics/130_PropertyEnrichment.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | using Serilog.SettingsComparisonTests.Support; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class PropertyEnrichment : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"130### Property-Enrichment 12 | Log events can be enriched with arbitrary properties."; 13 | 14 | public PropertyEnrichment(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | } 18 | 19 | [Theory] 20 | [InlineData("130-EnrichWithProperty.csx")] 21 | [InlineData("130-EnrichWithProperty.json")] 22 | [InlineData("130-EnrichWithProperty.config")] 23 | public void TestCase(string fileName) 24 | { 25 | WriteDocumentation(fileName); 26 | 27 | var loggerConfig = LoadConfig(fileName); 28 | 29 | LogEvent e = null; 30 | var logger = loggerConfig 31 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 32 | 33 | logger.Information("This will be enriched with 2 properties"); 34 | Assert.NotNull(e); 35 | Assert.Equal("MyApp", e.Properties["AppName"].LiteralValue()); 36 | Assert.Equal("MyServer", e.Properties["ServerName"].LiteralValue()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/200_AdvancedScenarios.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace Serilog.SettingsComparisonTests 5 | { 6 | [Collection(docs)] 7 | public class AdvancedScenarios : BaseSettingsSupportComparisonTests 8 | { 9 | public const string docs = @"200# Advanced scenarios 10 | The following scenarios are also supported."; 11 | 12 | public AdvancedScenarios(ITestOutputHelper outputHelper) 13 | : base(outputHelper) 14 | { 15 | } 16 | 17 | [Fact] 18 | public void Whatever() 19 | { 20 | 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/210-MinimumLevelOverrides.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/210-MinimumLevelOverrides.csx: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | 3 | LoggerConfiguration 4 | .MinimumLevel.Verbose() 5 | .MinimumLevel.Override("Microsoft", LogEventLevel.Error) 6 | .MinimumLevel.Override("Microsoft.Extensions", LogEventLevel.Information) 7 | .MinimumLevel.Override("System", LogEventLevel.Debug) 8 | ; 9 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/210-MinimumLevelOverrides.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "MinimumLevel": { 4 | "Default": "Verbose", 5 | "Override": { 6 | "Microsoft": "Error", 7 | "Microsoft.Extensions": "Information", 8 | "System": "Debug" 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/210_MinimumLevelOverrides.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Core; 2 | using Serilog.Events; 3 | using Serilog.SettingsComparisonTests.Support; 4 | using Xunit; 5 | using Xunit.Abstractions; 6 | 7 | namespace Serilog.SettingsComparisonTests 8 | { 9 | [Collection(docs)] 10 | public class MinimumLevelOverrides : BaseSettingsSupportComparisonTests 11 | { 12 | public const string docs = @"210### Minimum level overrides 13 | Minimum level can be overriden (up or down) for specific `SourceContext`s."; 14 | 15 | public MinimumLevelOverrides(ITestOutputHelper outputHelper) 16 | : base(outputHelper) 17 | { 18 | } 19 | 20 | [Theory] 21 | [InlineData("210-MinimumLevelOverrides.csx")] 22 | [InlineData("210-MinimumLevelOverrides.json")] 23 | [InlineData("210-MinimumLevelOverrides.config")] 24 | public void TestCase(string fileName) 25 | { 26 | WriteDocumentation(fileName); 27 | 28 | var loggerConfig = LoadConfig(fileName); 29 | 30 | LogEvent e = null; 31 | var logger = loggerConfig 32 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 33 | 34 | e = null; 35 | logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.SomeClass") 36 | .Warning("Should not be written (Override Microsoft >= Error)"); 37 | Assert.Null(e); 38 | logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.Extensions.SomeClass") 39 | .Debug("Should not be written (Override Microsoft.Extensions >= Information)"); 40 | Assert.Null(e); 41 | logger.ForContext(Constants.SourceContextPropertyName, "System.String") 42 | .Verbose("Should not be written (Override System >= Debug)"); 43 | Assert.Null(e); 44 | 45 | logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.SomeClass") 46 | .Error("Should be written (Override Microsoft >= Error)"); 47 | Assert.NotNull(e); 48 | e = null; 49 | logger.ForContext(Constants.SourceContextPropertyName, "Microsoft.Extensions.SomeClass") 50 | .Information("Should be written (Override Microsoft.Extensions >= Information)"); 51 | Assert.NotNull(e); 52 | e = null; 53 | logger.ForContext(Constants.SourceContextPropertyName, "System.String") 54 | .Debug("Should be written (Override System >= Debug)"); 55 | Assert.NotNull(e); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/221-AuditToWithSimpleParams.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/221-AuditToWithSimpleParams.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using TestDummies; 3 | 4 | LoggerConfiguration 5 | .AuditTo.Dummy(stringParam: "A string param", intParam: 666, nullableIntParam: null); 6 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/221-AuditToWithSimpleParams.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "AuditTo": [ 5 | { 6 | "Name": "Dummy", 7 | "Args": { 8 | "stringParam": "A string param", 9 | "intParam": 666, 10 | "nullableIntParam": "" 11 | } 12 | } 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/221_AuditToSink.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace Serilog.SettingsComparisonTests 5 | { 6 | [Collection(docs)] 7 | public class AuditToSink : BaseSettingsSupportComparisonTests 8 | { 9 | public const string docs = @"221### Sinks - `AuditTo` 10 | Some sinks provide *Audit* functionality via the configuration method `.AuditTo.MySink()`. This is also supported via configuration."; 11 | 12 | public AuditToSink(ITestOutputHelper outputHelper) 13 | : base(outputHelper) 14 | { 15 | } 16 | 17 | [Theory] 18 | [InlineData("221-AuditToWithSimpleParams.csx")] 19 | [InlineData("221-AuditToWithSimpleParams.json")] 20 | [InlineData("221-AuditToWithSimpleParams.config")] 21 | public void TestCase(string fileName) 22 | { 23 | WriteDocumentation(fileName); 24 | 25 | var loggerConfig = LoadConfig(fileName); 26 | 27 | loggerConfig.CreateLogger(); 28 | Assert.Equal("A string param", TestDummies.DummyAuditSink.StringParam); 29 | Assert.Equal(666, TestDummies.DummyAuditSink.IntParam); 30 | Assert.Null(TestDummies.DummyAuditSink.NullableIntParam); 31 | Assert.Equal("default", TestDummies.DummyAuditSink.StringParamWithDefault); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/222-LoggingLevelSwitch.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/222-LoggingLevelSwitch.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using Serilog.Core; 3 | using Serilog.Events; 4 | using TestDummies; 5 | 6 | var mySwitch = new LoggingLevelSwitch(LogEventLevel.Warning); 7 | 8 | LoggerConfiguration 9 | .MinimumLevel.ControlledBy(mySwitch) 10 | .WriteTo.DummyWithLevelSwitch(controlLevelSwitch: mySwitch); 11 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/222-LoggingLevelSwitch.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "LevelSwitches": { "$mySwitch": "Warning" }, 5 | "MinimumLevel": { 6 | "ControlledBy": "$mySwitch" 7 | }, 8 | "WriteTo": [ 9 | { 10 | "Name": "DummyWithLevelSwitch", 11 | "Args": { 12 | "controlLevelSwitch": "$mySwitch" 13 | } 14 | } 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/222_LoggingLevelSwitch.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | using Serilog.SettingsComparisonTests.Support; 3 | using TestDummies; 4 | using Xunit; 5 | using Xunit.Abstractions; 6 | 7 | namespace Serilog.SettingsComparisonTests 8 | { 9 | [Collection(docs)] 10 | public class LoggingLevelSwitch : BaseSettingsSupportComparisonTests 11 | { 12 | public const string docs = @"222### Sinks - `LoggingLevelSwitch` 13 | Some sinks such as the *Seq* sink accept a `LoggingLevelSwitch` that can be remote-controlled. In those case, the same `LoggingLevelSwitch` instance that is used to control the global minimum level must be used. 14 | The *reference* to the switch is noted with the symbol `$`."; 15 | 16 | public LoggingLevelSwitch(ITestOutputHelper outputHelper) 17 | : base(outputHelper) 18 | { 19 | } 20 | 21 | [Theory] 22 | [InlineData("222-LoggingLevelSwitch.csx")] 23 | [InlineData("222-LoggingLevelSwitch.json")] 24 | [InlineData("222-LoggingLevelSwitch.config")] 25 | public void TestCase(string fileName) 26 | { 27 | WriteDocumentation(fileName); 28 | 29 | LogEvent evt = null; 30 | var loggerConfig = LoadConfig(fileName) 31 | .WriteTo.Sink(new DelegatingSink(e => evt = e)); 32 | 33 | var logger = loggerConfig.CreateLogger(); 34 | Assert.False(DummyWithLevelSwitchSink.ControlLevelSwitch == null, "Sink ControlLevelSwitch should have been initialized"); 35 | 36 | var controlSwitch = DummyWithLevelSwitchSink.ControlLevelSwitch; 37 | Assert.NotNull(controlSwitch); 38 | 39 | logger.Information("A message that will not be logged"); 40 | Assert.True(evt is null, "LoggingLevelSwitch initial level was Warning. It should not log Information messages"); 41 | 42 | controlSwitch.MinimumLevel = LogEventLevel.Debug; 43 | logger.Debug("A message that will be logged"); 44 | Assert.True(evt != null, "LoggingLevelSwitch level was changed to Debug. It should log Debug messages"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/230-EnrichFromLogContext.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/230-EnrichFromLogContext.csx: -------------------------------------------------------------------------------- 1 | LoggerConfiguration.Enrich.FromLogContext(); 2 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/230-EnrichFromLogContext.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Enrich": [ "FromLogContext" ] 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/230_EnrichFromLogContext.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Context; 2 | using Serilog.Events; 3 | using Serilog.SettingsComparisonTests.Support; 4 | using Xunit; 5 | using Xunit.Abstractions; 6 | 7 | namespace Serilog.SettingsComparisonTests 8 | { 9 | [Collection(docs)] 10 | public class EnrichFromLogContext : BaseSettingsSupportComparisonTests 11 | { 12 | public const string docs = @"230### Enrichment from `LogContext` 13 | Log events can be enriched with `LogContext`."; 14 | 15 | public EnrichFromLogContext(ITestOutputHelper outputHelper) 16 | : base(outputHelper) 17 | { 18 | } 19 | 20 | [Theory] 21 | [InlineData("230-EnrichFromLogContext.csx")] 22 | [InlineData("230-EnrichFromLogContext.json")] 23 | [InlineData("230-EnrichFromLogContext.config")] 24 | public void TestCase(string fileName) 25 | { 26 | WriteDocumentation(fileName); 27 | 28 | var loggerConfig = LoadConfig(fileName); 29 | 30 | LogEvent e = null; 31 | var logger = loggerConfig 32 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 33 | using (LogContext.PushProperty("LogContextProperty", "value")) 34 | { 35 | logger.Information("This will be enriched with a property"); 36 | } 37 | 38 | Assert.NotNull(e); 39 | Assert.Equal("value", e.Properties["LogContextProperty"].LiteralValue()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/235-Destructure.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/235-Destructure.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using TestDummies; 3 | using TestDummies.Policies; 4 | 5 | LoggerConfiguration 6 | .Destructure.ToMaximumDepth(maximumDestructuringDepth: 3) 7 | .Destructure.ToMaximumStringLength(maximumStringLength: 3) 8 | .Destructure.ToMaximumCollectionCount(maximumCollectionCount: 3) 9 | .Destructure.AsScalar(typeof(System.Version)) 10 | .Destructure.With(new CustomPolicy()); 11 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/235-Destructure.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "Destructure": [ 5 | { 6 | "Name": "ToMaximumDepth", 7 | "Args": { "maximumDestructuringDepth": 3 } 8 | }, 9 | { 10 | "Name": "ToMaximumStringLength", 11 | "Args": { "maximumStringLength": 3 } 12 | }, 13 | { 14 | "Name": "ToMaximumCollectionCount", 15 | "Args": { "maximumCollectionCount": 3 } 16 | }, 17 | { 18 | "Name": "AsScalar", 19 | "Args": { "scalarType": "System.Version" } 20 | }, 21 | { 22 | "Name": "With", 23 | "Args": { "policy": "TestDummies.Policies.CustomPolicy, TestDummies" } 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/235_Destructure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Serilog.Events; 3 | using Serilog.SettingsComparisonTests.Support; 4 | using TestDummies.Policies; 5 | using Xunit; 6 | using Xunit.Abstractions; 7 | 8 | namespace Serilog.SettingsComparisonTests 9 | { 10 | [Collection(docs)] 11 | public class Destructure : BaseSettingsSupportComparisonTests 12 | { 13 | public const string docs = @"235### Custom Destructuring 14 | Specific *Destructuring* rules can be specified."; 15 | 16 | public Destructure(ITestOutputHelper outputHelper) 17 | : base(outputHelper) 18 | { 19 | } 20 | 21 | [Theory] 22 | [InlineData("235-Destructure.csx")] 23 | [InlineData("235-Destructure.json")] 24 | [InlineData("235-Destructure.config")] 25 | public void TestCase(string fileName) 26 | { 27 | WriteDocumentation(fileName); 28 | 29 | var loggerConfig = LoadConfig(fileName); 30 | 31 | LogEvent e = null; 32 | var logger = loggerConfig 33 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 34 | 35 | var nestedObject = new 36 | { 37 | A = new 38 | { 39 | B = new 40 | { 41 | C = new 42 | { 43 | D = "F" 44 | } 45 | } 46 | } 47 | }; 48 | 49 | var inputString = "ABCDEFGH"; 50 | var collection = new[] { 1, 2, 3, 4, 5, 6 }; 51 | var loginData = new LoginData 52 | { 53 | Password = "ThisIsSoSecret", 54 | Username = "tsimbalar" 55 | }; 56 | var version = new Version(2, 6, 1); 57 | 58 | logger.Information("{@Nested} {@String}, {@Collection}, {@LoginData}, {@Version}", 59 | nestedObject, inputString, collection, loginData, version); 60 | 61 | Assert.NotNull(e); 62 | var formattedNested = e.Properties["Nested"].ToString(); 63 | var formattedString = e.Properties["String"].ToString(); 64 | var formattedCollection = e.Properties["Collection"].ToString(); 65 | var formattedLoginData = e.Properties["LoginData"].ToString(); 66 | var formattedVersion = e.Properties["Version"]; 67 | 68 | Assert.Contains("C", formattedNested); 69 | Assert.DoesNotContain("D", formattedNested); 70 | 71 | Assert.Equal("\"AB…\"", formattedString); 72 | 73 | Assert.Contains("3", formattedCollection); 74 | Assert.DoesNotContain("4", formattedCollection); 75 | 76 | Assert.DoesNotContain("Password", formattedLoginData); 77 | Assert.DoesNotContain(loginData.Password, formattedLoginData); 78 | 79 | Assert.IsType(formattedVersion); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/240-FilterExpressions.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/240-FilterExpressions.csx: -------------------------------------------------------------------------------- 1 | #r ".\Serilog.Filters.Expressions.dll" 2 | 3 | LoggerConfiguration 4 | .Filter.ByExcluding("filter = 'exclude'"); 5 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/240-FilterExpressions.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "Serilog.Filters.Expressions" ], 4 | "Filter": [ 5 | { 6 | "Name": "ByExcluding", 7 | "Args": { 8 | "expression": "filter = 'exclude'" 9 | } 10 | } 11 | ] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/240_FilterExpressions.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | using Serilog.SettingsComparisonTests.Support; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class FilterExpressions : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"240### Filtering - Expressions 12 | Filtering can be specified using *filter expressions* thanks to the package *Serilog.Filters.Expressions*."; 13 | 14 | public FilterExpressions(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | } 18 | 19 | [Theory] 20 | [InlineData("240-FilterExpressions.csx")] 21 | [InlineData("240-FilterExpressions.json")] 22 | [InlineData("240-FilterExpressions.config")] 23 | public void TestCase(string fileName) 24 | { 25 | WriteDocumentation(fileName); 26 | 27 | var loggerConfig = LoadConfig(fileName); 28 | 29 | LogEvent e = null; 30 | var logger = loggerConfig 31 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 32 | 33 | logger.ForContext("filter", "exclude").Information("This will not be logged because filter = exclude is set"); 34 | Assert.Null(e); 35 | 36 | logger.ForContext("filter", "keep it !").Information("This will be logged because filter will let it through"); 37 | Assert.NotNull(e); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/250-SubLoggers.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/250-SubLoggers.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using TestDummies; 3 | 4 | LoggerConfiguration 5 | .WriteTo.Logger(lc => lc 6 | .Enrich.WithProperty("Prop1", "PropValue1") 7 | .WriteTo.DummyConsole() 8 | ) 9 | .WriteTo.Logger(lc => lc 10 | .Enrich.WithProperty("Prop2", "PropValue2") 11 | .WriteTo.Dummy() 12 | ); 13 | 14 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/250-SubLoggers.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo:SubLogger1": { 5 | "Name": "Logger", 6 | "Args": { 7 | "configureLogger": { 8 | "Properties": { 9 | "Prop1": "PropValue1" 10 | }, 11 | "WriteTo": [ "DummyConsole" ] 12 | } 13 | } 14 | }, 15 | "WriteTo:SubLogger2": { 16 | "Name": "Logger", 17 | "Args": { 18 | "configureLogger": { 19 | "Properties": { 20 | "Prop2": "PropValue2" 21 | }, 22 | "WriteTo": [ "Dummy" ] 23 | } 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/2-Advanced scenarios/250_SubLoggers.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Serilog.Events; 3 | using Serilog.SettingsComparisonTests.Support; 4 | using TestDummies; 5 | using TestDummies.Console; 6 | using Xunit; 7 | using Xunit.Abstractions; 8 | 9 | namespace Serilog.SettingsComparisonTests 10 | { 11 | [Collection(docs)] 12 | public class SubLoggers : BaseSettingsSupportComparisonTests 13 | { 14 | public const string docs = @"250### Sub-loggers / child loggers 15 | When conditional configuration is needed depending on the sinks, sub-loggers can be used. [More about sub-loggers](https://nblumhardt.com/2016/07/serilog-2-write-to-logger/)"; 16 | 17 | public SubLoggers(ITestOutputHelper outputHelper) 18 | : base(outputHelper) 19 | { 20 | } 21 | 22 | [Theory] 23 | [InlineData("250-SubLoggers.csx")] 24 | [InlineData("250-SubLoggers.json")] 25 | [InlineData("250-SubLoggers.config", Skip = "Not supported yet in the appSettings XML format. [![GitHub issue state](https://img.shields.io/github/issues/detail/s/serilog/serilog/1072.svg)](https://github.com/serilog/serilog/issues/1072)")] 26 | public void TestCase(string fileName) 27 | { 28 | WriteDocumentation(fileName); 29 | 30 | var loggerConfig = LoadConfig(fileName); 31 | 32 | LogEvent e = null; 33 | var logger = loggerConfig 34 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 35 | 36 | logger.Information("This message should end up in 3 different sinks with different enrichments in each"); 37 | 38 | Assert.NotNull(e); 39 | Assert.False(e.Properties.ContainsKey("Prop1"), "Property `Prop1` should not exist"); 40 | Assert.False(e.Properties.ContainsKey("Prop2"), "Property `Prop2` should not exist"); 41 | 42 | var consoleEvent = DummyConsoleSink.Emitted.SingleOrDefault(); 43 | Assert.NotNull(consoleEvent); 44 | Assert.Equal("PropValue1", consoleEvent.Properties["Prop1"].LiteralValue()); 45 | 46 | var dummySinkEvent = DummySink.Emitted.SingleOrDefault(); 47 | Assert.NotNull(dummySinkEvent); 48 | Assert.Equal("PropValue2", dummySinkEvent.Properties["Prop2"].LiteralValue()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/300_AdvancedSettings.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace Serilog.SettingsComparisonTests 5 | { 6 | [Collection(docs)] 7 | public class AdvancedSettings : BaseSettingsSupportComparisonTests 8 | { 9 | public const string docs = @"300# Advanced settings formats 10 | Below are the general rules for setting values."; 11 | 12 | public AdvancedSettings(ITestOutputHelper outputHelper) 13 | : base(outputHelper) 14 | { 15 | } 16 | 17 | [Fact] 18 | public void Whatever() 19 | { 20 | 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/310-MethodDiscovery.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/310-MethodDiscovery.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using Serilog.Events; 3 | using TestDummies; 4 | 5 | LoggerConfiguration 6 | .Filter.ByExcludingLevel(LogEventLevel.Warning) 7 | .Enrich.WithDummyUserName("UserExtraParam") 8 | .AuditTo.Dummy(stringParam: "A string param", intParam: 666) 9 | .WriteTo.Dummy() 10 | ; 11 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/310-MethodDiscovery.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "Filter": [ 5 | { 6 | "Name": "ByExcludingLevel", 7 | "Args": { 8 | "excludedLevel": "Warning" 9 | } 10 | } 11 | ], 12 | "Enrich": [ 13 | { 14 | "Name": "WithDummyUserName", 15 | "Args": { 16 | "extraParam": "UserExtraParam" 17 | } 18 | } 19 | ], 20 | "AuditTo": [ 21 | { 22 | "Name": "Dummy", 23 | "Args": { 24 | "stringParam": "A string param", 25 | "intParam": 666 26 | } 27 | } 28 | ], 29 | "WriteTo": [ "Dummy" ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/310_MethodDiscovery.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Serilog.Events; 3 | using Serilog.SettingsComparisonTests.Support; 4 | using TestDummies; 5 | using Xunit; 6 | using Xunit.Abstractions; 7 | 8 | namespace Serilog.SettingsComparisonTests 9 | { 10 | [Collection(docs)] 11 | public class MethodDiscovery : BaseSettingsSupportComparisonTests 12 | { 13 | public const string docs = @"310## Method Discovery 14 | Settings providers will discover extension methods for configuration. Remember to add `using` directives if those extension methods leave in an assembly other than *Serilog*. 15 | 16 | Extension methods to the following types are supported : 17 | 18 | | Type | C# API | xml prefix | json section 19 | | ---- | ------ | ---------- | ------------ 20 | | `LoggerSinkConfiguration` | `config.WriteTo.*` | `serilog:write-to:` | `WriteTo` 21 | | `LoggerAuditSinkConfiguration` | `config.AuditTo.*` | `serilog:audit-to:` | `AuditTo` 22 | | `LoggerEnrichmentConfiguration` | `config.Enrich.*` | `serilog:enrich:` | `Enrich` 23 | | `LoggerFilterConfiguration` | `config.Filter.*` | `serilog:filter:` | `Filter` 24 | 25 | "; 26 | 27 | public MethodDiscovery(ITestOutputHelper outputHelper) 28 | : base(outputHelper) 29 | { 30 | } 31 | 32 | [Theory] 33 | [InlineData("310-MethodDiscovery.csx")] 34 | [InlineData("310-MethodDiscovery.json")] 35 | [InlineData("310-MethodDiscovery.config")] 36 | public void TestCase(string fileName) 37 | { 38 | WriteDocumentation(fileName); 39 | 40 | var loggerConfig = LoadConfig(fileName); 41 | 42 | LogEvent e = null; 43 | var logger = loggerConfig 44 | .WriteTo.Sink(new DelegatingSink(le => e = le)).CreateLogger(); 45 | 46 | logger.Warning("This will be filtered out by Custom dummy filter"); 47 | Assert.Null(e); 48 | 49 | logger.Information("This one will be enriched and written to Dummy sinks"); 50 | Assert.NotNull(e); 51 | Assert.Equal("UserExtraParam", e.Properties["UserName"].LiteralValue()); 52 | 53 | var auditEvent = DummyAuditSink.Emitted.SingleOrDefault(); 54 | Assert.NotNull(auditEvent); 55 | Assert.Equal("A string param", DummyAuditSink.StringParam); 56 | Assert.Equal(666, DummyAuditSink.IntParam); 57 | 58 | var sinkEvent = DummySink.Emitted.SingleOrDefault(); 59 | Assert.NotNull(sinkEvent); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/320-SettingsValueConversions.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/320-SettingsValueConversions.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using System; 3 | using TestDummies; 4 | 5 | LoggerConfiguration 6 | .WriteTo.DummyWithManyParams( 7 | enumParam: MyEnum.Qux, 8 | timespanParam: new TimeSpan(2, 3, 4, 5), 9 | uriParam: new Uri("https://www.serilog.net")); 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/320-SettingsValueConversions.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "DummyWithManyParams", 7 | "Args": { 8 | "enumParam": "Qux", 9 | "timespanParam": "2.03:04:05", 10 | "uriParam": "https://www.serilog.net" 11 | } 12 | } 13 | ] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/320_SettingsValueConversions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using TestDummies; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class SettingsValueConversions : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"320## Setting values conversions 12 | ### Simple values 13 | Values for settings can be simple value types (`string`, `int`, `bool` etc), nullable versions of the previous. `Enum`s can also be parsed by name. Some specific types like `Uri` and `TimeSpan` are also supported."; 14 | 15 | public SettingsValueConversions(ITestOutputHelper outputHelper) 16 | : base(outputHelper) 17 | { 18 | 19 | } 20 | 21 | [Theory] 22 | [InlineData("320-SettingsValueConversions.csx")] 23 | [InlineData("320-SettingsValueConversions.json")] 24 | [InlineData("320-SettingsValueConversions.config")] 25 | public void TestCase(string fileName) 26 | { 27 | WriteDocumentation(fileName); 28 | 29 | var loggerConfig = LoadConfig(fileName); 30 | 31 | loggerConfig.CreateLogger(); 32 | 33 | Assert.Equal(MyEnum.Qux, DummySinkWithParams.EnumParam); 34 | Assert.Equal(new TimeSpan(2, 3, 4, 5), DummySinkWithParams.TimespanParam); 35 | Assert.Equal(new Uri("https://www.serilog.net"), DummySinkWithParams.UriParam); 36 | } 37 | 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/321-ComplexValues.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/321-ComplexValues.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using TestDummies; 3 | 4 | LoggerConfiguration 5 | .WriteTo.DummyWithComplexParams( 6 | poco: new Poco() 7 | { 8 | StringProperty = "myString", 9 | IntProperty = 42, 10 | Nested = new SubPoco() 11 | { 12 | SubProperty = "Sub" 13 | } 14 | }, 15 | intArray: new[] { 2, 4, 6 }, 16 | stringArray: new[] { "one", "two", "three" }, 17 | objArray: new SubPoco[] 18 | { 19 | new SubPoco() 20 | { 21 | SubProperty = "Sub1" 22 | }, 23 | new SubPoco() 24 | { 25 | SubProperty = "Sub2" 26 | } 27 | } 28 | ); 29 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/321-ComplexValues.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "DummyWithComplexParams", 7 | "Args": { 8 | "poco": { 9 | "stringProperty": "myString", 10 | "intProperty": 42, 11 | "nested": { 12 | "subProperty": "Sub" 13 | } 14 | }, 15 | "intArray": [ 2, 4, 6 ], 16 | "stringArray": [ "one", "two", "three" ], 17 | "objArray": [ 18 | { "subProperty": "Sub1" }, 19 | { "subProperty": "Sub2" } 20 | ] 21 | } 22 | } 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/321_ComplexValues.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using TestDummies; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class ComplexValues : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"321### Complex values 12 | Arrays or complex type can also be passed to configuration methods."; 13 | 14 | public ComplexValues(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | 18 | } 19 | 20 | [Theory] 21 | [InlineData("321-ComplexValues.csx")] 22 | [InlineData("321-ComplexValues.json")] 23 | [InlineData("321-ComplexValues.config", Skip = "Not supported yet in the appSettings XML format.")] 24 | public void TestCase(string fileName) 25 | { 26 | WriteDocumentation(fileName); 27 | 28 | var loggerConfig = LoadConfig(fileName); 29 | 30 | loggerConfig.CreateLogger(); 31 | 32 | DummySinkWithComplexParams.Poco.Should().BeEquivalentTo(new Poco() 33 | { 34 | StringProperty = "myString", 35 | IntProperty = 42, 36 | Nested = new SubPoco() 37 | { 38 | SubProperty = "Sub" 39 | } 40 | }); 41 | Assert.Equal(new[] { 2, 4, 6 }, DummySinkWithComplexParams.IntArray); 42 | Assert.Equal(new[] { "one", "two", "three" }, DummySinkWithComplexParams.StringArray); 43 | DummySinkWithComplexParams.ObjectArray.Should().BeEquivalentTo(new[] 44 | { 45 | new SubPoco() 46 | { 47 | SubProperty = "Sub1" 48 | }, 49 | new SubPoco() 50 | { 51 | SubProperty = "Sub2" 52 | }, 53 | }); 54 | } 55 | 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/330_InterfacesAndAbstractClasses.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using Xunit.Abstractions; 3 | 4 | namespace Serilog.SettingsComparisonTests 5 | { 6 | [Collection(docs)] 7 | public class InterfacesAndAbstractClasses : BaseSettingsSupportComparisonTests 8 | { 9 | public const string docs = @"330## Interfaces and abstract classes"; 10 | 11 | public InterfacesAndAbstractClasses(ITestOutputHelper outputHelper) 12 | : base(outputHelper) 13 | { 14 | } 15 | 16 | [Fact] 17 | public void Whatever() 18 | { 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/331-ImplementationDefaultConstructor.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/331-ImplementationDefaultConstructor.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using System; 3 | using Serilog.Formatting.Json; 4 | using TestDummies; 5 | using TestDummies.Console; 6 | 7 | LoggerConfiguration 8 | .WriteTo.DummyWithFormatter(formatter: new JsonFormatter()) 9 | .WriteTo.DummyConsole(theme: new CustomConsoleTheme()); 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/331-ImplementationDefaultConstructor.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "DummyWithFormatter", 7 | "Args": { 8 | "formatter": "Serilog.Formatting.Json.JsonFormatter" 9 | } 10 | }, 11 | { 12 | "Name": "DummyConsole", 13 | "Args": { 14 | "theme": "TestDummies.Console.CustomConsoleTheme, TestDummies" 15 | } 16 | } 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/331_ImplementationDefaultConstructor.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Formatting.Json; 2 | using TestDummies.Console; 3 | using Xunit; 4 | using Xunit.Abstractions; 5 | 6 | namespace Serilog.SettingsComparisonTests 7 | { 8 | [Collection(docs)] 9 | public class ImplementationDefaultConstructor : BaseSettingsSupportComparisonTests 10 | { 11 | public const string docs = @"331### Full type name of implementation with default constructor 12 | For parameters whose type is an `interface` or an `abstract class`, the full type name of an implementation " + 13 | "can be provided. If the type is not in the `Serilog` assembly, remember to include `using` directives."; 14 | 15 | public ImplementationDefaultConstructor(ITestOutputHelper outputHelper) 16 | : base(outputHelper) 17 | { 18 | } 19 | 20 | [Theory] 21 | [InlineData("331-ImplementationDefaultConstructor.csx")] 22 | [InlineData("331-ImplementationDefaultConstructor.json")] 23 | [InlineData("331-ImplementationDefaultConstructor.config")] 24 | public void TestCase(string fileName) 25 | { 26 | WriteDocumentation(fileName); 27 | 28 | var loggerConfig = LoadConfig(fileName); 29 | 30 | loggerConfig.CreateLogger(); 31 | 32 | Assert.NotNull(TestDummies.DummySink.Formatter); 33 | Assert.IsType(TestDummies.DummySink.Formatter); 34 | 35 | Assert.NotNull(DummyConsoleSink.Theme); 36 | Assert.IsType(DummyConsoleSink.Theme); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/332-ImplementationViaStaticProperty.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/332-ImplementationViaStaticProperty.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | #r ".\Serilog.Settings.Comparison.Tests.dll" 3 | using System; 4 | using Serilog.Formatting.Json; 5 | using TestDummies; 6 | using TestDummies.Console; 7 | using TestDummies.Console.Themes; 8 | using Serilog.SettingsComparisonTests.Support.Formatting; 9 | 10 | LoggerConfiguration 11 | .WriteTo.DummyWithFormatter(formatter: CustomFormatters.Formatter) 12 | .WriteTo.DummyConsole(theme: ConsoleThemes.Theme1); 13 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/332-ImplementationViaStaticProperty.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "DummyWithFormatter", 7 | "Args": { 8 | "formatter": "Serilog.SettingsComparisonTests.Support.Formatting.CustomFormatters::Formatter, Serilog.Settings.Comparison.Tests" 9 | } 10 | }, 11 | { 12 | "Name": "DummyConsole", 13 | "Args": { 14 | "theme": "TestDummies.Console.Themes.ConsoleThemes::Theme1, TestDummies" 15 | } 16 | } 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/332_StaticProperty.cs: -------------------------------------------------------------------------------- 1 | using Serilog.SettingsComparisonTests.Support.Formatting; 2 | using TestDummies.Console; 3 | using TestDummies.Console.Themes; 4 | using Xunit; 5 | using Xunit.Abstractions; 6 | 7 | namespace Serilog.SettingsComparisonTests 8 | { 9 | [Collection(docs)] 10 | public class StaticProperty : BaseSettingsSupportComparisonTests 11 | { 12 | public const string docs = @"332### Public static properties 13 | For parameters whose type is an `interface` or an `abstract class`, you can reference a static property that exposes an instance of that interface. Use the full containing type name followed by `::` and the `public static` property name."; 14 | 15 | public StaticProperty(ITestOutputHelper outputHelper) 16 | : base(outputHelper) 17 | { 18 | } 19 | 20 | [Theory] 21 | [InlineData("332-ImplementationViaStaticProperty.csx")] 22 | [InlineData("332-ImplementationViaStaticProperty.json")] 23 | [InlineData("332-ImplementationViaStaticProperty.config")] 24 | public void TestCase(string fileName) 25 | { 26 | WriteDocumentation(fileName); 27 | 28 | var loggerConfig = LoadConfig(fileName); 29 | 30 | loggerConfig.CreateLogger(); 31 | Assert.NotNull(TestDummies.DummySink.Formatter); 32 | Assert.Equal(CustomFormatters.Formatter, TestDummies.DummySink.Formatter); 33 | 34 | Assert.NotNull(DummyConsoleSink.Theme); 35 | Assert.Equal(ConsoleThemes.Theme1, DummyConsoleSink.Theme); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/390-EnvironmentVariableExpansion.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/390-EnvironmentVariableExpansion.csx: -------------------------------------------------------------------------------- 1 | #r ".\TestDummies.dll" 2 | using System; 3 | using TestDummies; 4 | 5 | 6 | LoggerConfiguration 7 | .WriteTo.Dummy( 8 | stringParam: Environment.ExpandEnvironmentVariables("%PATH%"), 9 | intParam: Int32.Parse(Environment.ExpandEnvironmentVariables("%NUMBER_OF_PROCESSORS%"))); 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/390-EnvironmentVariableExpansion.json: -------------------------------------------------------------------------------- 1 | { 2 | "Serilog": { 3 | "Using": [ "TestDummies" ], 4 | "WriteTo": [ 5 | { 6 | "Name": "Dummy", 7 | "Args": { 8 | "stringParam": "%PATH%", 9 | "intParam": "%NUMBER_OF_PROCESSORS%" 10 | } 11 | } 12 | ] 13 | } 14 | } -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/3-Advanced settings formats/390_EnvironmentVariableExpansion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | using Xunit.Abstractions; 4 | 5 | namespace Serilog.SettingsComparisonTests 6 | { 7 | [Collection(docs)] 8 | public class EnvironmentVariableExpansion : BaseSettingsSupportComparisonTests 9 | { 10 | public const string docs = @"390## Environment variable expansion 11 | Values like `%ENV_VARIABLE%` are replaced by the value of the environment variable `ENV_VARIABLE`. 12 | This can be used, for instance, to provide environment-dependent property-enrichment (ex: `%COMPUTERNAME%`) or paths (ex: %TEMP%)."; 13 | 14 | public EnvironmentVariableExpansion(ITestOutputHelper outputHelper) 15 | : base(outputHelper) 16 | { 17 | } 18 | 19 | [Theory] 20 | [InlineData("390-EnvironmentVariableExpansion.csx")] 21 | [InlineData("390-EnvironmentVariableExpansion.json")] 22 | [InlineData("390-EnvironmentVariableExpansion.config")] 23 | public void TestCase(string fileName) 24 | { 25 | WriteDocumentation(fileName); 26 | 27 | var loggerConfig = LoadConfig(fileName); 28 | 29 | loggerConfig.CreateLogger(); 30 | Assert.NotEqual("%PATH%", TestDummies.DummySink.StringParam); 31 | Assert.Equal(Environment.GetEnvironmentVariable("PATH"), TestDummies.DummySink.StringParam); 32 | Assert.NotEqual(0, TestDummies.DummySink.IntParam); 33 | Assert.Equal(Convert.ToInt32(Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS")), TestDummies.DummySink.IntParam); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/BaseSettingsSupportComparisonTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using Microsoft.Extensions.Configuration; 5 | using Serilog.Settings.Code; 6 | using TestDummies; 7 | using TestDummies.Console; 8 | using Xunit.Abstractions; 9 | 10 | namespace Serilog.SettingsComparisonTests 11 | { 12 | public abstract class BaseSettingsSupportComparisonTests : IDisposable 13 | { 14 | readonly ITestOutputHelper _outputHelper; 15 | 16 | protected BaseSettingsSupportComparisonTests(ITestOutputHelper outputHelper) 17 | { 18 | _outputHelper = outputHelper; 19 | 20 | ClearDummySinkStaticState(); 21 | } 22 | 23 | static void ClearDummySinkStaticState() 24 | { 25 | DummyConsoleSink.Reset(); 26 | DummyAuditSink.Reset(); 27 | DummySink.Reset(); 28 | DummySinkWithComplexParams.Reset(); 29 | DummyRollingFileAuditSink.Reset(); 30 | DummyRollingFileSink.Reset(); 31 | DummySinkWithParams.Reset(); 32 | DummyWithLevelSwitchSink.Reset(); 33 | } 34 | 35 | protected void WriteDocumentation(string fileName, bool includeInOutput = true) 36 | { 37 | if (!includeInOutput) 38 | { 39 | _outputHelper.WriteLine(""); 54 | } 55 | 56 | } 57 | 58 | static string GetMarkdownSnippetLanguage(string fileName) 59 | { 60 | var mdOuputFormat = fileName.Split('.').Last(); 61 | if (mdOuputFormat == "csx") mdOuputFormat = "csharp"; 62 | if (mdOuputFormat == "config") mdOuputFormat = "xml"; 63 | return mdOuputFormat; 64 | } 65 | 66 | static string GetLanguageDisplayName(string fileName) 67 | { 68 | var displayName = fileName.Split('.').Last(); 69 | if (displayName == "csx") displayName = "C#"; 70 | if (displayName == "config") displayName = "XML"; 71 | if (displayName == "json") displayName = "JSON"; 72 | return displayName; 73 | } 74 | 75 | protected static LoggerConfiguration LoadConfig(string fileName) 76 | { 77 | var fullFilePath = GetTestFileFullPath(fileName); 78 | if (fileName.EndsWith(".json")) return LoadJsonConfig(fullFilePath); 79 | if (fileName.EndsWith(".config")) return LoadXmlConfig(fullFilePath); 80 | if (fileName.EndsWith(".csx")) return LoadCSharpConfig(fullFilePath); 81 | throw new ArgumentException($"Only .json and .config are supported. Provided value : {fileName}", nameof(fileName)); 82 | } 83 | 84 | static string GetTestFileFullPath(string fileName) 85 | { 86 | return Directory.GetFiles(".", fileName, SearchOption.AllDirectories).SingleOrDefault() 87 | ?? fileName; 88 | } 89 | 90 | static LoggerConfiguration LoadXmlConfig(string fileName) 91 | { 92 | var xmlConfig = new LoggerConfiguration().ReadFrom.AppSettings(filePath: fileName); 93 | return xmlConfig; 94 | } 95 | 96 | static LoggerConfiguration LoadJsonConfig(string fileName) 97 | { 98 | var config = new ConfigurationBuilder() 99 | .AddJsonFile(fileName, optional: false) 100 | .Build(); 101 | 102 | var jsonConfig = new LoggerConfiguration().ReadFrom.Configuration(config); 103 | return jsonConfig; 104 | } 105 | 106 | static LoggerConfiguration LoadCSharpConfig(string fileName) 107 | { 108 | var code = File.ReadAllText(fileName); 109 | // this is a hack, but trying to avoid hard-coding a path in the files ... 110 | // replace .\ with an actual path 111 | code = code.Replace("#r \".\\", $"#r \"{Environment.CurrentDirectory}\\"); 112 | var jsonConfig = new LoggerConfiguration().ReadFrom.CodeString(code); 113 | return jsonConfig; 114 | } 115 | 116 | public void Dispose() 117 | { 118 | ClearDummySinkStaticState(); 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/Serilog.Settings.Comparison.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net46 5 | 6 | false 7 | 8 | Serilog.Settings.Comparison.Tests 9 | 10 | Serilog.SettingsComparisonTests 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | all 52 | runtime; build; native; contentfiles; analyzers 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/Support/DelegatingSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Serilog.Core; 3 | using Serilog.Events; 4 | 5 | namespace Serilog.SettingsComparisonTests.Support 6 | { 7 | public class DelegatingSink : ILogEventSink 8 | { 9 | readonly Action _write; 10 | 11 | public DelegatingSink(Action write) 12 | { 13 | if (write == null) throw new ArgumentNullException(nameof(write)); 14 | _write = write; 15 | } 16 | 17 | public void Emit(LogEvent logEvent) 18 | { 19 | _write(logEvent); 20 | } 21 | 22 | public static LogEvent GetLogEvent(Action writeAction) 23 | { 24 | LogEvent result = null; 25 | var l = new LoggerConfiguration() 26 | .MinimumLevel.Verbose() 27 | .WriteTo.Sink(new DelegatingSink(le => result = le)) 28 | .CreateLogger(); 29 | 30 | writeAction(l); 31 | return result; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/Support/Extensions.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Events; 2 | 3 | namespace Serilog.SettingsComparisonTests.Support 4 | { 5 | public static class Extensions 6 | { 7 | public static object LiteralValue(this LogEventPropertyValue @this) 8 | { 9 | return ((ScalarValue)@this).Value; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/Support/Formatting/CustomFormatters.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Formatting; 2 | 3 | namespace Serilog.SettingsComparisonTests.Support.Formatting 4 | { 5 | public static class CustomFormatters 6 | { 7 | public static ITextFormatter Formatter {get;} = new MyFormatter(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/Support/Formatting/MyFormatter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Serilog.Events; 4 | using Serilog.Formatting; 5 | 6 | namespace Serilog.SettingsComparisonTests.Support.Formatting 7 | { 8 | internal class MyFormatter : ITextFormatter 9 | { 10 | public void Format(LogEvent logEvent, TextWriter output) 11 | { 12 | throw new NotImplementedException(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/TODO.cs: -------------------------------------------------------------------------------- 1 |  2 | // Expected ToC 3 | // # 1- Basics 4 | // ## 101 Empty 5 | // ## 110 Minimum Level 6 | // ## 120 Sinks / WriteTo no params 7 | // ## 125 Sinks RestrictedTo 8 | // ## 128 Sinks WriteTo basic params 9 | // ## 130 Enrichment (properties) 10 | 11 | // # 2 - Advanced scenarios 12 | // ## 210 Minimum Level Overrides 13 | // ## 220 Sinks 14 | // ### 221 AuditTo 15 | // ### 222 LoggingLevelSwitch 16 | // ## 230 LogContext enrichment 17 | // ## 240 Filter 18 | // ## 250 Sub-loggers 19 | 20 | // # 3 - Advanced Settings formats 21 | // ## 310 Method Discovery 22 | // ## 320 Specific String conversions (Enum, IConvertible, Urls , Timespan etc) 23 | // ## 330 Interfaces / Abstract classes 24 | // ### 331 Default constructor 25 | // ### 332 Static property 26 | // ## 390 - Env variable expansion 27 | 28 | 29 | // specific handling for configuration reload for logginglevelswitch ?? 30 | // Serilog.Settings.Configuration : support for multiple sinks of the same kind .... 31 | // specific handling for Async or Logger (lambdas with a () => ILogger ?) 32 | 33 | -------------------------------------------------------------------------------- /test/Serilog.Settings.Comparison.Tests/xunit.runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "methodDisplay": "method" 3 | } 4 | -------------------------------------------------------------------------------- /test/TestDummies/Console/CustomConsoleTheme.cs: -------------------------------------------------------------------------------- 1 | using TestDummies.Console.Themes; 2 | 3 | namespace TestDummies.Console 4 | { 5 | public class CustomConsoleTheme : ConsoleTheme 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/TestDummies/Console/DummyConsoleSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | using TestDummies.Console.Themes; 6 | 7 | namespace TestDummies.Console 8 | { 9 | public class DummyConsoleSink : ILogEventSink 10 | { 11 | public DummyConsoleSink(ConsoleTheme theme = null) 12 | { 13 | Theme = theme ?? ConsoleTheme.None; 14 | } 15 | 16 | [ThreadStatic] 17 | public static ConsoleTheme Theme; 18 | 19 | [ThreadStatic] 20 | static List _emitted; 21 | 22 | public static List Emitted 23 | { 24 | get 25 | { 26 | if (_emitted == null) 27 | { 28 | _emitted = new List(); 29 | } 30 | return _emitted; 31 | } 32 | } 33 | 34 | public void Emit(LogEvent logEvent) 35 | { 36 | Emitted.Add(logEvent); 37 | } 38 | 39 | public static void Reset() 40 | { 41 | _emitted = null; 42 | } 43 | } 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /test/TestDummies/Console/Themes/ConcreteConsoleTheme.cs: -------------------------------------------------------------------------------- 1 | namespace TestDummies.Console.Themes 2 | { 3 | class ConcreteConsoleTheme : ConsoleTheme 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/TestDummies/Console/Themes/ConsoleTheme.cs: -------------------------------------------------------------------------------- 1 | namespace TestDummies.Console.Themes 2 | { 3 | public abstract class ConsoleTheme 4 | { 5 | public static ConsoleTheme None { get; } = new EmptyConsoleTheme(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/TestDummies/Console/Themes/ConsoleThemes.cs: -------------------------------------------------------------------------------- 1 | namespace TestDummies.Console.Themes 2 | { 3 | public static class ConsoleThemes 4 | { 5 | public static ConsoleTheme Theme1 { get; } = new ConcreteConsoleTheme(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/TestDummies/Console/Themes/EmptyConsoleTheme.cs: -------------------------------------------------------------------------------- 1 | namespace TestDummies.Console.Themes 2 | { 3 | class EmptyConsoleTheme : ConsoleTheme 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/TestDummies/DummyAuditSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | using Serilog.Formatting; 6 | 7 | namespace TestDummies 8 | { 9 | /// 10 | /// Just a dummy sink that allows to verify that the proper params are passed from configuration 11 | /// 12 | public class DummyAuditSink : ILogEventSink 13 | { 14 | 15 | public DummyAuditSink(string stringParam, int intParam, string stringParamWithDefault, int? nullableIntParam, ITextFormatter formatter) 16 | { 17 | StringParam = stringParam; 18 | IntParam = intParam; 19 | StringParamWithDefault = stringParamWithDefault; 20 | NullableIntParam = nullableIntParam; 21 | Formatter = formatter; 22 | } 23 | 24 | [ThreadStatic] 25 | public static ITextFormatter Formatter; 26 | [ThreadStatic] 27 | public static string StringParam; 28 | [ThreadStatic] 29 | public static int IntParam; 30 | [ThreadStatic] 31 | public static string StringParamWithDefault; 32 | [ThreadStatic] 33 | public static int? NullableIntParam; 34 | 35 | 36 | [ThreadStatic] 37 | static List _emitted; 38 | 39 | public static List Emitted 40 | { 41 | get 42 | { 43 | if (_emitted == null) 44 | { 45 | _emitted = new List(); 46 | } 47 | return _emitted; 48 | } 49 | } 50 | 51 | public void Emit(LogEvent logEvent) 52 | { 53 | Emitted.Add(logEvent); 54 | } 55 | 56 | public static void Reset() 57 | { 58 | Formatter = null; 59 | IntParam = default(int); 60 | NullableIntParam = null; 61 | StringParam = null; 62 | StringParamWithDefault = null; 63 | _emitted = null; 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /test/TestDummies/DummyEnricher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Serilog.Core; 3 | using Serilog.Events; 4 | 5 | namespace TestDummies 6 | { 7 | public class DummyEnricher : ILogEventEnricher 8 | { 9 | private readonly string _userName; 10 | 11 | public DummyEnricher(string userName) 12 | { 13 | _userName = userName; 14 | } 15 | 16 | public DummyEnricher() : this(null) 17 | { 18 | 19 | } 20 | 21 | public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) 22 | { 23 | logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("ThreadId", Guid.Empty.ToString(), false)); 24 | 25 | if (_userName != null) 26 | { 27 | logEvent.AddOrUpdateProperty(propertyFactory.CreateProperty("UserName", _userName, false)); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/TestDummies/DummyEventLevelFilter.cs: -------------------------------------------------------------------------------- 1 | using Serilog.Core; 2 | using Serilog.Events; 3 | 4 | namespace TestDummies 5 | { 6 | public class DummyEventLevelFilter : ILogEventFilter 7 | { 8 | LogEventLevel excludedLevel; 9 | 10 | public DummyEventLevelFilter(LogEventLevel excludedLevel) 11 | { 12 | this.excludedLevel = excludedLevel; 13 | } 14 | 15 | public bool IsEnabled(LogEvent logEvent) 16 | { 17 | return logEvent.Level != excludedLevel; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /test/TestDummies/DummyLoggerConfigurationExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Serilog; 3 | using Serilog.Events; 4 | using Serilog.Formatting; 5 | using Serilog.Configuration; 6 | using Serilog.Core; 7 | using TestDummies.Console; 8 | using TestDummies.Console.Themes; 9 | 10 | namespace TestDummies 11 | { 12 | public static class DummyLoggerConfigurationExtensions 13 | { 14 | public static LoggerConfiguration WithDummyThreadId(this LoggerEnrichmentConfiguration enrich) 15 | { 16 | return enrich.With(new DummyEnricher()); 17 | } 18 | 19 | public static LoggerConfiguration WithDummyUserName(this LoggerEnrichmentConfiguration enrich, string extraParam) 20 | { 21 | return enrich.With(new DummyEnricher(extraParam)); 22 | } 23 | 24 | public static LoggerConfiguration Dummy( 25 | this LoggerSinkConfiguration loggerSinkConfiguration 26 | ) 27 | { 28 | return loggerSinkConfiguration.Dummy(LevelAlias.Minimum); 29 | } 30 | 31 | public static LoggerConfiguration Dummy( 32 | this LoggerSinkConfiguration loggerSinkConfiguration, 33 | LogEventLevel restrictedToMinimumLevel) 34 | { 35 | return loggerSinkConfiguration.Dummy("not provided", -1, restrictedToMinimumLevel: restrictedToMinimumLevel); 36 | } 37 | 38 | public static LoggerConfiguration Dummy( 39 | this LoggerSinkConfiguration loggerSinkConfiguration, 40 | string stringParam, 41 | int intParam, 42 | string stringParamWithDefault = "default", 43 | int? nullableIntParam = 42, 44 | LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum 45 | ) 46 | { 47 | return loggerSinkConfiguration.Sink(new DummySink(stringParam, intParam, stringParamWithDefault, nullableIntParam, null), 48 | restrictedToMinimumLevel); 49 | } 50 | 51 | // AuditTo 52 | public static LoggerConfiguration Dummy( 53 | this LoggerAuditSinkConfiguration loggerSinkConfiguration, 54 | string stringParam, 55 | int intParam, 56 | string stringParamWithDefault = "default", 57 | int? nullableIntParam = 42, 58 | LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum) 59 | { 60 | return loggerSinkConfiguration.Sink(new DummyAuditSink(stringParam, intParam, stringParamWithDefault, nullableIntParam, null), 61 | restrictedToMinimumLevel); 62 | } 63 | 64 | public static LoggerConfiguration DummyWithManyParams( 65 | this LoggerSinkConfiguration loggerSinkConfiguration, 66 | MyEnum enumParam, 67 | TimeSpan timespanParam, 68 | Uri uriParam 69 | ) 70 | { 71 | return loggerSinkConfiguration.Sink(new DummySinkWithParams(enumParam, timespanParam, uriParam), LevelAlias.Minimum); 72 | } 73 | 74 | public static LoggerConfiguration DummyWithComplexParams(this LoggerSinkConfiguration loggerSinkConfiguration, 75 | Poco poco, 76 | int[] intArray, 77 | string[] stringArray, 78 | SubPoco[] objArray) 79 | { 80 | return loggerSinkConfiguration.Sink(new DummySinkWithComplexParams(poco, intArray, stringArray, objArray), LevelAlias.Minimum); 81 | } 82 | 83 | public static LoggerConfiguration DummyWithFormatter( 84 | this LoggerSinkConfiguration loggerSinkConfiguration, 85 | LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, 86 | ITextFormatter formatter = null 87 | ) 88 | { 89 | return loggerSinkConfiguration.Sink(new DummySink(null, 0, null, null, formatter), 90 | restrictedToMinimumLevel); 91 | } 92 | 93 | public static LoggerConfiguration DummyRollingFile( 94 | this LoggerAuditSinkConfiguration loggerSinkConfiguration, 95 | string pathFormat, 96 | LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, 97 | string outputTemplate = null, 98 | IFormatProvider formatProvider = null) 99 | { 100 | return loggerSinkConfiguration.Sink(new DummyRollingFileAuditSink(), restrictedToMinimumLevel); 101 | } 102 | 103 | public static LoggerConfiguration DummyWithLevelSwitch( 104 | this LoggerSinkConfiguration loggerSinkConfiguration, 105 | LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, 106 | LoggingLevelSwitch controlLevelSwitch = null) 107 | { 108 | return loggerSinkConfiguration.Sink(new DummyWithLevelSwitchSink(controlLevelSwitch), restrictedToMinimumLevel); 109 | } 110 | 111 | public static LoggerConfiguration DummyConsole( 112 | this LoggerSinkConfiguration loggerSinkConfiguration, 113 | LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, 114 | ConsoleTheme theme = null) 115 | { 116 | return loggerSinkConfiguration.Sink(new DummyConsoleSink(theme), restrictedToMinimumLevel); 117 | } 118 | 119 | public static LoggerConfiguration ByExcludingLevel(this LoggerFilterConfiguration loggerFilterConfiguration, 120 | LogEventLevel excludedLevel) 121 | { 122 | return loggerFilterConfiguration.With(new DummyEventLevelFilter(excludedLevel)); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /test/TestDummies/DummyRollingFileAuditSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | 6 | namespace TestDummies 7 | { 8 | public class DummyRollingFileAuditSink : ILogEventSink 9 | { 10 | [ThreadStatic] 11 | static List _emitted; 12 | 13 | public static List Emitted 14 | { 15 | get 16 | { 17 | if (_emitted == null) 18 | { 19 | _emitted = new List(); 20 | } 21 | return _emitted; 22 | } 23 | } 24 | 25 | public void Emit(LogEvent logEvent) 26 | { 27 | Emitted.Add(logEvent); 28 | } 29 | 30 | public static void Reset() 31 | { 32 | _emitted = null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/TestDummies/DummyRollingFileSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | 6 | namespace TestDummies 7 | { 8 | public class DummyRollingFileSink : ILogEventSink 9 | { 10 | [ThreadStatic] 11 | static List _emitted; 12 | 13 | public static List Emitted 14 | { 15 | get 16 | { 17 | if (_emitted == null) 18 | { 19 | _emitted = new List(); 20 | } 21 | return _emitted; 22 | } 23 | } 24 | 25 | public void Emit(LogEvent logEvent) 26 | { 27 | Emitted.Add(logEvent); 28 | } 29 | 30 | public static void Reset() 31 | { 32 | _emitted = null; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/TestDummies/DummySink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | using Serilog.Formatting; 6 | 7 | namespace TestDummies 8 | { 9 | /// 10 | /// Just a dummy sink that allows to verify that the proper params are passed from configuration 11 | /// 12 | public class DummySink : ILogEventSink 13 | { 14 | 15 | public DummySink(string stringParam, int intParam, string stringParamWithDefault, int? nullableIntParam, ITextFormatter formatter) 16 | { 17 | StringParam = stringParam; 18 | IntParam = intParam; 19 | StringParamWithDefault = stringParamWithDefault; 20 | NullableIntParam = nullableIntParam; 21 | Formatter = formatter; 22 | } 23 | 24 | [ThreadStatic] 25 | public static ITextFormatter Formatter; 26 | [ThreadStatic] 27 | public static string StringParam; 28 | [ThreadStatic] 29 | public static int IntParam; 30 | [ThreadStatic] 31 | public static string StringParamWithDefault; 32 | [ThreadStatic] 33 | public static int? NullableIntParam; 34 | 35 | [ThreadStatic] 36 | static List _emitted; 37 | 38 | public static List Emitted 39 | { 40 | get 41 | { 42 | if (_emitted == null) 43 | { 44 | _emitted = new List(); 45 | } 46 | return _emitted; 47 | } 48 | } 49 | 50 | public void Emit(LogEvent logEvent) 51 | { 52 | Emitted.Add(logEvent); 53 | } 54 | 55 | public static void Reset() 56 | { 57 | Formatter = null; 58 | IntParam = default(int); 59 | NullableIntParam = null; 60 | StringParam = null; 61 | StringParamWithDefault = null; 62 | _emitted = null; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /test/TestDummies/DummySinkWithComplexParams.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | 6 | namespace TestDummies 7 | { 8 | public class DummySinkWithComplexParams : ILogEventSink 9 | { 10 | public DummySinkWithComplexParams(Poco poco, int[] intArray, string[] stringArray, SubPoco[] objArray) 11 | { 12 | Poco = poco; 13 | IntArray = intArray; 14 | StringArray = stringArray; 15 | ObjectArray = objArray; 16 | } 17 | 18 | [ThreadStatic] 19 | public static int[] IntArray; 20 | 21 | [ThreadStatic] 22 | public static string[] StringArray; 23 | 24 | [ThreadStatic] 25 | public static SubPoco[] ObjectArray; 26 | 27 | [ThreadStatic] 28 | public static Poco Poco; 29 | 30 | [ThreadStatic] 31 | static List _emitted; 32 | 33 | public static List Emitted 34 | { 35 | get 36 | { 37 | if (_emitted == null) 38 | { 39 | _emitted = new List(); 40 | } 41 | return _emitted; 42 | } 43 | } 44 | 45 | public void Emit(LogEvent logEvent) 46 | { 47 | Emitted.Add(logEvent); 48 | } 49 | 50 | public static void Reset() 51 | { 52 | IntArray = default(int[]); 53 | StringArray = default(string[]); 54 | ObjectArray = default(SubPoco[]); 55 | Poco = default(Poco); 56 | 57 | _emitted = null; 58 | } 59 | } 60 | 61 | public class Poco 62 | { 63 | public string StringProperty { get; set; } 64 | public int IntProperty { get; set; } 65 | public SubPoco Nested { get; set; } 66 | } 67 | 68 | public class SubPoco 69 | { 70 | public string SubProperty { get; set; } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /test/TestDummies/DummySinkWithParams.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | 6 | namespace TestDummies 7 | { 8 | public class DummySinkWithParams : ILogEventSink 9 | { 10 | public DummySinkWithParams(MyEnum enumParam, TimeSpan timespanParam, Uri uriParam) 11 | { 12 | EnumParam = enumParam; 13 | TimespanParam = timespanParam; 14 | UriParam = uriParam; 15 | } 16 | 17 | [ThreadStatic] 18 | public static MyEnum EnumParam; 19 | 20 | [ThreadStatic] 21 | public static TimeSpan TimespanParam; 22 | 23 | [ThreadStatic] 24 | public static Uri UriParam; 25 | 26 | [ThreadStatic] 27 | static List _emitted; 28 | 29 | public static List Emitted 30 | { 31 | get 32 | { 33 | if (_emitted == null) 34 | { 35 | _emitted = new List(); 36 | } 37 | return _emitted; 38 | } 39 | } 40 | 41 | public void Emit(LogEvent logEvent) 42 | { 43 | Emitted.Add(logEvent); 44 | } 45 | 46 | public static void Reset() 47 | { 48 | EnumParam = default(MyEnum); 49 | TimespanParam = default(TimeSpan); 50 | UriParam = default(Uri); 51 | _emitted = null; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /test/TestDummies/DummyWithLevelSwitchSink.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Serilog.Core; 4 | using Serilog.Events; 5 | 6 | namespace TestDummies 7 | { 8 | public class DummyWithLevelSwitchSink : ILogEventSink 9 | { 10 | public DummyWithLevelSwitchSink(LoggingLevelSwitch loggingControlLevelSwitch) 11 | { 12 | ControlLevelSwitch = loggingControlLevelSwitch; 13 | } 14 | 15 | [ThreadStatic] 16 | public static LoggingLevelSwitch ControlLevelSwitch; 17 | 18 | [ThreadStatic] 19 | static List _emitted; 20 | 21 | public static List Emitted 22 | { 23 | get 24 | { 25 | if (_emitted == null) 26 | { 27 | _emitted = new List(); 28 | } 29 | return _emitted; 30 | } 31 | } 32 | 33 | public void Emit(LogEvent logEvent) 34 | { 35 | Emitted.Add(logEvent); 36 | } 37 | 38 | public static void Reset() 39 | { 40 | ControlLevelSwitch = default(LoggingLevelSwitch); 41 | _emitted = null; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/TestDummies/MyEnum.cs: -------------------------------------------------------------------------------- 1 | namespace TestDummies 2 | { 3 | public enum MyEnum 4 | { 5 | Foo, 6 | Bar, 7 | Qux 8 | } 9 | } -------------------------------------------------------------------------------- /test/TestDummies/Policies/CustomPolicy.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Serilog.Core; 3 | using Serilog.Events; 4 | 5 | namespace TestDummies.Policies 6 | { 7 | public class LoginData 8 | { 9 | public string Username { get; set; } 10 | public string Password { get; set; } 11 | } 12 | 13 | public class CustomPolicy : IDestructuringPolicy 14 | { 15 | public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result) 16 | { 17 | result = null; 18 | 19 | if (value is LoginData) 20 | { 21 | result = new StructureValue( 22 | new List 23 | { 24 | new LogEventProperty("Username", new ScalarValue(((LoginData)value).Username)) 25 | }); 26 | } 27 | 28 | return (result != null); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /test/TestDummies/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyConfiguration("")] 8 | [assembly: AssemblyCompany("")] 9 | [assembly: AssemblyProduct("TestDummies")] 10 | [assembly: AssemblyTrademark("")] 11 | 12 | // Setting ComVisible to false makes the types in this assembly not visible 13 | // to COM components. If you need to access a type in this assembly from 14 | // COM, set the ComVisible attribute to true on that type. 15 | [assembly: ComVisible(false)] 16 | 17 | // The following GUID is for the ID of the typelib if this project is exposed to COM 18 | [assembly: Guid("2bb12ce5-c867-43bd-ae5d-253fe3248c7f")] 19 | -------------------------------------------------------------------------------- /test/TestDummies/TestDummies.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net452 5 | TestDummies 6 | ../../assets/Serilog.snk 7 | true 8 | true 9 | TestDummies 10 | false 11 | false 12 | false 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | --------------------------------------------------------------------------------