Browse Source

feat: 记录发送请求与响应标头用于环境调试.

pull/568/head
cKey 4 years ago
parent
commit
2d6e40889e
  1. 42
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs
  2. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/IWebhookManager.cs
  3. 9
      aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookManager.cs
  4. 2
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs
  5. 25
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs
  6. 14
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs
  7. 6
      aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs
  8. 172
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220413084629_Add-Field-Request-And-Response-Headers-With-SendAttempts.Designer.cs
  9. 39
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220413084629_Add-Field-Request-And-Response-Headers-With-SendAttempts.cs
  10. 12
      aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs

42
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/DefaultWebhookSender.cs

@ -1,8 +1,11 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -52,13 +55,17 @@ namespace LINGYUN.Abp.Webhooks
var isSucceed = false; var isSucceed = false;
HttpStatusCode? statusCode = null; HttpStatusCode? statusCode = null;
var content = FailedRequestDefaultContent; var content = FailedRequestDefaultContent;
var reqHeaders = GetHeaders(request.Headers);
IDictionary<string, string> resHeaders = null;
try try
{ {
var response = await SendHttpRequest(request); var response = await SendHttpRequest(request);
isSucceed = response.isSucceed;
statusCode = response.statusCode; isSucceed = response.IsSuccessStatusCode;
content = response.content; statusCode = response.StatusCode;
resHeaders = GetHeaders(response.Headers);
content = await response.Content.ReadAsStringAsync();
} }
catch (TaskCanceledException) catch (TaskCanceledException)
{ {
@ -75,7 +82,13 @@ namespace LINGYUN.Abp.Webhooks
} }
finally finally
{ {
await _webhookManager.StoreResponseOnWebhookSendAttemptAsync(webhookSendAttemptId, webhookSenderArgs.TenantId, statusCode, content); await _webhookManager.StoreResponseOnWebhookSendAttemptAsync(
webhookSendAttemptId,
webhookSenderArgs.TenantId,
statusCode,
content,
reqHeaders,
resHeaders);
} }
if (!isSucceed) if (!isSucceed)
@ -113,17 +126,26 @@ namespace LINGYUN.Abp.Webhooks
} }
} }
protected virtual async Task<(bool isSucceed, HttpStatusCode statusCode, string content)> SendHttpRequest(HttpRequestMessage request) protected virtual async Task<HttpResponseMessage> SendHttpRequest(HttpRequestMessage request)
{ {
var client = _httpClientFactory.CreateClient(AbpWebhooksModule.WebhooksClient); var client = _httpClientFactory.CreateClient(AbpWebhooksModule.WebhooksClient);
var response = await client.SendAsync(request); return await client.SendAsync(request);
}
var isSucceed = response.IsSuccessStatusCode; private IDictionary<string, string> GetHeaders(HttpHeaders headers)
var statusCode = response.StatusCode; {
var content = await response.Content.ReadAsStringAsync(); var res = new Dictionary<string, string>();
return (isSucceed, statusCode, content); if (headers != null && headers.Any())
{
foreach (var header in headers)
{
res.Add(header.Key, header.Value.JoinAsString(";"));
}
}
return res;
} }
} }
} }

9
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/IWebhookManager.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -16,7 +17,11 @@ namespace LINGYUN.Abp.Webhooks
Task<Guid> InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs); Task<Guid> InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs);
Task StoreResponseOnWebhookSendAttemptAsync( Task StoreResponseOnWebhookSendAttemptAsync(
Guid webhookSendAttemptId, Guid? tenantId, Guid webhookSendAttemptId,
HttpStatusCode? statusCode, string content); Guid? tenantId,
HttpStatusCode? statusCode,
string content,
IDictionary<string, string> requestHeaders = null,
IDictionary<string, string> responseHeaders = null);
} }
} }

9
aspnet-core/modules/webhooks/LINGYUN.Abp.Webhooks/LINGYUN/Abp/Webhooks/WebhookManager.cs

@ -1,5 +1,6 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
@ -75,6 +76,12 @@ namespace LINGYUN.Abp.Webhooks
public abstract Task<Guid> InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs); public abstract Task<Guid> InsertAndGetIdWebhookSendAttemptAsync(WebhookSenderArgs webhookSenderArgs);
public abstract Task StoreResponseOnWebhookSendAttemptAsync(Guid webhookSendAttemptId, Guid? tenantId, HttpStatusCode? statusCode, string content); public abstract Task StoreResponseOnWebhookSendAttemptAsync(
Guid webhookSendAttemptId,
Guid? tenantId,
HttpStatusCode? statusCode,
string content,
IDictionary<string, string> requestHeaders = null,
IDictionary<string, string> responseHeaders = null);
} }
} }

2
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain.Shared/LINGYUN/Abp/WebhooksManagement/WebhookSendRecordConsts.cs

@ -3,4 +3,6 @@
public static class WebhookSendRecordConsts public static class WebhookSendRecordConsts
{ {
public static int MaxResponseLength { get; set; } = int.MaxValue; public static int MaxResponseLength { get; set; } = int.MaxValue;
public static int MaxHeadersLength { get; set; } = int.MaxValue;
} }

