public void Log <TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func <TState, Exception, string> formatter) { //fix none! if (logLevel == LogLevel.None) { return; } //防止循环调用:相比在Reporter控制,这里更提升效率 if (RemoteIgnoreLoggers.Instance.ShouldIgnore(Category)) { //防止循环调用 return; } var reporter = LogReporter.Instance; if (!reporter.ShouldReport()) { return; } var category = Category ?? this.GetType().FullName; var msg = $"[{logLevel}] {formatter(state, exception)}"; var reportLogArgs = ReportLogArgs.Create(category, msg, (int)logLevel); reportLogArgs.ClientId = ClientId; //立即返回,不等待 #pragma warning disable 4014 reporter.ReportLog(reportLogArgs); #pragma warning restore 4014 }
/// <summary> /// 服务器端用来接受和存储:ReportLogArgs /// </summary> /// <param name="args"></param> /// <returns></returns> public virtual async Task ReportLog(ReportLogArgs args) { var validateResult = args.Validate(); validateResult.Data = args; if (!validateResult.Success) { validateResult.Message += "=> Failed From Caller"; await this.Clients.Caller.SendAsync(ReportLogConst.ReportLogCallback, validateResult); return; } try { validateResult.Message += "=> Success From All"; RemoteLogRepository.Instance.Log(args); await SendToGroupsAsync(validateResult, args, args.ClientId); } catch (Exception ex) { _logger.LogError(ex, "Ex From Caller"); validateResult.Message = ex.Message; validateResult.Success = false; await this.Clients.Caller.SendAsync(ReportLogConst.ReportLogCallback, validateResult); } }
public void Log(ReportLogArgs args) { //所有的日志,都被加上了Remote.的前缀,可以防止循环调用 LoggerFactory ??= RootServiceProvider.Instance.Root.GetService <ILoggerFactory>(); var remoteCategory = GetRemoteCategory(args.Category, args.ClientId); var logger = LoggerFactory.CreateLogger(remoteCategory); logger.Log(args.Level.AsLogLevel(), args.Message.ToString()); }
private async Task SendToGroupsAsync(ReportLogResult validateResult, ReportLogArgs args, string groupName) { //sendTo: SomeClient,* //永远额外发送给组: * if (groupName == ReportLogConst.AnyClientId) { await this.Clients.Groups(groupName).SendAsync(ReportLogConst.ReportLogCallback, validateResult); } else { await this.Clients.Groups(groupName, ReportLogConst.AnyClientId).SendAsync(ReportLogConst.ReportLogCallback, validateResult); } }
public static bool Validate(ReportLogArgs args, out string message) { if (args == null) { message = "日志参数不能为空"; return(false); } if (args.Message == null) { message = "日志消息不能为空"; return(false); } message = string.Empty; return(true); }
public async Task <MessageResult> TestReportLog([FromBody] ReportLogArgs args) { var messageResult = new MessageResult(); messageResult.Data = args; var reporter = LogReporter.Instance; if (reporter.ShouldReport()) { messageResult.Message = "Not ShouldReport!"; return(messageResult); } await reporter.ReportLog(args); messageResult.Success = true; return(messageResult); }
/// <summary> /// 发送的前提: /// 1 Config != null && Config.Enabled /// 2 Init Invoked Success /// </summary> /// <param name="args"></param> /// <returns></returns> public async Task ReportLog(ReportLogArgs args) { try { #region InvokeAsync vs SendAsync //The InvokeAsync method returns a Task which completes when the server method returns. //The return value, if any, is provided as the result of the Task. //Any exceptions thrown by the method on the server produce a faulted Task. //Use await syntax to wait for the server method to complete and try...catch syntax to handle errors. //The SendAsync method returns a Task which completes when the message has been sent to the server. //No return value is provided since this Task doesn't wait until the server method completes. //Any exceptions thrown on the client while sending the message produce a faulted Task. //Use await and try...catch syntax to handle send errors. //eg: //var result = await Connection.InvokeAsync<TResult>("ReportLog", args); //await Connection.InvokeAsync("ReportLog", args); #endregion if (string.IsNullOrEmpty(args.ClientId)) { args.ClientId = Config.ClientId; } InnerLog("Connection.SendAsync ReportLog"); //todo: cache logs and delay flush //todo: 改造为批量接口,减少发送次数 await Connection.SendAsync("ReportLog", args); } catch (Exception ex) { InnerLog("Connection.SendAsync ReportLog Ex" + ex.Message); } }
public static ReportLogResult Validate(this ReportLogArgs args) { var validate = ReportLogArgs.Validate(args, out var message); return(ReportLogResult.Create(validate, message, args)); }