Skip to content

Commit a5c158c

Browse files
authored
Merge pull request #640 from serilog-mssql/dev
# 9.0.0 * Updated SqlClient to 6.1.1 and removed Azure.Identity workaround for issue #624 * Updated all dependencies except .NET 9 NuGets * Implemented #636: Added support for non-clustered index sort direction (thanks to @gumbarros)
2 parents e91ce9a + 2fcf5c2 commit a5c158c

File tree

17 files changed

+267
-43
lines changed

17 files changed

+267
-43
lines changed

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 9.0.0
2+
* Updated SqlClient to 6.1.1 and removed Azure.Identity workaround for issue #624
3+
* Updated all dependencies except .NET 9 NuGets
4+
* Implemented #636: Added support for non-clustered index sort direction (thanks to @gumbarros)
5+
16
# 8.2.2
27
* Fixed issue #624: Enforce new version of transient dependency to fix vulnerability and avoid nuget.org version de-listing until SqlClient 6.1 is released.
38

DEVELOPMENT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Whenever the `dev` branch is updated (after merging a pull request), the `Releas
66

77
## Creating a latest Release
88

9-
### Normal Update (no major version change) {#normal-update}
9+
### Normal Update (no major version change)
1010

1111
1. On the `dev` branch, update CHANGES.md and `VersionPrefix` in Serilog.Sinks.MSSqlServer.csproj.
1212

@@ -18,6 +18,6 @@ Whenever the `dev` branch is updated (after merging a pull request), the `Releas
1818

1919
1. On the `dev` branch, update CHANGES.md and increase the major version in `VersionPrefix` in Serilog.Sinks.MSSqlServer.csproj. Also set `EnablePackageValidation` to false because on an intial release of a new major version you don't have a baseline version yet on nuget.org to compare with.
2020

