Skip to content

Commit 8197007

Browse files
committed
add getting-started examples that will be shown in README of NuGet packages
1 parent 477983f commit 8197007

File tree

8 files changed

+279
-0
lines changed

8 files changed

+279
-0
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Hosting;
7+
using Microsoft.Extensions.Logging;
8+
9+
using Smdn.Net.MuninNode;
10+
using Smdn.Net.MuninNode.DependencyInjection;
11+
using Smdn.Net.MuninNode.Hosting;
12+
using Smdn.Net.MuninPlugin;
13+
14+
// A interface/class that gets the measurements from some kind of sensor.
15+
interface ITemperatureSensor {
16+
double GetMeasurementValue();
17+
}
18+
19+
class TemperatureSensor : ITemperatureSensor {
20+
public double GetMeasurementValue() => Random.Shared.Next(20, 30); // 20~30 degree Celsius
21+
}
22+
23+
class Program {
24+
static async Task Main(string[] args)
25+
{
26+
var builder = Host.CreateApplicationBuilder(args);
27+
28+
builder
29+
.Services
30+
// Add sensor devices.
31+
.AddKeyedSingleton<ITemperatureSensor>("sensor1", new TemperatureSensor())
32+
.AddKeyedSingleton<ITemperatureSensor>("sensor2", new TemperatureSensor())
33+
// Add a Munin-Node background service.
34+
.AddHostedMuninNodeService(
35+
// Configure the Munin-Node options.
36+
options => {
37+
options.HostName = "munin-node.localhost";
38+
options.UseAnyAddress(port: 14949);
39+
options.AllowFromLoopbackOnly();
40+
},
41+
// Build the Munin-Node.
42+
nodeBuilder => {
43+
// Create and add a Munin-Plugin to report measurements via the Munin-Node.
44+
nodeBuilder.AddPlugin(
45+
serviceProvider => PluginFactory.CreatePlugin(
46+
name: "temperature",
47+
// Configure the 'fields' that identify the data source.
48+
// See: https://guide.munin-monitoring.org/en/latest/reference/plugin.html#data-source-attributes
49+
fields: [
50+
PluginFactory.CreateField(
51+
label: "sensor1",
52+
fetchValue: () => serviceProvider
53+
.GetRequiredKeyedService<ITemperatureSensor>("sensor1")
54+
.GetMeasurementValue()
55+
),
56+
PluginFactory.CreateField(
57+
label: "sensor2",
58+
fetchValue: () => serviceProvider
59+
.GetRequiredKeyedService<ITemperatureSensor>("sensor2")
60+
.GetMeasurementValue()
61+
),
62+
],
63+
// Configures the 'attributes' of the graph when drawn data as a graph.
64+
// See: https://guide.munin-monitoring.org/en/latest/reference/plugin.html#global-attributes
65+
graphAttributes: new PluginGraphAttributes(
66+
category: "sensors",
67+
title: "Temperature",
68+
verticalLabel: "Degree Celsius",
69+
scale: false,
70+
arguments: "--base 1000 --lower-limit 0 --upper-limit 50"
71+
)
72+
)
73+
);
74+
// One or more plug-ins can be added.
75+
// nodeBuilder.AddPlugin(...);
76+
// nodeBuilder.AddPlugin(...);
77+
}
78+
)
79+
// Add other services.
80+
.AddLogging(builder => builder
81+
.AddSimpleConsole(static options => options.SingleLine = true)
82+
.AddFilter(static level => LogLevel.Trace <= level)
83+
);
84+
85+
// Build and run app.
86+
using var app = builder.Build();
87+
88+
await app.RunAsync();
89+
}
90+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!--
2+
SPDX-FileCopyrightText: 2025 smdn <smdn@smdn.jp>
3+
SPDX-License-Identifier: MIT
4+
-->
5+
<Project Sdk="Microsoft.NET.Sdk">
6+
<PropertyGroup>
7+
<OutputType>Exe</OutputType>
8+
<TargetFramework>net8.0</TargetFramework>
9+
</PropertyGroup>
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
12+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
13+
<PackageReference Include="Smdn.Net.MuninNode.Hosting" Version="3.0.0" />
14+
</ItemGroup>
15+
</Project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Getting started
2+
3+
## How to run the example
4+
Execute the command `dotnet run`.
5+
6+
## Notes
7+
The code in this example is to be included in the README of the NuGet package.
8+
9+
Therefore, the content should be simple and ready to run.
10+
Also, the copyright and license information for individual files should be omitted for convenience of appearing on NuGet.org.
11+
12+
## Copyright and License Information
13+
- [Program.cs](Program.cs): Copyright © 2025 [smdn](mailto:smdn@smdn.jp), [MIT License](../../../LICENSE.txt)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.Logging;
7+
8+
using Smdn.Net.MuninNode;
9+
using Smdn.Net.MuninNode.DependencyInjection;
10+
using Smdn.Net.MuninPlugin;
11+
12+
// A interface/class that gets the measurements from some kind of sensor.
13+
interface ITemperatureSensor {
14+
double GetMeasurementValue();
15+
}
16+
17+
class TemperatureSensor : ITemperatureSensor {
18+
public double GetMeasurementValue() => Random.Shared.Next(20, 30); // 20~30 degree Celsius
19+
}
20+
21+
class Program {
22+
static async Task Main()
23+
{
24+
var services = new ServiceCollection();
25+
26+
services
27+
// Add sensor devices.
28+
.AddKeyedSingleton<ITemperatureSensor>("sensor1", new TemperatureSensor())
29+
.AddKeyedSingleton<ITemperatureSensor>("sensor2", new TemperatureSensor())
30+
// Add a Munin service.
31+
.AddMunin(muninBuilder => muninBuilder
32+
// Add a Munin-Node and configure the options.
33+
.AddNode(options => {
34+
options.HostName = "munin-node.localhost";
35+
options.UseAnyAddress(port: 14949);
36+
options.AllowFromLoopbackOnly();
37+
})
38+
// Create and add a Munin-Plugin to report measurements via the Munin-Node.
39+
.AddPlugin(
40+
serviceProvider => PluginFactory.CreatePlugin(
41+
name: "temperature",
42+
// Configure the 'fields' that identify the data source.
43+
// See: https://guide.munin-monitoring.org/en/latest/reference/plugin.html#data-source-attributes
44+
fields: [
45+
PluginFactory.CreateField(
46+
label: "sensor1",
47+
fetchValue: () => serviceProvider
48+
.GetRequiredKeyedService<ITemperatureSensor>("sensor1")
49+
.GetMeasurementValue()
50+
),
51+
PluginFactory.CreateField(
52+
label: "sensor2",
53+
fetchValue: () => serviceProvider
54+
.GetRequiredKeyedService<ITemperatureSensor>("sensor2")
55+
.GetMeasurementValue()
56+
),
57+
],
58+
// Configures the 'attributes' of the graph when drawn data as a graph.
59+
// See: https://guide.munin-monitoring.org/en/latest/reference/plugin.html#global-attributes
60+
graphAttributes: new PluginGraphAttributes(
61+
category: "sensors",
62+
title: "Temperature",
63+
verticalLabel: "Degree Celsius",
64+
scale: false,
65+
arguments: "--base 1000 --lower-limit 0 --upper-limit 50"
66+
)
67+
)
68+
)
69+
// One or more plug-ins can be added.
70+
//.AddPlugin(...)
71+
//.AddPlugin(...)
72+
)
73+
// Add other services.
74+
.AddLogging(builder => builder
75+
.AddSimpleConsole(static options => options.SingleLine = true)
76+
.AddFilter(static level => LogLevel.Trace <= level)
77+
);
78+
79+
// Keep the node running until Ctrl+C is pressed.
80+
var cts = new CancellationTokenSource();
81+
82+
Console.CancelKeyPress += (_, args) => {
83+
cts.Cancel();
84+
args.Cancel = true;
85+
};
86+
87+
// Build services and run munin-node service.
88+
var node = services.BuildServiceProvider().GetRequiredService<IMuninNode>();
89+
90+
try {
91+
// When the RunAsync method finishes processing one connection,
92+
// it immediately waits for the next connection.
93+
// Therefore, the method will not return until the cancellation is
94+
// requested by CancellationToken.
95+
await node.RunAsync(cts.Token);
96+
}
97+
catch (OperationCanceledException ex) when (ex.CancellationToken == cts.Token) {
98+
Console.WriteLine("stopped");
99+
}
100+
}
101+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!--
2+
SPDX-FileCopyrightText: 2025 smdn <smdn@smdn.jp>
3+
SPDX-License-Identifier: MIT
4+
-->
5+
<Project Sdk="Microsoft.NET.Sdk">
6+
<PropertyGroup>
7+
<OutputType>Exe</OutputType>
8+
<TargetFramework>net8.0</TargetFramework>
9+
</PropertyGroup>
10+
<ItemGroup>
11+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
12+
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
13+
<PackageReference Include="Smdn.Net.MuninNode" Version="2.2.0" />
14+
</ItemGroup>
15+
</Project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Getting started
2+
3+
## How to run the example
4+
Execute the command `dotnet run`.
5+
6+
## Notes
7+
The code in this example is to be included in the README of the NuGet package.
8+
9+
Therefore, the content should be simple and ready to run.
10+
Also, the copyright and license information for individual files should be omitted for convenience of appearing on NuGet.org.
11+
12+
## Copyright and License Information
13+
- [Program.cs](Program.cs): Copyright © 2025 [smdn](mailto:smdn@smdn.jp), [MIT License](../../../LICENSE.txt)

src/Smdn.Net.MuninNode.Hosting/Smdn.Net.MuninNode.Hosting.csproj

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ This library uses [Smdn.Net.MuninNode](https://www.nuget.org/packages/Smdn.Net.M
4343
<PackageReadmeFileContent><![CDATA[# $(PackageId) $(PackageVersion)
4444
$(Description)
4545
46+
## Getting started
47+
First, add the [$(PackageId)](https://www.nuget.org/packages/$(PackageId)) package and any other packages you need to the project file.
48+
49+
```
50+
dotnet add package $(PackageId)
51+
dotnet add package Microsoft.Extensions.Hosting
52+
dotnet add package Microsoft.Extensions.Logging.Console
53+
```
54+
55+
Using the API of the `Smdn.Net.MuninNode.DependencyInjection` and `Smdn.Net.MuninNode.Hosting` namespaces, and the `HostApplicationBuilder`, `WebApplicationBuilder` and so on, you can configure and run a Munin-Node as a hosted service in the following way.
56+
57+
```cs
58+
$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\..\examples\$(PackageId)\getting-started\Program.cs').TrimEnd())
59+
```
60+
4661
## Contributing
4762
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)).
4863
]]></PackageReadmeFileContent>

src/Smdn.Net.MuninNode/Smdn.Net.MuninNode.csproj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,23 @@ This library also provides abstraction APIs for implementing Munin-Plugin. By us
4444
<PackageReadmeFileContent><![CDATA[# $(PackageId) $(PackageVersion)
4545
$(Description)
4646
47+
## Getting started
48+
First, add the [$(PackageId)](https://www.nuget.org/packages/$(PackageId)) package and any other packages you need to the project file.
49+
50+
```
51+
dotnet add package $(PackageId)
52+
dotnet add package Microsoft.Extensions.DependencyInjection
53+
dotnet add package Microsoft.Extensions.Logging.Console
54+
```
55+
56+
Using the API of the `Smdn.Net.MuninNode.DependencyInjection` namespace and the `ServiceCollection`, you can configure and run a Munin-Node the following way.
57+
58+
```cs
59+
$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\..\examples\$(PackageId)\getting-started\Program.cs').TrimEnd())
60+
```
61+
62+
More examples can be found on the [GitHub repository]($(RepositoryUrl)/tree/main/examples/$(PackageId)/), including examples of using library features.
63+
4764
## Contributing
4865
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)).
4966
]]></PackageReadmeFileContent>

0 commit comments

Comments
 (0)