25
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/DefaultWebhookManager.cs

@ -1,5 +1,7 @@
using LINGYUN.Abp.Webhooks; using LINGYUN.Abp.Webhooks;
using Newtonsoft.Json;
using System; using System;
using System.Collections.Generic;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -47,12 +49,31 @@ public class DefaultWebhookManager : WebhookManager, ITransientDependency
} }
[UnitOfWork] [UnitOfWork]
public async override Task StoreResponseOnWebhookSendAttemptAsync(Guid webhookSendAttemptId, Guid? tenantId, HttpStatusCode? statusCode, string content) public async override Task StoreResponseOnWebhookSendAttemptAsync(
Guid webhookSendAttemptId,
Guid? tenantId,
HttpStatusCode? statusCode,
string content,
IDictionary<string, string> requestHeaders = null,
IDictionary<string, string> responseHeaders = null)
{ {
using (CurrentTenant.Change(tenantId)) using (CurrentTenant.Change(tenantId))
{ {
var reqHeaders = "{}";
var resHeaders = "{}";
if (requestHeaders != null)
{
reqHeaders = JsonConvert.SerializeObject(requestHeaders);
}
if (responseHeaders != null)
{
resHeaders = JsonConvert.SerializeObject(responseHeaders);
}
var record = await WebhookSendAttemptRepository.GetAsync(webhookSendAttemptId); var record = await WebhookSendAttemptRepository.GetAsync(webhookSendAttemptId);
record.SetResponse(content, statusCode); record.SetResponse(content, statusCode, resHeaders);
// 加入标头信息,便于维护人员调试
record.SetRequestHeaders(reqHeaders);
await WebhookSendAttemptRepository.UpdateAsync(record); await WebhookSendAttemptRepository.UpdateAsync(record);
} }

14
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.Domain/LINGYUN/Abp/WebhooksManagement/WebhookSendRecord.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Net; using System.Net;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Auditing; using Volo.Abp.Auditing;
@ -18,6 +19,10 @@ public class WebhookSendRecord : Entity<Guid>, IHasCreationTime, IHasModificatio
public virtual HttpStatusCode? ResponseStatusCode { get; set; } public virtual HttpStatusCode? ResponseStatusCode { get; set; }
public virtual string RequestHeaders { get; protected set; }
public virtual string ResponseHeaders { get; protected set; }
public virtual DateTime CreationTime { get; set; } public virtual DateTime CreationTime { get; set; }
public virtual DateTime? LastModificationTime { get; set; } public virtual DateTime? LastModificationTime { get; set; }
@ -42,9 +47,16 @@ public class WebhookSendRecord : Entity<Guid>, IHasCreationTime, IHasModificatio
public void SetResponse( public void SetResponse(
string response, string response,
HttpStatusCode? statusCode = null) HttpStatusCode? statusCode = null,
string responseHeaders = null)
{ {
Response = Check.Length(response, nameof(response), WebhookSendRecordConsts.MaxResponseLength); Response = Check.Length(response, nameof(response), WebhookSendRecordConsts.MaxResponseLength);
ResponseStatusCode = statusCode; ResponseStatusCode = statusCode;
ResponseHeaders = Check.Length(responseHeaders, nameof(responseHeaders), WebhookSendRecordConsts.MaxHeadersLength);
}
public void SetRequestHeaders(string requestHeaders = null)
{
RequestHeaders = Check.Length(requestHeaders, nameof(requestHeaders), WebhookSendRecordConsts.MaxHeadersLength);
} }
} }

6
aspnet-core/modules/webhooks/LINGYUN.Abp.WebhooksManagement.EntityFrameworkCore/LINGYUN/Abp/WebhooksManagement/EntityFrameworkCore/WebhooksManagementDbContextModelCreatingExtensions.cs

@ -41,6 +41,12 @@ public static class WebhooksManagementDbContextModelCreatingExtensions
b.Property(p => p.Response) b.Property(p => p.Response)
.HasColumnName(nameof(WebhookSendRecord.Response)) .HasColumnName(nameof(WebhookSendRecord.Response))
.HasMaxLength(WebhookSendRecordConsts.MaxResponseLength); .HasMaxLength(WebhookSendRecordConsts.MaxResponseLength);
b.Property(p => p.RequestHeaders)
.HasColumnName(nameof(WebhookSendRecord.RequestHeaders))
.HasMaxLength(WebhookSendRecordConsts.MaxHeadersLength);
b.Property(p => p.ResponseHeaders)
.HasColumnName(nameof(WebhookSendRecord.ResponseHeaders))
.HasMaxLength(WebhookSendRecordConsts.MaxHeadersLength);
b.ConfigureByConvention(); b.ConfigureByConvention();

172
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220413084629_Add-Field-Request-And-Response-Headers-With-SendAttempts.Designer.cs

