Skip to content

Commit

Permalink
Merge pull request #78 from serilog/dev
Browse files Browse the repository at this point in the history
3.4.1 Release
  • Loading branch information
nblumhardt authored Oct 10, 2022
2 parents 0ee44d1 + 56f298e commit 25c6509
Show file tree
Hide file tree
Showing 157 changed files with 7,361 additions and 7,637 deletions.
12 changes: 6 additions & 6 deletions Build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ echo "build: Build started"
Push-Location $PSScriptRoot

if(Test-Path .\artifacts) {
echo "build: Cleaning .\artifacts"
Remove-Item .\artifacts -Force -Recurse
echo "build: Cleaning ./artifacts"
Remove-Item ./artifacts -Force -Recurse
}

& dotnet restore --no-cache
Expand All @@ -18,24 +18,24 @@ $buildSuffix = @{ $true = "$($suffix)-$($commitHash)"; $false = "$($branch)-$($c
echo "build: Package version suffix is $suffix"
echo "build: Build version suffix is $buildSuffix"

foreach ($src in ls src/*) {
foreach ($src in gci src/*) {
Push-Location $src

echo "build: Packaging project in $src"

& dotnet build -c Release --version-suffix=$buildSuffix

if($suffix) {
& dotnet pack -c Release --include-source --no-build -o ..\..\artifacts --version-suffix=$suffix
& dotnet pack -c Release --include-source --no-build -o ../../artifacts --version-suffix=$suffix
} else {
& dotnet pack -c Release --include-source --no-build -o ..\..\artifacts
& dotnet pack -c Release --include-source --no-build -o ../../artifacts
}
if($LASTEXITCODE -ne 0) { exit 1 }

Pop-Location
}

foreach ($test in ls test/*.Tests) {
foreach ($test in gci test/*.Tests) {
Push-Location $test

echo "build: Testing project in $test"
Expand Down
5 changes: 3 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<Nullable>enable</Nullable>
Expand All @@ -7,5 +6,7 @@
<AssemblyOriginatorKeyFile>../../assets/Serilog.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>
</Project>
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,12 @@ Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1)

This expression takes advantage of `LastIndexOf()` returning -1 when no `.` character appears in `SourceContext`, to yield a `startIndex` of 0 in that case.

**Write not-referenced context properties (only if there are any):**

```
{#if rest(true) <> {}} <Context: {rest(true)}>{#end}
```

**Access a property with a non-identifier name:**

```
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
version: '{build}'
skip_tags: true
image: Visual Studio 2019
image: Visual Studio 2022
build_script:
- ps: ./Build.ps1
- pwsh: ./Build.ps1
artifacts:
- path: artifacts/Serilog.*.nupkg
deploy:
Expand Down
189 changes: 93 additions & 96 deletions example/Sample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,113 +1,110 @@
using System;
using System.Collections.Generic;
using Serilog;
using Serilog;
using Serilog.Debugging;
using Serilog.Templates;
using Serilog.Templates.Themes;

namespace Sample
namespace Sample;

// ReSharper disable once ClassNeverInstantiated.Global
public class Program
{
// ReSharper disable once ClassNeverInstantiated.Global
public class Program
public static void Main()
{
public static void Main()
{
SelfLog.Enable(Console.Error);

TextFormattingExample1();
JsonFormattingExample();
PipelineComponentExample();
TextFormattingExample2();
}

static void TextFormattingExample1()
{
using var log = new LoggerConfiguration()
.Enrich.WithProperty("Application", "Sample")
.WriteTo.Console(new ExpressionTemplate(
"[{@t:HH:mm:ss} {@l:u3}" +
"{#if SourceContext is not null} ({Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1)}){#end}] " +
"{@m} (first item is {coalesce(Items[0], '<empty>')}) {rest()}\n{@x}",
theme: TemplateTheme.Code))
.CreateLogger();
SelfLog.Enable(Console.Error);

log.Information("Running {Example}", nameof(TextFormattingExample1));

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Tea", "Coffee" });

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Apricots" });
}

static void JsonFormattingExample()
{
using var log = new LoggerConfiguration()
.Enrich.WithProperty("Application", "Example")
.WriteTo.Console(new ExpressionTemplate(
"{ {@t: UtcDateTime(@t), @mt, @l: if @l = 'Information' then undefined() else @l, @x, ..@p} }\n"))
.CreateLogger();
TextFormattingExample1();
JsonFormattingExample();
PipelineComponentExample();
TextFormattingExample2();
}

log.Information("Running {Example}", nameof(JsonFormattingExample));
static void TextFormattingExample1()
{
using var log = new LoggerConfiguration()
.Enrich.WithProperty("Application", "Sample")
.WriteTo.Console(new ExpressionTemplate(
"[{@t:HH:mm:ss} {@l:u3}" +
"{#if SourceContext is not null} ({Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1)}){#end}] " +
"{@m} (first item is {coalesce(Items[0], '<empty>')}) {rest()}\n{@x}",
theme: TemplateTheme.Code))
.CreateLogger();

log.Information("Running {Example}", nameof(TextFormattingExample1));

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Tea", "Coffee" });

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Apricots" });
}

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Tea", "Coffee" });
static void JsonFormattingExample()
{
using var log = new LoggerConfiguration()
.Enrich.WithProperty("Application", "Example")
.WriteTo.Console(new ExpressionTemplate(
"{ {@t: UtcDateTime(@t), @mt, @l: if @l = 'Information' then undefined() else @l, @x, ..@p} }\n"))
.CreateLogger();

log.ForContext<Program>()
.Warning("Cart is empty");
}
log.Information("Running {Example}", nameof(JsonFormattingExample));

static void PipelineComponentExample()
{
using var log = new LoggerConfiguration()
.Enrich.WithProperty("Application", "Example")
.Enrich.WithComputed("FirstItem", "coalesce(Items[0], '<empty>')")
.Enrich.WithComputed("SourceContext", "coalesce(Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), '<no source>')")
.Filter.ByIncludingOnly("Items is null or Items[?] like 'C%'")
.WriteTo.Console(outputTemplate:
"[{Timestamp:HH:mm:ss} {Level:u3} ({SourceContext})] {Message:lj} (first item is {FirstItem}){NewLine}{Exception}")
.CreateLogger();
log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Tea", "Coffee" });

log.Information("Running {Example}", nameof(PipelineComponentExample));
log.ForContext<Program>()
.Warning("Cart is empty");
}

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Tea", "Coffee" });
static void PipelineComponentExample()
{
using var log = new LoggerConfiguration()
.Enrich.WithProperty("Application", "Example")
.Enrich.WithComputed("FirstItem", "coalesce(Items[0], '<empty>')")
.Enrich.WithComputed("SourceContext", "coalesce(Substring(SourceContext, LastIndexOf(SourceContext, '.') + 1), '<no source>')")
.Filter.ByIncludingOnly("Items is null or Items[?] like 'C%'")
.WriteTo.Console(outputTemplate:
"[{Timestamp:HH:mm:ss} {Level:u3} ({SourceContext})] {Message:lj} (first item is {FirstItem}){NewLine}{Exception}")
.CreateLogger();

log.Information("Running {Example}", nameof(PipelineComponentExample));

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Tea", "Coffee" });

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Apricots" });
}

log.ForContext<Program>()
.Information("Cart contains {@Items}", new[] { "Apricots" });
}
static void TextFormattingExample2()
{
// Emulates `Microsoft.Extensions.Logging`'s `ConsoleLogger`.

static void TextFormattingExample2()
var melon = new TemplateTheme(TemplateTheme.Literate, new Dictionary<TemplateThemeStyle, string>
{
// Emulates `Microsoft.Extensions.Logging`'s `ConsoleLogger`.

var melon = new TemplateTheme(TemplateTheme.Literate, new Dictionary<TemplateThemeStyle, string>
{
// `Information` is dark green in MEL.
[TemplateThemeStyle.LevelInformation] = "\x1b[38;5;34m",
[TemplateThemeStyle.String] = "\x1b[38;5;159m",
[TemplateThemeStyle.Number] = "\x1b[38;5;159m"
});

using var log = new LoggerConfiguration()
.WriteTo.Console(new ExpressionTemplate(
"{@l:w4}: {SourceContext}\n" +
"{#if Scope is not null}" +
" {#each s in Scope}=> {s}{#delimit} {#end}\n" +
"{#end}" +
" {@m}\n" +
"{@x}",
theme: melon))
.CreateLogger();

var program = log.ForContext<Program>();
program.Information("Host listening at {ListenUri}", "https://hello-world.local");

program
.ForContext("Scope", new[] {"Main", "TextFormattingExample2()"})
.Information("HTTP {Method} {Path} responded {StatusCode} in {Elapsed:0.000} ms", "GET", "/api/hello", 200, 1.23);

program.Warning("We've reached the end of the line");
}
// `Information` is dark green in MEL.
[TemplateThemeStyle.LevelInformation] = "\x1b[38;5;34m",
[TemplateThemeStyle.String] = "\x1b[38;5;159m",
[TemplateThemeStyle.Number] = "\x1b[38;5;159m"
});

using var log = new LoggerConfiguration()
.WriteTo.Console(new ExpressionTemplate(
"{@l:w4}: {SourceContext}\n" +
"{#if Scope is not null}" +
" {#each s in Scope}=> {s}{#delimit} {#end}\n" +
"{#end}" +
" {@m}\n" +
"{@x}",
theme: melon))
.CreateLogger();

var program = log.ForContext<Program>();
program.Information("Host listening at {ListenUri}", "https://hello-world.local");

program
.ForContext("Scope", new[] {"Main", "TextFormattingExample2()"})
.Information("HTTP {Method} {Path} responded {StatusCode} in {Elapsed:0.000} ms", "GET", "/api/hello", 200, 1.23);

program.Warning("We've reached the end of the line");
}
}
}
2 changes: 1 addition & 1 deletion example/Sample/Sample.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net6.0</TargetFramework>
<OutputType>Exe</OutputType>
</PropertyGroup>

Expand Down
31 changes: 14 additions & 17 deletions src/Serilog.Expressions/Expressions/Ast/AccessorExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
namespace Serilog.Expressions.Ast;

namespace Serilog.Expressions.Ast
class AccessorExpression : Expression
{
class AccessorExpression : Expression
public AccessorExpression(Expression receiver, string memberName)
{
public AccessorExpression(Expression receiver, string memberName)
{
MemberName = memberName ?? throw new ArgumentNullException(nameof(memberName));
Receiver = receiver;
}
MemberName = memberName ?? throw new ArgumentNullException(nameof(memberName));
Receiver = receiver;
}

public string MemberName { get; }
public string MemberName { get; }

public Expression Receiver { get; }
public Expression Receiver { get; }

public override string ToString()
{
if (SerilogExpression.IsValidIdentifier(MemberName))
return Receiver + "." + MemberName;
public override string ToString()
{
if (SerilogExpression.IsValidIdentifier(MemberName))
return Receiver + "." + MemberName;

return $"{Receiver}['{SerilogExpression.EscapeStringContent(MemberName)}']";
}
return $"{Receiver}['{SerilogExpression.EscapeStringContent(MemberName)}']";
}
}
}
37 changes: 17 additions & 20 deletions src/Serilog.Expressions/Expressions/Ast/AmbientNameExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,28 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
namespace Serilog.Expressions.Ast;

namespace Serilog.Expressions.Ast
class AmbientNameExpression : Expression
{
class AmbientNameExpression : Expression
{
readonly bool _requiresEscape;
readonly bool _requiresEscape;

public AmbientNameExpression(string name, bool isBuiltIn)
{
PropertyName = name ?? throw new ArgumentNullException(nameof(name));
IsBuiltIn = isBuiltIn;
_requiresEscape = !SerilogExpression.IsValidIdentifier(name);
}
public AmbientNameExpression(string name, bool isBuiltIn)
{
PropertyName = name ?? throw new ArgumentNullException(nameof(name));
IsBuiltIn = isBuiltIn;
_requiresEscape = !SerilogExpression.IsValidIdentifier(name);
}

public string PropertyName { get; }
public string PropertyName { get; }

public bool IsBuiltIn { get; }
public bool IsBuiltIn { get; }

public override string ToString()
{
if (_requiresEscape)
return $"@Properties['{SerilogExpression.EscapeStringContent(PropertyName)}']";
public override string ToString()
{
if (_requiresEscape)
return $"@Properties['{SerilogExpression.EscapeStringContent(PropertyName)}']";

return (IsBuiltIn ? "@" : "") + PropertyName;
}
return (IsBuiltIn ? "@" : "") + PropertyName;
}
}
}
Loading

0 comments on commit 25c6509

Please sign in to comment.