21-
1. Create a PR to merge the `dev` branch into `main`. The `Release` action will be triggered. This works the same as described above under [Normal Update]({#normal-update).
21+
1. Create a PR to merge the `dev` branch into `main`. The `Release` action will be triggered. This works the same as described above under [Normal Update](#normal-update-no-major-version-change).
2222

2323
1. After the release is done make some changes in Serilog.Sinks.MSSqlServer.csproj on the `dev` branch. Set `EnablePackageValidation` back to true and `PackageValidationBaselineVersion` to the version of the new major release you just created (e.g. 7.0.0). Then also increase the patch version number in `VersionPrefix` (e.g. 7.0.1).

Directory.Packages.props

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,22 @@
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
44
</PropertyGroup>
55
<ItemGroup>
6-
<PackageVersion Include="BenchmarkDotNet" Version="0.14.0" />
7-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
6+
<PackageVersion Include="BenchmarkDotNet" Version="0.15.2" />
7+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
88
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="8.0.1" />
9-
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.3" />
9+
<PackageVersion Include="Microsoft.Data.SqlClient" Version="6.1.1" />
1010
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
1111
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
1212
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
1313
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" />
14-
<PackageVersion Include="Microsoft.Identity.Client" Version="4.73.1" />
1514
<PackageVersion Include="coverlet.collector" Version="3.2.0" />
16-
<PackageVersion Include="FluentAssertions" Version="6.12.1" />
17-
<PackageVersion Include="Dapper.StrongName" Version="2.1.35" />
18-
<PackageVersion Include="Moq" Version="4.18.2" />
19-
<PackageVersion Include="xunit" Version="2.9.2" />
15+
<PackageVersion Include="FluentAssertions" Version="8.6.0" />
16+
<PackageVersion Include="Dapper.StrongName" Version="2.1.66" />
17+
<PackageVersion Include="Moq" Version="4.20.72" />
18+
<PackageVersion Include="xunit" Version="2.9.3" />
2019
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2" />
21-
<PackageVersion Include="Serilog" Version="4.1.0" />
20+
<PackageVersion Include="Serilog" Version="4.3.0" />
2221
<PackageVersion Include="Serilog.Extensions.Hosting" Version="8.0.0" />
2322
<PackageVersion Include="Serilog.Settings.Configuration" Version="8.0.4" />
2423
</ItemGroup>
25-
</Project>
24+
</Project>

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ columnOpts.Store.Add(StandardColumn.LogEvent);
110110
columnOpts.LogEvent.DataLength = 2048;
111111
columnOpts.PrimaryKey = columnOpts.TimeStamp;
112112
columnOpts.TimeStamp.NonClusteredIndex = true;
113+
columnOpts.TimeStamp.NonClusteredIndexDirection = SqlIndexDirection.Desc;
113114

114115
var log = new LoggerConfiguration()
115116
.WriteTo.MSSqlServer(
@@ -349,6 +350,7 @@ Each Standard Column in the `ColumnOptions.Store` list and any custom columns yo
349350
* `AllowNull`
350351
* `DataLength`
351352
* `NonClusteredIndex`
353+
* `NonClusteredIndexDirection`
352354

353355
### ColumnName
354356

@@ -412,9 +414,20 @@ Supported SQL column data types that use this property:
412414

413415
Any individual column can be defined as a non-clustered index, including the table primary key. Use this with caution, indexing carries a relatively high write-throughput penalty. One way to mitigate this is to keep non-clustered indexes offline and use batch reindexing on a scheduled basis.
414416

417+
### NonClusteredIndexDirection
418+
419+
Specifies the sort direction (`ASC` or `DESC`) for a non-clustered index on the SQL column.
420+
The default value is `ASC`.
421+
422+
It is especially useful for the timestamp column,
423+
where choosing the correct sort direction can optimize query performance for workloads that typically scan
424+
recent data first.
425+
426+
This only has effect if `NonClusteredIndex` is `true`.
427+
415428
## Standard Columns
416429

417-
By default (and consistent with the SQL DDL to create a table shown earlier) these columns are included in a new `ColumnOptions.Store` list:
430+
By default (and consistent with the SQL DDL to create a table shown earlier), these columns are included in a new `ColumnOptions.Store` list:
418431

419432
- `StandardColumn.Id`
420433
- `StandardColumn.Message`

sample/WorkerServiceDemo/appsettings.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
"removeStandardColumns": [ "MessageTemplate", "Properties" ],
2626
"timeStamp": {
2727
"columnName": "Timestamp",
28-
"convertToUtc": false
28+
"allowNulls": false,
29+
"convertToUtc": false,
30+
"nonClusteredIndex": true,
31+
"nonClusteredIndexDirection": "Desc"
2932
},
3033
"customColumns": [
3134
{
@@ -43,6 +46,12 @@
4346
"propertyName": "NonstructuredProperty.WithNameContainingDots.Name",
4447
"resolveHierarchicalPropertyName": false,
4548
"dataType": "12"
49+
},
50+
{
51+
"columnName": "AdditionalColumn4",
52+
"dataType": "0",
53+
"nonClusteredIndex": true,
54+
"nonClusteredIndexDirection": "Desc"
4655
}
4756
]
4857
},

src/Serilog.Sinks.MSSqlServer/Configuration/Implementations/Microsoft.Extensions.Configuration/MicrosoftExtensionsColumnOptionsProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ private static void SetCommonColumnOptions(IConfigurationSection section, SqlCol
3434
SetProperty.IfNotNull<bool>(section["allowNull"], (val) => target.AllowNull = val);
3535
SetProperty.IfNotNull<int>(section["dataLength"], (val) => target.DataLength = val);
3636
SetProperty.IfNotNull<bool>(section["nonClusteredIndex"], (val) => target.NonClusteredIndex = val);
37+
SetProperty.IfEnumNotNull<SqlIndexDirection>(section["nonClusteredIndexDirection"],
38+
(val) => target.NonClusteredIndexDirection = val);
3739
}
3840

3941
private static void AddRemoveStandardColumns(IConfigurationSection config, ColumnOptions columnOptions)

src/Serilog.Sinks.MSSqlServer/Configuration/Implementations/SetProperty.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,25 @@ public static void IfNotNull<T>(string value, PropertySetter<T> setter)
2929
var setting = (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
3030
setter(setting);
3131
}
32-
// don't change the property if the conversion fails
32+
// don't change the property if the conversion fails
33+
catch (InvalidCastException) { }
34+
catch (OverflowException) { }
35+
}
36+
37+
/// <summary>
38+
/// This will only set a value (execute the PropertySetter delegate) if the value is non-null.
39+
/// It also converts the provided value to the requested enum type. This allows configuration to only
40+
/// apply property changes when external configuration has actually provided a value.
41+
/// </summary>
42+
public static void IfEnumNotNull<T>(string value, PropertySetter<T> setter) where T : System.Enum
43+
{
44+
if (value == null || setter == null) return;
45+
try
46+
{
47+
var setting = (T)Enum.Parse(typeof(T), value, ignoreCase: true);
48+
setter(setting);
49+
}
50+
// don't change the property if the conversion fails
3351
catch (InvalidCastException) { }
3452
catch (OverflowException) { }
3553
}

src/Serilog.Sinks.MSSqlServer/Configuration/Implementations/System.Configuration/ColumnConfig.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ public string NonClusteredIndex
8383
set { this[nameof(NonClusteredIndex)] = value; }
8484
}
8585

86+
[ConfigurationProperty("NonClusteredIndexDirection")]
87+
public string NonClusteredIndexDirection
88+
{
89+
get { return (string)this[nameof(NonClusteredIndexDirection)]; }
90+
set { this[nameof(NonClusteredIndexDirection)] = value; }
91+
}
92+
8693
internal SqlColumn AsSqlColumn()
8794
{
8895
var sqlColumn = new SqlColumn();
@@ -106,6 +113,9 @@ internal SqlColumn AsSqlColumn()
106113

107114
SetProperty.IfProvided<bool>(this, nameof(NonClusteredIndex), (val) => sqlColumn.NonClusteredIndex = val);
108115

116+
SetProperty.IfEnumProvided<SqlIndexDirection>(this, nameof(NonClusteredIndexDirection),
117+
(val) => sqlColumn.NonClusteredIndexDirection = val);
118+
109119
return sqlColumn;
110120
}
111121
}

src/Serilog.Sinks.MSSqlServer/Configuration/Implementations/System.Configuration/SetPropertyValueOrigin.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,22 @@ public static void IfProvided<T>(ConfigurationElement element, string propertyNa
2222
IfNotNull((string)property.Value, setter);
2323
}
2424

25+
/// <summary>
26+
/// Test the underlying enum property collection's value-origin flag for a non-default string value. Empty strings allowed.
27+
/// </summary>
28+
public static void IfEnumProvided<T>(ConfigurationElement element, string propertyName, PropertySetter<T> setter)
29+
where T : System.Enum
30+
{
31+
if (element == null)
32+
{
33+
return;
34+
}
35+
36+
var property = element.ElementInformation.Properties[propertyName];
37+
if (property.ValueOrigin == PropertyValueOrigin.Default) return;
38+
IfEnumNotNull((string)property.Value, setter);
39+
}
40+
2541
/// <summary>
2642
/// Test the underlying property collection's value-origin flag for a non-default, non-null, non-empty string value.
2743
/// </summary>

src/Serilog.Sinks.MSSqlServer/Configuration/Implementations/System.Configuration/SystemConfigurationColumnOptionsProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ private static void SetCommonColumnOptions(ColumnConfig source, SqlColumn target
2626
SetProperty.IfProvided<bool>(source, nameof(target.AllowNull), value => target.AllowNull = value);
2727
SetProperty.IfProvided<int>(source, nameof(target.DataLength), value => target.DataLength = value);
2828
SetProperty.IfProvided<bool>(source, nameof(target.NonClusteredIndex), value => target.NonClusteredIndex = value);
29+
SetProperty.IfEnumProvided<SqlIndexDirection>(source, nameof(target.NonClusteredIndexDirection), value => target.NonClusteredIndexDirection = value);
2930
}
3031

3132
private static void ReadPropertiesColumnOptions(MSSqlServerConfigurationSection config, ColumnOptions columnOptions)

0 commit comments

Comments
 (0)