private static async Task SuccessAction(IInvocation invocation, string dataIntercept, object o = null) { //invocation.ReturnValue = o; //var type = invocation.Method.ReturnType; //if (typeof(Task).IsAssignableFrom(type)) //{ // //var resultProperty = type.GetProperty("Result"); // //类型错误 都可以不要invocation参数,直接将o系列化保存到日记中 // dataIntercept += ($"【执行完成结果】:{JsonConvert.SerializeObject(invocation.ReturnValue)}"); //} //else //{ // dataIntercept += ($"【执行完成结果】:{invocation.ReturnValue}"); //} dataIntercept += ($"【执行完成结果】:{JsonConvert.SerializeObject(o)}"); await Task.Run(() => { Parallel.For(0, 1, e => { // LogLock.OutSql2Log("AOPLog", new string[] { dataIntercept }); SerilogServer.WriteLog("AOPLog", new string[] { dataIntercept }); }); }); }
/// <summary> /// 执行指定任务 /// </summary> /// <param name="context"></param> /// <param name="action"></param> public async Task <string> ExecuteJob(IJobExecutionContext context, Func <Task> func) { //记录Job时间 Stopwatch stopwatch = new Stopwatch(); //JOBID int jobid = context.JobDetail.Key.Name.ToInt32Req(); //JOB组名 string groupName = context.JobDetail.Key.Group; //日志 string jobHistory = $"【{DateTime.Now:yyyy-MM-dd HH:mm:ss}】【执行开始】【Id:{jobid},组别:{groupName}】"; //耗时 double taskSeconds = 0; try { stopwatch.Start(); await func();//执行任务 stopwatch.Stop(); jobHistory += $",【{DateTime.Now:yyyy-MM-dd HH:mm:ss}】【执行成功】"; } catch (Exception ex) { JobExecutionException e2 = new JobExecutionException(ex); e2.RefireImmediately = true; //true 是立即重新执行任务 jobHistory += $",【{DateTime.Now:yyyy-MM-dd HH:mm:ss}】【执行失败:{ex.Message}】"; } finally { taskSeconds = Math.Round(stopwatch.Elapsed.TotalSeconds, 3); // 总秒数 jobHistory += $",【{DateTime.Now:yyyy-MM-dd HH:mm:ss}】【执行结束】(耗时:{taskSeconds}秒)"; if (_tasksQzSvc != null) { var separator = "<br>"; var model = await _tasksQzSvc.QueryById(jobid); if (model != null) { model.RunTimes += 1; model.PerformTime = DateTime.Now; // 这里注意数据库字段的长度问题,超过限制,会造成数据库remark不更新问题。 model.TasksLog = $"{jobHistory}{separator}" + string.Join(separator, StringHelper.GetTopDataBySeparator(model.TasksLog, separator, 5)); await _tasksQzSvc.Update(model); SerilogServer.WriteLog("任务调度--" + model.JobName, new string[] { jobHistory }, false); } } } Console.Out.WriteLine(jobHistory); return(jobHistory); }
public async Task InvokeAsync(HttpContext context) { if (Appsettings.app("Middleware", "IPLog", "Enabled").ObjToBool()) { // 过滤,只有接口 if (context.Request.Path.Value.Contains("api")) { context.Request.EnableBuffering(); try { // 存储请求数据 var request = context.Request; var requestInfo = JsonConvert.SerializeObject(new RequestInfo() { Ip = GetClientIP(context), Url = request.Path.ObjToString().TrimEnd('/').ToLower(), Datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Date = DateTime.Now.ToString("yyyy-MM-dd"), Week = GetWeek(), }); if (!string.IsNullOrEmpty(requestInfo)) { // 自定义log输出 //Parallel.For(0, 1, e => //{ LogLock.OutSql2Log("RequestIpInfoLog", new string[] { requestInfo + "," }, false); //}); // 这种方案也行,用的是Serilog var logFileName = FileHelper.GetAvailableFileNameWithPrefixOrderSize(_environment.ContentRootPath, "RequestIpInfoLog"); SerilogServer.WriteLog(logFileName, new string[] { requestInfo + "," }, false); request.Body.Position = 0; } await _next(context); } catch (Exception) { } } else { await _next(context); } } else { await _next(context); } }
public async Task InvokeAsync(HttpContext context) { if (Appsettings.App("Middleware", "IPLog", "Enabled").ToBoolReq()) { // 过滤,只有接口 if (context.Request.Path.Value.Contains("api")) { //reuqest支持buff,否则body只能读取一次 context.Request.EnableBuffering(); try { // 存储请求数据 var request = context.Request; var requestInfo = JsonConvert.SerializeObject(new RequestInfo() { ClientIP = GetClientIP(context)?.Replace("::ffff:", ""), Url = context.Request.Scheme + "://" + context.Request.Host + context.Request.PathBase + context.Request.Path, Datetime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Week = DateHelper.GetWeek(), }); if (!string.IsNullOrEmpty(requestInfo)) { // 自定义log输出 //Parallel.For(0, 1, e => //{ // LogLock.OutSql2Log("RequestIpInfoLog", new string[] { requestInfo + "," }, false); //}); SerilogServer.WriteLog("RequestIpInfoLog", new string[] { requestInfo + ", " }, false); // 这里读取过body Position是读取过几次 而此操作优于控制器先行 控制器只会读取Position为零次的 request.Body.Position = 0; } await _next(context); // 执行下一个中间件 } catch (Exception) { } } else { await _next(context); } } else { await _next(context); } }
private void LogEx(Exception ex, string dataIntercept) { if (ex != null) { //执行的 service 中,收录异常 MiniProfiler.Current.CustomTiming("Errors:", ex.Message); //执行的 service 中,捕获异常 dataIntercept += ($"【执行完成结果】:方法中出现异常:{ex.Message + ex.InnerException}\r\n"); // 异常日志里有详细的堆栈信息 Parallel.For(0, 1, e => { // LogLock.OutSql2Log("AOPLog", new string[] { dataIntercept }); SerilogServer.WriteLog("AOPLog", new string[] { dataIntercept }); }); } }
/// <summary> /// 存储请求数据 /// </summary> /// <param name="context"></param> /// <returns></returns> private async Task RequestDataLog(HttpContext context) { var request = context.Request; var sr = new StreamReader(request.Body); var content = $" QueryData:{request.Path + request.QueryString}\r\n BodyData:{await sr.ReadToEndAsync()}"; if (!string.IsNullOrEmpty(content)) { //Parallel.For(0, 1, e => //{ // LogLock.OutSql2Log("RequestResponseLog", new string[] { "Request Data:", content }); //}); SerilogServer.WriteLog("RequestLog", new string[] { "Request Data:", content }); request.Body.Position = 0; } }
/// <summary> /// 存储响应数据 /// </summary> /// <param name="response"></param> /// <param name="ms"></param> private void ResponseDataLog(HttpResponse response, MemoryStream ms) { ms.Position = 0; var ResponseBody = new StreamReader(ms).ReadToEnd(); // 去除 Html var reg = "<[^>]+>"; var isHtml = Regex.IsMatch(ResponseBody, reg); if (!string.IsNullOrEmpty(ResponseBody)) { //Parallel.For(0, 1, e => //{ // LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody }); //}); SerilogServer.WriteLog("ResponseLog", new string[] { "Response Data:", ResponseBody }); } }
/// <summary> /// 实例化IInterceptor唯一方法 /// </summary> /// <param name="invocation">包含被拦截方法的信息</param> public void Intercept(IInvocation invocation) { string UserName = _accessor.HttpContext?.User?.Identity?.Name; //记录被拦截方法信息的日志信息 var dataIntercept = "" + $"【当前操作用户】:{ UserName} \r\n" + $"【当前执行方法】:{ invocation.Method.Name} \r\n" + $"【携带的参数有】: {string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray())} \r\n"; try { MiniProfiler.Current.Step($"执行Service方法:{invocation.Method.Name}() -> "); //在被拦截的方法执行完毕后 继续执行当前方法,注意是被拦截的是异步的 invocation.Proceed(); // 异步获取异常,先执行 if (IsAsyncMethod(invocation.Method)) { #region 方案一 //Wait task execution and modify return value if (invocation.Method.ReturnType == typeof(Task)) { invocation.ReturnValue = InternalAsyncHelper.AwaitTaskWithPostActionAndFinally( (Task)invocation.ReturnValue, async() => await SuccessAction(invocation, dataIntercept), /*成功时执行*/ ex => { LogEx(ex, dataIntercept); }); } //Task<TResult> else { invocation.ReturnValue = InternalAsyncHelper.CallAwaitTaskWithPostActionAndFinallyAndGetResult( invocation.Method.ReturnType.GenericTypeArguments[0], invocation.ReturnValue, async(o) => await SuccessAction(invocation, dataIntercept, o),/*成功时执行*/ ex => { LogEx(ex, dataIntercept); }); } #endregion 方案一 #region 如果方案一不行,试试方案二 //var type = invocation.Method.ReturnType; //var resultProperty = type.GetProperty("Result"); //dataIntercept += ($"【执行完成结果】:{JsonConvert.SerializeObject(resultProperty.GetValue(invocation.ReturnValue))}"); //Parallel.For(0, 1, e => //{ // LogLock.OutSql2Log("AOPLog", new string[] { dataIntercept }); //}); #endregion 如果方案一不行,试试方案二 } else {// 同步1 dataIntercept += ($"【执行完成结果】:{invocation.ReturnValue}"); Parallel.For(0, 1, e => { //LogLock.OutSql2Log("AOPLog", new string[] { dataIntercept }); SerilogServer.WriteLog("AOPLog", new string[] { dataIntercept }); }); } } catch (Exception ex)// 同步2 { LogEx(ex, dataIntercept); } //每次更新日志,推送到客户端——实时短信 _hubContext.Clients.All.SendAsync("ReceiveUpdate", LogLock.GetLogData()).Wait(); }
public async Task InvokeAsync(HttpContext context) { if (Appsettings.app("Middleware", "RecordAccessLogs", "Enabled").ObjToBool()) { var api = context.Request.Path.ObjToString().TrimEnd('/').ToLower(); var ignoreApis = Appsettings.app("Middleware", "RecordAccessLogs", "IgnoreApis"); // 过滤,只有接口 if (api.Contains("api") && !ignoreApis.Contains(api)) { _stopwatch.Restart(); var userAccessModel = new UserAccessModel(); HttpRequest request = context.Request; userAccessModel.API = api; userAccessModel.User = _user.Name; userAccessModel.IP = IPLogMildd.GetClientIP(context); userAccessModel.BeginTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); userAccessModel.RequestMethod = request.Method; userAccessModel.Agent = request.Headers["User-Agent"].ObjToString(); // 获取请求body内容 if (request.Method.ToLower().Equals("post") || request.Method.ToLower().Equals("put")) { // 启用倒带功能,就可以让 Request.Body 可以再次读取 request.EnableBuffering(); Stream stream = request.Body; byte[] buffer = new byte[request.ContentLength.Value]; stream.Read(buffer, 0, buffer.Length); userAccessModel.RequestData = Encoding.UTF8.GetString(buffer); request.Body.Position = 0; } else if (request.Method.ToLower().Equals("get") || request.Method.ToLower().Equals("delete")) { userAccessModel.RequestData = HttpUtility.UrlDecode(request.QueryString.ObjToString(), Encoding.UTF8); } // 获取Response.Body内容 var originalBodyStream = context.Response.Body; using (var responseBody = new MemoryStream()) { context.Response.Body = responseBody; await _next(context); var responseBodyData = await GetResponse(context.Response); await responseBody.CopyToAsync(originalBodyStream); } // 响应完成记录时间和存入日志 context.Response.OnCompleted(() => { _stopwatch.Stop(); userAccessModel.OPTime = _stopwatch.ElapsedMilliseconds + "ms"; // 自定义log输出 var requestInfo = JsonConvert.SerializeObject(userAccessModel); //Parallel.For(0, 1, e => //{ // LogLock.OutSql2Log("RecordAccessLogs", new string[] { requestInfo + "," }, false); //}); var logFileName = FileHelper.GetAvailableFileNameWithPrefixOrderSize(_environment.ContentRootPath, "RecordAccessLogs"); SerilogServer.WriteLog(logFileName, new string[] { requestInfo + "," }, false); return(Task.CompletedTask); }); } else { await _next(context); } } else { await _next(context); } }
public static void AddSqlsugarSetup(this IServiceCollection services) { if (services == null) { throw new ArgumentNullException(nameof(services)); } // 默认添加主数据库连接 MainDb.CurrentDbConnId = Appsettings.App(new string[] { "MainDB" }); // 把多个连接对象注入服务,这里必须采用Scope,因为有事务操作 services.AddScoped <ISqlSugarClient>(o => { // 连接字符串 var listConfig = new List <ConnectionConfig>(); // 从库 var listConfig_Slave = new List <SlaveConnectionConfig>(); BaseDBConfig.MutiConnectionString.Item2.ForEach(s => { listConfig_Slave.Add(new SlaveConnectionConfig() { HitRate = s.HitRate, ConnectionString = s.Connection }); }); BaseDBConfig.MutiConnectionString.Item1.ForEach(m => { listConfig.Add(new ConnectionConfig() { ConfigId = m.ConnId.ToString().ToLower(), //设置库的唯一标识 ConnectionString = m.Connection, //必填, 数据库连接字符串 DbType = (DbType)m.DbType, //必填, 数据库类型 IsAutoCloseConnection = true, //是否关闭数据库连接, 设置为true无需使用using或者Close操作 //IsShardSameThread = false, //默认SystemTable, 字段信息读取, 如:该属性是不是主键,标识列等等信息 AopEvents = new AopEvents { OnLogExecuting = (sql, p) => { if (Appsettings.App(new string[] { "AppSettings", "SqlAOP", "OutToLogFile", "Enabled" }).ToBoolReq()) { Parallel.For(0, 1, e => { MiniProfiler.Current.CustomTiming("SQL:", GetParas(p) + "【SQL语句】:" + sql); // LogLock.OutSql2Log("SqlLog", new string[] { GetParas(p), "【SQL语句】:" + sql }); SerilogServer.WriteLog("SqlLog", new string[] { GetParas(p), "【SQL语句】:" + sql }); }); } if (Appsettings.App(new string[] { "AppSettings", "SqlAOP", "OutToConsole", "Enabled" }).ToBoolReq()) { ConsoleHelper.WriteColorLine(string.Join("\r\n", new string[] { "--------", "【SQL语句】:" + GetWholeSql(p, sql) }), ConsoleColor.DarkCyan); } } }, MoreSettings = new ConnMoreSettings() { IsAutoRemoveDataCache = true }, // 从库 SlaveConnectionConfigs = listConfig_Slave, // 自定义特性 ConfigureExternalServices = new ConfigureExternalServices() { EntityService = (property, column) => { if (column.IsPrimarykey && property.PropertyType == typeof(int)) { column.IsIdentity = true; } } }, InitKeyType = InitKeyType.Attribute } ); }); SqlSugarClient db = new SqlSugarClient(listConfig); db.QueryFilter .Add(new SqlFilterItem() //单表全局过滤器 { FilterValue = filterDb => { return(new SqlFilterResult() { Sql = " DeleteTime IS NULL" }); }, IsJoinQuery = false //单表查询生效 }); return(db); }); }