@ -0,0 +1,172 @@
// <auto-generated />
using System;
using LY.MicroService.WebhooksManagement.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Volo.Abp.EntityFrameworkCore;
#nullable disable
namespace LY.MicroService.WebhooksManagement.Migrations
{
[DbContext(typeof(WebhooksManagementMigrationsDbContext))]
[Migration("20220413084629_Add-Field-Request-And-Response-Headers-With-SendAttempts")]
partial class AddFieldRequestAndResponseHeadersWithSendAttempts
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "6.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<string>("Data")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("Data");
b.Property<DateTime?>("DeletionTime")
.HasColumnType("datetime(6)")
.HasColumnName("DeletionTime");
b.Property<bool>("IsDeleted")
.ValueGeneratedOnAdd()
.HasColumnType("tinyint(1)")
.HasDefaultValue(false)
.HasColumnName("IsDeleted");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("WebhookName")
.IsRequired()
.HasMaxLength(100)
.HasColumnType("varchar(100)")
.HasColumnName("WebhookName");
b.HasKey("Id");
b.ToTable("AbpWebhooksEvents", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime");
b.Property<string>("RequestHeaders")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("RequestHeaders");
b.Property<string>("Response")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("Response");
b.Property<string>("ResponseHeaders")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("ResponseHeaders");
b.Property<int?>("ResponseStatusCode")
.HasColumnType("int");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)");
b.Property<Guid>("WebhookEventId")
.HasColumnType("char(36)");
b.Property<Guid>("WebhookSubscriptionId")
.HasColumnType("char(36)");
b.HasKey("Id");
b.HasIndex("WebhookEventId");
b.ToTable("AbpWebhooksSendAttempts", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSubscription", b =>
{
b.Property<Guid>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("char(36)");
b.Property<DateTime>("CreationTime")
.HasColumnType("datetime(6)")
.HasColumnName("CreationTime");
b.Property<Guid?>("CreatorId")
.HasColumnType("char(36)")
.HasColumnName("CreatorId");
b.Property<string>("Headers")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("Headers");
b.Property<bool>("IsActive")
.HasColumnType("tinyint(1)");
b.Property<string>("Secret")
.HasMaxLength(128)
.HasColumnType("varchar(128)")
.HasColumnName("Secret");
b.Property<Guid?>("TenantId")
.HasColumnType("char(36)");
b.Property<string>("WebhookUri")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("varchar(255)")
.HasColumnName("WebhookUri");
b.Property<string>("Webhooks")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("Webhooks");
b.HasKey("Id");
b.ToTable("AbpWebhooksSubscriptions", (string)null);
});
modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", b =>
{
b.HasOne("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", "WebhookEvent")
.WithOne()
.HasForeignKey("LINGYUN.Abp.WebhooksManagement.WebhookSendRecord", "WebhookEventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("WebhookEvent");
});
#pragma warning restore 612, 618
}
}
}

39
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/20220413084629_Add-Field-Request-And-Response-Headers-With-SendAttempts.cs

@ -0,0 +1,39 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace LY.MicroService.WebhooksManagement.Migrations
{
public partial class AddFieldRequestAndResponseHeadersWithSendAttempts : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "RequestHeaders",
table: "AbpWebhooksSendAttempts",
type: "longtext",
maxLength: 2147483647,
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<string>(
name: "ResponseHeaders",
table: "AbpWebhooksSendAttempts",
type: "longtext",
maxLength: 2147483647,
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "RequestHeaders",
table: "AbpWebhooksSendAttempts");
migrationBuilder.DropColumn(
name: "ResponseHeaders",
table: "AbpWebhooksSendAttempts");
}
}
}

12
aspnet-core/services/LY.MicroService.WebhooksManagement.HttpApi.Host/Migrations/WebhooksManagementMigrationsDbContextModelSnapshot.cs

@ -18,7 +18,7 @@ namespace LY.MicroService.WebhooksManagement.Migrations
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql) .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.MySql)
.HasAnnotation("ProductVersion", "6.0.3") .HasAnnotation("ProductVersion", "6.0.4")
.HasAnnotation("Relational:MaxIdentifierLength", 64); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", b => modelBuilder.Entity("LINGYUN.Abp.WebhooksManagement.WebhookEventRecord", b =>
@ -74,11 +74,21 @@ namespace LY.MicroService.WebhooksManagement.Migrations
.HasColumnType("datetime(6)") .HasColumnType("datetime(6)")
.HasColumnName("LastModificationTime"); .HasColumnName("LastModificationTime");
b.Property<string>("RequestHeaders")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("RequestHeaders");
b.Property<string>("Response") b.Property<string>("Response")
.HasMaxLength(2147483647) .HasMaxLength(2147483647)
.HasColumnType("longtext") .HasColumnType("longtext")
.HasColumnName("Response"); .HasColumnName("Response");
b.Property<string>("ResponseHeaders")
.HasMaxLength(2147483647)
.HasColumnType("longtext")
.HasColumnName("ResponseHeaders");
b.Property<int?>("ResponseStatusCode") b.Property<int?>("ResponseStatusCode")
.HasColumnType("int"); .HasColumnType("int");

Loading…
Cancel
Save