Smdn.Net.MuninNode version 1.3.0
smdn
released this
11 Oct 11:32
·
20 commits
to main
since this release
Released package
Release notes
The full release notes are available at gist.
Change log
Change log in this release:
- 2024-10-11 update assembly version
- 2024-10-11 add support for {fieldname}.negative field attribute
- 2024-10-11 change links to refer to HTTPS pages
- 2024-10-11 redefine PackageValidationBaselineVersion to fix broken API compat baseline
- 2024-10-11 improve package readme
- 2024-10-11 add target framework net8.0
- 2024-10-11 fix CA warnings
- 2024-10-11 bump Smdn.MSBuild.ProjectAssets.*
API changes
API changes in this release:
diff --git a/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net6.0.apilist.cs b/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net6.0.apilist.cs
index 4bf85bf..130febd 100644
--- a/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net6.0.apilist.cs
+++ b/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net6.0.apilist.cs
@@ -1,210 +1,215 @@
-// Smdn.Net.MuninNode.dll (Smdn.Net.MuninNode-1.2.0)
+// Smdn.Net.MuninNode.dll (Smdn.Net.MuninNode-1.3.0)
// Name: Smdn.Net.MuninNode
-// AssemblyVersion: 1.2.0.0
-// InformationalVersion: 1.2.0+b0e11cd6b408018ad93f29b49e58cab7e9ef6b1b
+// AssemblyVersion: 1.3.0.0
+// InformationalVersion: 1.3.0+191d215fe57392cb544e2ffea221644a1007cfc0
// TargetFramework: .NETCoreApp,Version=v6.0
// Configuration: Release
// Referenced assemblies:
// Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// Smdn.Fundamental.Exception, Version=3.0.0.0, Culture=neutral
// System.Collections, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.ComponentModel, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.IO.Pipelines, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// System.Linq, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.Memory, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// System.Net.Primitives, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.Net.Sockets, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.Security.Cryptography.Algorithms, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
// System.Text.RegularExpressions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Smdn.Net.MuninNode;
using Smdn.Net.MuninPlugin;
namespace Smdn.Net.MuninNode {
public class LocalNode : NodeBase {
public LocalNode(IPluginProvider pluginProvider, string hostName, int port, ILogger? logger = null) {}
public LocalNode(IPluginProvider pluginProvider, string hostName, int port, IServiceProvider? serviceProvider = null) {}
public LocalNode(IReadOnlyCollection<IPlugin> plugins, int port, IServiceProvider? serviceProvider = null) {}
public LocalNode(IReadOnlyCollection<IPlugin> plugins, string hostName, int port, IServiceProvider? serviceProvider = null) {}
public IPEndPoint LocalEndPoint { get; }
protected override Socket CreateServerSocket() {}
protected override bool IsClientAcceptable(IPEndPoint remoteEndPoint) {}
}
public abstract class NodeBase :
IAsyncDisposable,
IDisposable
{
private protected class PluginProvider : IPluginProvider {
public PluginProvider(IReadOnlyCollection<IPlugin> plugins) {}
public IReadOnlyCollection<IPlugin> Plugins { get; }
public INodeSessionCallback? SessionCallback { get; }
}
protected NodeBase(IPluginProvider pluginProvider, string hostName, ILogger? logger) {}
protected NodeBase(IReadOnlyCollection<IPlugin> plugins, string hostName, ILogger? logger) {}
public virtual Encoding Encoding { get; }
public string HostName { get; }
protected ILogger? Logger { get; }
public virtual Version NodeVersion { get; }
[Obsolete("This member will be deprecated in future version.")]
public IReadOnlyCollection<IPlugin> Plugins { get; }
public async ValueTask AcceptAsync(bool throwIfCancellationRequested, CancellationToken cancellationToken) {}
public async ValueTask AcceptSingleSessionAsync(CancellationToken cancellationToken = default) {}
protected abstract Socket CreateServerSocket();
protected virtual void Dispose(bool disposing) {}
public void Dispose() {}
public async ValueTask DisposeAsync() {}
protected virtual async ValueTask DisposeAsyncCore() {}
protected abstract bool IsClientAcceptable(IPEndPoint remoteEndPoint);
public void Start() {}
}
}
namespace Smdn.Net.MuninPlugin {
public interface INodeSessionCallback {
ValueTask ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken);
ValueTask ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken);
}
public interface IPlugin {
IPluginDataSource DataSource { get; }
PluginGraphAttributes GraphAttributes { get; }
string Name { get; }
INodeSessionCallback? SessionCallback { get; }
}
public interface IPluginDataSource {
IReadOnlyCollection<IPluginField> Fields { get; }
}
public interface IPluginField {
PluginFieldAttributes Attributes { get; }
string Name { get; }
ValueTask<string> GetFormattedValueStringAsync(CancellationToken cancellationToken);
}
public interface IPluginProvider {
IReadOnlyCollection<IPlugin> Plugins { get; }
INodeSessionCallback? SessionCallback { get; }
}
public enum PluginFieldGraphStyle : int {
Area = 1,
AreaStack = 3,
Default = 0,
Line = 100,
LineStack = 200,
LineStackWidth1 = 201,
LineStackWidth2 = 202,
LineStackWidth3 = 203,
LineWidth1 = 101,
LineWidth2 = 102,
LineWidth3 = 103,
Stack = 2,
}
public class Plugin :
INodeSessionCallback,
IPlugin,
IPluginDataSource
{
public Plugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<IPluginField> fields) {}
public IReadOnlyCollection<IPluginField> Fields { get; }
public PluginGraphAttributes GraphAttributes { get; }
public string Name { get; }
IPluginDataSource IPlugin.DataSource { get; }
INodeSessionCallback? IPlugin.SessionCallback { get; }
IReadOnlyCollection<IPluginField> IPluginDataSource.Fields { get; }
protected virtual ValueTask ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken) {}
protected virtual ValueTask ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken) {}
ValueTask INodeSessionCallback.ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken) {}
ValueTask INodeSessionCallback.ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken) {}
}
public static class PluginFactory {
public static IPluginField CreateField(string label, Func<double?> fetchValue) {}
public static IPluginField CreateField(string label, PluginFieldGraphStyle graphStyle, Func<double?> fetchValue) {}
public static IPluginField CreateField(string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, Func<double?> fetchValue) {}
public static IPluginField CreateField(string name, string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, Func<double?> fetchValue) {}
+ public static IPluginField CreateField(string name, string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName, Func<double?> fetchValue) {}
public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<IPluginField> fields) {}
public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<PluginFieldBase> fields) {}
public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, PluginFieldBase field) {}
public static IPlugin CreatePlugin(string name, string fieldLabel, Func<double?> fetchFieldValue, PluginGraphAttributes graphAttributes) {}
public static IPlugin CreatePlugin(string name, string fieldLabel, PluginFieldGraphStyle fieldGraphStyle, Func<double?> fetchFieldValue, PluginGraphAttributes graphAttributes) {}
}
public abstract class PluginFieldBase : IPluginField {
protected PluginFieldBase(string label, string? name, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default, PluginFieldNormalValueRange normalRangeForWarning = default, PluginFieldNormalValueRange normalRangeForCritical = default) {}
+ protected PluginFieldBase(string label, string? name, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName) {}
public PluginFieldGraphStyle GraphStyle { get; }
public string Label { get; }
public string Name { get; }
+ public string? NegativeFieldName { get; }
public PluginFieldNormalValueRange NormalRangeForCritical { get; }
public PluginFieldNormalValueRange NormalRangeForWarning { get; }
PluginFieldAttributes IPluginField.Attributes { get; }
protected abstract ValueTask<double?> FetchValueAsync(CancellationToken cancellationToken);
async ValueTask<string> IPluginField.GetFormattedValueStringAsync(CancellationToken cancellationToken) {}
}
public sealed class PluginGraphAttributes {
[Obsolete("This member will be deprecated in future version.")]
public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan updateRate, int? width = null, int? height = null) {}
public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan? updateRate = null, int? width = null, int? height = null) {}
public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan? updateRate, int? width, int? height, IEnumerable<string>? order) {}
public string Arguments { get; }
public string Category { get; }
public int? Height { get; }
public string? Order { get; }
public bool Scale { get; }
public string Title { get; }
public TimeSpan? UpdateRate { get; }
public string VerticalLabel { get; }
public int? Width { get; }
}
public readonly struct PluginFieldAttributes {
public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default) {}
public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default, PluginFieldNormalValueRange normalRangeForWarning = default, PluginFieldNormalValueRange normalRangeForCritical = default) {}
+ public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName) {}
public PluginFieldGraphStyle GraphStyle { get; }
public string Label { get; }
+ public string? NegativeFieldName { get; }
public PluginFieldNormalValueRange NormalRangeForCritical { get; }
public PluginFieldNormalValueRange NormalRangeForWarning { get; }
}
public readonly struct PluginFieldNormalValueRange {
public static readonly PluginFieldNormalValueRange None; // = "Smdn.Net.MuninPlugin.PluginFieldNormalValueRange"
public static PluginFieldNormalValueRange CreateMax(double max) {}
public static PluginFieldNormalValueRange CreateMin(double min) {}
public static PluginFieldNormalValueRange CreateRange(double min, double max) {}
public bool HasValue { get; }
public double? Max { get; }
public double? Min { get; }
}
}
-// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.2.2.0.
-// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
+// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.4.1.0.
+// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net8.0.apilist.cs b/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net8.0.apilist.cs
new file mode 100644
index 0000000..73b3402
--- /dev/null
+++ b/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-net8.0.apilist.cs
@@ -0,0 +1,215 @@
+// Smdn.Net.MuninNode.dll (Smdn.Net.MuninNode-1.3.0)
+// Name: Smdn.Net.MuninNode
+// AssemblyVersion: 1.3.0.0
+// InformationalVersion: 1.3.0+191d215fe57392cb544e2ffea221644a1007cfc0
+// TargetFramework: .NETCoreApp,Version=v8.0
+// Configuration: Release
+// Referenced assemblies:
+// Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
+// Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
+// Smdn.Fundamental.Exception, Version=3.0.0.0, Culture=neutral
+// System.Collections, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.ComponentModel, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.IO.Pipelines, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
+// System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.Memory, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
+// System.Net.Primitives, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.Net.Sockets, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.Security.Cryptography, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+// System.Text.RegularExpressions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+#nullable enable annotations
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Smdn.Net.MuninNode;
+using Smdn.Net.MuninPlugin;
+
+namespace Smdn.Net.MuninNode {
+ public class LocalNode : NodeBase {
+ public LocalNode(IPluginProvider pluginProvider, string hostName, int port, ILogger? logger = null) {}
+ public LocalNode(IPluginProvider pluginProvider, string hostName, int port, IServiceProvider? serviceProvider = null) {}
+ public LocalNode(IReadOnlyCollection<IPlugin> plugins, int port, IServiceProvider? serviceProvider = null) {}
+ public LocalNode(IReadOnlyCollection<IPlugin> plugins, string hostName, int port, IServiceProvider? serviceProvider = null) {}
+
+ public IPEndPoint LocalEndPoint { get; }
+
+ protected override Socket CreateServerSocket() {}
+ protected override bool IsClientAcceptable(IPEndPoint remoteEndPoint) {}
+ }
+
+ public abstract class NodeBase :
+ IAsyncDisposable,
+ IDisposable
+ {
+ private protected class PluginProvider : IPluginProvider {
+ public PluginProvider(IReadOnlyCollection<IPlugin> plugins) {}
+
+ public IReadOnlyCollection<IPlugin> Plugins { get; }
+ public INodeSessionCallback? SessionCallback { get; }
+ }
+
+ protected NodeBase(IPluginProvider pluginProvider, string hostName, ILogger? logger) {}
+ protected NodeBase(IReadOnlyCollection<IPlugin> plugins, string hostName, ILogger? logger) {}
+
+ public virtual Encoding Encoding { get; }
+ public string HostName { get; }
+ protected ILogger? Logger { get; }
+ public virtual Version NodeVersion { get; }
+ [Obsolete("This member will be deprecated in future version.")]
+ public IReadOnlyCollection<IPlugin> Plugins { get; }
+
+ public async ValueTask AcceptAsync(bool throwIfCancellationRequested, CancellationToken cancellationToken) {}
+ public async ValueTask AcceptSingleSessionAsync(CancellationToken cancellationToken = default) {}
+ protected abstract Socket CreateServerSocket();
+ protected virtual void Dispose(bool disposing) {}
+ public void Dispose() {}
+ public async ValueTask DisposeAsync() {}
+ protected virtual async ValueTask DisposeAsyncCore() {}
+ protected abstract bool IsClientAcceptable(IPEndPoint remoteEndPoint);
+ public void Start() {}
+ }
+}
+
+namespace Smdn.Net.MuninPlugin {
+ public interface INodeSessionCallback {
+ ValueTask ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken);
+ ValueTask ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken);
+ }
+
+ public interface IPlugin {
+ IPluginDataSource DataSource { get; }
+ PluginGraphAttributes GraphAttributes { get; }
+ string Name { get; }
+ INodeSessionCallback? SessionCallback { get; }
+ }
+
+ public interface IPluginDataSource {
+ IReadOnlyCollection<IPluginField> Fields { get; }
+ }
+
+ public interface IPluginField {
+ PluginFieldAttributes Attributes { get; }
+ string Name { get; }
+
+ ValueTask<string> GetFormattedValueStringAsync(CancellationToken cancellationToken);
+ }
+
+ public interface IPluginProvider {
+ IReadOnlyCollection<IPlugin> Plugins { get; }
+ INodeSessionCallback? SessionCallback { get; }
+ }
+
+ public enum PluginFieldGraphStyle : int {
+ Area = 1,
+ AreaStack = 3,
+ Default = 0,
+ Line = 100,
+ LineStack = 200,
+ LineStackWidth1 = 201,
+ LineStackWidth2 = 202,
+ LineStackWidth3 = 203,
+ LineWidth1 = 101,
+ LineWidth2 = 102,
+ LineWidth3 = 103,
+ Stack = 2,
+ }
+
+ public class Plugin :
+ INodeSessionCallback,
+ IPlugin,
+ IPluginDataSource
+ {
+ public Plugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<IPluginField> fields) {}
+
+ public IReadOnlyCollection<IPluginField> Fields { get; }
+ public PluginGraphAttributes GraphAttributes { get; }
+ public string Name { get; }
+ IPluginDataSource IPlugin.DataSource { get; }
+ INodeSessionCallback? IPlugin.SessionCallback { get; }
+ IReadOnlyCollection<IPluginField> IPluginDataSource.Fields { get; }
+
+ protected virtual ValueTask ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken) {}
+ protected virtual ValueTask ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken) {}
+ ValueTask INodeSessionCallback.ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken) {}
+ ValueTask INodeSessionCallback.ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken) {}
+ }
+
+ public static class PluginFactory {
+ public static IPluginField CreateField(string label, Func<double?> fetchValue) {}
+ public static IPluginField CreateField(string label, PluginFieldGraphStyle graphStyle, Func<double?> fetchValue) {}
+ public static IPluginField CreateField(string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, Func<double?> fetchValue) {}
+ public static IPluginField CreateField(string name, string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, Func<double?> fetchValue) {}
+ public static IPluginField CreateField(string name, string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName, Func<double?> fetchValue) {}
+ public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<IPluginField> fields) {}
+ public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<PluginFieldBase> fields) {}
+ public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, PluginFieldBase field) {}
+ public static IPlugin CreatePlugin(string name, string fieldLabel, Func<double?> fetchFieldValue, PluginGraphAttributes graphAttributes) {}
+ public static IPlugin CreatePlugin(string name, string fieldLabel, PluginFieldGraphStyle fieldGraphStyle, Func<double?> fetchFieldValue, PluginGraphAttributes graphAttributes) {}
+ }
+
+ public abstract class PluginFieldBase : IPluginField {
+ protected PluginFieldBase(string label, string? name, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default, PluginFieldNormalValueRange normalRangeForWarning = default, PluginFieldNormalValueRange normalRangeForCritical = default) {}
+ protected PluginFieldBase(string label, string? name, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName) {}
+
+ public PluginFieldGraphStyle GraphStyle { get; }
+ public string Label { get; }
+ public string Name { get; }
+ public string? NegativeFieldName { get; }
+ public PluginFieldNormalValueRange NormalRangeForCritical { get; }
+ public PluginFieldNormalValueRange NormalRangeForWarning { get; }
+ PluginFieldAttributes IPluginField.Attributes { get; }
+
+ protected abstract ValueTask<double?> FetchValueAsync(CancellationToken cancellationToken);
+ async ValueTask<string> IPluginField.GetFormattedValueStringAsync(CancellationToken cancellationToken) {}
+ }
+
+ public sealed class PluginGraphAttributes {
+ [Obsolete("This member will be deprecated in future version.")]
+ public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan updateRate, int? width = null, int? height = null) {}
+ public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan? updateRate = null, int? width = null, int? height = null) {}
+ public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan? updateRate, int? width, int? height, IEnumerable<string>? order) {}
+
+ public string Arguments { get; }
+ public string Category { get; }
+ public int? Height { get; }
+ public string? Order { get; }
+ public bool Scale { get; }
+ public string Title { get; }
+ public TimeSpan? UpdateRate { get; }
+ public string VerticalLabel { get; }
+ public int? Width { get; }
+ }
+
+ public readonly struct PluginFieldAttributes {
+ public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default) {}
+ public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default, PluginFieldNormalValueRange normalRangeForWarning = default, PluginFieldNormalValueRange normalRangeForCritical = default) {}
+ public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName) {}
+
+ public PluginFieldGraphStyle GraphStyle { get; }
+ public string Label { get; }
+ public string? NegativeFieldName { get; }
+ public PluginFieldNormalValueRange NormalRangeForCritical { get; }
+ public PluginFieldNormalValueRange NormalRangeForWarning { get; }
+ }
+
+ public readonly struct PluginFieldNormalValueRange {
+ public static readonly PluginFieldNormalValueRange None; // = "Smdn.Net.MuninPlugin.PluginFieldNormalValueRange"
+
+ public static PluginFieldNormalValueRange CreateMax(double max) {}
+ public static PluginFieldNormalValueRange CreateMin(double min) {}
+ public static PluginFieldNormalValueRange CreateRange(double min, double max) {}
+
+ public bool HasValue { get; }
+ public double? Max { get; }
+ public double? Min { get; }
+ }
+}
+// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.4.1.0.
+// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
diff --git a/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-netstandard2.1.apilist.cs b/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-netstandard2.1.apilist.cs
index 817c4b6..48ee340 100644
--- a/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-netstandard2.1.apilist.cs
+++ b/doc/api-list/Smdn.Net.MuninNode/Smdn.Net.MuninNode-netstandard2.1.apilist.cs
@@ -1,203 +1,208 @@
-// Smdn.Net.MuninNode.dll (Smdn.Net.MuninNode-1.2.0)
+// Smdn.Net.MuninNode.dll (Smdn.Net.MuninNode-1.3.0)
// Name: Smdn.Net.MuninNode
-// AssemblyVersion: 1.2.0.0
-// InformationalVersion: 1.2.0+b0e11cd6b408018ad93f29b49e58cab7e9ef6b1b
+// AssemblyVersion: 1.3.0.0
+// InformationalVersion: 1.3.0+191d215fe57392cb544e2ffea221644a1007cfc0
// TargetFramework: .NETStandard,Version=v2.1
// Configuration: Release
// Referenced assemblies:
// Microsoft.Extensions.DependencyInjection.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// Microsoft.Extensions.Logging.Abstractions, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// Smdn.Fundamental.Encoding.Buffer, Version=3.0.0.0, Culture=neutral
// Smdn.Fundamental.Exception, Version=3.0.0.0, Culture=neutral
// System.IO.Pipelines, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
// netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
#nullable enable annotations
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Smdn.Net.MuninNode;
using Smdn.Net.MuninPlugin;
namespace Smdn.Net.MuninNode {
public class LocalNode : NodeBase {
public LocalNode(IPluginProvider pluginProvider, string hostName, int port, ILogger? logger = null) {}
public LocalNode(IPluginProvider pluginProvider, string hostName, int port, IServiceProvider? serviceProvider = null) {}
public LocalNode(IReadOnlyCollection<IPlugin> plugins, int port, IServiceProvider? serviceProvider = null) {}
public LocalNode(IReadOnlyCollection<IPlugin> plugins, string hostName, int port, IServiceProvider? serviceProvider = null) {}
public IPEndPoint LocalEndPoint { get; }
protected override Socket CreateServerSocket() {}
protected override bool IsClientAcceptable(IPEndPoint remoteEndPoint) {}
}
public abstract class NodeBase :
IAsyncDisposable,
IDisposable
{
private protected class PluginProvider : IPluginProvider {
public PluginProvider(IReadOnlyCollection<IPlugin> plugins) {}
public IReadOnlyCollection<IPlugin> Plugins { get; }
public INodeSessionCallback? SessionCallback { get; }
}
protected NodeBase(IPluginProvider pluginProvider, string hostName, ILogger? logger) {}
protected NodeBase(IReadOnlyCollection<IPlugin> plugins, string hostName, ILogger? logger) {}
public virtual Encoding Encoding { get; }
public string HostName { get; }
protected ILogger? Logger { get; }
public virtual Version NodeVersion { get; }
[Obsolete("This member will be deprecated in future version.")]
public IReadOnlyCollection<IPlugin> Plugins { get; }
public async ValueTask AcceptAsync(bool throwIfCancellationRequested, CancellationToken cancellationToken) {}
public async ValueTask AcceptSingleSessionAsync(CancellationToken cancellationToken = default) {}
protected abstract Socket CreateServerSocket();
protected virtual void Dispose(bool disposing) {}
public void Dispose() {}
public async ValueTask DisposeAsync() {}
protected virtual ValueTask DisposeAsyncCore() {}
protected abstract bool IsClientAcceptable(IPEndPoint remoteEndPoint);
public void Start() {}
}
}
namespace Smdn.Net.MuninPlugin {
public interface INodeSessionCallback {
ValueTask ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken);
ValueTask ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken);
}
public interface IPlugin {
IPluginDataSource DataSource { get; }
PluginGraphAttributes GraphAttributes { get; }
string Name { get; }
INodeSessionCallback? SessionCallback { get; }
}
public interface IPluginDataSource {
IReadOnlyCollection<IPluginField> Fields { get; }
}
public interface IPluginField {
PluginFieldAttributes Attributes { get; }
string Name { get; }
ValueTask<string> GetFormattedValueStringAsync(CancellationToken cancellationToken);
}
public interface IPluginProvider {
IReadOnlyCollection<IPlugin> Plugins { get; }
INodeSessionCallback? SessionCallback { get; }
}
public enum PluginFieldGraphStyle : int {
Area = 1,
AreaStack = 3,
Default = 0,
Line = 100,
LineStack = 200,
LineStackWidth1 = 201,
LineStackWidth2 = 202,
LineStackWidth3 = 203,
LineWidth1 = 101,
LineWidth2 = 102,
LineWidth3 = 103,
Stack = 2,
}
public class Plugin :
INodeSessionCallback,
IPlugin,
IPluginDataSource
{
public Plugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<IPluginField> fields) {}
public IReadOnlyCollection<IPluginField> Fields { get; }
public PluginGraphAttributes GraphAttributes { get; }
public string Name { get; }
IPluginDataSource IPlugin.DataSource { get; }
INodeSessionCallback? IPlugin.SessionCallback { get; }
IReadOnlyCollection<IPluginField> IPluginDataSource.Fields { get; }
protected virtual ValueTask ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken) {}
protected virtual ValueTask ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken) {}
ValueTask INodeSessionCallback.ReportSessionClosedAsync(string sessionId, CancellationToken cancellationToken) {}
ValueTask INodeSessionCallback.ReportSessionStartedAsync(string sessionId, CancellationToken cancellationToken) {}
}
public static class PluginFactory {
public static IPluginField CreateField(string label, Func<double?> fetchValue) {}
public static IPluginField CreateField(string label, PluginFieldGraphStyle graphStyle, Func<double?> fetchValue) {}
public static IPluginField CreateField(string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, Func<double?> fetchValue) {}
public static IPluginField CreateField(string name, string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, Func<double?> fetchValue) {}
+ public static IPluginField CreateField(string name, string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName, Func<double?> fetchValue) {}
public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<IPluginField> fields) {}
public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, IReadOnlyCollection<PluginFieldBase> fields) {}
public static IPlugin CreatePlugin(string name, PluginGraphAttributes graphAttributes, PluginFieldBase field) {}
public static IPlugin CreatePlugin(string name, string fieldLabel, Func<double?> fetchFieldValue, PluginGraphAttributes graphAttributes) {}
public static IPlugin CreatePlugin(string name, string fieldLabel, PluginFieldGraphStyle fieldGraphStyle, Func<double?> fetchFieldValue, PluginGraphAttributes graphAttributes) {}
}
public abstract class PluginFieldBase : IPluginField {
protected PluginFieldBase(string label, string? name, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default, PluginFieldNormalValueRange normalRangeForWarning = default, PluginFieldNormalValueRange normalRangeForCritical = default) {}
+ protected PluginFieldBase(string label, string? name, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName) {}
public PluginFieldGraphStyle GraphStyle { get; }
public string Label { get; }
public string Name { get; }
+ public string? NegativeFieldName { get; }
public PluginFieldNormalValueRange NormalRangeForCritical { get; }
public PluginFieldNormalValueRange NormalRangeForWarning { get; }
PluginFieldAttributes IPluginField.Attributes { get; }
protected abstract ValueTask<double?> FetchValueAsync(CancellationToken cancellationToken);
async ValueTask<string> IPluginField.GetFormattedValueStringAsync(CancellationToken cancellationToken) {}
}
public sealed class PluginGraphAttributes {
[Obsolete("This member will be deprecated in future version.")]
public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan updateRate, int? width = null, int? height = null) {}
public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan? updateRate = null, int? width = null, int? height = null) {}
public PluginGraphAttributes(string title, string category, string verticalLabel, bool scale, string arguments, TimeSpan? updateRate, int? width, int? height, IEnumerable<string>? order) {}
public string Arguments { get; }
public string Category { get; }
public int? Height { get; }
public string? Order { get; }
public bool Scale { get; }
public string Title { get; }
public TimeSpan? UpdateRate { get; }
public string VerticalLabel { get; }
public int? Width { get; }
}
public readonly struct PluginFieldAttributes {
public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default) {}
public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default, PluginFieldNormalValueRange normalRangeForWarning = default, PluginFieldNormalValueRange normalRangeForCritical = default) {}
+ public PluginFieldAttributes(string label, PluginFieldGraphStyle graphStyle, PluginFieldNormalValueRange normalRangeForWarning, PluginFieldNormalValueRange normalRangeForCritical, string? negativeFieldName) {}
public PluginFieldGraphStyle GraphStyle { get; }
public string Label { get; }
+ public string? NegativeFieldName { get; }
public PluginFieldNormalValueRange NormalRangeForCritical { get; }
public PluginFieldNormalValueRange NormalRangeForWarning { get; }
}
public readonly struct PluginFieldNormalValueRange {
public static readonly PluginFieldNormalValueRange None; // = "Smdn.Net.MuninPlugin.PluginFieldNormalValueRange"
public static PluginFieldNormalValueRange CreateMax(double max) {}
public static PluginFieldNormalValueRange CreateMin(double min) {}
public static PluginFieldNormalValueRange CreateRange(double min, double max) {}
public bool HasValue { get; }
public double? Max { get; }
public double? Min { get; }
}
}
-// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.2.2.0.
-// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.2.0.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
+// API list generated by Smdn.Reflection.ReverseGenerating.ListApi.MSBuild.Tasks v1.4.1.0.
+// Smdn.Reflection.ReverseGenerating.ListApi.Core v1.3.1.0 (https://github.com/smdn/Smdn.Reflection.ReverseGenerating)
Full changes
Full changes in this release:
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.csproj b/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.csproj
index 9295e42..6384660 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.csproj
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.csproj
@@ -4,24 +4,21 @@ SPDX-License-Identifier: MIT
-->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFrameworks>netstandard2.1;net6.0</TargetFrameworks>
- <VersionPrefix>1.2.0</VersionPrefix>
+ <TargetFrameworks>netstandard2.1;net6.0;net8.0</TargetFrameworks>
+ <VersionPrefix>1.3.0</VersionPrefix>
<VersionSuffix></VersionSuffix>
- <PackageValidationBaselineVersion>1.0.0</PackageValidationBaselineVersion>
+ <PackageValidationBaselineVersion>1.2.0</PackageValidationBaselineVersion>
<RootNamespace/> <!-- empty the root namespace so that the namespace is determined only by the directory name, for code style rule IDE0030 -->
<Nullable>enable</Nullable>
<DefineConstants
Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '7.0.0'))"
>$(DefineConstants);LANG_VERSION_11_OR_GREATER</DefineConstants> <!-- required to use the UTF-8 string literals in C# 11 -->
- </PropertyGroup>
-
- <PropertyGroup Condition=" '$(Configuration)' == 'Release' " Label="Required properties to generate API list">
- <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
+ <NoWarn>CS1591;$(NoWarn)</NoWarn> <!-- CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member' -->
</PropertyGroup>
<PropertyGroup Label="assembly attributes">
<Description>
-<![CDATA[A .NET implementation of [Munin-Node](http://guide.munin-monitoring.org/en/latest/node/index.html) and [Munin-Plugin](http://guide.munin-monitoring.org/en/latest/plugin/index.html).
+<![CDATA[A .NET implementation of [Munin-Node](https://guide.munin-monitoring.org/en/latest/node/index.html) and [Munin-Plugin](https://guide.munin-monitoring.org/en/latest/plugin/index.html).
This library provides Munin-Node implementation for .NET, which enables to you to create custom Munin-Node using the .NET languages and libraries.
@@ -33,6 +30,7 @@ This library also provides abstraction APIs for implementing Munin-Plugin. By us
<PropertyGroup Label="package properties">
<PackageTags>Munin,Munin-Node,Munin-Plugin</PackageTags>
+ <GenerateNupkgReadmeFileDependsOnTargets>$(GenerateNupkgReadmeFileDependsOnTargets);GenerateReadmeFileContent</GenerateNupkgReadmeFileDependsOnTargets>
</PropertyGroup>
<ItemGroup>
@@ -42,4 +40,15 @@ This library also provides abstraction APIs for implementing Munin-Plugin. By us
<PackageReference Include="Smdn.Fundamental.Encoding.Buffer" Version="[3.0.0,4.0.0)" Condition="$(TargetFramework.StartsWith('net4')) or $(TargetFramework.StartsWith('netstandard'))" />
<PackageReference Include="Smdn.Fundamental.Exception" Version="[3.0.0,4.0.0)" />
</ItemGroup>
+
+ <Target Name="GenerateReadmeFileContent">
+ <PropertyGroup>
+ <PackageReadmeFileContent><![CDATA[# $(PackageId) $(PackageVersion)
+$(Description)
+
+## Contributing
+This project welcomes contributions, feedbacks and suggestions. You can contribute to this project by submitting [Issues]($(RepositoryUrl)/issues/new/choose) or [Pull Requests]($(RepositoryUrl)/pulls/) on the [GitHub repository]($(RepositoryUrl)).
+]]></PackageReadmeFileContent>
+ </PropertyGroup>
+ </Target>
</Project>
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/LocalNode.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/LocalNode.cs
index b42f9dc..9810630 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/LocalNode.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/LocalNode.cs
@@ -19,7 +21,7 @@ public class LocalNode : NodeBase {
public IPEndPoint LocalEndPoint { get; }
- /// <inheritdoc cref="LocalNode(IReadOnlyCollection{IPlugin}, int, string, IServiceProvider)"/>
+ /// <inheritdoc cref="LocalNode(IReadOnlyCollection{IPlugin}, string, int, IServiceProvider)"/>
public LocalNode(
IReadOnlyCollection<IPlugin> plugins,
int port,
@@ -177,7 +179,9 @@ public class LocalNode : NodeBase {
return server;
}
catch {
+#pragma warning disable CA1508
server?.Dispose();
+#pragma warning restore CA1508
throw;
}
}
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/NodeBase.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/NodeBase.cs
index d3a7ebd..df4b7a1 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/NodeBase.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninNode/NodeBase.cs
@@ -27,16 +28,16 @@ namespace Smdn.Net.MuninNode;
/// <summary>
/// Provides an extensible base class with basic Munin-Node functionality.
/// </summary>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/node/index.html">The Munin node</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/node/index.html">The Munin node</seealso>
public abstract class NodeBase : IDisposable, IAsyncDisposable {
- private static readonly Version defaultNodeVersion = new(1, 0, 0, 0);
+ private static readonly Version DefaultNodeVersion = new(1, 0, 0, 0);
[Obsolete("This member will be deprecated in future version.")]
public IReadOnlyCollection<IPlugin> Plugins => pluginProvider.Plugins;
public string HostName { get; }
- public virtual Version NodeVersion => defaultNodeVersion;
+ public virtual Version NodeVersion => DefaultNodeVersion;
public virtual Encoding Encoding => Encoding.Default;
private readonly IPluginProvider pluginProvider;
@@ -355,12 +356,12 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
CancellationToken cancellationToken
)
{
- const int minimumBufferSize = 256;
+ const int MinimumBufferSize = 256;
for (; ; ) {
cancellationToken.ThrowIfCancellationRequested();
- var memory = writer.GetMemory(minimumBufferSize);
+ var memory = writer.GetMemory(MinimumBufferSize);
try {
if (!socket.Connected)
@@ -544,7 +545,7 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
return false;
}
- private static readonly byte commandQuitShort = (byte)'.';
+ private static readonly byte CommandQuitShort = (byte)'.';
#if LANG_VERSION_11_OR_GREATER
private ValueTask RespondToCommandAsync(
@@ -567,7 +568,7 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
}
else if (
ExpectCommand(commandLine, "quit"u8, out _) ||
- (commandLine.Length == 1 && commandLine.FirstSpan[0] == commandQuitShort)
+ (commandLine.Length == 1 && commandLine.FirstSpan[0] == CommandQuitShort)
) {
client.Close();
#if SYSTEM_THREADING_TASKS_VALUETASK_COMPLETEDTASK
@@ -649,9 +650,14 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
#endif
#pragma warning disable IDE0230
- private static readonly ReadOnlyMemory<byte> endOfLine = new[] { (byte)'\n' };
+ private static readonly ReadOnlyMemory<byte> EndOfLine = new[] { (byte)'\n' };
#pragma warning restore IDE0230
+ private static readonly string[] ResponseLinesUnknownService = [
+ "# Unknown service",
+ ".",
+ ];
+
private static ValueTask SendResponseAsync(
Socket client,
Encoding encoding,
@@ -687,7 +693,7 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
).ConfigureAwait(false);
await client.SendAsync(
- buffer: endOfLine,
+ buffer: EndOfLine,
socketFlags: SocketFlags.None,
cancellationToken: cancellationToken
).ConfigureAwait(false);
@@ -731,8 +737,8 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
CancellationToken cancellationToken
)
{
- // TODO: multigraph (http://guide.munin-monitoring.org/en/latest/plugin/protocol-multigraph.html)
- // TODO: dirtyconfig (http://guide.munin-monitoring.org/en/latest/plugin/protocol-dirtyconfig.html)
+ // TODO: multigraph (https://guide.munin-monitoring.org/en/latest/plugin/protocol-multigraph.html)
+ // TODO: dirtyconfig (https://guide.munin-monitoring.org/en/latest/plugin/protocol-dirtyconfig.html)
// XXX: ignores capability arguments
return SendResponseAsync(
client: client,
@@ -773,10 +779,7 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
await SendResponseAsync(
client,
Encoding,
- new[] {
- "# Unknown service",
- ".",
- },
+ ResponseLinesUnknownService,
cancellationToken
).ConfigureAwait(false);
@@ -834,10 +837,7 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
return SendResponseAsync(
client,
Encoding,
- new[] {
- "# Unknown service",
- ".",
- },
+ ResponseLinesUnknownService,
cancellationToken
);
}
@@ -861,8 +861,15 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
if (!string.IsNullOrEmpty(graphAttrs.Order))
responseLines.Add($"graph_order {graphAttrs.Order}");
- foreach (var field in plugin.DataSource.Fields) {
+ // The fields referenced by {fieldname}.negative must be defined ahread of others,
+ // and thus lists the negative field settings first.
+ // Otherwise, the following error occurs when generating the graph.
+ // "[RRD ERROR] Unable to graph /var/cache/munin/www/XXX.png : undefined v name XXXXXXXXXXXXXX"
+ var orderedFields = plugin.DataSource.Fields.OrderBy(f => IsNegativeField(f, plugin.DataSource.Fields) ? 0 : 1);
+
+ foreach (var field in orderedFields) {
var fieldAttrs = field.Attributes;
+ bool? graph = null;
responseLines.Add($"{field.Name}.label {fieldAttrs.Label}");
@@ -877,6 +884,22 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
if (fieldAttrs.NormalRangeForCritical.HasValue)
AddFieldValueRange("critical", fieldAttrs.NormalRangeForCritical);
+ if (!string.IsNullOrEmpty(fieldAttrs.NegativeFieldName)) {
+ var negativeField = plugin.DataSource.Fields.FirstOrDefault(
+ f => string.Equals(fieldAttrs.NegativeFieldName, f.Name, StringComparison.Ordinal)
+ );
+
+ if (negativeField is not null)
+ responseLines.Add($"{field.Name}.negative {negativeField.Name}");
+ }
+
+ // this field is defined as the negative field of other field, so should not be graphed
+ if (IsNegativeField(field, plugin.DataSource.Fields))
+ graph = false;
+
+ if (graph is bool drawGraph)
+ responseLines.Add($"{field.Name}.graph {(drawGraph ? "yes" : "no")}");
+
void AddFieldValueRange(string attr, PluginFieldNormalValueRange range)
{
if (range.Min.HasValue && range.Max.HasValue)
@@ -896,5 +919,10 @@ public abstract class NodeBase : IDisposable, IAsyncDisposable {
responseLines: responseLines,
cancellationToken: cancellationToken
);
+
+ static bool IsNegativeField(IPluginField field, IReadOnlyCollection<IPluginField> fields)
+ => fields.Any(
+ f => string.Equals(field.Name, f.Attributes.NegativeFieldName, StringComparison.Ordinal)
+ );
}
}
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPlugin.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPlugin.cs
index 6130160..cf725ac 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPlugin.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPlugin.cs
@@ -6,7 +6,7 @@ namespace Smdn.Net.MuninPlugin;
/// <summary>
/// Provides an interface that abstracts the plugin.
/// </summary>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html">Plugin reference</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html">Plugin reference</seealso>
public interface IPlugin {
/// <summary>Gets a plugin name.</summary>
/// <remarks>This value is used as the plugin name returned by the 'list' argument, or the plugin name specified by the 'fetch' argument.</remarks>
@@ -20,7 +20,7 @@ public interface IPlugin {
/// <seealso cref="IPluginDataSource"/>
IPluginDataSource DataSource { get; }
- /// <summary>Gets a <see cref="INodeSessionCallback"/>, which defines the callbacks when a request session from the <c>munin-update</c> starts or ends, such as fetching data or getting configurations.
+ /// <summary>Gets a <see cref="INodeSessionCallback"/>, which defines the callbacks when a request session from the <c>munin-update</c> starts or ends, such as fetching data or getting configurations.</summary>
/// <remarks>Callbacks of this interface can be used to initiate bulk collection of field values.</remarks>
/// <seealso cref="INodeSessionCallback"/>
/// <seealso cref="MuninNode.NodeBase"/>
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginDataSource.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginDataSource.cs
index 715881b..9dc380d 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginDataSource.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginDataSource.cs
@@ -9,7 +9,7 @@ namespace Smdn.Net.MuninPlugin;
/// Provides an interface that abstracts the data source for the plugin.
/// </summary>
public interface IPluginDataSource {
- /// <summary>Gets a collection of plugin fields (<see cref="IPluginField"/>) provided by this data source.
+ /// <summary>Gets a collection of plugin fields (<see cref="IPluginField"/>) provided by this data source.</summary>
/// <seealso cref="IPluginField"/>
IReadOnlyCollection<IPluginField> Fields { get; }
}
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginField.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginField.cs
index 29f1033..469ce16 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginField.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginField.cs
@@ -10,10 +10,10 @@ namespace Smdn.Net.MuninPlugin;
/// Provides an interface that abstracts the fields of the plugin.
/// This interface represents the 'field name attributes'.
/// </summary>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes">Plugin reference - Field name attributes</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes">Plugin reference - Field name attributes</seealso>
public interface IPluginField {
/// <summary>Gets a value for the <c>fieldname</c>. This value represents the <c>fieldname</c> itself for the attribute <c>{fieldname}.xxx</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes">Plugin reference - Field name attributes</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes">Plugin reference - Field name attributes</seealso>
string Name { get; }
/// <summary>Gets a collection of attributes that describes the <c>fieldname</c>.</summary>
@@ -24,7 +24,7 @@ public interface IPluginField {
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken" /> to monitor for cancellation requests.</param>
/// <returns>
- /// A <see cref="ValueTask{string?}"/> representing the current value of the field.
+ /// A <see cref="ValueTask{String}"/> representing the current value of the field.
/// Returns a field's numeric value in its string representation.
/// By returning <c>"U"</c> instead of numeric value, the field can also be reported as having a value of 'UNKNOWN'.
/// </returns>
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginProvider.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginProvider.cs
index 875400c..92cd30b 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginProvider.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/IPluginProvider.cs
@@ -18,7 +18,7 @@ public interface IPluginProvider {
/// <seealso cref="MuninNode.NodeBase"/>
IReadOnlyCollection<IPlugin> Plugins { get; }
- /// <summary>Gets a <see cref="INodeSessionCallback"/>, which defines the callbacks when a request session from the <c>munin-update</c> starts or ends, such as fetching data or getting configurations.
+ /// <summary>Gets a <see cref="INodeSessionCallback"/>, which defines the callbacks when a request session from the <c>munin-update</c> starts or ends, such as fetching data or getting configurations.</summary>
/// <seealso cref="INodeSessionCallback"/>
/// <seealso cref="MuninNode.NodeBase"/>
INodeSessionCallback? SessionCallback { get; }
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreateField.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreateField.cs
index 50ec013..3656e58 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreateField.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreateField.cs
@@ -19,6 +19,7 @@ partial class PluginFactory {
graphStyle: PluginFieldGraphStyle.Default,
normalRangeForWarning: PluginFieldNormalValueRange.None,
normalRangeForCritical: PluginFieldNormalValueRange.None,
+ negativeFieldName: null,
fetchValue: fetchValue
);
@@ -33,6 +34,7 @@ partial class PluginFactory {
graphStyle: graphStyle,
normalRangeForWarning: PluginFieldNormalValueRange.None,
normalRangeForCritical: PluginFieldNormalValueRange.None,
+ negativeFieldName: null,
fetchValue: fetchValue
);
@@ -49,6 +51,7 @@ partial class PluginFactory {
graphStyle: graphStyle,
normalRangeForWarning: normalRangeForWarning,
normalRangeForCritical: normalRangeForCritical,
+ negativeFieldName: null,
fetchValue: fetchValue
);
@@ -66,6 +69,26 @@ partial class PluginFactory {
graphStyle: graphStyle,
normalRangeForWarning: normalRangeForWarning,
normalRangeForCritical: normalRangeForCritical,
+ negativeFieldName: null,
+ fetchValue: fetchValue
+ );
+
+ public static IPluginField CreateField(
+ string name,
+ string label,
+ PluginFieldGraphStyle graphStyle,
+ PluginFieldNormalValueRange normalRangeForWarning,
+ PluginFieldNormalValueRange normalRangeForCritical,
+ string? negativeFieldName,
+ Func<double?> fetchValue
+ )
+ => new ValueFromFuncPluginField(
+ label: label,
+ name: name,
+ graphStyle: graphStyle,
+ normalRangeForWarning: normalRangeForWarning,
+ normalRangeForCritical: normalRangeForCritical,
+ negativeFieldName: negativeFieldName,
fetchValue: fetchValue
);
@@ -78,6 +101,7 @@ partial class PluginFactory {
PluginFieldGraphStyle graphStyle,
PluginFieldNormalValueRange normalRangeForWarning,
PluginFieldNormalValueRange normalRangeForCritical,
+ string? negativeFieldName,
Func<double?> fetchValue
)
: base(
@@ -85,7 +109,8 @@ partial class PluginFactory {
name: name,
graphStyle: graphStyle,
normalRangeForWarning: normalRangeForWarning,
- normalRangeForCritical: normalRangeForCritical
+ normalRangeForCritical: normalRangeForCritical,
+ negativeFieldName: negativeFieldName
)
{
this.fetchValue = fetchValue ?? throw new ArgumentNullException(nameof(fetchValue));
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreatePlugin.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreatePlugin.cs
index 741ae54..e91d533 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreatePlugin.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFactory.CreatePlugin.cs
@@ -41,6 +41,7 @@ partial class PluginFactory {
graphStyle: fieldGraphStyle,
normalRangeForWarning: PluginFieldNormalValueRange.None,
normalRangeForCritical: PluginFieldNormalValueRange.None,
+ negativeFieldName: null,
fetchValue: fetchFieldValue
)
);
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldAttributes.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldAttributes.cs
index 22a37cf..096a1a2 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldAttributes.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldAttributes.cs
@@ -9,29 +9,38 @@ namespace Smdn.Net.MuninPlugin;
/// Defines field attributes that should be returned when the plugin is called with the 'config' argument.
/// This type represents the collection of 'field name attributes'.
/// </summary>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes">Plugin reference - Field name attributes</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes">Plugin reference - Field name attributes</seealso>
public readonly struct PluginFieldAttributes {
/// <summary>Gets a value for the <c>{fieldname}.label</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-label">Plugin reference - Field name attributes - {fieldname}.label</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-label">Plugin reference - Field name attributes - {fieldname}.label</seealso>
public string Label { get; }
/// <summary>Gets a value for the <c>{fieldname}.draw</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-draw">Plugin reference - Field name attributes - {fieldname}.draw</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-draw">Plugin reference - Field name attributes - {fieldname}.draw</seealso>
/// <seealso cref="PluginFieldGraphStyle"/>
public PluginFieldGraphStyle GraphStyle { get; }
/// <summary>Gets a value for the <c>{fieldname}.warning</c>.</summary>
/// <remarks>This property defines the upper limit, lower limit, or range of normal value, that is not treated as warning.</remarks>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-warning">Plugin reference - Field name attributes - {fieldname}.warning</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-warning">Plugin reference - Field name attributes - {fieldname}.warning</seealso>
/// <seealso cref="PluginFieldNormalValueRange"/>
public PluginFieldNormalValueRange NormalRangeForWarning { get; }
/// <summary>Gets a value for the <c>{fieldname}.critical</c>.</summary>
/// <remarks>This property defines the upper limit, lower limit, or range of normal value, that is not treated as critical.</remarks>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-critical">Plugin reference - Field name attributes - {fieldname}.critical</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-critical">Plugin reference - Field name attributes - {fieldname}.critical</seealso>
/// <seealso cref="PluginFieldNormalValueRange"/>
public PluginFieldNormalValueRange NormalRangeForCritical { get; }
+ /// <summary>Gets a value for the <c>{fieldname}.negative</c>.</summary>
+ /// <remarks>
+ /// This property specifies that the specified field is drawn as the negative side of this field.
+ /// If a valid field name is specified for this property, it also implicitly sets the attribute <c>{fieldname}.graph no</c>.
+ /// </remarks>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-negative">Plugin reference - Field name attributes - {fieldname}.critical</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/develop/plugins/plugin-bcp.html#plugin-bcp-direction">Best Current Practices for good plugin graphs - Direction</seealso>
+ public string? NegativeFieldName { get; }
+
public PluginFieldAttributes(
string label,
PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default
@@ -40,7 +49,8 @@ public readonly struct PluginFieldAttributes {
label: label,
graphStyle: graphStyle,
normalRangeForWarning: default,
- normalRangeForCritical: default
+ normalRangeForCritical: default,
+ negativeFieldName: null
)
{
}
@@ -50,6 +60,23 @@ public readonly struct PluginFieldAttributes {
PluginFieldGraphStyle graphStyle = PluginFieldGraphStyle.Default,
PluginFieldNormalValueRange normalRangeForWarning = default,
PluginFieldNormalValueRange normalRangeForCritical = default
+ )
+ : this(
+ label: label,
+ graphStyle: graphStyle,
+ normalRangeForWarning: normalRangeForWarning,
+ normalRangeForCritical: normalRangeForCritical,
+ negativeFieldName: null
+ )
+ {
+ }
+
+ public PluginFieldAttributes(
+ string label,
+ PluginFieldGraphStyle graphStyle,
+ PluginFieldNormalValueRange normalRangeForWarning,
+ PluginFieldNormalValueRange normalRangeForCritical,
+ string? negativeFieldName
)
{
if (label is null)
@@ -61,5 +88,6 @@ public readonly struct PluginFieldAttributes {
GraphStyle = graphStyle;
NormalRangeForWarning = normalRangeForWarning;
NormalRangeForCritical = normalRangeForCritical;
+ NegativeFieldName = negativeFieldName;
}
}
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldBase.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldBase.cs
index 808d264..84ab32b 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldBase.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldBase.cs
@@ -14,13 +14,15 @@ public abstract class PluginFieldBase : IPluginField {
public PluginFieldGraphStyle GraphStyle { get; }
public PluginFieldNormalValueRange NormalRangeForWarning { get; }
public PluginFieldNormalValueRange NormalRangeForCritical { get; }
+ public string? NegativeFieldName { get; }
#pragma warning disable CA1033
PluginFieldAttributes IPluginField.Attributes => new(
label: Label,
graphStyle: GraphStyle,
normalRangeForWarning: NormalRangeForWarning,
- normalRangeForCritical: NormalRangeForCritical
+ normalRangeForCritical: NormalRangeForCritical,
+ negativeFieldName: NegativeFieldName
);
#pragma warning restore CA1033
@@ -30,27 +32,47 @@ public abstract class PluginFieldBase : IPluginField {
PluginFieldGraphStyle graphStyle = default,
PluginFieldNormalValueRange normalRangeForWarning = default,
PluginFieldNormalValueRange normalRangeForCritical = default
+ )
+ : this(
+ label: label,
+ name: name,
+ graphStyle: graphStyle,
+ normalRangeForWarning: normalRangeForWarning,
+ normalRangeForCritical: normalRangeForCritical,
+ negativeFieldName: null
+ )
+ {
+ }
+
+ protected PluginFieldBase(
+ string label,
+ string? name,
+ PluginFieldGraphStyle graphStyle,
+ PluginFieldNormalValueRange normalRangeForWarning,
+ PluginFieldNormalValueRange normalRangeForCritical,
+ string? negativeFieldName
)
{
if (label is null)
throw new ArgumentNullException(nameof(label));
if (label.Length == 0)
throw ExceptionUtils.CreateArgumentMustBeNonEmptyString(nameof(label));
- if (!regexValidFieldLabel.IsMatch(label))
- throw new ArgumentException($"'{label}' is invalid for field name. The value of {nameof(label)} must match the following regular expression: '{regexValidFieldLabel}'", nameof(label));
+ if (!RegexValidFieldLabel.IsMatch(label))
+ throw new ArgumentException($"'{label}' is invalid for field name. The value of {nameof(label)} must match the following regular expression: '{RegexValidFieldLabel}'", nameof(label));
name ??= GetDefaultNameFromLabel(label);
if (name.Length == 0)
throw ExceptionUtils.CreateArgumentMustBeNonEmptyString(nameof(name));
- if (!regexValidFieldName.IsMatch(name))
- throw new ArgumentException($"'{name}' is invalid for field name. The value of {nameof(name)} must match the following regular expression: '{regexValidFieldName}'", nameof(name));
+ if (!RegexValidFieldName.IsMatch(name))
+ throw new ArgumentException($"'{name}' is invalid for field name. The value of {nameof(name)} must match the following regular expression: '{RegexValidFieldName}'", nameof(name));
Label = label;
Name = name;
GraphStyle = graphStyle;
NormalRangeForWarning = normalRangeForWarning;
NormalRangeForCritical = normalRangeForCritical;
+ NegativeFieldName = negativeFieldName;
}
/// <summary>Gets a value for plugin field.</summary>
@@ -60,39 +82,41 @@ public abstract class PluginFieldBase : IPluginField {
#pragma warning disable CA1033
async ValueTask<string> IPluginField.GetFormattedValueStringAsync(CancellationToken cancellationToken)
{
- const string unknownValueString = "U";
+ const string UnknownValueString = "U";
var value = await FetchValueAsync(cancellationToken).ConfigureAwait(false);
- return value?.ToString(provider: null) ?? unknownValueString; // TODO: format specifier
+ return value?.ToString(provider: null) ?? UnknownValueString; // TODO: format specifier
}
#pragma warning restore CA1033
- // http://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes
+ // https://guide.munin-monitoring.org/en/latest/reference/plugin.html#field-name-attributes
// Field name attributes
// Attribute: {fieldname}.label
// Value: anything except # and \
- private static readonly Regex regexValidFieldLabel = new(
+ private static readonly Regex RegexValidFieldLabel = new(
pattern: $@"^[^{Regex.Escape("#\\")}]+$",
options: RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant
);
- // http://guide.munin-monitoring.org/en/latest/reference/plugin.html#notes-on-field-names
+ // https://guide.munin-monitoring.org/en/latest/reference/plugin.html#notes-on-field-names
// Notes on field names
// The characters must be [a-zA-Z0-9_], while the first character must be [a-zA-Z_].
- private static readonly Regex regexValidFieldName = new(
+#pragma warning disable SYSLIB1045
+ private static readonly Regex RegexValidFieldName = new(
pattern: $@"^[a-zA-Z_][a-zA-Z0-9_]*$",
options: RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant
);
- private static readonly Regex regexInvalidFieldNamePrefix = new(
+ private static readonly Regex RegexInvalidFieldNamePrefix = new(
pattern: $@"^[0-9_]+",
options: RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant
);
- private static readonly Regex regexInvalidFieldNameChars = new(
+ private static readonly Regex RegexInvalidFieldNameChars = new(
pattern: $@"[^a-zA-Z0-9_]",
options: RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.CultureInvariant
);
+#pragma warning restore SYSLIB1045
private static string GetDefaultNameFromLabel(string label)
{
@@ -101,8 +125,8 @@ public abstract class PluginFieldBase : IPluginField {
if (label.Length == 0)
throw ExceptionUtils.CreateArgumentMustBeNonEmptyString(nameof(label));
- return regexInvalidFieldNameChars.Replace(
- regexInvalidFieldNamePrefix.Replace(label, string.Empty),
+ return RegexInvalidFieldNameChars.Replace(
+ RegexInvalidFieldNamePrefix.Replace(label, string.Empty),
string.Empty
);
}
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldGraphStyle.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldGraphStyle.cs
index f561581..642796b 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldGraphStyle.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldGraphStyle.cs
@@ -6,7 +6,7 @@ namespace Smdn.Net.MuninPlugin;
/// <summary>
/// Represents the style of how the field should be drawn on the graph.
/// </summary>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-draw">Plugin reference - Field name attributes - {fieldname}.draw</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-draw">Plugin reference - Field name attributes - {fieldname}.draw</seealso>
public enum PluginFieldGraphStyle {
Default = default,
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldNormalValueRange.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldNormalValueRange.cs
index bbc3c51..4b842c8 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldNormalValueRange.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginFieldNormalValueRange.cs
@@ -12,8 +12,8 @@ namespace Smdn.Net.MuninPlugin;
/// With <c>{fieldname}.warning</c> or <c>{fieldname}.ciritical</c>, you can define the upper and lower limits of values that are considered to be warning or critical.
/// This type defines the upper limit, lower limit, or range that is considered to be normal value.
/// </remarks>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-critical">Plugin reference - Field name attributes - {fieldname}.critical</seealso>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-warning">Plugin reference - Field name attributes - {fieldname}.warning</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-critical">Plugin reference - Field name attributes - {fieldname}.critical</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#fieldname-warning">Plugin reference - Field name attributes - {fieldname}.warning</seealso>
public readonly struct PluginFieldNormalValueRange {
private static double ValidateValue(double val, string paramName)
{
diff --git a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginGraphAttributes.cs b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginGraphAttributes.cs
index 0331728..3e76d32 100644
--- a/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginGraphAttributes.cs
+++ b/src/Smdn.Net.MuninNode/Smdn.Net.MuninPlugin/PluginGraphAttributes.cs
@@ -11,44 +11,44 @@ namespace Smdn.Net.MuninPlugin;
/// Defines graph attributes that should be returned when the plugin is called with the 'config' argument.
/// This type represents the collection of 'field name attributes'.
/// </summary>
-/// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#global-attributes">Plugin reference - Global attributes</seealso>
+/// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#global-attributes">Plugin reference - Global attributes</seealso>
public sealed class PluginGraphAttributes {
/// <summary>Gets a value for the <c>graph_title</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-title">Plugin reference - Global attributes - graph_title</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-title">Plugin reference - Global attributes - graph_title</seealso>
public string Title { get; }
/// <summary>Gets a value for the <c>graph_category</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-category">Plugin reference - Global attributes - graph_category</seealso>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/graph-category.html">Plugin graph categories</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-category">Plugin reference - Global attributes - graph_category</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/graph-category.html">Plugin graph categories</seealso>
public string Category { get; }
/// <summary>Gets a value for the <c>graph_args</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-args">Plugin reference - Global attributes - graph_args</seealso>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/example/graph/graph_args.html">Recommended graph_args</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-args">Plugin reference - Global attributes - graph_args</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/example/graph/graph_args.html">Recommended graph_args</seealso>
public string Arguments { get; }
/// <summary>Gets a value indicating whether the field value should be scaled. Represents the value for the <c>graph_scale</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-scale">Plugin reference - Global attributes - graph_scale</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-scale">Plugin reference - Global attributes - graph_scale</seealso>
public bool Scale { get; }
/// <summary>Gets a value for the <c>graph_vlabel</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-vlabel">Plugin reference - Global attributes - graph_vlabel</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-vlabel">Plugin reference - Global attributes - graph_vlabel</seealso>
public string VerticalLabel { get; }
/// <summary>Gets a value for the <c>update_rate</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#update-rate">Plugin reference - Global attributes - update_rate</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#update-rate">Plugin reference - Global attributes - update_rate</seealso>
public TimeSpan? UpdateRate { get; }
/// <summary>Gets a value for the <c>graph_width</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-width">Plugin reference - Global attributes - graph_width</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-width">Plugin reference - Global attributes - graph_width</seealso>
public int? Width { get; }
/// <summary>Gets a value for the <c>graph_height</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-height">Plugin reference - Global attributes - graph_height</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-height">Plugin reference - Global attributes - graph_height</seealso>
public int? Height { get; }
/// <summary>Gets a value for the <c>graph_order</c>.</summary>
- /// <seealso href="http://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-order">Plugin reference - Global attributes - graph_order</seealso>
+ /// <seealso href="https://guide.munin-monitoring.org/en/latest/reference/plugin.html#graph-order">Plugin reference - Global attributes - graph_order</seealso>
public string? Order { get; }
public PluginGraphAttributes(
Notes
Full Changelog: releases/Smdn.Net.MuninNode-1.2.0...releases/Smdn.Net.MuninNode-1.3.0