This is an automated email from the ASF dual-hosted git repository.
ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 91323af877 IGNITE-20569 .NET: Use Microsoft.Extensions.Logging instead
of custom approach (#2874)
91323af877 is described below
commit 91323af877c2591d7238fae03c373c0539e75afe
Author: Pavel Tupitsyn <[email protected]>
AuthorDate: Fri Nov 24 15:37:19 2023 +0200
IGNITE-20569 .NET: Use Microsoft.Extensions.Logging instead of custom
approach (#2874)
* Remove custom `ILogger` and related code
* Adopt industry standard `Microsoft.Extensions.Logging`
* Reference `Microsoft.Extensions.Logging.Abstractions` - contains
interfaces only, no implementations (besides `NullLogger`)
* `IgniteClientConfiguration` accepts `ILoggerFactory`, as recommended in
[Logging guidance for .NET library
authors](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging-library-authors)
* Change all logging calls to use [Compile-time logging source
generation](https://learn.microsoft.com/en-us/dotnet/core/extensions/logger-message-generator)
for max performance
* `IsEnabled` checks are built in
As a result, any popular logging library can be used with Ignite.NET, such
as Serilog, NLog, log4net, etc.
---
.../ManyConnectionsBenchmark.cs | 5 +-
.../Apache.Ignite.Tests/Apache.Ignite.Tests.csproj | 1 +
.../dotnet/Apache.Ignite.Tests/ConsoleLogger.cs | 101 +++++++
.../dotnet/Apache.Ignite.Tests/HeartbeatTests.cs | 16 +-
.../dotnet/Apache.Ignite.Tests/IgniteTestsBase.cs | 6 +-
.../dotnet/Apache.Ignite.Tests/Linq/LinqTests.cs | 12 +-
.../dotnet/Apache.Ignite.Tests/ListLogger.cs | 107 ++-----
.../Apache.Ignite.Tests/ListLoggerFactory.cs | 92 ++++++
.../dotnet/Apache.Ignite.Tests/LoggingTests.cs | 60 +++-
.../dotnet/Apache.Ignite.Tests/MultiClusterTest.cs | 5 +-
.../dotnet/Apache.Ignite.Tests/ReconnectTests.cs | 22 +-
.../Apache.Ignite.Tests/SocketTimeoutTest.cs | 5 +-
.../dotnet/Apache.Ignite.Tests/SslTests.cs | 4 +-
.../dotnet/Apache.Ignite.Tests/TestUtils.cs | 3 +
.../dotnet/Apache.Ignite.Tests/VersionTests.cs | 2 +-
.../dotnet/Apache.Ignite/Apache.Ignite.csproj | 1 +
.../Apache.Ignite/IgniteClientConfiguration.cs | 9 +-
.../Apache.Ignite/Internal/ClientFailoverSocket.cs | 39 +--
.../dotnet/Apache.Ignite/Internal/ClientSocket.cs | 84 ++----
.../Internal/Linq/IgniteQueryExecutor.cs | 12 +-
.../dotnet/Apache.Ignite/Internal/Linq/README.md | 2 +-
.../dotnet/Apache.Ignite/Internal/LogMessages.cs | 207 +++++++++++++
.../Apache.Ignite/Internal/Table/RecordView.cs | 47 +--
.../dotnet/Apache.Ignite/Internal/Table/Table.cs | 11 +-
.../dotnet/Apache.Ignite/Internal/VersionUtils.cs | 2 +-
.../dotnet/Apache.Ignite/Log/CategoryLogger.cs | 95 ------
.../dotnet/Apache.Ignite/Log/ConsoleLogger.cs | 120 --------
.../dotnet/Apache.Ignite/Log/IDateTimeProvider.cs | 33 --
.../dotnet/Apache.Ignite/Log/IIgniteLogger.cs | 57 ----
.../Apache.Ignite/Log/LocalDateTimeProvider.cs | 47 ---
.../platforms/dotnet/Apache.Ignite/Log/LogLevel.cs | 53 ----
.../dotnet/Apache.Ignite/Log/LoggerExtensions.cs | 333 ---------------------
modules/platforms/dotnet/README.md | 29 +-
33 files changed, 620 insertions(+), 1002 deletions(-)
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/ManyConnectionsBenchmark.cs
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/ManyConnectionsBenchmark.cs
index 117d034426..c24eab2339 100644
---
a/modules/platforms/dotnet/Apache.Ignite.Benchmarks/ManyConnectionsBenchmark.cs
+++
b/modules/platforms/dotnet/Apache.Ignite.Benchmarks/ManyConnectionsBenchmark.cs
@@ -21,7 +21,8 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
-using Log;
+using Microsoft.Extensions.Logging;
+using Tests;
/// <summary>
/// Establishes many connections to the server node to see how it affects
server-side performance.
@@ -57,7 +58,7 @@ public static class ManyConnectionsBenchmark
var cfg = new IgniteClientConfiguration
{
RetryPolicy = new RetryNonePolicy(),
- Logger = new ConsoleLogger { MinLevel = LogLevel.Warn },
+ LoggerFactory =
TestUtils.GetConsoleLoggerFactory(LogLevel.Warning),
HeartbeatInterval = TimeSpan.FromMinutes(5)
};
diff --git
a/modules/platforms/dotnet/Apache.Ignite.Tests/Apache.Ignite.Tests.csproj
b/modules/platforms/dotnet/Apache.Ignite.Tests/Apache.Ignite.Tests.csproj
index 0e776fe96c..12dbc80cb0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/Apache.Ignite.Tests.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Apache.Ignite.Tests.csproj
@@ -31,6 +31,7 @@
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Console"
Version="6.0.0" />
<!-- Test-only dependency to use as a reference implementation. -->
<PackageReference Include="MessagePack" Version="[2.1.90,)" />
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/ConsoleLogger.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/ConsoleLogger.cs
new file mode 100644
index 0000000000..bdc770e82b
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/ConsoleLogger.cs
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache.Ignite.Tests;
+
+using System;
+using System.Globalization;
+using System.Text;
+using Microsoft.Extensions.Logging;
+
+/// <summary>
+/// Console logger for tests. We don't use <see
cref="Microsoft.Extensions.Logging.Console.ConsoleLogger"/> because it is
asynchronous,
+/// which means the log messages may not correspond to the current test.
+/// </summary>
+public class ConsoleLogger : ILogger, ILoggerFactory
+{
+ private readonly string _categoryName;
+ private readonly LogLevel _minLevel;
+
+ public ConsoleLogger(LogLevel minLevel)
+ : this(string.Empty, minLevel)
+ {
+ // No-op.
+ }
+
+ public ConsoleLogger(string categoryName, LogLevel minLevel)
+ {
+ _categoryName = categoryName;
+ _minLevel = minLevel;
+ }
+
+ public void Log<TState>(
+ LogLevel logLevel,
+ EventId eventId,
+ TState state,
+ Exception? exception,
+ Func<TState, Exception?, string> formatter)
+ {
+ if (!IsEnabled(logLevel))
+ {
+ return;
+ }
+
+ var sb = new StringBuilder().AppendFormat(
+ CultureInfo.InvariantCulture,
+ "[{0:HH:mm:ss}] [{1}] [{2}] ",
+ DateTime.Now,
+ GetLogLevelString(logLevel),
+ _categoryName);
+
+ sb.Append(formatter(state, exception));
+
+ if (exception != null)
+ {
+ sb.AppendFormat(CultureInfo.InvariantCulture, " (exception: {0})",
exception);
+ }
+
+ Console.WriteLine(sb.ToString());
+ }
+
+ public bool IsEnabled(LogLevel logLevel) => logLevel >= _minLevel;
+
+ public IDisposable BeginScope<TState>(TState state) => new
DisposeAction(() => { });
+
+ public void Dispose()
+ {
+ // No-op.
+ }
+
+ public ILogger CreateLogger(string categoryName) => new
ConsoleLogger(categoryName, _minLevel);
+
+ public void AddProvider(ILoggerProvider provider) => throw new
NotSupportedException();
+
+ private static string GetLogLevelString(LogLevel logLevel) =>
+ logLevel switch
+ {
+ LogLevel.Trace => "trce",
+ LogLevel.Debug => "dbug",
+ LogLevel.Information => "info",
+ LogLevel.Warning => "warn",
+ LogLevel.Error => "fail",
+ LogLevel.Critical => "crit",
+
+ // ReSharper disable once PatternIsRedundant
+ LogLevel.None or _ => throw new
ArgumentOutOfRangeException(nameof(logLevel))
+ };
+}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/HeartbeatTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/HeartbeatTests.cs
index 010425a634..bae85b5fb3 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/HeartbeatTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/HeartbeatTests.cs
@@ -19,7 +19,7 @@ namespace Apache.Ignite.Tests
{
using System;
using System.Threading.Tasks;
- using Log;
+ using Microsoft.Extensions.Logging;
using NUnit.Framework;
/// <summary>
@@ -30,12 +30,12 @@ namespace Apache.Ignite.Tests
[Test]
public async Task TestServerDoesNotDisconnectIdleClientWithHeartbeats()
{
- var logger = new ListLogger(enabledLevels: new[] { LogLevel.Error,
LogLevel.Warn });
+ var logger = new ListLoggerFactory(enabledLevels: new[] {
LogLevel.Error, LogLevel.Warning });
var cfg = new IgniteClientConfiguration
{
Endpoints = { "127.0.0.1:" + ServerPort },
- Logger = logger
+ LoggerFactory = logger
};
using var client = await IgniteClient.StartAsync(cfg);
@@ -53,7 +53,7 @@ namespace Apache.Ignite.Tests
var log = await
ConnectAndGetLog(IgniteClientConfiguration.DefaultHeartbeatInterval);
StringAssert.Contains(
- "[Warn] Server-side IdleTimeout is 00:00:03, " +
+ "[Warning] Server-side IdleTimeout is 00:00:03, " +
"configured IgniteClientConfiguration.HeartbeatInterval is
00:00:30, which is longer than recommended IdleTimeout / 3. " +
"Overriding heartbeat interval with max(IdleTimeout / 3,
500ms): 00:00:01",
log);
@@ -65,7 +65,7 @@ namespace Apache.Ignite.Tests
var log = await ConnectAndGetLog(TimeSpan.FromMilliseconds(50));
StringAssert.Contains(
- "[Info] Server-side IdleTimeout is 00:00:03, " +
+ "[Information] Server-side IdleTimeout is 00:00:03, " +
"using configured IgniteClientConfiguration.HeartbeatInterval:
00:00:00.0500000",
log);
}
@@ -76,7 +76,7 @@ namespace Apache.Ignite.Tests
var log = await ConnectAndGetLog(TimeSpan.FromSeconds(4));
StringAssert.Contains(
- "[Warn] Server-side IdleTimeout is 00:00:03, " +
+ "[Warning] Server-side IdleTimeout is 00:00:03, " +
"configured IgniteClientConfiguration.HeartbeatInterval is
00:00:04, which is longer than recommended IdleTimeout / 3. " +
"Overriding heartbeat interval with max(IdleTimeout / 3,
500ms): 00:00:01",
log);
@@ -91,11 +91,11 @@ namespace Apache.Ignite.Tests
private static async Task<string> ConnectAndGetLog(TimeSpan
heartbeatInterval)
{
- var logger = new ListLogger();
+ var logger = new ListLoggerFactory();
var cfg = new IgniteClientConfiguration(GetConfig())
{
- Logger = logger,
+ LoggerFactory = logger,
HeartbeatInterval = heartbeatInterval
};
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/IgniteTestsBase.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/IgniteTestsBase.cs
index c5f46c5953..da222099d9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/IgniteTestsBase.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/IgniteTestsBase.cs
@@ -23,7 +23,7 @@ namespace Apache.Ignite.Tests
using System.Threading.Tasks;
using Ignite.Table;
using Internal.Proto;
- using Log;
+ using Microsoft.Extensions.Logging;
using NUnit.Framework;
using Table;
@@ -180,13 +180,13 @@ namespace Apache.Ignite.Tests
"127.0.0.1:" + ServerNode.Port,
"127.0.0.1:" + (ServerNode.Port + 1)
},
- Logger = new ConsoleLogger { MinLevel = LogLevel.Trace }
+ LoggerFactory = TestUtils.GetConsoleLoggerFactory(LogLevel.Trace)
};
protected static IgniteClientConfiguration
GetConfig(IEnumerable<IgniteProxy> proxies) =>
new(proxies.Select(x => x.Endpoint).ToArray())
{
- Logger = new ConsoleLogger { MinLevel = LogLevel.Trace }
+ LoggerFactory =
TestUtils.GetConsoleLoggerFactory(LogLevel.Trace)
};
protected List<IgniteProxy> GetProxies()
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/Linq/LinqTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/Linq/LinqTests.cs
index 8d0b353c2f..2d91b21acc 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/Linq/LinqTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/Linq/LinqTests.cs
@@ -24,7 +24,7 @@ using System.Linq;
using System.Threading.Tasks;
using Ignite.Sql;
using Ignite.Table;
-using Log;
+using Microsoft.Extensions.Logging;
using NodaTime;
using NUnit.Framework;
using Table;
@@ -689,8 +689,8 @@ public partial class LinqTests : IgniteTestsBase
public async Task TestGeneratedSqlIsLoggedWithDebugLevel()
{
var config = GetConfig();
- var logger = new ListLogger { EnabledLevels = { LogLevel.Debug } };
- config.Logger = logger;
+ var logger = new ListLoggerFactory(new[] { LogLevel.Debug });
+ config.LoggerFactory = logger;
using var client = await IgniteClient.StartAsync(config);
var table = (await client.Tables.GetTableAsync(TableName))!;
@@ -700,16 +700,16 @@ public partial class LinqTests : IgniteTestsBase
.Where(x => x.Key > 5 && x.Val!.ToUpper() == "abc")
.SumAsync(x => x.Key);
- var logEntry = logger.Entries.Single(x => x.Category ==
"IgniteQueryExecutor");
+ var logEntry = logger.Entries.Single(x => x.Category ==
"Apache.Ignite.Internal.Linq.IgniteQueryExecutor");
var expectedMessage =
- "Executing SQL statement generated by LINQ provider: SqlStatement
{ " +
+ "Executing SQL statement generated by LINQ provider
[statement=SqlStatement { " +
"Query = select sum(_T0.KEY) from PUBLIC.TBL1 as _T0 where
((_T0.KEY > ?) and (upper(_T0.VAL) IS NOT DISTINCT FROM ?)), " +
"Timeout = 00:00:15, " +
"Schema = PUBLIC, " +
"PageSize = 123, " +
"Properties = { } }, " +
- "parameters: 5, abc";
+ "parameters=5, abc]";
Assert.AreEqual(expectedMessage, logEntry.Message);
Assert.AreEqual(LogLevel.Debug, logEntry.Level);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/ListLogger.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/ListLogger.cs
index 77b443369f..7a117ec98c 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/ListLogger.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/ListLogger.cs
@@ -21,28 +21,25 @@ namespace Apache.Ignite.Tests
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
- using Internal.Common;
- using Log;
+ using Microsoft.Extensions.Logging;
using NUnit.Framework;
/// <summary>
/// Stores log entries in a list.
/// </summary>
- public class ListLogger : IIgniteLogger
+ public class ListLogger : ILogger
{
- /** */
- private readonly List<Entry> _entries = new();
+ private readonly string _categoryName;
+ private readonly Action<Entry> _addEntry;
- /** */
- private readonly object _lock = new();
-
- /** */
- private readonly IIgniteLogger? _wrappedLogger;
-
- public ListLogger(IIgniteLogger? wrappedLogger = null,
IEnumerable<LogLevel>? enabledLevels = null)
+ public ListLogger(
+ string categoryName,
+ Action<Entry> addEntry,
+ IEnumerable<LogLevel>? enabledLevels = null)
{
- _wrappedLogger = wrappedLogger;
- EnabledLevels = enabledLevels?.ToList() ?? new() { LogLevel.Debug,
LogLevel.Info, LogLevel.Warn, LogLevel.Error };
+ _categoryName = categoryName;
+ _addEntry = addEntry;
+ EnabledLevels = enabledLevels?.ToList() ?? new() { LogLevel.Debug,
LogLevel.Information, LogLevel.Warning, LogLevel.Error };
}
/// <summary>
@@ -50,83 +47,29 @@ namespace Apache.Ignite.Tests
/// </summary>
public List<LogLevel> EnabledLevels { get; }
- /// <summary>
- /// Gets the entries.
- /// </summary>
- public List<Entry> Entries
- {
- get
- {
- lock (_lock)
- {
- return _entries.ToList();
- }
- }
- }
-
- /// <summary>
- /// Gets the log as a string.
- /// </summary>
- /// <returns>Log string.</returns>
- public string GetLogString()
- {
- lock (_lock)
- {
- return _entries.Select(e => $"{e.Category} [{e.Level}]
{e.Message}").StringJoin();
- }
- }
-
- /// <summary>
- /// Clears the entries.
- /// </summary>
- public void Clear()
- {
- lock (_lock)
- {
- _entries.Clear();
- }
- }
-
- /** <inheritdoc /> */
- public void Log(
- LogLevel level,
- string message,
- object?[]? args,
- IFormatProvider? formatProvider,
- string? category,
- string? nativeErrorInfo,
- Exception? ex)
+ public void Log<TState>(
+ LogLevel logLevel,
+ EventId eventId,
+ TState state,
+ Exception? exception,
+ Func<TState, Exception?, string> formatter)
{
- Assert.NotNull(message);
+ Assert.NotNull(state);
+ Assert.NotNull(formatter);
- if (!IsEnabled(level))
+ if (!IsEnabled(logLevel))
{
return;
}
- _wrappedLogger?.Log(level, message, args, formatProvider,
category, nativeErrorInfo, ex);
-
- lock (_lock)
- {
- if (args != null)
- {
- message = string.Format(formatProvider, message, args);
- }
-
- if (ex != null)
- {
- message += Environment.NewLine + ex;
- }
-
- _entries.Add(new Entry(message, level, category, ex));
- }
+ var message = formatter(state, exception);
+ _addEntry(new Entry(message, logLevel, _categoryName, exception));
}
/** <inheritdoc /> */
- public bool IsEnabled(LogLevel level)
- {
- return EnabledLevels.Contains(level);
- }
+ public bool IsEnabled(LogLevel logLevel) =>
EnabledLevels.Contains(logLevel);
+
+ public IDisposable BeginScope<TState>(TState state) => throw new
NotImplementedException();
[SuppressMessage("Microsoft.Design",
"CA1034:NestedTypesShouldNotBeVisible", Justification = "Tests.")]
public record Entry(string Message, LogLevel Level, string? Category,
Exception? Exception);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/ListLoggerFactory.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/ListLoggerFactory.cs
new file mode 100644
index 0000000000..62d5e3d8d4
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/ListLoggerFactory.cs
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache.Ignite.Tests;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Internal.Common;
+using Microsoft.Extensions.Logging;
+
+public class ListLoggerFactory : ILoggerFactory
+{
+ private readonly List<ListLogger.Entry> _entries = new();
+
+ private readonly object _lock = new();
+
+ public ListLoggerFactory(ICollection<LogLevel>? enabledLevels = null)
+ {
+ EnabledLevels = enabledLevels;
+ }
+
+ public ICollection<LogLevel>? EnabledLevels { get; }
+
+ /// <summary>
+ /// Gets the entries.
+ /// </summary>
+ public List<ListLogger.Entry> Entries
+ {
+ get
+ {
+ lock (_lock)
+ {
+ return _entries.ToList();
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ // No-op.
+ }
+
+ public ILogger CreateLogger(string categoryName) => new
ListLogger(categoryName, AddEntry, enabledLevels: EnabledLevels);
+
+ public void AddProvider(ILoggerProvider provider) => throw new
NotSupportedException();
+
+ /// <summary>
+ /// Gets the log as a string.
+ /// </summary>
+ /// <returns>Log string.</returns>
+ public string GetLogString()
+ {
+ lock (_lock)
+ {
+ return _entries.Select(e => $"{e.Category} [{e.Level}]
{e.Message}").StringJoin();
+ }
+ }
+
+ /// <summary>
+ /// Clears the entries.
+ /// </summary>
+ public void Clear()
+ {
+ lock (_lock)
+ {
+ _entries.Clear();
+ }
+ }
+
+ private void AddEntry(ListLogger.Entry entry)
+ {
+ lock (_lock)
+ {
+ _entries.Add(entry);
+ }
+ }
+}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/LoggingTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/LoggingTests.cs
index 77e726a3b3..1b52c32645 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/LoggingTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/LoggingTests.cs
@@ -19,9 +19,11 @@ namespace Apache.Ignite.Tests;
using System;
using System.Diagnostics.CodeAnalysis;
+using System.IO;
using System.Threading.Tasks;
using Internal;
-using Log;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Logging.Console;
using NUnit.Framework;
/// <summary>
@@ -33,11 +35,8 @@ public class LoggingTests
[SuppressMessage("ReSharper", "AccessToDisposedClosure", Justification =
"Reviewed.")]
public async Task TestBasicLogging()
{
- var logger = new ListLogger(new ConsoleLogger { MinLevel =
LogLevel.Trace });
- logger.EnabledLevels.Clear();
- logger.EnabledLevels.AddRange(Enum.GetValues<LogLevel>());
-
- var cfg = new IgniteClientConfiguration { Logger = logger };
+ var logger = new ListLoggerFactory(Enum.GetValues<LogLevel>());
+ var cfg = new IgniteClientConfiguration { LoggerFactory = logger };
using var servers = FakeServerGroup.Create(3);
using (var client = await servers.ConnectClientAsync(cfg))
@@ -51,15 +50,48 @@ public class LoggingTests
var log = logger.GetLogString();
StringAssert.Contains(
- $"ClientFailoverSocket [Info] Ignite.NET client version
{VersionUtils.GetInformationalVersion()} is starting",
+ $"Apache.Ignite.Internal.ClientFailoverSocket [Information] " +
+ $"Ignite.NET client version {VersionUtils.InformationalVersion} is
starting",
log);
- StringAssert.Contains("Connection established", log);
- StringAssert.Contains("Handshake succeeded", log);
- StringAssert.Contains("Trying to establish secondary connections -
awaiting 2 tasks", log);
- StringAssert.Contains("2 secondary connections established, 0 failed",
log);
- StringAssert.Contains("Sending request [op=TablesGet", log);
- StringAssert.Contains("Sending request [op=SqlExec", log);
- StringAssert.Contains("Connection closed", log);
+ StringAssert.Contains("[Debug] Connection established", log);
+ StringAssert.Contains("[Debug] Handshake succeeded [remoteAddress=[",
log);
+ StringAssert.Contains("ClientFailoverSocket [Debug] Trying to
establish secondary connections - awaiting 2 tasks", log);
+ StringAssert.Contains("ClientFailoverSocket [Debug] 2 secondary
connections established, 0 failed", log);
+ StringAssert.Contains("[Trace] Sending request [requestId=1,
op=TablesGet, remoteAddress=", log);
+ StringAssert.Contains("[Trace] Received response [requestId=1,
remoteAddress=", log);
+ StringAssert.Contains("op=SqlExec", log);
+ StringAssert.Contains("[Debug] Connection closed gracefully", log);
+ }
+
+ [Test]
+ public async Task TestMicrosoftConsoleLogger()
+ {
+ var oldWriter = Console.Out;
+ var writer = new StringWriter();
+ Console.SetOut(writer);
+
+ try
+ {
+ var cfg = new IgniteClientConfiguration
+ {
+ LoggerFactory = LoggerFactory.Create(builder =>
+ builder.AddSimpleConsole(opt => opt.ColorBehavior =
LoggerColorBehavior.Disabled)
+ .SetMinimumLevel(LogLevel.Trace))
+ };
+
+ using var server = new FakeServer();
+ using var client = await server.ConnectClientAsync(cfg);
+ await client.Tables.GetTablesAsync();
+
+ var log = writer.ToString();
+ StringAssert.Contains("dbug: Apache.Ignite.Internal.ClientSocket",
log);
+ StringAssert.Contains("Connection established", log);
+ StringAssert.Contains("Handshake succeeded [remoteAddress=[", log);
+ }
+ finally
+ {
+ Console.SetOut(oldWriter);
+ }
}
}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/MultiClusterTest.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/MultiClusterTest.cs
index 9478150dba..cec14fdbc1 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/MultiClusterTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/MultiClusterTest.cs
@@ -21,7 +21,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-using Log;
using NUnit.Framework;
/// <summary>
@@ -35,10 +34,10 @@ public class MultiClusterTest
using var server1 = new FakeServer(nodeName: "s1") { ClusterId = new
Guid(1, 0, 0, new byte[8]) };
using var server2 = new FakeServer(nodeName: "s2") { ClusterId = new
Guid(2, 0, 0, new byte[8]) };
- var log = new ListLogger(new ConsoleLogger());
+ var log = new ListLoggerFactory();
var cfg = new IgniteClientConfiguration(server1.Endpoint,
server2.Endpoint)
{
- Logger = log
+ LoggerFactory = log
};
using var client = await IgniteClient.StartAsync(cfg);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/ReconnectTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/ReconnectTests.cs
index 60767f09fd..1c04272072 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/ReconnectTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/ReconnectTests.cs
@@ -21,7 +21,7 @@ using System;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;
using Internal;
-using Log;
+using Microsoft.Extensions.Logging;
using NUnit.Framework;
/// <summary>
@@ -72,7 +72,7 @@ public class ReconnectTests
{
var cfg = new IgniteClientConfiguration
{
- Logger = new ConsoleLogger { MinLevel = LogLevel.Debug }
+ LoggerFactory = TestUtils.GetConsoleLoggerFactory(LogLevel.Debug)
};
using var server = new FakeServer();
@@ -92,7 +92,7 @@ public class ReconnectTests
{
HeartbeatInterval = TimeSpan.FromMilliseconds(100),
ReconnectInterval = TimeSpan.FromMilliseconds(300),
- Logger = new ConsoleLogger { MinLevel = LogLevel.Trace }
+ LoggerFactory = TestUtils.GetConsoleLoggerFactory(LogLevel.Trace)
};
using var servers = FakeServerGroup.Create(10);
@@ -134,15 +134,17 @@ public class ReconnectTests
}
[Test]
+ [SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates",
Justification = "Test")]
public async Task TestReconnectAfterFullClusterRestart()
{
- var logger = new ConsoleLogger { MinLevel = LogLevel.Trace };
+ var loggerFactory = TestUtils.GetConsoleLoggerFactory(LogLevel.Trace);
+ var logger = loggerFactory.CreateLogger("test");
var cfg = new IgniteClientConfiguration
{
ReconnectInterval = TimeSpan.FromMilliseconds(100),
SocketTimeout = TimeSpan.FromSeconds(2),
- Logger = logger
+ LoggerFactory = loggerFactory
};
using var servers = FakeServerGroup.Create(10);
@@ -151,24 +153,24 @@ public class ReconnectTests
Assert.DoesNotThrowAsync(async () => await
client.Tables.GetTablesAsync());
// Drop all connections and block new connections.
- logger.Debug("Dropping all connections and blocking new
connections...");
+ logger.LogDebug("Dropping all connections and blocking new
connections...");
servers.DropNewConnections = true;
servers.DropExistingConnections();
- logger.Debug("Dropped all connections and blocked new connections.");
+ logger.LogDebug("Dropped all connections and blocked new
connections.");
// Client fails to perform operations.
Assert.ThrowsAsync<IgniteClientConnectionException>(async () => await
client.Tables.GetTablesAsync());
// Allow new connections.
- logger.Debug("Allowing new connections...");
+ logger.LogDebug("Allowing new connections...");
servers.DropNewConnections = false;
- logger.Debug("Allowed new connections.");
+ logger.LogDebug("Allowed new connections.");
// Client works again.
Assert.DoesNotThrowAsync(async () => await
client.Tables.GetTablesAsync());
// All connections are restored.
- logger.Debug("Waiting for all connections to be restored...");
+ logger.LogDebug("Waiting for all connections to be restored...");
client.WaitForConnections(10);
}
}
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/SocketTimeoutTest.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/SocketTimeoutTest.cs
index 6e852abade..3806d6eefe 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/SocketTimeoutTest.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/SocketTimeoutTest.cs
@@ -20,7 +20,6 @@ namespace Apache.Ignite.Tests;
using System;
using System.Linq;
using System.Threading.Tasks;
-using Log;
using NUnit.Framework;
/// <summary>
@@ -53,14 +52,14 @@ public class SocketTimeoutTest
HeartbeatDelay = TimeSpan.FromMilliseconds(100)
};
- var log = new ListLogger(new ConsoleLogger { MinLevel = LogLevel.Trace
});
+ var log = new ListLoggerFactory();
var cfg = new IgniteClientConfiguration
{
SocketTimeout = TimeSpan.FromMilliseconds(50),
HeartbeatInterval = TimeSpan.FromMilliseconds(100),
RetryPolicy = new RetryNonePolicy(),
- Logger = log
+ LoggerFactory = log
};
using var client = await server.ConnectClientAsync(cfg);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/SslTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/SslTests.cs
index 283f24cfd3..81aa7788c9 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/SslTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/SslTests.cs
@@ -26,7 +26,7 @@ using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
-using Log;
+using Microsoft.Extensions.Logging;
using NUnit.Framework;
/// <summary>
@@ -91,7 +91,7 @@ public class SslTests : IgniteTestsBase
ClientCertificates = new X509Certificate2Collection(new
X509Certificate2(CertificatePath, CertificatePassword))
}
},
- Logger = new ConsoleLogger { MinLevel = LogLevel.Trace }
+ LoggerFactory = TestUtils.GetConsoleLoggerFactory(LogLevel.Trace)
};
using var client = await IgniteClient.StartAsync(cfg);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/TestUtils.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/TestUtils.cs
index 1927c122b9..8707cd5452 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/TestUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/TestUtils.cs
@@ -23,6 +23,7 @@ namespace Apache.Ignite.Tests
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
+ using Microsoft.Extensions.Logging;
using NUnit.Framework;
public static class TestUtils
@@ -76,6 +77,8 @@ namespace Apache.Ignite.Tests
return (T) field!.GetValue(obj)!;
}
+ public static ILoggerFactory GetConsoleLoggerFactory(LogLevel
minLevel) => new ConsoleLogger(minLevel);
+
private static string GetSolutionDir()
{
var dir =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/VersionTests.cs
b/modules/platforms/dotnet/Apache.Ignite.Tests/VersionTests.cs
index f551488825..36618ac337 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/VersionTests.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/VersionTests.cs
@@ -27,7 +27,7 @@ public class VersionTests
[Test]
public void TestAssemblyInformationalVersionHasGitCommitHash()
{
- var informationalVersion = VersionUtils.GetInformationalVersion();
+ var informationalVersion = VersionUtils.InformationalVersion;
StringAssert.StartsWith(GetAssemblyVersion(), informationalVersion);
var parts = informationalVersion.Split('+');
diff --git a/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
b/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
index 02c6efcd15..614ad9274d 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
+++ b/modules/platforms/dotnet/Apache.Ignite/Apache.Ignite.csproj
@@ -37,6 +37,7 @@
<PackageReference Include="JetBrains.Annotations" Version="2022.3.1"
PrivateAssets="all" />
<PackageReference Include="NodaTime" Version="[3.*,)" />
<PackageReference Include="Remotion.Linq" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Logging.Abstractions"
Version="[6.*,)" />
</ItemGroup>
<ItemGroup>
diff --git
a/modules/platforms/dotnet/Apache.Ignite/IgniteClientConfiguration.cs
b/modules/platforms/dotnet/Apache.Ignite/IgniteClientConfiguration.cs
index 93f9c0853a..bb48973557 100644
--- a/modules/platforms/dotnet/Apache.Ignite/IgniteClientConfiguration.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/IgniteClientConfiguration.cs
@@ -22,7 +22,8 @@ namespace Apache.Ignite
using System.ComponentModel;
using System.Linq;
using Internal.Common;
- using Log;
+ using Microsoft.Extensions.Logging;
+ using Microsoft.Extensions.Logging.Abstractions;
/// <summary>
/// Ignite client driver configuration.
@@ -80,7 +81,7 @@ namespace Apache.Ignite
{
IgniteArgumentCheck.NotNull(other);
- Logger = other.Logger;
+ LoggerFactory = other.LoggerFactory;
SocketTimeout = other.SocketTimeout;
Endpoints = other.Endpoints.ToList();
RetryPolicy = other.RetryPolicy;
@@ -91,9 +92,9 @@ namespace Apache.Ignite
}
/// <summary>
- /// Gets or sets the logger.
+ /// Gets or sets the logger factory. Default is <see
cref="NullLoggerFactory.Instance"/>.
/// </summary>
- public IIgniteLogger? Logger { get; set; }
+ public ILoggerFactory LoggerFactory { get; set; } =
NullLoggerFactory.Instance;
/// <summary>
/// Gets or sets the socket timeout.
diff --git
a/modules/platforms/dotnet/Apache.Ignite/Internal/ClientFailoverSocket.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/ClientFailoverSocket.cs
index 6e6e79a9f5..4650b2d150 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/ClientFailoverSocket.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/ClientFailoverSocket.cs
@@ -30,7 +30,7 @@ namespace Apache.Ignite.Internal
using System.Threading.Tasks;
using Buffers;
using Ignite.Network;
- using Log;
+ using Microsoft.Extensions.Logging;
using Network;
using Proto;
using Transactions;
@@ -44,7 +44,7 @@ namespace Apache.Ignite.Internal
private static long _globalEndPointIndex;
/** Logger. */
- private readonly IIgniteLogger? _logger;
+ private readonly ILogger _logger;
/** Endpoints with corresponding hosts - from configuration. */
private readonly IReadOnlyList<SocketEndpoint> _endpoints;
@@ -82,7 +82,8 @@ namespace Apache.Ignite.Internal
/// Initializes a new instance of the <see
cref="ClientFailoverSocket"/> class.
/// </summary>
/// <param name="configuration">Client configuration.</param>
- private ClientFailoverSocket(IgniteClientConfiguration configuration)
+ /// <param name="logger">Logger.</param>
+ private ClientFailoverSocket(IgniteClientConfiguration configuration,
ILogger logger)
{
if (configuration.Endpoints.Count == 0)
{
@@ -91,7 +92,7 @@ namespace Apache.Ignite.Internal
$"Invalid {nameof(IgniteClientConfiguration)}:
{nameof(IgniteClientConfiguration.Endpoints)} is empty. Nowhere to connect.");
}
- _logger = configuration.Logger.GetLogger(GetType());
+ _logger = logger;
_endpoints = GetIpEndPoints(configuration).ToList();
Configuration = new(configuration); // Defensive copy.
@@ -119,10 +120,10 @@ namespace Apache.Ignite.Internal
/// <returns>A <see cref="Task"/> representing the asynchronous
operation.</returns>
public static async Task<ClientFailoverSocket>
ConnectAsync(IgniteClientConfiguration configuration)
{
- var socket = new ClientFailoverSocket(configuration);
+ var logger =
configuration.LoggerFactory.CreateLogger<ClientFailoverSocket>();
+ logger.LogClientStartInfo(VersionUtils.InformationalVersion);
- var logger =
configuration.Logger.GetLogger(typeof(ClientFailoverSocket));
- logger?.Info("Ignite.NET client version " +
VersionUtils.GetInformationalVersion() + " is starting");
+ var socket = new ClientFailoverSocket(configuration, logger);
await socket.GetNextSocketAsync().ConfigureAwait(false);
@@ -307,7 +308,7 @@ namespace Apache.Ignite.Internal
}
catch (Exception e)
{
- _logger?.Warn(e, $"Failed to connect to preferred node
[{preferredNode}]: {e.Message}");
+
_logger.LogFailedToConnectPreferredNodeDebug(preferredNode.Name, e.Message);
}
}
@@ -347,13 +348,13 @@ namespace Apache.Ignite.Internal
}
catch (Exception e)
{
- _logger?.Warn(e, "Error while trying to establish
secondary connections: " + e.Message);
+
_logger.LogErrorWhileEstablishingSecondaryConnectionsWarn(e, e.Message);
}
}
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
+ if (_logger.IsEnabled(LogLevel.Debug))
{
- _logger.Debug("Trying to establish secondary connections -
awaiting {0} tasks...", tasks.Count);
+
_logger.LogTryingToEstablishSecondaryConnectionsDebug(tasks.Count);
}
// Await every task separately instead of using WhenAll to
capture exceptions and avoid extra allocations.
@@ -366,14 +367,14 @@ namespace Apache.Ignite.Internal
}
catch (Exception e)
{
- _logger?.Warn(e, "Error while trying to establish
secondary connections: " + e.Message);
+
_logger.LogErrorWhileEstablishingSecondaryConnectionsWarn(e, e.Message);
failed++;
}
}
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
+ if (_logger.IsEnabled(LogLevel.Debug))
{
- _logger.Debug($"{tasks.Count - failed} secondary
connections established, {failed} failed.");
+
_logger.LogSecondaryConnectionsEstablishedDebug(tasks.Count - failed, failed);
}
if (Configuration.ReconnectInterval <= TimeSpan.Zero)
@@ -530,7 +531,7 @@ namespace Apache.Ignite.Internal
}
catch (SocketException e)
{
- _logger?.Debug(e, "Failed to parse host: " + host);
+ _logger.LogFailedToParseHostDebug(e, host, e.Message);
if (suppressExceptions)
{
@@ -608,9 +609,9 @@ namespace Apache.Ignite.Internal
{
if (!ShouldRetry(exception, op, attempt, retryPolicy))
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
+ if (_logger.IsEnabled(LogLevel.Debug))
{
- _logger.Debug($"Not retrying operation [opCode={(int)op},
opType={op}, attempt={attempt}, lastError={exception}]");
+ _logger.LogRetryingOperationDebug("Not retrying", (int)op,
op, attempt, exception.Message);
}
if (errors == null)
@@ -627,9 +628,9 @@ namespace Apache.Ignite.Internal
inner);
}
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
+ if (_logger.IsEnabled(LogLevel.Debug))
{
- _logger.Debug($"Retrying operation [opCode={(int)op},
opType={op}, attempt={attempt}, lastError={exception}]");
+ _logger.LogRetryingOperationDebug("Retrying", (int)op, op,
attempt, exception.Message);
}
Metrics.RequestsRetried.Add(1);
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
index 591c6a78e8..9a119c7aa5 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/ClientSocket.cs
@@ -31,7 +31,7 @@ namespace Apache.Ignite.Internal
using System.Threading.Tasks;
using Buffers;
using Ignite.Network;
- using Log;
+ using Microsoft.Extensions.Logging;
using Network;
using Proto;
using Proto.MsgPack;
@@ -90,7 +90,7 @@ namespace Apache.Ignite.Internal
private readonly TimeSpan _socketTimeout;
/** Logger. */
- private readonly IIgniteLogger? _logger;
+ private readonly ILogger _logger;
/** Event listener. */
private readonly IClientSocketEventListener _listener;
@@ -117,7 +117,7 @@ namespace Apache.Ignite.Internal
IgniteClientConfiguration configuration,
ConnectionContext connectionContext,
IClientSocketEventListener listener,
- IIgniteLogger? logger)
+ ILogger logger)
{
_stream = stream;
ConnectionContext = connectionContext;
@@ -168,7 +168,8 @@ namespace Apache.Ignite.Internal
IClientSocketEventListener listener)
{
using var cts = new CancellationTokenSource();
- var logger = configuration.Logger.GetLogger(nameof(ClientSocket) +
"-" + Interlocked.Increment(ref _socketId));
+ var logger =
configuration.LoggerFactory.CreateLogger(typeof(ClientSocket).FullName! + "-" +
+
Interlocked.Increment(ref _socketId));
bool connected = false;
Socket? socket = null;
@@ -187,11 +188,7 @@ namespace Apache.Ignite.Internal
.ConfigureAwait(false);
connected = true;
-
- if (logger?.IsEnabled(LogLevel.Debug) == true)
- {
- logger.Debug($"Connection established
[remoteAddress={socket.RemoteEndPoint}]");
- }
+ logger.LogConnectionEstablishedDebug(socket.RemoteEndPoint);
Metrics.ConnectionsEstablished.Add(1);
Metrics.ConnectionsActiveIncrement();
@@ -204,22 +201,14 @@ namespace Apache.Ignite.Internal
.ConfigureAwait(false) is { } sslStream)
{
stream = sslStream;
-
- if (logger?.IsEnabled(LogLevel.Debug) == true)
- {
- logger.Debug(
- $"SSL connection established
[remoteAddress={socket.RemoteEndPoint}]: {sslStream.NegotiatedCipherSuite}");
- }
+
logger.LogSslConnectionEstablishedDebug(socket.RemoteEndPoint,
sslStream.NegotiatedCipherSuite);
}
var context = await HandshakeAsync(stream, endPoint.EndPoint,
configuration, cts.Token)
.WaitAsync(configuration.SocketTimeout, cts.Token)
.ConfigureAwait(false);
- if (logger?.IsEnabled(LogLevel.Debug) == true)
- {
- logger.Debug($"Handshake succeeded
[remoteAddress={socket.RemoteEndPoint}]: {context}.");
- }
+ logger.LogHandshakeSucceededDebug(socket.RemoteEndPoint,
context);
return new ClientSocket(stream, configuration, context,
listener, logger);
}
@@ -237,10 +226,10 @@ namespace Apache.Ignite.Internal
}
catch (Exception disposeEx)
{
- logger?.Warn(disposeEx, "Failed to dispose socket after
failed connection attempt: " + disposeEx.Message);
+
logger.LogFailedToDisposeSocketAfterFailedConnectionAttemptWarn(disposeEx,
disposeEx.Message);
}
- logger?.Warn(ex, $"Connection failed before or during
handshake [remoteAddress={endPoint.EndPoint}]: {ex.Message}.");
+ logger.LogConnectionFailedBeforeOrDuringHandshakeWarn(ex,
endPoint.EndPoint, ex.Message);
if (ex.GetBaseException() is TimeoutException)
{
@@ -561,7 +550,7 @@ namespace Apache.Ignite.Internal
private static int ReadMessageSize(Span<byte> responseLenBytes) =>
BinaryPrimitives.ReadInt32BigEndian(responseLenBytes);
- private static TimeSpan GetHeartbeatInterval(TimeSpan
configuredInterval, TimeSpan serverIdleTimeout, IIgniteLogger? logger)
+ private static TimeSpan GetHeartbeatInterval(TimeSpan
configuredInterval, TimeSpan serverIdleTimeout, ILogger logger)
{
if (configuredInterval <= TimeSpan.Zero)
{
@@ -572,9 +561,7 @@ namespace Apache.Ignite.Internal
if (serverIdleTimeout <= TimeSpan.Zero)
{
- logger?.Info(
- $"Server-side IdleTimeout is not set, using configured
{nameof(IgniteClientConfiguration)}." +
- $"{nameof(IgniteClientConfiguration.HeartbeatInterval)}:
{configuredInterval}");
+ logger.LogServerSizeIdleTimeoutNotSetInfo(configuredInterval);
return configuredInterval;
}
@@ -588,20 +575,13 @@ namespace Apache.Ignite.Internal
if (configuredInterval < recommendedHeartbeatInterval)
{
- logger?.Info(
- $"Server-side IdleTimeout is {serverIdleTimeout}, " +
- $"using configured {nameof(IgniteClientConfiguration)}." +
- $"{nameof(IgniteClientConfiguration.HeartbeatInterval)}: "
+
- configuredInterval);
+ logger.LogServerSideIdleTimeoutIgnoredInfo(serverIdleTimeout,
configuredInterval);
return configuredInterval;
}
- logger?.Warn(
- $"Server-side IdleTimeout is {serverIdleTimeout}, configured "
+
-
$"{nameof(IgniteClientConfiguration)}.{nameof(IgniteClientConfiguration.HeartbeatInterval)}
" +
- $"is {configuredInterval}, which is longer than recommended
IdleTimeout / 3. " +
- $"Overriding heartbeat interval with max(IdleTimeout / 3,
500ms): {recommendedHeartbeatInterval}");
+
logger.LogServerSideIdleTimeoutOverridesConfiguredHeartbeatIntervalWarn(
+ serverIdleTimeout, configuredInterval,
recommendedHeartbeatInterval);
return recommendedHeartbeatInterval;
}
@@ -626,10 +606,7 @@ namespace Apache.Ignite.Internal
// Reset heartbeat timer - don't sent heartbeats when connection
is active anyway.
_heartbeatTimer.Change(dueTime: _heartbeatInterval, period:
TimeSpan.FromMilliseconds(-1));
- if (_logger?.IsEnabled(LogLevel.Trace) == true)
- {
- _logger.Trace($"Sending request [op={op},
remoteAddress={ConnectionContext.ClusterNode.Address}, requestId={requestId}]");
- }
+ _logger.LogSendingRequestTrace(requestId, op,
ConnectionContext.ClusterNode.Address);
await
_sendLock.WaitAsync(_disposeTokenSource.Token).ConfigureAwait(false);
@@ -672,7 +649,7 @@ namespace Apache.Ignite.Internal
{
var message = "Exception while writing to socket, connection
closed: " + e.Message;
- _logger?.Error(e, message);
+ _logger.LogSocketIoError(e, message);
var connEx = new
IgniteClientConnectionException(ErrorGroups.Client.Connection, message, new
SocketException());
Dispose(connEx);
@@ -708,7 +685,7 @@ namespace Apache.Ignite.Internal
{
var message = "Exception while reading from socket, connection
closed: " + e.Message;
- _logger?.Error(e, message);
+ _logger.LogSocketIoError(e, message);
Dispose(new
IgniteClientConnectionException(ErrorGroups.Client.Connection, message, e));
}
}
@@ -732,26 +709,24 @@ namespace Apache.Ignite.Internal
var message = $"Unexpected response ID ({requestId}) received
from the server " +
$"[remoteAddress={ConnectionContext.ClusterNode.Address}], closing the socket.";
- _logger?.Error(message);
+ _logger.LogUnexpectedResponseIdError(null, message);
Dispose(new
IgniteClientConnectionException(ErrorGroups.Client.Protocol, message));
return;
}
Metrics.RequestsActiveDecrement();
+ _logger.LogReceivedResponseTrace(requestId,
ConnectionContext.ClusterNode.Address);
var flags = (ResponseFlags)reader.ReadInt32();
if (flags.HasFlag(ResponseFlags.PartitionAssignmentChanged))
{
- if (_logger?.IsEnabled(LogLevel.Info) == true)
- {
- _logger.Info(
- $"Partition assignment change notification received
[remoteAddress={ConnectionContext.ClusterNode.Address}]");
- }
+ long timestamp = reader.ReadInt64();
- // TODO IGNITE-20900: Read and propagate assignment timestamp
- separate ticket.
- _ = reader.ReadInt64();
+
_logger.LogPartitionAssignmentChangeNotificationInfo(ConnectionContext.ClusterNode.Address,
timestamp);
+
+ // TODO IGNITE-20900: Propagate assignment timestamp.
_listener.OnAssignmentChanged(this);
}
@@ -793,9 +768,10 @@ namespace Apache.Ignite.Internal
}
catch (Exception e)
{
- _logger?.Error(e, "Heartbeat failed: " + e.Message);
+ var message = "Heartbeat failed: " + e.Message;
+ _logger.LogHeartbeatError(e, message);
- Dispose(e);
+ Dispose(new
IgniteClientConnectionException(ErrorGroups.Client.Connection, message, e));
}
}
@@ -816,7 +792,7 @@ namespace Apache.Ignite.Internal
if (ex != null)
{
- _logger?.Warn(ex, $"Connection closed
[remoteAddress={ConnectionContext.ClusterNode.Address}]: " + ex.Message);
+ _logger.LogConnectionClosedWithErrorWarn(ex,
ConnectionContext.ClusterNode.Address, ex.Message);
if (ex.GetBaseException() is TimeoutException)
{
@@ -827,9 +803,9 @@ namespace Apache.Ignite.Internal
Metrics.ConnectionsLost.Add(1);
}
}
- else if (_logger?.IsEnabled(LogLevel.Debug) == true)
+ else
{
- _logger.Debug($"Connection closed
[remoteAddress={ConnectionContext.ClusterNode.Address}]");
+
_logger.LogConnectionClosedGracefullyDebug(ConnectionContext.ClusterNode.Address);
}
_heartbeatTimer.Dispose();
diff --git
a/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/IgniteQueryExecutor.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/IgniteQueryExecutor.cs
index f1eaaa61ea..28e5781cbf 100644
---
a/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/IgniteQueryExecutor.cs
+++
b/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/IgniteQueryExecutor.cs
@@ -25,7 +25,7 @@ using System.Threading.Tasks;
using Common;
using Ignite.Sql;
using Ignite.Transactions;
-using Log;
+using Microsoft.Extensions.Logging;
using Remotion.Linq;
using Remotion.Linq.Clauses.ResultOperators;
using Sql;
@@ -38,7 +38,7 @@ internal sealed class IgniteQueryExecutor : IQueryExecutor
private readonly Sql _sql;
private readonly ITransaction? _transaction;
private readonly QueryableOptions? _options;
- private readonly IIgniteLogger? _logger;
+ private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="IgniteQueryExecutor" />
class.
@@ -52,7 +52,7 @@ internal sealed class IgniteQueryExecutor : IQueryExecutor
_sql = sql;
_transaction = transaction;
_options = options;
- _logger = configuration.Logger.GetLogger(GetType());
+ _logger =
configuration.LoggerFactory.CreateLogger<IgniteQueryExecutor>();
}
/// <summary>
@@ -123,10 +123,10 @@ internal sealed class IgniteQueryExecutor : IQueryExecutor
var selectorOptions = GetResultSelectorOptions(queryModel,
queryData.HasOuterJoins);
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
+ // Explicit enabled check because of StringJoin.
+ if (_logger.IsEnabled(LogLevel.Debug))
{
- _logger.Debug($"Executing SQL statement generated by LINQ
provider: {statement}, " +
- $"parameters: {queryData.Parameters.StringJoin()}");
+ _logger.LogExecutingSqlStatementDebug(statement,
queryData.Parameters.StringJoin());
}
IResultSet<T> resultSet = await _sql.ExecuteAsyncInternal(
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/README.md
b/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/README.md
index 8b02e7ef8e..68f5dd3ec5 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/README.md
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Linq/README.md
@@ -93,7 +93,7 @@ string sql = query.ToQueryString();
```csharp
var cfg = new IgniteClientConfiguration
{
- Logger = new ConsoleLogger { MinLevel = LogLevel.Debug },
+ Logger = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Debug)),
...
};
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/LogMessages.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/LogMessages.cs
new file mode 100644
index 0000000000..8ccaed4ecc
--- /dev/null
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/LogMessages.cs
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+namespace Apache.Ignite.Internal;
+
+using System;
+using System.Net;
+using System.Net.Security;
+using Ignite.Sql;
+using Microsoft.Extensions.Logging;
+using Proto;
+
+/// <summary>
+/// Source-generated logger delegates.
+/// </summary>
+internal static partial class LogMessages
+{
+ [LoggerMessage(
+ Message = "Schema loaded [tableId={TableId},
schemaVersion={SchemaVersion}]",
+ Level = LogLevel.Debug,
+ EventId = 1001)]
+ internal static partial void LogSchemaLoadedDebug(this ILogger logger, int
tableId, int schemaVersion);
+
+ [LoggerMessage(
+ Message = "Retrying unmapped columns error [tableId={TableId},
schemaVersion={SchemaVersion}, message={Message}]",
+ Level = LogLevel.Debug,
+ EventId = 1002)]
+ internal static partial void LogRetryingUnmappedColumnsErrorDebug(this
ILogger logger, int tableId, int? schemaVersion, string message);
+
+ [LoggerMessage(
+ Message = "Retrying SchemaVersionMismatch error [tableId={TableId}, " +
+ "schemaVersion={SchemaVersion},
expectedSchemaVersion={ExpectedSchemaVersion}]",
+ Level = LogLevel.Debug,
+ EventId = 1003)]
+ internal static partial void LogRetryingSchemaVersionMismatchErrorDebug(
+ this ILogger logger, int tableId, int? schemaVersion, int?
expectedSchemaVersion);
+
+ [LoggerMessage(
+ Message = "Executing SQL statement generated by LINQ provider
[statement={Statement}, parameters={Parameters}]",
+ Level = LogLevel.Debug,
+ SkipEnabledCheck = true,
+ EventId = 1004)]
+ internal static partial void LogExecutingSqlStatementDebug(this ILogger
logger, SqlStatement statement, string parameters);
+
+ [LoggerMessage(
+ Message = "Connection established [remoteAddress={Endpoint}]",
+ Level = LogLevel.Debug,
+ EventId = 1005)]
+ internal static partial void LogConnectionEstablishedDebug(this ILogger
logger, EndPoint? endpoint);
+
+ [LoggerMessage(
+ Message = "SSL connection established [remoteAddress={Endpoint},
cipherSuite={CipherSuite}]",
+ Level = LogLevel.Debug,
+ EventId = 1006)]
+ internal static partial void LogSslConnectionEstablishedDebug(this ILogger
logger, EndPoint? endpoint, TlsCipherSuite cipherSuite);
+
+ [LoggerMessage(
+ Message = "Handshake succeeded [remoteAddress={Endpoint},
context={Context}]",
+ Level = LogLevel.Debug,
+ EventId = 1007)]
+ internal static partial void LogHandshakeSucceededDebug(this ILogger
logger, EndPoint? endpoint, ConnectionContext context);
+
+ [LoggerMessage(
+ Message = "Failed to dispose socket after failed connection attempt:
{Message}",
+ Level = LogLevel.Warning,
+ EventId = 1008)]
+ internal static partial void
LogFailedToDisposeSocketAfterFailedConnectionAttemptWarn(
+ this ILogger logger, Exception ex, string message);
+
+ [LoggerMessage(
+ Message = "Connection failed before or during handshake
[remoteAddress={Endpoint}]: {Message}",
+ Level = LogLevel.Warning,
+ EventId = 1009)]
+ internal static partial void
LogConnectionFailedBeforeOrDuringHandshakeWarn(
+ this ILogger logger, Exception ex, EndPoint? endpoint, string message);
+
+ [LoggerMessage(
+ Message = "Server-side IdleTimeout is not set, using configured
IgniteClientConfiguration.HeartbeatInterval: {Interval}",
+ Level = LogLevel.Information,
+ EventId = 1010)]
+ internal static partial void LogServerSizeIdleTimeoutNotSetInfo(this
ILogger logger, TimeSpan interval);
+
+ [LoggerMessage(
+ Message = "Server-side IdleTimeout is {ServerIdleTimeout}, " +
+ "using configured
IgniteClientConfiguration.HeartbeatInterval: {ConfiguredInterval}",
+ Level = LogLevel.Information,
+ EventId = 1011)]
+ internal static partial void LogServerSideIdleTimeoutIgnoredInfo(
+ this ILogger logger, TimeSpan serverIdleTimeout, TimeSpan
configuredInterval);
+
+ [LoggerMessage(
+ Message = "Server-side IdleTimeout is {ServerIdleTimeout}, " +
+ "configured IgniteClientConfiguration.HeartbeatInterval is
{ConfiguredInterval}, " +
+ "which is longer than recommended IdleTimeout / 3. " +
+ "Overriding heartbeat interval with max(IdleTimeout / 3,
500ms): {RecommendedHeartbeatInterval}",
+ Level = LogLevel.Warning,
+ EventId = 1012)]
+ internal static partial void
LogServerSideIdleTimeoutOverridesConfiguredHeartbeatIntervalWarn(
+ this ILogger logger, TimeSpan serverIdleTimeout, TimeSpan
configuredInterval, TimeSpan recommendedHeartbeatInterval);
+
+ [LoggerMessage(
+ Message = "Sending request [requestId={RequestId}, op={Op},
remoteAddress={RemoteAddress}]",
+ Level = LogLevel.Trace,
+ EventId = 1013)]
+ internal static partial void LogSendingRequestTrace(this ILogger logger,
long requestId, ClientOp op, IPEndPoint remoteAddress);
+
+ [LoggerMessage(
+ Message = "{Message}",
+ Level = LogLevel.Error,
+ EventId = 1014)]
+ internal static partial void LogSocketIoError(this ILogger logger,
Exception? ex, string message);
+
+ [LoggerMessage(
+ Message = "{Message}",
+ Level = LogLevel.Error,
+ EventId = 1015)]
+ internal static partial void LogHeartbeatError(this ILogger logger,
Exception? ex, string message);
+
+ [LoggerMessage(
+ Message = "{Message}",
+ Level = LogLevel.Error,
+ EventId = 1016)]
+ internal static partial void LogUnexpectedResponseIdError(this ILogger
logger, Exception? ex, string message);
+
+ [LoggerMessage(
+ Message = "Partition assignment change notification received
[remoteAddress={RemoteAddress}, timestamp={Timestamp}",
+ Level = LogLevel.Information,
+ EventId = 1017)]
+ internal static partial void LogPartitionAssignmentChangeNotificationInfo(
+ this ILogger logger, IPEndPoint remoteAddress, long timestamp);
+
+ [LoggerMessage(
+ Message = "Connection closed with error
[remoteAddress={RemoteAddress}]: {Message}",
+ Level = LogLevel.Warning,
+ EventId = 1018)]
+ internal static partial void LogConnectionClosedWithErrorWarn(
+ this ILogger logger, Exception ex, IPEndPoint remoteAddress, string
message);
+
+ [LoggerMessage(
+ Message = "Connection closed gracefully
[remoteAddress={RemoteAddress}]",
+ Level = LogLevel.Debug,
+ EventId = 1019)]
+ internal static partial void LogConnectionClosedGracefullyDebug(this
ILogger logger, IPEndPoint remoteAddress);
+
+ [LoggerMessage(
+ Message = "Ignite.NET client version {Version} is starting",
+ Level = LogLevel.Information,
+ EventId = 1020)]
+ internal static partial void LogClientStartInfo(this ILogger logger,
string version);
+
+ [LoggerMessage(
+ Message = "Failed to connect to preferred node [name={NodeName}]:
{Message}",
+ Level = LogLevel.Debug,
+ EventId = 1021)]
+ internal static partial void LogFailedToConnectPreferredNodeDebug(this
ILogger logger, string nodeName, string message);
+
+ [LoggerMessage(
+ Message = "Error while trying to establish secondary connections:
{Message}",
+ Level = LogLevel.Warning,
+ EventId = 1022)]
+ internal static partial void
LogErrorWhileEstablishingSecondaryConnectionsWarn(this ILogger logger,
Exception e, string message);
+
+ [LoggerMessage(
+ Message = "Trying to establish secondary connections - awaiting
{Tasks} tasks...",
+ Level = LogLevel.Debug,
+ EventId = 1023)]
+ internal static partial void
LogTryingToEstablishSecondaryConnectionsDebug(this ILogger logger, int tasks);
+
+ [LoggerMessage(
+ Message = "{Established} secondary connections established, {Failed}
failed.",
+ Level = LogLevel.Debug,
+ EventId = 1024)]
+ internal static partial void LogSecondaryConnectionsEstablishedDebug(this
ILogger logger, int established, int failed);
+
+ [LoggerMessage(
+ Message = "Failed to parse host '{Host}': {Message}",
+ Level = LogLevel.Debug,
+ EventId = 1025)]
+ internal static partial void LogFailedToParseHostDebug(this ILogger
logger, Exception e, string host, string message);
+
+ [LoggerMessage(
+ Message = "{Retrying} operation [opCode={Op}, opType={OpType},
attempt={Attempt}, lastError={LastErrorMessage}]",
+ Level = LogLevel.Debug,
+ EventId = 1026)]
+ internal static partial void LogRetryingOperationDebug(
+ this ILogger logger, string retrying, int op, ClientOp opType, int
attempt, string lastErrorMessage);
+
+ [LoggerMessage(
+ Message = "Received response [requestId={RequestId},
remoteAddress={RemoteAddress}]",
+ Level = LogLevel.Trace,
+ EventId = 1027)]
+ internal static partial void LogReceivedResponseTrace(this ILogger logger,
long requestId, IPEndPoint remoteAddress);
+}
diff --git
a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/RecordView.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/RecordView.cs
index f8222b7cd7..277d48fe74 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/RecordView.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/RecordView.cs
@@ -29,7 +29,7 @@ namespace Apache.Ignite.Internal.Table
using Ignite.Table;
using Ignite.Transactions;
using Linq;
- using Log;
+ using Microsoft.Extensions.Logging;
using Proto;
using Serialization;
using Sql;
@@ -51,7 +51,7 @@ namespace Apache.Ignite.Internal.Table
/** SQL. */
private readonly Sql _sql;
- private readonly IIgniteLogger? _logger;
+ private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="RecordView{T}"/>
class.
@@ -64,7 +64,7 @@ namespace Apache.Ignite.Internal.Table
_table = table;
_ser = ser;
_sql = sql;
- _logger = table.Socket.Configuration.Logger.GetLogger(GetType());
+ _logger =
table.Socket.Configuration.LoggerFactory.CreateLogger<RecordView<T>>();
}
/// <summary>
@@ -427,22 +427,16 @@ namespace Apache.Ignite.Internal.Table
catch (IgniteException e) when (e.Code ==
ErrorGroups.Table.SchemaVersionMismatch &&
schemaVersionOverride !=
e.GetExpectedSchemaVersion())
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Retrying SchemaVersionMismatch error
[tableId={_table.Id}, schemaVersion={schema?.Version}, " +
-
$"expectedSchemaVersion={e.GetExpectedSchemaVersion()}]");
- }
-
schemaVersionOverride = e.GetExpectedSchemaVersion();
+
+ _logger.LogRetryingSchemaVersionMismatchErrorDebug(_table.Id,
schema?.Version, schemaVersionOverride);
+
return await DoRecordOutOpAsync(op, transaction, record,
keyOnly, schemaVersionOverride).ConfigureAwait(false);
}
catch (Exception e) when (e.CausedByUnmappedColumns() &&
schemaVersionOverride == null)
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Retrying unmapped columns error
[tableId={_table.Id}, schemaVersion={schema?.Version}]");
- }
+ _logger.LogRetryingUnmappedColumnsErrorDebug(_table.Id,
schema?.Version, e.Message);
schemaVersionOverride = Table.SchemaVersionForceLatest;
return await DoRecordOutOpAsync(op, transaction, record,
keyOnly, schemaVersionOverride).ConfigureAwait(false);
@@ -474,22 +468,16 @@ namespace Apache.Ignite.Internal.Table
catch (IgniteException e) when (e.Code ==
ErrorGroups.Table.SchemaVersionMismatch &&
schemaVersionOverride !=
e.GetExpectedSchemaVersion())
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Retrying SchemaVersionMismatch error
[tableId={_table.Id}, schemaVersion={schema?.Version}, " +
-
$"expectedSchemaVersion={e.GetExpectedSchemaVersion()}]");
- }
-
schemaVersionOverride = e.GetExpectedSchemaVersion();
+
+ _logger.LogRetryingSchemaVersionMismatchErrorDebug(_table.Id,
schema?.Version, schemaVersionOverride);
+
return await DoTwoRecordOutOpAsync(op, transaction, record,
record2, keyOnly, schemaVersionOverride).ConfigureAwait(false);
}
catch (Exception e) when (e.CausedByUnmappedColumns() &&
schemaVersionOverride == null)
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Retrying unmapped columns error
[tableId={_table.Id}, schemaVersion={schema?.Version}]");
- }
+ _logger.LogRetryingUnmappedColumnsErrorDebug(_table.Id,
schema?.Version, e.Message);
schemaVersionOverride = Table.SchemaVersionForceLatest;
return await DoTwoRecordOutOpAsync(op, transaction, record,
record2, keyOnly, schemaVersionOverride).ConfigureAwait(false);
@@ -527,24 +515,17 @@ namespace Apache.Ignite.Internal.Table
catch (IgniteException e) when (e.Code ==
ErrorGroups.Table.SchemaVersionMismatch &&
schemaVersionOverride !=
e.GetExpectedSchemaVersion())
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Retrying SchemaVersionMismatch error
[tableId={_table.Id}, schemaVersion={schema?.Version}, " +
-
$"expectedSchemaVersion={e.GetExpectedSchemaVersion()}]");
- }
-
schemaVersionOverride = e.GetExpectedSchemaVersion();
+ _logger.LogRetryingSchemaVersionMismatchErrorDebug(_table.Id,
schema?.Version, schemaVersionOverride);
+
// ReSharper disable once PossibleMultipleEnumeration (we have
to retry, but this is very rare)
return await DoMultiRecordOutOpAsync(op, transaction, recs,
keyOnly, schemaVersionOverride).ConfigureAwait(false);
}
catch (Exception e) when (e.CausedByUnmappedColumns() &&
schemaVersionOverride == null)
{
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Retrying unmapped columns error
[tableId={_table.Id}, schemaVersion={schema?.Version}]");
- }
+ _logger.LogRetryingUnmappedColumnsErrorDebug(_table.Id,
schema?.Version, e.Message);
schemaVersionOverride = Table.SchemaVersionForceLatest;
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
index 5582b13f19..80e5e97502 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/Table/Table.cs
@@ -28,7 +28,7 @@ namespace Apache.Ignite.Internal.Table
using Ignite.Sql;
using Ignite.Table;
using Ignite.Transactions;
- using Log;
+ using Microsoft.Extensions.Logging;
using Proto;
using Proto.MsgPack;
using Serialization;
@@ -65,7 +65,7 @@ namespace Apache.Ignite.Internal.Table
private readonly object _latestSchemaLock = new();
/** */
- private readonly IIgniteLogger? _logger;
+ private readonly ILogger _logger;
/** */
private readonly SemaphoreSlim _partitionAssignmentSemaphore = new(1);
@@ -94,7 +94,7 @@ namespace Apache.Ignite.Internal.Table
Name = name;
Id = id;
- _logger = socket.Configuration.Logger.GetLogger(GetType());
+ _logger = socket.Configuration.LoggerFactory.CreateLogger<Table>();
RecordBinaryView = new RecordView<IIgniteTuple>(
this,
@@ -372,10 +372,7 @@ namespace Apache.Ignite.Internal.Table
_schemas[schemaVersion] = Task.FromResult(schema);
- if (_logger?.IsEnabled(LogLevel.Debug) == true)
- {
- _logger.Debug($"Schema loaded [tableId={Id},
schemaVersion={schema.Version}]");
- }
+ _logger.LogSchemaLoadedDebug(Id, schema.Version);
lock (_latestSchemaLock)
{
diff --git a/modules/platforms/dotnet/Apache.Ignite/Internal/VersionUtils.cs
b/modules/platforms/dotnet/Apache.Ignite/Internal/VersionUtils.cs
index 1a020aa7fe..a62c5187c6 100644
--- a/modules/platforms/dotnet/Apache.Ignite/Internal/VersionUtils.cs
+++ b/modules/platforms/dotnet/Apache.Ignite/Internal/VersionUtils.cs
@@ -28,7 +28,7 @@ internal static class VersionUtils
/// Gets the informational version.
/// </summary>
/// <returns>Version string.</returns>
- public static string GetInformationalVersion() =>
+ public static readonly string InformationalVersion =
typeof(VersionUtils).Assembly
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()
?.InformationalVersion!;
diff --git a/modules/platforms/dotnet/Apache.Ignite/Log/CategoryLogger.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/CategoryLogger.cs
deleted file mode 100644
index 67acfbc606..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/CategoryLogger.cs
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
- using Internal.Common;
-
- /// <summary>
- /// Wrapping logger with a predefined category.
- /// <para />
- /// When <see cref="Log"/> method is called, and <c>category</c> parameter
is null, predefined category
- /// will be used.
- /// </summary>
- public sealed class CategoryLogger : IIgniteLogger
- {
- /** Wrapped logger. */
- private readonly IIgniteLogger _logger;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="CategoryLogger"/>
class.
- /// </summary>
- /// <param name="logger">The logger to wrap.</param>
- /// <param name="category">The category.</param>
- public CategoryLogger(IIgniteLogger logger, string category)
- {
- IgniteArgumentCheck.NotNull(logger);
-
- // If logger is already a CategoryLogger, get underlying logger
instead to avoid unnecessary nesting.
- _logger = logger is CategoryLogger catLogger ? catLogger._logger :
logger;
-
- Category = category;
- }
-
- /// <summary>
- /// Gets the category name.
- /// </summary>
- public string Category { get; }
-
- /// <summary>
- /// Logs the specified message.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments to format <paramref
name="message" />.
- /// Can be null (formatting will not occur).</param>
- /// <param name="formatProvider">The format provider. Can be null if
<paramref name="args" /> is null.</param>
- /// <param name="category">The logging category name.</param>
- /// <param name="nativeErrorInfo">The native error information.</param>
- /// <param name="ex">The exception. Can be null.</param>
- public void Log(
- LogLevel level,
- string message,
- object?[]? args,
- IFormatProvider? formatProvider,
- string? category,
- string? nativeErrorInfo,
- Exception? ex)
- {
- _logger.Log(level, message, args, formatProvider, category ??
Category, nativeErrorInfo, ex);
- }
-
- /// <summary>
- /// Determines whether the specified log level is enabled.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <returns>
- /// Value indicating whether the specified log level is enabled.
- /// </returns>
- public bool IsEnabled(LogLevel level)
- {
- return _logger.IsEnabled(level);
- }
-
- /// <inheritdoc />
- public override string ToString() =>
- new IgniteToStringBuilder(GetType())
- .Append(Category)
- .Build();
- }
-}
diff --git a/modules/platforms/dotnet/Apache.Ignite/Log/ConsoleLogger.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/ConsoleLogger.cs
deleted file mode 100644
index 39ff5d2ea3..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/ConsoleLogger.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
- using System.Globalization;
- using System.Text;
- using Internal.Common;
-
- /// <summary>
- /// Logs to Console.
- /// <para />
- /// Simple logger implementation without dependencies, provided out of the
box for convenience.
- /// For anything more complex please use NLog/log4net integrations.
- /// </summary>
- public sealed class ConsoleLogger : IIgniteLogger
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="ConsoleLogger"/>
class.
- /// Uses <see cref="LogLevel.Warn"/> minimum level.
- /// </summary>
- public ConsoleLogger()
- {
- MinLevel = LogLevel.Warn;
- }
-
- /// <summary>
- /// Gets or sets the minimum level to be logged. Any levels lower than
that are ignored.
- /// Default is <see cref="LogLevel.Warn"/>.
- /// </summary>
- public LogLevel MinLevel { get; set; }
-
- /// <summary>
- /// Gets or sets DateTime provider.
- /// </summary>
- public IDateTimeProvider? DateTimeProvider { get; set; }
-
- /// <summary>
- /// Logs the specified message.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments to format <paramref
name="message" />.
- /// Can be null (formatting will not occur).</param>
- /// <param name="formatProvider">The format provider. Can be null if
<paramref name="args" /> is null.</param>
- /// <param name="category">The logging category name.</param>
- /// <param name="nativeErrorInfo">The native error information.</param>
- /// <param name="ex">The exception. Can be null.</param>
- public void Log(
- LogLevel level,
- string message,
- object?[]? args,
- IFormatProvider? formatProvider,
- string? category,
- string? nativeErrorInfo,
- Exception? ex)
- {
- if (!IsEnabled(level))
- {
- return;
- }
-
- var dateTimeProvider = DateTimeProvider ??
LocalDateTimeProvider.Instance;
-
- var sb = new StringBuilder().AppendFormat(
- CultureInfo.InvariantCulture,
- "[{0:HH:mm:ss}] [{1}] [{2}] ",
- dateTimeProvider.Now(),
- level,
- category);
-
- if (args is { Length: > 0 })
- {
- sb.AppendFormat(formatProvider, message, args);
- }
- else
- {
- sb.Append(message);
- }
-
- if (ex != null)
- {
- sb.AppendFormat(CultureInfo.InvariantCulture, " (exception:
{0})", ex);
- }
-
- Console.WriteLine(sb.ToString());
- }
-
- /// <summary>
- /// Determines whether the specified log level is enabled.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <returns>Value indicating whether the specified log level is
enabled.</returns>
- public bool IsEnabled(LogLevel level)
- {
- return level >= MinLevel;
- }
-
- /// <inheritdoc />
- public override string ToString() =>
- new IgniteToStringBuilder(GetType())
- .Append(MinLevel)
- .Build();
- }
-}
diff --git a/modules/platforms/dotnet/Apache.Ignite/Log/IDateTimeProvider.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/IDateTimeProvider.cs
deleted file mode 100644
index c7e40407f9..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/IDateTimeProvider.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
-
- /// <summary>
- /// <see cref="DateTime"/> abstraction for logging.
- /// </summary>
- public interface IDateTimeProvider
- {
- /// <summary>
- /// Gets current <see cref="DateTime"/>.
- /// </summary>
- /// <returns>Current DateTime.</returns>
- DateTime Now();
- }
-}
diff --git a/modules/platforms/dotnet/Apache.Ignite/Log/IIgniteLogger.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/IIgniteLogger.cs
deleted file mode 100644
index 134c5664d2..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/IIgniteLogger.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
-
- /// <summary>
- /// Defines Ignite logging interface.
- /// <para />
- /// This interface only provides essential log methods.
- /// All convenience overloads are in <see cref="LoggerExtensions"/>.
- /// </summary>
- public interface IIgniteLogger
- {
- /// <summary>
- /// Logs the specified message.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments to format <paramref
name="message" />.
- /// Can be null (formatting will not occur).</param>
- /// <param name="formatProvider">The format provider. Can be null if
<paramref name="args" /> is null.</param>
- /// <param name="category">The logging category name.</param>
- /// <param name="nativeErrorInfo">The native error information.</param>
- /// <param name="ex">The exception. Can be null.</param>
- void Log(
- LogLevel level,
- string message,
- object?[]? args,
- IFormatProvider? formatProvider,
- string? category,
- string? nativeErrorInfo,
- Exception? ex);
-
- /// <summary>
- /// Determines whether the specified log level is enabled.
- /// </summary>
- /// <param name="level">The level.</param>
- /// <returns>Value indicating whether the specified log level is
enabled.</returns>
- bool IsEnabled(LogLevel level);
- }
-}
diff --git
a/modules/platforms/dotnet/Apache.Ignite/Log/LocalDateTimeProvider.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/LocalDateTimeProvider.cs
deleted file mode 100644
index 7bafd37941..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/LocalDateTimeProvider.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
- using System.Diagnostics.CodeAnalysis;
- using Internal.Common;
-
- /// <summary>
- /// Returns <see cref="DateTime.Now"/>.
- /// </summary>
- public sealed class LocalDateTimeProvider : IDateTimeProvider
- {
- /// <summary>
- /// Default instance.
- /// </summary>
- [SuppressMessage(
- "Microsoft.Security",
- "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes",
- Justification = "Type is immutable.")]
- public static readonly LocalDateTimeProvider Instance = new();
-
- /// <inheritdoc />
- public DateTime Now()
- {
- return DateTime.Now;
- }
-
- /// <inheritdoc />
- public override string ToString() =>
IgniteToStringBuilder.Build(GetType());
- }
-}
diff --git a/modules/platforms/dotnet/Apache.Ignite/Log/LogLevel.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/LogLevel.cs
deleted file mode 100644
index b9a486f96c..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/LogLevel.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
-
- /// <summary>
- /// Defines log levels.
- /// </summary>
- [Serializable]
- public enum LogLevel
- {
- /// <summary>
- /// Trace log level.
- /// </summary>
- Trace = 0,
-
- /// <summary>
- /// Debug log level.
- /// </summary>
- Debug = 1,
-
- /// <summary>
- /// Info log level.
- /// </summary>
- Info = 2,
-
- /// <summary>
- /// Warning log level.
- /// </summary>
- Warn = 3,
-
- /// <summary>
- /// Error log level.
- /// </summary>
- Error = 4
- }
-}
diff --git a/modules/platforms/dotnet/Apache.Ignite/Log/LoggerExtensions.cs
b/modules/platforms/dotnet/Apache.Ignite/Log/LoggerExtensions.cs
deleted file mode 100644
index d91af1749f..0000000000
--- a/modules/platforms/dotnet/Apache.Ignite/Log/LoggerExtensions.cs
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-namespace Apache.Ignite.Log
-{
- using System;
- using System.Globalization;
- using Internal.Common;
-
- /// <summary>
- /// Extension methods for <see cref="IIgniteLogger" />.
- /// </summary>
- public static class LoggerExtensions
- {
- // 4 overloads per level (message, message+args, ex+message,
ex+message+args)
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Trace"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- public static void Trace(this IIgniteLogger logger, string message)
- {
- Log(logger, LogLevel.Trace, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Trace"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Trace(this IIgniteLogger logger, string message,
params object?[]? args)
- {
- Log(logger, LogLevel.Trace, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Trace"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- public static void Trace(this IIgniteLogger logger, Exception? ex,
string message)
- {
- Log(logger, LogLevel.Trace, ex, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Trace"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Trace(this IIgniteLogger logger, Exception? ex,
string message, params object?[]? args)
- {
- Log(logger, LogLevel.Trace, ex, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Debug"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- public static void Debug(this IIgniteLogger logger, string message)
- {
- Log(logger, LogLevel.Debug, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Debug"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Debug(this IIgniteLogger logger, string message,
params object?[]? args)
- {
- Log(logger, LogLevel.Debug, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Debug"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- public static void Debug(this IIgniteLogger logger, Exception? ex,
string message)
- {
- Log(logger, LogLevel.Debug, ex, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Debug"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Debug(this IIgniteLogger logger, Exception? ex,
string message, params object?[]? args)
- {
- Log(logger, LogLevel.Debug, ex, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Info"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- public static void Info(this IIgniteLogger logger, string message)
- {
- Log(logger, LogLevel.Info, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Info"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Info(this IIgniteLogger logger, string message,
params object?[]? args)
- {
- Log(logger, LogLevel.Info, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Info"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- public static void Info(this IIgniteLogger logger, Exception? ex,
string message)
- {
- Log(logger, LogLevel.Info, ex, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Info"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Info(this IIgniteLogger logger, Exception? ex,
string message, params object?[]? args)
- {
- Log(logger, LogLevel.Info, ex, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Warn"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- public static void Warn(this IIgniteLogger logger, string message)
- {
- Log(logger, LogLevel.Warn, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Warn"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Warn(this IIgniteLogger logger, string message,
params object?[]? args)
- {
- Log(logger, LogLevel.Warn, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Warn"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- public static void Warn(this IIgniteLogger logger, Exception? ex,
string message)
- {
- Log(logger, LogLevel.Warn, ex, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Warn"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Warn(this IIgniteLogger logger, Exception? ex,
string message, params object?[]? args)
- {
- Log(logger, LogLevel.Warn, ex, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Error"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- public static void Error(this IIgniteLogger logger, string message)
- {
- Log(logger, LogLevel.Error, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Error"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Error(this IIgniteLogger logger, string message,
params object?[]? args)
- {
- Log(logger, LogLevel.Error, message, args);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Error"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- public static void Error(this IIgniteLogger logger, Exception? ex,
string message)
- {
- Log(logger, LogLevel.Error, ex, message);
- }
-
- /// <summary>
- /// Logs the message with <see cref="LogLevel.Error"/> level.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Error(this IIgniteLogger logger, Exception? ex,
string message, params object?[]? args)
- {
- Log(logger, LogLevel.Error, ex, message, args);
- }
-
- /// <summary>
- /// Logs the message.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="level">The level.</param>
- /// <param name="message">The message.</param>
- public static void Log(this IIgniteLogger logger, LogLevel level,
string message)
- {
- IgniteArgumentCheck.NotNull(logger);
-
- logger.Log(level, message, null, null, null, null, null);
- }
-
- /// <summary>
- /// Logs the message.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="level">The level.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Log(this IIgniteLogger logger, LogLevel level,
string message, params object?[]? args)
- {
- IgniteArgumentCheck.NotNull(logger);
-
- logger.Log(level, message, args, CultureInfo.InvariantCulture,
null, null, null);
- }
-
- /// <summary>
- /// Logs the message.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="level">The level.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- public static void Log(this IIgniteLogger logger, LogLevel level,
Exception? ex, string message)
- {
- IgniteArgumentCheck.NotNull(logger);
-
- logger.Log(level, message, null, null, null, null, ex);
- }
-
- /// <summary>
- /// Logs the message.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="level">The level.</param>
- /// <param name="ex">The exception.</param>
- /// <param name="message">The message.</param>
- /// <param name="args">The arguments.</param>
- public static void Log(this IIgniteLogger logger, LogLevel level,
Exception? ex, string message, params object?[]? args)
- {
- IgniteArgumentCheck.NotNull(logger);
-
- logger.Log(level, message, args, CultureInfo.InvariantCulture,
null, null, ex);
- }
-
- /// <summary>
- /// Gets the <see cref="CategoryLogger"/> with a specified category
that wraps provided logger.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="category">The category.</param>
- /// <returns>Logger that uses specified category when no other
category is provided.</returns>
- public static IIgniteLogger? GetLogger(this IIgniteLogger? logger,
string category)
- {
- IgniteArgumentCheck.NotNull(category);
-
- return logger == null ? null : new CategoryLogger(logger,
category);
- }
-
- /// <summary>
- /// Gets the <see cref="CategoryLogger"/> with a specified category
that wraps provided logger.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="category">The category as a type.</param>
- /// <returns>Logger that uses specified category when no other
category is provided.</returns>
- public static IIgniteLogger? GetLogger(this IIgniteLogger? logger,
Type category)
- {
- IgniteArgumentCheck.NotNull(category);
-
- return logger == null ? null : new CategoryLogger(logger,
category.Name);
- }
- }
-}
diff --git a/modules/platforms/dotnet/README.md
b/modules/platforms/dotnet/README.md
index c48e566963..281884c7fe 100644
--- a/modules/platforms/dotnet/README.md
+++ b/modules/platforms/dotnet/README.md
@@ -79,10 +79,7 @@ var cfg = new IgniteClientConfiguration
},
// Retry all read operations in case of network issues.
- RetryPolicy = new RetryReadPolicy { RetryLimit = 32 },
-
- // Log to console.
- Logger = new ConsoleLogger { MinLevel = LogLevel.Debug }
+ RetryPolicy = new RetryReadPolicy { RetryLimit = 32 }
};
```
@@ -239,7 +236,29 @@ Ignite client implements a number of features to improve
reliability and perform
## Logging
-To enable logging, set `IgniteClientConfiguration.Logger` property.
`ConsoleLogger` is provided out of the box. Other loggers can be integrated by
implementing `IIgniteLogger` interface.
+To enable logging, set `IgniteClientConfiguration.LoggerFactory` property. It
uses the standard
[Microsoft.Extensions.Logging](https://docs.microsoft.com/en-us/dotnet/core/extensions/logging)
API.
+
+For example, to log to console (requires
`Microsoft.Extensions.Logging.Console` package):
+
+```cs
+var cfg = new IgniteClientConfiguration
+{
+ LoggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Debug))
+};
+```
+
+Or with Serilog (requires `Serilog.Extensions.Logging` and
`Serilog.Sinks.Console` packages):
+
+```cs
+var cfg = new IgniteClientConfiguration
+{
+ LoggerFactory = LoggerFactory.Create(builder =>
+ builder.AddSerilog(new LoggerConfiguration()
+ .MinimumLevel.Debug()
+ .WriteTo.Console()
+ .CreateLogger()))
+};
+```
## Metrics