提交 35f86386 编写于 作者: 麦壳饼's avatar 麦壳饼

加入IoTDB的健康检查

上级 07cbd628

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32526.322
VisualStudioVersion = 17.2.32616.157
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.InfluxDB", "src\HealthChecks.InfluxDB\HealthChecks.InfluxDB.csproj", "{838026DE-179A-4FD9-A1CC-93C90B1C4BB8}"
EndProject
......@@ -11,12 +11,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "example", "src\example\exam
EndProject
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{86D31BB9-6FFD-4F77-8722-A5CEB2168967}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "解决方案项", "解决方案项", "{CF3DA4EB-CBDD-47E6-B917-082A514F3B37}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{78584F50-F5B6-4723-BA2A-B8AEB2D30EB2}"
ProjectSection(SolutionItems) = preProject
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.IoTDB", "src\HealthChecks.IoTDB\HealthChecks.IoTDB.csproj", "{C40E109C-3B0E-4AAD-8350-7018C472E788}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -39,11 +41,15 @@ Global
{86D31BB9-6FFD-4F77-8722-A5CEB2168967}.Debug|Any CPU.Build.0 = Debug|Any CPU
{86D31BB9-6FFD-4F77-8722-A5CEB2168967}.Release|Any CPU.ActiveCfg = Release|Any CPU
{86D31BB9-6FFD-4F77-8722-A5CEB2168967}.Release|Any CPU.Build.0 = Release|Any CPU
{C40E109C-3B0E-4AAD-8350-7018C472E788}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C40E109C-3B0E-4AAD-8350-7018C472E788}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C40E109C-3B0E-4AAD-8350-7018C472E788}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C40E109C-3B0E-4AAD-8350-7018C472E788}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {21AB4CD2-241A-4CA8-9363-3FAFCB5FDCD4}
SolutionGuid = {D64E5B57-832A-40FF-BA2E-D4155E19E1B0}
EndGlobalSection
EndGlobal
......@@ -6,6 +6,7 @@ services:
links:
- influx
- cassandra
- iotdb
build:
context: .
dockerfile: src/example/Dockerfile
......@@ -51,6 +52,16 @@ services:
- ./data/cassandra/logs:/var/log/cassandra
networks:
- iotsharp-network
iotdb:
image: apache/iotdb:0.13.0-node
restart: always
container_name: iotdb
ports:
- 6667:6667
networks:
- iotsharp-network
networks:
iotsharp-network:
driver: bridge
\ No newline at end of file
......@@ -6,6 +6,8 @@
<PackageId>IoTSharp.HealthChecks.Cassandra</PackageId>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Nullable>enable</Nullable>
<Company>IoTSharp</Company>
<Authors>maikebing</Authors>
</PropertyGroup>
<ItemGroup>
......
......@@ -6,6 +6,8 @@
<PackageId>IoTSharp.HealthChecks.InfluxDB</PackageId>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Nullable>enable</Nullable>
<Company>IoTSharp</Company>
<Authors>maikebing</Authors>
</PropertyGroup>
<ItemGroup>
......
......@@ -33,7 +33,7 @@ namespace HealthChecks.InfluxDB
var ready = await _influxdb_client.ReadyAsync();
var ping = await _influxdb_client.PingAsync();
var hs = ping && ready.Status == Ready.StatusEnum.Ready ? HealthStatus.Healthy : context.Registration.FailureStatus;
return new HealthCheckResult(hs, hs == HealthStatus.Healthy ? "" : $"Status:{ready.Status} Started:{ready.Started} Up:{ready.Up}");
return new HealthCheckResult(hs, hs == HealthStatus.Healthy ? "" : $"Status:{ready?.Status} Started:{ready?.Started} Up:{ready?.Up}");
}
catch (Exception ex)
{
......
using Apache.IoTDB;
using HealthChecks.IoTDB;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System;
using System.Collections.Generic;
namespace Microsoft.Extensions.DependencyInjection
{
public static class IoTDBHealthCheckBuilderExtensions
{
private const string NAME = "IoTDB";
/// <summary>
/// Add a health check for IoTDB services using connection string.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="connectionString">The IoTDB connection string to be used.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'IoTDB' will be used for the name.</param>
/// <param name="failureStatus">
/// The <see cref="HealthStatus"/> that should be reported when the health check fails. Optional. If <c>null</c> then
/// the default status of <see cref="HealthStatus.Unhealthy"/> will be reported.
/// </param>
/// <param name="tags">A list of tags that can be used to filter sets of health checks. Optional.</param>
/// <param name="timeout">An optional <see cref="TimeSpan"/> representing the timeout of the check.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
public static IHealthChecksBuilder AddIoTDB(this IHealthChecksBuilder builder, string connectionString, string? name = default, HealthStatus? failureStatus = default, IEnumerable<string>? tags = default, TimeSpan? timeout = default)
{
builder.Services
.AddSingleton(sp => new IoTDBHealthCheck(connectionString));
return builder.Add(new HealthCheckRegistration(
name ?? NAME,
sp => sp.GetRequiredService<IoTDBHealthCheck>(),
failureStatus,
tags,
timeout));
}
/// <summary>
/// Add a health check for IoTDB services using <see cref="CassandraClient"/> from service provider.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/>.</param>
/// <param name="name">The health check name. Optional. If <c>null</c> the type name 'IoTDB' will be used for the name.</param>
/// <param name="failureStatus">
/// The <see cref="HealthStatus"/> that should be reported when the health check fails. Optional. If <c>null</c> then
/// the default status of <see cref="HealthStatus.Unhealthy"/> will be reported.
/// </param>
/// <param name="tags">A list of tags that can be used to filter sets of health checks. Optional.</param>
/// <param name="timeout">An optional System.TimeSpan representing the timeout of the check.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/>.</returns>
public static IHealthChecksBuilder AddIoTDB(this IHealthChecksBuilder builder, HealthStatus? failureStatus = default, IEnumerable<string>? tags = default, TimeSpan? timeout = default)
{
builder.Services.AddSingleton(sp => new IoTDBHealthCheck(sp.GetRequiredService<SessionPool>()));
return builder.Add(new HealthCheckRegistration(
NAME,
sp => sp.GetRequiredService<IoTDBHealthCheck>(),
failureStatus,
tags,
timeout));
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<PackageTags>HealthCheck;Health;IoTDB</PackageTags>
<Description>HealthChecks.IoTDB is the health check package for IoTDB.</Description>
<PackageId>IoTSharp.HealthChecks.IoTDB</PackageId>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Nullable>enable</Nullable>
<Company>IoTSharp</Company>
<Authors>maikebing</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Apache.IoTDB" Version="0.13.0.6" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="6.0.5" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions" Version="6.0.5" />
</ItemGroup>
</Project>
using Apache.IoTDB;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace HealthChecks.IoTDB
{
public class IoTDBHealthCheck
: IHealthCheck, IDisposable
{
private readonly SessionPool session_pool ;
private readonly bool _enableRpcCompression;
public IoTDBHealthCheck(string connectionString)
{
Dictionary<string, string> pairs = new Dictionary<string, string>();
connectionString.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(f =>
{
var kv = f.Split('=');
pairs.TryAdd(key: kv[0], value: kv[1]);
});
string host = pairs.GetValueOrDefault("Server") ?? "127.0.0.1";
int port = int.Parse(pairs.GetValueOrDefault("Port") ?? "6667");
string username = pairs.GetValueOrDefault("User") ?? "root";
string password = pairs.GetValueOrDefault("Password") ?? "root";
int fetchSize = int.Parse(pairs.GetValueOrDefault("fetchSize") ?? "1800");
bool enableRpcCompression = bool.Parse(pairs.GetValueOrDefault("enableRpcCompression") ?? "false");
int poolSize = int.Parse(pairs.GetValueOrDefault("poolSize")??"8") ;
string zoneId = pairs.GetValueOrDefault("zoneId") ?? "UTC+08:00";
session_pool = new SessionPool(host, port, username, password, fetchSize, zoneId, poolSize);
_enableRpcCompression = enableRpcCompression;
}
public IoTDBHealthCheck(SessionPool session )
{
session_pool = session;
}
public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
{
try
{
await session_pool.Open(_enableRpcCompression);
var state = session_pool.IsOpen();
await session_pool.SetTimeZone("GMT+8:00");
var tz = await session_pool.GetTimeZone() == "GMT+8:00";
await session_pool.Close();
return new HealthCheckResult(state && tz ? HealthStatus.Healthy : (state || tz ? HealthStatus.Degraded: context.Registration.FailureStatus));
}
catch (Exception ex)
{
return new HealthCheckResult(context.Registration.FailureStatus, exception: ex);
}
}
public void Dispose()
{
}
}
}
# Cassandra Health Check
This health check verifies the ability to communicate with a Cassandra server.
## Example Usage
With all of the following examples, you can additionally add the following parameters:
- `name`: The health check name. Default if not specified is `Cassandra`.
- `failureStatus`: The `HealthStatus` that should be reported when the health check fails. Default is `HealthStatus.Unhealthy`.
- `tags`: A list of tags that can be used to filter sets of health checks.
- `timeout`: A `System.TimeSpan` representing the timeout of the check.
### Basic
This will create a new `CassandraClient` and reuse it on every request to get the health check result. Use
the extension method where you provide the `Uri` to connect with.
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddHealthChecks()
.AddCassandra("");
}
```
If you are sharing a single `CassandraClient` for every time a health check is requested,
you must ensure automatic recovery is enabled so that the `CassandraClient` can be re-established if lost.
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<CassandraClient>(sp => Cluster.Builder()
.AddContactPoint("127.0.0.1")
.WithGraphOptions(new GraphOptions().SetName("demo"))
.Build())
.AddHealthChecks()
.AddCassandra();
}
```
......@@ -15,13 +15,14 @@ namespace example
builder.Services.AddControllers();
builder.Services.AddHealthChecksUI(setup =>
{
setup.AddHealthCheckEndpoint("IoTSharp HealthChecks", $"http://{System.Net.Dns.GetHostName()}/healthz");
setup.AddHealthCheckEndpoint("IoTSharp HealthChecks", $"http://localhost/healthz");
}).AddInMemoryStorage()
.Services.
AddHealthChecks()
.AddCheck<RandomHealthCheck>("random")
.AddInfluxDB(builder.Configuration.GetConnectionString("influx"))
.AddCassandra(builder.Configuration.GetConnectionString("cassandra"));
.AddCassandra(builder.Configuration.GetConnectionString("cassandra"))
.AddIoTDB(builder.Configuration.GetConnectionString("iotdb"));
var app = builder.Build();
......
......@@ -2,7 +2,9 @@
"ConnectionStrings": {
"influx": "http://influx:8086/?org=iotsharp&bucket=iotsharp-bucket&token=iotsharp-tokeniotsharp-tokeniotsharp-tokeniotsharp-tokeniotsharp-token&&latest=-72h",
"cassandra1": "Contact Points=cassandra;Username=user1;Password=P@ssword!",
"cassandra": "Contact Points=cassandra"
"cassandra": "Contact Points=cassandra",
"iotdb": "Server=iotdb"
},
"Logging": {
"LogLevel": {
......
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<DockerComposeProjectPath>..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..</DockerfileContext>
<DockerComposeProjectPath>..\..\docker-compose.dcproj</DockerComposeProjectPath>
<Company>IoTSharp</Company>
<Authors>maikebing</Authors>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="6.0.4" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="6.0.4" />
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="6.0.4" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="6.0.4" />
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="6.0.4" />
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="6.0.4" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HealthChecks.Cassandra\HealthChecks.Cassandra.csproj" />
<ProjectReference Include="..\HealthChecks.InfluxDB\HealthChecks.InfluxDB.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\HealthChecks.Cassandra\HealthChecks.Cassandra.csproj" />
<ProjectReference Include="..\HealthChecks.InfluxDB\HealthChecks.InfluxDB.csproj" />
<ProjectReference Include="..\HealthChecks.IoTDB\HealthChecks.IoTDB.csproj" />
</ItemGroup>
</Project>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册