-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #224 from datalust/dev
8.0.0 Release
- Loading branch information
Showing
14 changed files
with
373 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/PreserveDottedPropertyNames.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Copyright © Serilog Contributors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
using System.Collections.Generic; | ||
using Serilog.Events; | ||
|
||
namespace Serilog.Sinks.Seq.Conventions; | ||
|
||
/// <summary> | ||
/// Maintains verbatim processing of property names. A property named <c>"a.b"</c> will be transmitted to Seq as a | ||
/// scalar value with name <c>"a.b"</c>. | ||
/// </summary> | ||
class PreserveDottedPropertyNames: IDottedPropertyNameConvention | ||
{ | ||
/// <inheritdoc /> | ||
public IReadOnlyDictionary<string, LogEventPropertyValue> ProcessDottedPropertyNames(IReadOnlyDictionary<string, LogEventPropertyValue> maybeDotted) | ||
{ | ||
return maybeDotted; | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
src/Serilog.Sinks.Seq/Sinks/Seq/Conventions/UnflattenDottedPropertyNames.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
// Copyright © Serilog Contributors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
using System.Linq; | ||
using Serilog.Events; | ||
|
||
namespace Serilog.Sinks.Seq.Conventions; | ||
|
||
/// <summary> | ||
/// Experimental. Unflatten property names. A property with name <c>"a.b"</c> will be transmitted to Seq as | ||
/// a structure with name <c>"a"</c>, and one member <c>"b"</c>. | ||
/// </summary> | ||
/// <remarks>This behavior is enabled when the <c>Serilog.Parsing.MessageTemplateParser.AcceptDottedPropertyNames</c> | ||
/// <see cref="AppContext"/> switch is set to value <c langword="true"/>.</remarks> | ||
class UnflattenDottedPropertyNames: IDottedPropertyNameConvention | ||
{ | ||
const int MaxDepth = 10; | ||
|
||
/// <inheritdoc /> | ||
public IReadOnlyDictionary<string, LogEventPropertyValue> ProcessDottedPropertyNames(IReadOnlyDictionary<string, LogEventPropertyValue> maybeDotted) | ||
{ | ||
return DottedToNestedRecursive(maybeDotted, 0); | ||
} | ||
|
||
static IReadOnlyDictionary<string, LogEventPropertyValue> DottedToNestedRecursive(IReadOnlyDictionary<string, LogEventPropertyValue> maybeDotted, int depth) | ||
{ | ||
if (depth == MaxDepth) | ||
return maybeDotted; | ||
|
||
// Assume that the majority of entries will be bare or have unique prefixes. | ||
var result = new Dictionary<string, LogEventPropertyValue>(maybeDotted.Count); | ||
|
||
// Sorted for determinism. | ||
var dotted = new SortedDictionary<string, LogEventPropertyValue>(StringComparer.Ordinal); | ||
|
||
// First - give priority to bare names, since these would otherwise be claimed by the parents of further nested | ||
// layers and we'd have nowhere to put them when resolving conflicts. (Dotted entries that conflict can keep their dotted keys). | ||
|
||
foreach (var kv in maybeDotted) | ||
{ | ||
if (IsDottedIdentifier(kv.Key)) | ||
{ | ||
// Stash for processing in the next stage. | ||
dotted.Add(kv.Key, kv.Value); | ||
} | ||
else | ||
{ | ||
result.Add(kv.Key, kv.Value); | ||
} | ||
} | ||
|
||
// Then - for dotted keys with a prefix not already present in the result, convert to structured data and add to | ||
// the result. Any set of dotted names that collide with a preexisting key will be left as-is. | ||
|
||
string? prefix = null; | ||
Dictionary<string, LogEventPropertyValue>? nested = null; | ||
foreach (var kv in dotted) | ||
{ | ||
var (newPrefix, rem) = TakeFirstIdentifier(kv.Key); | ||
|
||
if (prefix != null && prefix != newPrefix) | ||
{ | ||
result.Add(prefix, MakeStructureValue(DottedToNestedRecursive(nested!, depth + 1))); | ||
prefix = null; | ||
nested = null; | ||
} | ||
|
||
if (nested != null && !nested.ContainsKey(rem)) | ||
{ | ||
prefix = newPrefix; | ||
nested.Add(rem, kv.Value); | ||
} | ||
else if (nested == null && !result.ContainsKey(newPrefix)) | ||
{ | ||
prefix = newPrefix; | ||
nested = new () { { rem, kv.Value } }; | ||
} | ||
else | ||
{ | ||
result.Add(kv.Key, kv.Value); | ||
} | ||
} | ||
|
||
if (prefix != null) | ||
{ | ||
result[prefix] = MakeStructureValue(DottedToNestedRecursive(nested!, depth + 1)); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
static LogEventPropertyValue MakeStructureValue(IReadOnlyDictionary<string,LogEventPropertyValue> properties) | ||
{ | ||
return new StructureValue(properties.Select(kv => new LogEventProperty(kv.Key, kv.Value)), typeTag: null); | ||
} | ||
|
||
internal static bool IsDottedIdentifier(string key) => | ||
key.Contains('.') && | ||
!key.StartsWith(".", StringComparison.Ordinal) && | ||
!key.EndsWith(".", StringComparison.Ordinal) && | ||
key.Split('.').All(IsIdentifier); | ||
|
||
static bool IsIdentifier(string s) => s.Length != 0 && | ||
!char.IsDigit(s[0]) && | ||
s.All(ch => char.IsLetter(ch) || char.IsDigit(ch) || ch == '_'); | ||
|
||
static (string, string) TakeFirstIdentifier(string dottedIdentifier) | ||
{ | ||
// We can do this simplistically because keys in `dotted` conform to `IsDottedName`. | ||
Debug.Assert(IsDottedIdentifier(dottedIdentifier)); | ||
|
||
var firstDot = dottedIdentifier.IndexOf('.'); | ||
var prefix = dottedIdentifier.Substring(0, firstDot); | ||
var rem = dottedIdentifier.Substring(firstDot + 1); | ||
return (prefix, rem); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
src/Serilog.Sinks.Seq/Sinks/Seq/IDottedPropertyNameConvention.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Copyright © Serilog Contributors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
using System.Collections.Generic; | ||
using Serilog.Events; | ||
|
||
namespace Serilog.Sinks.Seq; | ||
|
||
/// <summary> | ||
/// Enables switching between the experimental "unflattening" behavior applied to dotted property names, and the | ||
/// regular verbatim property name handling. | ||
/// </summary> | ||
interface IDottedPropertyNameConvention | ||
{ | ||
/// <summary> | ||
/// Convert the properties in <paramref name="maybeDotted"/> into the form specified by the current property | ||
/// name processing convention. | ||
/// </summary> | ||
/// <param name="maybeDotted">The properties associated with a log event.</param> | ||
/// <returns>The processed properties.</returns> | ||
IReadOnlyDictionary<string, LogEventPropertyValue> ProcessDottedPropertyNames(IReadOnlyDictionary<string, LogEventPropertyValue> maybeDotted); | ||
} |
Oops, something went wrong.