feat: 格式化健康检查邮件
This commit is contained in:
parent
9fe03299a4
commit
8c38717f73
|
@ -6,7 +6,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="3.1.1" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="3.1.1" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="3.1.2-beta01" />
|
||||
<PackageReference Include="Longbow" Version="3.1.0" />
|
||||
<PackageReference Include="Longbow.AlipayAuth" Version="3.1.0" />
|
||||
<PackageReference Include="Longbow.Cache" Version="3.1.2-beta-02" />
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="3.1.1" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="3.1.1" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="3.1.2-beta01" />
|
||||
<PackageReference Include="Longbow" Version="3.1.0" />
|
||||
<PackageReference Include="Longbow.Cache" Version="3.1.2-beta-02" />
|
||||
<PackageReference Include="Longbow.Data" Version="3.1.0" />
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
using Bootstrap.Client.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bootstrap.Client.Controllers.Api
|
||||
|
@ -30,12 +35,13 @@ namespace Bootstrap.Client.Controllers.Api
|
|||
/// 邮件发送健康检查方法
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <param name="env"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<bool> Healths([FromServices]IConfiguration config, [FromBody]string message)
|
||||
public async Task<bool> Healths([FromServices]IConfiguration config, [FromServices]IWebHostEnvironment env, [FromBody]string message)
|
||||
{
|
||||
return await SendMailAsync(config, "Healths Report", message);
|
||||
return await SendMailAsync(config, "Healths Report", message.FormatHealths(env.WebRootPath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Mail;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -22,6 +25,70 @@ namespace Bootstrap.Client.Extensions
|
|||
message.Push();
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="webRootPath"></param>
|
||||
/// <returns></returns>
|
||||
public static string FormatHealths(this string message, string webRootPath)
|
||||
{
|
||||
var cate = new Dictionary<string, string>()
|
||||
{
|
||||
["db"] = "数据库",
|
||||
["file"] = "组件文件",
|
||||
["mem"] = "内存",
|
||||
["Gitee"] = "Gitee 接口",
|
||||
["gc"] = "垃圾回收器",
|
||||
["dotnet-runtime"] = "运行时",
|
||||
["environment"] = "环境变量"
|
||||
};
|
||||
var state = new Dictionary<string, string>()
|
||||
{
|
||||
{ "0", "不健康" },
|
||||
{ "1", "亚健康" },
|
||||
{ "2", "健康" }
|
||||
};
|
||||
var styleFile = System.IO.File.ReadAllText(Path.Combine(webRootPath, "html\\healths.html".ReplaceOSPlatformPath()));
|
||||
var itemTemplate = System.IO.File.ReadAllText(Path.Combine(webRootPath, "html\\item.html".ReplaceOSPlatformPath()));
|
||||
var trTemplate = "<tr><td>{0}</td><td>{1}</td></tr>";
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(styleFile);
|
||||
var root = JsonDocument.Parse(message).RootElement;
|
||||
var items = root.GetProperty("Keys").EnumerateArray();
|
||||
foreach (var item in items)
|
||||
{
|
||||
var itemName = item.GetString();
|
||||
|
||||
// 通过 itemName 读取检查项明细内容
|
||||
var data = root.GetProperty("Report").GetProperty("Entries").GetProperty(itemName);
|
||||
var rowData = new StringBuilder();
|
||||
foreach (var row in data.GetProperty("Data").EnumerateObject())
|
||||
{
|
||||
rowData.AppendFormat(trTemplate, row.Name, row.Value.GetRawText().Replace("\\r\\n", "<br>").Replace("\\n", "<br>"));
|
||||
}
|
||||
sb.Append(string.Format(itemTemplate, cate[itemName], data.GetProperty("Duration").GetString(), state[data.GetProperty("Status").GetRawText()], rowData.ToString()));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 消息格式枚举
|
||||
/// </summary>
|
||||
public enum MessageFormat
|
||||
{
|
||||
/// <summary>
|
||||
/// 程序异常
|
||||
/// </summary>
|
||||
Exception,
|
||||
|
||||
/// <summary>
|
||||
/// 健康检查结果
|
||||
/// </summary>
|
||||
Healths
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -120,16 +187,19 @@ namespace Bootstrap.Client.Extensions
|
|||
{
|
||||
var content = new StringBuilder();
|
||||
SmtpClient? sender = null;
|
||||
string from = "";
|
||||
string to = "";
|
||||
string title = "";
|
||||
MailMessage? mail = null;
|
||||
foreach (var msg in messages)
|
||||
{
|
||||
if (mail == null)
|
||||
{
|
||||
mail = new MailMessage(msg.From, msg.To)
|
||||
{
|
||||
Subject = msg.Title,
|
||||
IsBodyHtml = true
|
||||
};
|
||||
}
|
||||
if (sender == null)
|
||||
{
|
||||
from = msg.From;
|
||||
to = msg.To;
|
||||
title = msg.Title;
|
||||
sender = new SmtpClient(msg.Host)
|
||||
{
|
||||
Credentials = new NetworkCredential(msg.From, msg.Password),
|
||||
|
@ -141,7 +211,11 @@ namespace Bootstrap.Client.Extensions
|
|||
// 合并消息
|
||||
content.AppendLine(msg.Message);
|
||||
}
|
||||
if (sender != null) await sender.SendMailAsync(from, to, title, content.ToString());
|
||||
if (sender != null && mail != null)
|
||||
{
|
||||
mail.Body = content.ToString();
|
||||
await sender.SendMailAsync(mail);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<style>
|
||||
.header {
|
||||
display: flex;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.header span:first-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.header span:nth-child(2) {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
margin-bottom: 45px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
font-weight: 700;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
td {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
td,
|
||||
td {
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
padding-left: 10px;
|
||||
}
|
||||
</style>
|
||||
<h2>健康检查结果</h2>
|
|
@ -0,0 +1,16 @@
|
|||
<div class="header">
|
||||
<span>{0}</span>
|
||||
<span>耗时: {1}</span>
|
||||
<span>状态: {2}</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>检查项</th>
|
||||
<th>检查值</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{3}
|
||||
</tbody>
|
||||
</table>
|
|
@ -0,0 +1,68 @@
|
|||
<style>
|
||||
.header {
|
||||
display: flex;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.header span:first-child {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.header span:nth-child(2) {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
background-color: #fff;
|
||||
font-size: 14px;
|
||||
margin-bottom: 45px;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
font-weight: 700;
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
td {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
td,
|
||||
td {
|
||||
border-bottom: 1px solid #dcdfe6;
|
||||
padding: 15px;
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
padding-left: 10px;
|
||||
}
|
||||
</style>
|
||||
<h2>健康检查结果</h2>
|
||||
<div class="header">
|
||||
<span>数据库</span>
|
||||
<span>耗时: 00:00:00.0068991</span>
|
||||
<span>状态: 健康</span>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>检查项</th>
|
||||
<th>检查值</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>ConnectionString</td>
|
||||
<td>"Data Source=BootstrapAdmin.db;"</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
Loading…
Reference in New Issue