Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR introduces version 10.0.0 of the Longbow.Logging component, adding comprehensive logging functionality with support for file-based and database logging. The PR upgrades multiple Microsoft.Extensions package dependencies to version 10.* and targets .NET 10.0, which may not be stable or available yet.
Key Changes:
- Added complete Longbow.Logging library with FileLogger and DBLogger implementations
- Updated test project dependencies from version 9.* to 10.* for Microsoft.Extensions packages
- Added comprehensive unit tests for the new logging functionality
Reviewed Changes
Copilot reviewed 30 out of 30 changed files in this pull request and generated 27 comments.
Show a summary per file
| File | Description |
|---|---|
| test/UnitTestTcpSocket/UnitTestTcpSocket.csproj | Updated Microsoft.Extensions.DependencyInjection to version 10.* |
| test/UnitTestSocket/UnitTestSocket.csproj | Updated Microsoft.Extensions.Options.ConfigurationExtensions to version 10.* |
| test/UnitTestModbus/UnitTestModbus.csproj | Updated Microsoft.Extensions.DependencyInjection to version 10.* |
| test/UnitTestLogging/appsettings.json | Added configuration for file logger with batch and scope settings |
| test/UnitTestLogging/UnitTestLogging.csproj | New test project targeting net10.0 with version 10.* dependencies |
| test/UnitTestLogging/TestHelper.cs | Helper class for triggering configuration file change events |
| test/UnitTestLogging/LoggerProviderTest.cs | Tests for LoggerProvider creation and disposal |
| test/UnitTestLogging/FileLoggerWriterTest.cs | Tests for file logger writer including batch processing and file rolling |
| test/UnitTestLogging/FileLoggerTest.cs | Tests for file logger integration with DI container (contains syntax error) |
| test/UnitTestLogging/DBLoggerTest.cs | Tests for database logger provider and IP address extensions |
| test/Directory.Build.props | Updated Microsoft.NET.Test.Sdk to version 18.* |
| src/Longbow.Logging/readme.zh-CN.md | Chinese documentation for the logging library |
| src/Longbow.Logging/readme.md | English documentation for the logging library |
| src/Longbow.Logging/exceptionManagement.json | Example configuration for exception logging |
| src/Longbow.Logging/Longbow.Logging.csproj | Project file with multi-targeting support and version 10.* package references |
| src/Longbow.Logging/LoggerProviderConfigureOptions.cs | Configuration helper for logger providers |
| src/Longbow.Logging/Logger/LoggerProvider.cs | Base logger provider implementation |
| src/Longbow.Logging/Logger/LoggerBase.cs | Abstract base class for logger implementations |
| src/Longbow.Logging/Logger/Logger.cs | Console logger implementation |
| src/Longbow.Logging/LogMessage.cs | Log message data structure |
| src/Longbow.Logging/FormatExceptionExtensions.cs | Exception formatting utilities for detailed error output |
| src/Longbow.Logging/FileLogger/FileLoggerWriter.cs | File writing logic with batch processing support |
| src/Longbow.Logging/FileLogger/FileLoggerProvider.cs | File logger provider with configuration monitoring |
| src/Longbow.Logging/FileLogger/FileLoggerOptions.cs | Configuration options for file logging |
| src/Longbow.Logging/FileLogger/FileLogger.cs | File logger implementation |
| src/Longbow.Logging/Extensions/FileLoggerFactoryExtensions.cs | DI registration extensions for file and database loggers |
| src/Longbow.Logging/DBLogger/DBLoggerProvider.cs | Database logger provider implementation |
| src/Longbow.Logging/DBLogger/DBLogger.cs | Database logger implementation (contains signature error) |
| src/Longbow.Logging/ConfigurationExtensions.cs | Configuration extensions for environment variables (contains typo) |
| Longbow.Utility2026.slnx | Added Longbow.Logging project to solution |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// <typeparam name="TOptions"></typeparam> | ||
| /// <typeparam name="TProvider"></typeparam> |
There was a problem hiding this comment.
The empty XML comment lacks a description. Consider adding a meaningful summary that explains the purpose of the LoggerProviderConfigureOptions class.
| /// <typeparam name="TOptions"></typeparam> | |
| /// <typeparam name="TProvider"></typeparam> | |
| /// <typeparam name="TOptions">The options type to be configured for the logger provider.</typeparam> | |
| /// <typeparam name="TProvider">The logger provider type for which the options are being configured.</typeparam> |
| public abstract class LoggerBase(string name, Func<string, LogLevel, bool>? filter, IExternalScopeProvider? scopeProvider, IConfiguration? config) : ILogger | ||
| { | ||
| /// <summary> | ||
| /// |
There was a problem hiding this comment.
The empty XML comment lacks a description. Consider adding a meaningful summary that explains the purpose of the LogName property.
| /// | |
| /// Gets the name of the logger instance. |
| protected string LogName { get; } = name; | ||
|
|
||
| /// <summary> | ||
| /// |
There was a problem hiding this comment.
The empty XML comment lacks a description. Consider adding a meaningful summary that explains the purpose of the Filter property.
| /// | |
| /// Gets the filter function used to determine whether logging is enabled for a given category and log level. |
| public static class ConfigurationExtensions | ||
| { | ||
| /// <summary> | ||
| /// 获得 环境变量中的 OS 属性值 近 Windows 平台有效 |
There was a problem hiding this comment.
Typo: "近 Windows 平台有效" should be "仅 Windows 平台有效" (only valid for Windows platform).
| /// 获得 环境变量中的 OS 属性值 近 Windows 平台有效 | |
| /// 获得 环境变量中的 OS 属性值 仅 Windows 平台有效 |
| public static class TestHelper | ||
| { | ||
| /// <summary> | ||
| /// |
There was a problem hiding this comment.
The empty XML comment lacks a description. Consider adding a meaningful summary that explains the purpose of the TestHelper class.
| /// | |
| /// Triggers a reload of the app settings file and invokes the specified callback when the configuration changes. |
|
|
||
| // 生产长度不满足内部判断条件的干扰文件 | ||
| var fn = $"Log01.log"; | ||
| using (var fs = File.AppendText(Path.Combine(folder, fn))) { } |
| if (propertyValue != null) | ||
| { | ||
| #region Loop through the public properties of the exception object and record their value | ||
| // Loop through the public properties of the exception object and record their value. | ||
| // Cast the collection into a local variable. | ||
| // Check if the collection contains values. | ||
| if (propertyValue is NameValueCollection currentAdditionalInfo && currentAdditionalInfo.Count > 0) | ||
| { | ||
| strInfo.AppendFormat("AdditionalInformation{0}", Environment.NewLine); | ||
| // Loop through the collection adding the information to the string builder. | ||
| foreach (string? infoKey in currentAdditionalInfo) | ||
| { | ||
| if (!string.IsNullOrEmpty(infoKey)) strInfo.AppendFormat("{1}: {2}{0}", Environment.NewLine, infoKey, currentAdditionalInfo[infoKey]); | ||
| } |
There was a problem hiding this comment.
These 'if' statements can be combined.
| if (propertyValue != null) | |
| { | |
| #region Loop through the public properties of the exception object and record their value | |
| // Loop through the public properties of the exception object and record their value. | |
| // Cast the collection into a local variable. | |
| // Check if the collection contains values. | |
| if (propertyValue is NameValueCollection currentAdditionalInfo && currentAdditionalInfo.Count > 0) | |
| { | |
| strInfo.AppendFormat("AdditionalInformation{0}", Environment.NewLine); | |
| // Loop through the collection adding the information to the string builder. | |
| foreach (string? infoKey in currentAdditionalInfo) | |
| { | |
| if (!string.IsNullOrEmpty(infoKey)) strInfo.AppendFormat("{1}: {2}{0}", Environment.NewLine, infoKey, currentAdditionalInfo[infoKey]); | |
| } | |
| if (propertyValue is NameValueCollection currentAdditionalInfo && currentAdditionalInfo.Count > 0) | |
| { | |
| #region Loop through the public properties of the exception object and record their value | |
| // Loop through the public properties of the exception object and record their value. | |
| // Cast the collection into a local variable. | |
| // Check if the collection contains values. | |
| strInfo.AppendFormat("AdditionalInformation{0}", Environment.NewLine); | |
| // Loop through the collection adding the information to the string builder. | |
| foreach (string? infoKey in currentAdditionalInfo) | |
| { | |
| if (!string.IsNullOrEmpty(infoKey)) strInfo.AppendFormat("{1}: {2}{0}", Environment.NewLine, infoKey, currentAdditionalInfo[infoKey]); |
| if (disposing) | ||
| { | ||
| if (!disposedValue) | ||
| { | ||
| disposedValue = true; | ||
|
|
||
| _messageQueue.CompleteAdding(); | ||
| _cancellationTokenSource.Cancel(); | ||
| _logTask.Wait(Option.TaskWaitTime); | ||
|
|
||
| _cancellationTokenSource.Dispose(); | ||
| _messageQueue.Dispose(); | ||
| } |
There was a problem hiding this comment.
These 'if' statements can be combined.
| if (disposing) | |
| { | |
| if (!disposedValue) | |
| { | |
| disposedValue = true; | |
| _messageQueue.CompleteAdding(); | |
| _cancellationTokenSource.Cancel(); | |
| _logTask.Wait(Option.TaskWaitTime); | |
| _cancellationTokenSource.Dispose(); | |
| _messageQueue.Dispose(); | |
| } | |
| if (disposing && !disposedValue) | |
| { | |
| disposedValue = true; | |
| _messageQueue.CompleteAdding(); | |
| _cancellationTokenSource.Cancel(); | |
| _logTask.Wait(Option.TaskWaitTime); | |
| _cancellationTokenSource.Dispose(); | |
| _messageQueue.Dispose(); |
Link issues
fixes #35
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge