diff --git a/CHANGELOG.md b/CHANGELOG.md index 72519ff21..efb8b7c90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,3 +24,6 @@ ## 0.0.7 - 【#44】兼容青龙最新版本(v2.12.0),修复因青龙调整目录结构导致的bug - 更新`publish-image.yml`,只有`release`时才打`latest tag`,手动运行时不打`latest tag` +## 0.0.8 +- 【#55】新增日志推送端:Microsoft Teams +- 【#27】更新README diff --git a/README.md b/README.md index b037bafff..0dcd8a20d 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ BiliBiliTool - **所有代码都是开源且透明的,任何人均可查看,程序不会保存或滥用任何用户的个人信息** - **应用内几乎所有功能都开放为了配置(如任务开关、日期、upId等),请仔细阅读配置文档,自己对自己的配置负责** -_(如果图片挂了,是因为 GitHub 的服务器在国外,经常会刷不出,有梯子的可以架起梯子,没有的也可以先参考 [我的博客](https://www.cnblogs.com/RayWang/p/13909784.html),但博客内容不保证最新)_ +_(如果图片挂了,请自己架梯子,没有的也可以先参考 [我的博客](https://www.cnblogs.com/RayWang/p/13909784.html),但内容不保证最新)_ ## 1. 如何使用 @@ -156,7 +156,12 @@ P.S.这里的运行环境指的是 `.NET Runtime 6.0.0` ,安装方法可详见 对于已安装.net环境,且使用的是依赖包,同上,可在终端中执行命令:`dotnet Ray.BiliBiliTool.Console.dll` -对于使用独立包的,可在终端中执行命令:`Ray.BiliBiliTool.Console`。 +对于使用独立包的,可在终端中执行命令: + +``` +chmod +x ./Ray.BiliBiliTool.Console +Ray.BiliBiliTool.Console +``` 其他系统依此类推,运行结果图示如下: diff --git a/Ray.BiliBiliTool.sln b/Ray.BiliBiliTool.sln index ac954cdb2..41fd70ae3 100644 --- a/Ray.BiliBiliTool.sln +++ b/Ray.BiliBiliTool.sln @@ -148,6 +148,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{75A9CC5C docker\build\buildImage_arm64.cmd = docker\build\buildImage_arm64.cmd EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ray.Serilog.Sinks.MicrosoftTeams", "src\Ray.Serilog.Sinks\Ray.Serilog.Sinks.MicrosoftTeams\Ray.Serilog.Sinks.MicrosoftTeams.csproj", "{F249A822-EFD3-4F0A-9C10-95A96676D61A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -226,6 +228,10 @@ Global {F6B8ED3A-5428-4D26-8172-8B41FBF0C4CF}.Debug|Any CPU.Build.0 = Debug|Any CPU {F6B8ED3A-5428-4D26-8172-8B41FBF0C4CF}.Release|Any CPU.ActiveCfg = Release|Any CPU {F6B8ED3A-5428-4D26-8172-8B41FBF0C4CF}.Release|Any CPU.Build.0 = Release|Any CPU + {F249A822-EFD3-4F0A-9C10-95A96676D61A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F249A822-EFD3-4F0A-9C10-95A96676D61A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F249A822-EFD3-4F0A-9C10-95A96676D61A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F249A822-EFD3-4F0A-9C10-95A96676D61A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -263,6 +269,7 @@ Global {830361B7-BCC1-4853-879A-761B0FD86826} = {73DD457B-E06E-45ED-A6BA-7E3C02F8BDF1} {F6B8ED3A-5428-4D26-8172-8B41FBF0C4CF} = {E9BDDCBE-A57D-4E3B-8252-708088386ADF} {75A9CC5C-DF92-4D72-A14C-625AA902855B} = {A93210FD-27B6-40E4-B08D-391F96CA2754} + {F249A822-EFD3-4F0A-9C10-95A96676D61A} = {4BAFC980-7A73-45C3-9460-8B8CCB87939B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {197319DA-1148-4A99-847C-8B270B6A29AB} diff --git a/common.props b/common.props index e462eccc0..b43ce0fd9 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ Ray - 0.0.7 + 0.0.8 $(NoWarn);CS1591;CS0436 diff --git a/docs/configuration.md b/docs/configuration.md index dfd1b71cd..e1be7ebe6 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -59,6 +59,8 @@ - [3.6.8.2. PushPlus的Topic](#3682-pushplus的topic) - [3.6.8.3. PushPlus的Channel](#3683-pushplus的channel) - [3.6.8.4. PushPlus的Webhook](#3684-pushplus的webhook) + - [3.6.9. Microsoft Teams](#369-microsoft-teams) + - [3.6.9.1. Microsoft Teams的Webhook](#3691-microsoft-teams的webhook) - [3.7. 日志相关](#37-日志相关) - [3.7.1. Console日志输出等级](#371-console日志输出等级) - [3.7.2. Console日志输出样式](#372-console日志输出样式) @@ -665,6 +667,25 @@ webhook编码(不是地址),在官网平台设定,仅在channel使用webhook | 命令行示范 | | | GitHub Secrets | `PUSHPLUSWEBHOOK` | + +#### 3.6.9. Microsoft Teams + +官网: https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook + + +##### 3.6.9.1. Microsoft Teams的Webhook + +webhook的完整地址,在Teams的Channel中获取,详细获取方式请参考官网。 + +| TITLE | CONTENT | +| ---------- | -------------- | +| 配置Key | `Serilog__WriteTo__10__Args__webhook` | +| 值域 | 一串字符串 | +| 默认值 | 空 | +| 环境变量 | `Serilog__WriteTo__10__Args__webhook` | +| 命令行示范 | | +| GitHub Secrets | | + ### 3.7. 日志相关 diff --git a/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj b/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj index 535ef48f9..2a525d2db 100644 --- a/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj +++ b/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj @@ -76,6 +76,7 @@ + diff --git a/src/Ray.BiliBiliTool.Console/appsettings.json b/src/Ray.BiliBiliTool.Console/appsettings.json index 0422ff7a4..a60dd7efc 100644 --- a/src/Ray.BiliBiliTool.Console/appsettings.json +++ b/src/Ray.BiliBiliTool.Console/appsettings.json @@ -154,6 +154,14 @@ "webhook": "", //webhook编码(不是地址),仅在channel使用webhook渠道和CP渠道时需要填写 "restrictedToMinimumLevel": "Information" } + }, + //10.MicrosoftTeams + { + "Name": "MicrosoftTeamsBatched", + "Args": { + "webhook": "", //webhook完整地址 + "restrictedToMinimumLevel": "Information" + } } ], "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ] diff --git a/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsApiClient.cs b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsApiClient.cs new file mode 100644 index 000000000..1865379c0 --- /dev/null +++ b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsApiClient.cs @@ -0,0 +1,39 @@ +using System; +using System.Net.Http; +using System.Text; +using Ray.Serilog.Sinks.Batched; + +namespace Ray.Serilog.Sinks.MicrosoftTeams +{ + public class MicrosoftTeamsApiClient : PushService + { + //https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook + + private readonly Uri _apiUrl; + private readonly HttpClient _httpClient = new HttpClient(); + + public MicrosoftTeamsApiClient( + string webhook + ) + { + _apiUrl = new Uri(webhook); + } + + public override string ClientName => "MicrosoftTeams"; + + protected override string NewLineStr => "
"; + + public override HttpResponseMessage DoSend() + { + var json = new + { + text=Msg + }.ToJson(); + + var content = new StringContent(json, Encoding.UTF8, "application/json"); + + var response = _httpClient.PostAsync(_apiUrl, content).GetAwaiter().GetResult(); + return response; + } + } +} diff --git a/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsBatchedSink.cs b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsBatchedSink.cs new file mode 100644 index 000000000..1d7d00e67 --- /dev/null +++ b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsBatchedSink.cs @@ -0,0 +1,38 @@ +using System; +using Ray.Serilog.Sinks.Batched; +using Serilog.Events; + +namespace Ray.Serilog.Sinks.MicrosoftTeams +{ + public class MicrosoftTeamsBatchedSink : BatchedSink + { + private readonly string _webhook; + + public MicrosoftTeamsBatchedSink( + string webhook, + Predicate predicate, + bool sendBatchesAsOneMessages, + string outputTemplate, + IFormatProvider formatProvider, + LogEventLevel minimumLogEventLevel + ) + : base(predicate, sendBatchesAsOneMessages, outputTemplate, formatProvider, minimumLogEventLevel) + { + _webhook = webhook; + } + + public override void Emit(LogEvent logEvent) + { + if (_webhook.IsNullOrEmpty()) return; + base.Emit(logEvent); + } + + protected override PushService PushService => new MicrosoftTeamsApiClient( + webhook: _webhook); + + public override void Dispose() + { + //todo + } + } +} diff --git a/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsConfigurationExtensions.cs b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsConfigurationExtensions.cs new file mode 100644 index 000000000..e85fd6fcf --- /dev/null +++ b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/MicrosoftTeamsConfigurationExtensions.cs @@ -0,0 +1,40 @@ +using System; +using Ray.Serilog.Sinks.Batched; +using Serilog; +using Serilog.Configuration; +using Serilog.Events; + +namespace Ray.Serilog.Sinks.MicrosoftTeams +{ + public static class MicrosoftTeamsConfigurationExtensions + { + public static LoggerConfiguration MicrosoftTeamsBatched( + this LoggerSinkConfiguration loggerSinkConfiguration, + string webhook = "", + string containsTrigger = Constants.DefaultContainsTrigger, + bool sendBatchesAsOneMessages = true, + string outputTemplate = Constants.DefaultOutputTemplate, + IFormatProvider formatProvider = null, + LogEventLevel restrictedToMinimumLevel = LogEventLevel.Verbose + ) + { + if (loggerSinkConfiguration == null) + throw new ArgumentNullException(nameof(loggerSinkConfiguration)); + if (outputTemplate == null) + throw new ArgumentNullException(nameof(outputTemplate)); + + if (containsTrigger.IsNullOrEmpty()) containsTrigger = Constants.DefaultContainsTrigger; + Predicate predicate = x => x.MessageTemplate.Text.Contains(containsTrigger); + + return loggerSinkConfiguration.Sink( + new MicrosoftTeamsBatchedSink( + webhook, + predicate, + sendBatchesAsOneMessages, + outputTemplate, + formatProvider, + restrictedToMinimumLevel), + restrictedToMinimumLevel); + } + } +} diff --git a/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/Ray.Serilog.Sinks.MicrosoftTeams.csproj b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/Ray.Serilog.Sinks.MicrosoftTeams.csproj new file mode 100644 index 000000000..55eb04647 --- /dev/null +++ b/src/Ray.Serilog.Sinks/Ray.Serilog.Sinks.MicrosoftTeams/Ray.Serilog.Sinks.MicrosoftTeams.csproj @@ -0,0 +1,14 @@ + + + + net6.0 + enable + enable + + + + + + + + diff --git a/test/LogTest/LogTest.csproj b/test/LogTest/LogTest.csproj index b5e400b4a..97f27ee26 100644 --- a/test/LogTest/LogTest.csproj +++ b/test/LogTest/LogTest.csproj @@ -21,6 +21,7 @@ + diff --git a/test/LogTest/TestMicrosoftTeams.cs b/test/LogTest/TestMicrosoftTeams.cs new file mode 100644 index 000000000..e5e2d131c --- /dev/null +++ b/test/LogTest/TestMicrosoftTeams.cs @@ -0,0 +1,41 @@ +using System; +using System.Diagnostics; +using System.Threading; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Ray.BiliBiliTool.Console; +using Ray.BiliBiliTool.Infrastructure; +using Ray.Serilog.Sinks.CoolPushBatched; +using Ray.Serilog.Sinks.MicrosoftTeams; +using Ray.Serilog.Sinks.PushPlusBatched; +using Ray.Serilog.Sinks.ServerChanBatched; +using Xunit; + +namespace LogTest +{ + public class TestMicrosoftTeams + { + private string _webhook; + + public TestMicrosoftTeams() + { + Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development"); + Program.CreateHost(new string[] { }); + + _webhook = Global.ConfigurationRoot["Serilog:WriteTo:10:Args:webhook"]; + } + + [Fact] + public void Test() + { + var client = new MicrosoftTeamsApiClient(webhook: _webhook); + + var msg = LogConstants.Msg2; + + var result = client.PushMessage(msg); + Debug.WriteLine(result.Content.ReadAsStringAsync().Result); + + Assert.True(result.StatusCode == System.Net.HttpStatusCode.OK); + } + } +}