Ver Fonte

😎完善超级API接口日志

zuohuaijun há 2 anos atrás
pai
commit
7d6675213b

+ 1 - 1
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -19,7 +19,7 @@
     <PackageReference Include="AspNet.Security.OAuth.Gitee" Version="6.0.15" />
     <PackageReference Include="AspNet.Security.OAuth.Weixin" Version="6.0.15" />
     <PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
-    <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.13.7" />
+    <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.13.8" />
     <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.2.24" />
     <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.2.24" />
     <PackageReference Include="Furion.Pure" Version="4.9.2.24" />

+ 4 - 4
Admin.NET/Admin.NET.Core/Hub/OnlineUserHub.cs

@@ -44,14 +44,14 @@ public class OnlineUserHub : Hub<IOnlineUserHub>
         var claims = JWTEncryption.ReadJwtToken(token)?.Claims;
         var client = Parser.GetDefault().Parse(httpContext.Request.Headers["User-Agent"]);
 
-        var userId = claims.FirstOrDefault(u => u.Type == ClaimConst.UserId)?.Value;
-        var tenantId = claims.FirstOrDefault(u => u.Type == ClaimConst.TenantId)?.Value;
+        var userId = claims?.FirstOrDefault(u => u.Type == ClaimConst.UserId)?.Value;
+        var tenantId = claims?.FirstOrDefault(u => u.Type == ClaimConst.TenantId)?.Value;
         var user = new SysOnlineUser
         {
             ConnectionId = Context.ConnectionId,
             UserId = string.IsNullOrWhiteSpace(userId) ? 0 : long.Parse(userId),
-            UserName = claims.FirstOrDefault(u => u.Type == ClaimConst.Account)?.Value,
-            RealName = claims.FirstOrDefault(u => u.Type == ClaimConst.RealName)?.Value,
+            UserName = claims?.FirstOrDefault(u => u.Type == ClaimConst.Account)?.Value,
+            RealName = claims?.FirstOrDefault(u => u.Type == ClaimConst.RealName)?.Value,
             Time = DateTime.Now,
             Ip = httpContext.Connection.RemoteIpAddress.MapToIPv4().ToString(),
             Browser = client.UA.Family + client.UA.Major,

+ 8 - 3
Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs

@@ -74,9 +74,14 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
         string remoteIPv4 = loggingMonitor.remoteIPv4;
         (string ipLocation, double? longitude, double? latitude) = GetIpAddress(remoteIPv4);
 
-        var client = Parser.GetDefault().Parse(loggingMonitor.userAgent.ToString());
-        var browser = $"{client.UA.Family} {client.UA.Major}.{client.UA.Minor} / {client.Device.Family}";
-        var os = $"{client.OS.Family} {client.OS.Major} {client.OS.Minor}";
+        var browser = "";
+        var os = "";
+        if (loggingMonitor.userAgent != null)
+        {
+            var client = Parser.GetDefault().Parse(loggingMonitor.userAgent.ToString());
+            browser = $"{client.UA.Family} {client.UA.Major}.{client.UA.Minor} / {client.Device.Family}";
+            os = $"{client.OS.Family} {client.OS.Major} {client.OS.Minor}";
+        }
 
         // 捕捉异常,否则会由于 unhandled exception 导致程序崩溃
         try

+ 1 - 1
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj

@@ -24,7 +24,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Rezero.Api" Version="1.0.7" />
+    <PackageReference Include="Rezero.Api" Version="1.0.10" />
   </ItemGroup>  
 
   <ItemGroup>

+ 68 - 0
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Service/SuperApiAop.cs

@@ -4,9 +4,16 @@
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
+using Admin.NET.Core;
+using Furion.ClayObject;
+using Furion.DataEncryption;
 using Furion.FriendlyException;
+using Furion.JsonSerialization;
 using Microsoft.AspNetCore.Authentication;
 using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using NewLife;
 using ReZero.SuperAPI;
 
 namespace Admin.NET.Plugin.ReZero.Service;
@@ -30,11 +37,72 @@ public class SuperApiAop : DefaultSuperApiAop
 
     public override async Task OnExecutedAsync(InterfaceContext aopContext)
     {
+        InitLogContext(aopContext, LogLevel.Information);
+
         await base.OnExecutedAsync(aopContext);
     }
 
     public override async Task OnErrorAsync(InterfaceContext aopContext)
     {
+        InitLogContext(aopContext, LogLevel.Error);
+
         await base.OnErrorAsync(aopContext);
     }
+
+    /// <summary>
+    /// 保存超级API接口日志
+    /// </summary>
+    /// <param name="aopContext"></param>
+    /// <param name="logLevel"></param>
+    private void InitLogContext(InterfaceContext aopContext, LogLevel logLevel)
+    {
+        var api = aopContext.InterfaceInfo;
+        var context = aopContext.HttpContext;
+
+        var accessToken = context.Response.Headers["access-token"].ToString();
+        var token = string.IsNullOrWhiteSpace(accessToken)
+            ? context.Request.Headers["Authorization"].ToString()
+            : "Bearer " + accessToken;
+        var claims = JWTEncryption.ReadJwtToken(token)?.Claims;
+        var userName = claims?.FirstOrDefault(u => u.Type == ClaimConst.Account)?.Value;
+        var realName = claims?.FirstOrDefault(u => u.Type == ClaimConst.RealName)?.Value;
+
+        var paths = api.Url.Split('/');
+        var actionName = paths[paths.Length - 1];
+
+        var apiInfo = Clay.Object(new
+        {
+            requestUrl = api.Url,
+            httpMethod = api.HttpMethod,
+            displayTitle = api.Name,
+            actionTypeName = actionName,
+            controllerName = aopContext.InterfaceType == InterfaceType.DynamicApi ? $"ReZero动态-{api.GroupName}" : $"ReZero系统-{api.GroupName}",
+            remoteIPv4 = context.GetRemoteIpAddressToIPv4(),
+            userAgent = context.Request.Headers["User-Agent"],
+            returnInformation = new
+            {
+                httpStatusCode = context.Response.StatusCode,
+            },
+            authorizationClaims = new[]
+            {
+                new
+                {
+                    type = ClaimConst.Account,
+                    value = userName
+                },
+                new
+                {
+                    type = ClaimConst.RealName,
+                    value = realName
+                },
+            },
+            exception = aopContext.Exception == null ? null : JSON.Serialize(aopContext.Exception)
+        });
+
+        var logger = App.GetRequiredService<ILoggerFactory>().CreateLogger("System.Logging.LoggingMonitor");
+        using var scope = logger.ScopeContext(new Dictionary<object, object> {
+            { "loggingMonitor", apiInfo.ToString() }
+        });
+        logger.Log(logLevel, "ReZero超级API接口日志");
+    }
 }