Skip to content

Commit 9be8e65

Browse files
authored
Merge pull request #375 from KodrAus/feat/cluster-health
Support probing cluster health through seqcli
2 parents d77699e + 3528570 commit 9be8e65

File tree

8 files changed

+110
-121
lines changed

8 files changed

+110
-121
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright Datalust Pty Ltd and Contributors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Globalization;
17+
using System.Linq;
18+
using System.Threading.Tasks;
19+
using SeqCli.Cli.Features;
20+
using SeqCli.Config;
21+
using SeqCli.Connection;
22+
using SeqCli.Util;
23+
using Seq.Api.Model.Cluster;
24+
using Serilog;
25+
26+
namespace SeqCli.Cli.Commands.Cluster;
27+
28+
[Command("cluster", "health",
29+
"Probe a Seq node's `/health/cluster` endpoint, and print the returned status",
30+
Example = "seqcli cluster health -s https://seq.example.com")]
31+
class HealthCommand : Command
32+
{
33+
readonly SeqConnectionFactory _connectionFactory;
34+
35+
readonly ConnectionFeature _connection;
36+
readonly OutputFormatFeature _output;
37+
38+
public HealthCommand(SeqConnectionFactory connectionFactory, SeqCliOutputConfig outputConfig)
39+
{
40+
_connectionFactory = connectionFactory ?? throw new ArgumentNullException(nameof(connectionFactory));
41+
42+
_output = Enable(new OutputFormatFeature(outputConfig));
43+
_connection = Enable<ConnectionFeature>();
44+
}
45+
46+
protected override async Task<int> Run()
47+
{
48+
var connection = _connectionFactory.Connect(_connection);
49+
50+
var health = await connection.Cluster.CheckHealthAsync();
51+
52+
if (_output.Json)
53+
{
54+
_output.WriteObject(health);
55+
} else if (!string.IsNullOrWhiteSpace(health.Description)) {
56+
Console.WriteLine($"{health.Status}: {health.Description}");
57+
} else {
58+
Console.WriteLine($"{health.Status}");
59+
}
60+
61+
return (health.Status) switch
62+
{
63+
HealthStatus.Healthy => 0,
64+
HealthStatus.Degraded => 101,
65+
HealthStatus.Unhealthy => 102,
66+
// Catch-all for any future statuses
67+
// We give the main ones well-defined exit codes
68+
_ => (int)health.Status
69+
};
70+
}
71+
}

src/SeqCli/Cli/Commands/Node/DemoteCommand.cs

Lines changed: 0 additions & 95 deletions
This file was deleted.

src/SeqCli/Cli/Commands/Node/ListCommand.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ protected override async Task<int> Run()
5555
var connection = _connectionFactory.Connect(_connection);
5656

5757
var list = _id != null ?
58-
new[] { await connection.ClusterNodes.FindAsync(_id) } :
59-
(await connection.ClusterNodes.ListAsync())
58+
new[] { await connection.Cluster.FindAsync(_id) } :
59+
(await connection.Cluster.ListAsync())
6060
.Where(n => _name == null || _name == n.Name);
6161

6262
_output.ListEntities(list);

src/SeqCli/Cli/Features/OutputFormatFeature.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,39 @@ public void WriteEntity(Entity entity)
138138
}
139139
}
140140

141+
public void WriteObject(object value)
142+
{
143+
if (value == null) throw new ArgumentNullException(nameof(value));
144+
145+
if (_json)
146+
{
147+
var jo = JObject.FromObject(
148+
value,
149+
JsonSerializer.CreateDefault(new JsonSerializerSettings {
150+
DateParseHandling = DateParseHandling.None,
151+
Converters = {
152+
new StringEnumConverter()
153+
}
154+
}));
155+
156+
// Using the same method of JSON colorization as above
157+
158+
var writer = new LoggerConfiguration()
159+
.Destructure.With<JsonNetDestructuringPolicy>()
160+
.Enrich.With<StripStructureTypeEnricher>()
161+
.WriteTo.Console(
162+
outputTemplate: "{@Message:j}{NewLine}",
163+
theme: Theme,
164+
applyThemeToRedirectedOutput: ApplyThemeToRedirectedOutput)
165+
.CreateLogger();
166+
writer.Information("{@Entity}", jo);
167+
}
168+
else
169+
{
170+
Console.WriteLine(value.ToString());
171+
}
172+
}
173+
141174
public void ListEntities(IEnumerable<Entity> list)
142175
{
143176
foreach (var entity in list)

src/SeqCli/SeqCli.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
</ItemGroup>
2929
<ItemGroup>
3030
<PackageReference Include="newtonsoft.json" Version="13.0.3" />
31-
<PackageReference Include="Seq.Api" Version="2024.3.0" />
31+
<PackageReference Include="Seq.Api" Version="2025.1.0-*" />
3232
<PackageReference Include="Serilog" Version="4.0.2" />
3333
<PackageReference Include="Serilog.Expressions" Version="5.0.0" />
3434
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />

test/SeqCli.EndToEnd/License/LicenseApplyTestsCasecs.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ public Task ExecuteAsync(SeqConnection connection, ILogger logger, CliCommandRun
2121
var filename = _testDataFolder.ItemPath("license.txt");
2222
File.WriteAllText(filename, "Ceci n'est pas une licence");
2323
runner.Exec("license apply", $"--certificate=\"{filename}\"");
24-
Assert.Equal(
25-
"The command failed: 400 - The license format is invalid: data precedes any keys.",
26-
runner.LastRunProcess.Output.Trim());
24+
Assert.Contains(
25+
"The license format is invalid: data precedes any keys.",
26+
runner.LastRunProcess!.Output.Trim());
2727
return Task.CompletedTask;
2828
}
2929
}

test/SeqCli.EndToEnd/Node/NodeDemoteTestCase.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

test/SeqCli.EndToEnd/Node/NodeListTestCase.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public Task ExecuteAsync(SeqConnection connection, ILogger logger, CliCommandRun
1414
var exit = runner.Exec("node list --json");
1515
Assert.Equal(0, exit);
1616

17-
Assert.Contains("\"Role\":", runner.LastRunProcess!.Output);
1817
Assert.Contains("\"Name\":", runner.LastRunProcess!.Output);
1918
Assert.Contains("\"StateDescription\":", runner.LastRunProcess!.Output);
2019
return Task.CompletedTask;

0 commit comments

Comments
 (0)