/// <summary> /// 在没有 async/await 语法(C# 5.0 以下)的情况下可以使用 TPL 的 `ContinueWith` 方法。 /// </summary> public static Task <GetLogsResult> InvokeUsingTpl(ILogServiceClient client) => client.GetLogsAsync ( // 「必填参数」作为方法的普通必须参数 "example-logstore", DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow, // 「可选参数」作为方法的可选参数,可通过命名参数方式指定 offset: 1, line: 10 ) .ContinueWith(task => { var response = task.Result; // 此处获取 `Result` 不会阻塞,因为在 `ContinueWith` 方法中保证了前置任务必定已完成。 var result = response // 此方法会确保返回的响应失败时候抛出`LogServiceException`。 .EnsureSuccess() // 此处获取Result是安全的。 .Result; Console.WriteLine($"RequestId:{response.RequestId}"); Console.WriteLine($"日志总数:{result.Count}"); Console.WriteLine($"首条日志:{result.Logs.FirstOrDefault()}"); return(result); });
/// <summary> /// 在调用时可使用扩展方法,扩展方法会将简单的请求对象的属性展开到方法入参中。 /// 使用扩展方法 `using Aliyun.Api.Log;` 即可。 /// </summary> public static async Task <GetLogsResult> InvokeUsingExtension(ILogServiceClient client) { var response = await client.GetLogsAsync ( // 「必填参数」作为方法的普通必须参数 "example-logstore", DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow, // 「可选参数」作为方法的可选参数,可通过命名参数方式指定 offset : 1, line : 10 ); var result = response // 此方法会确保返回的响应失败时候抛出`LogServiceException`。 .EnsureSuccess() // 此处获取Result是安全的。 .Result; Console.WriteLine($"RequestId:{response.RequestId}"); Console.WriteLine($"日志总数:{result.Count}"); Console.WriteLine($"首条日志:{result.Logs.FirstOrDefault()}"); return(result); }
/// <summary> /// 执行请求方法。 /// </summary> public static async Task <GetLogsResult> Invoke(ILogServiceClient client) { var response = await client.GetLogsAsync ( // 「必填参数」会在 Request 构造器中列出,并且不可set; new GetLogsRequest("example-logstore", (Int32)DateTimeOffset.UtcNow.AddDays(-1).ToUnixTimeSeconds(), (Int32)DateTimeOffset.UtcNow.ToUnixTimeSeconds()) { // 「可选参数」不会在 Request 构造器中列出,可通过setter设置。 Offset = 1, Line = 100, } ); var result = response // 此方法会确保返回的响应失败时候抛出`LogServiceException`。 .EnsureSuccess() // 此处获取Result是安全的。 .Result; Console.WriteLine($"RequestId:{response.RequestId}"); Console.WriteLine($"日志总数:{result.Count}"); Console.WriteLine($"首条日志:{result.Logs.FirstOrDefault()}"); return(result); }
/// <summary> /// 处理服务器返回(包含在Response中)的错误。 /// </summary> public static async Task <GetLogsResult> InvokeWithErrorHandling(ILogServiceClient client) { var response = await client.GetLogsAsync ( // 「必填参数」作为方法的普通必须参数 "example-logstore", DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow, // 「可选参数」作为方法的可选参数,可通过命名参数方式指定 offset : 1, line : 10 ); GetLogsResult result; // 尝试处理可处理的错误。 if (!response.IsSuccess) { // 错误码 var errorCode = response.Error.ErrorCode; // 错误消息 var errorMessage = response.Error.ErrorMessage; Console.WriteLine($"RequestId:{response.RequestId}"); Console.WriteLine($"错误码:{errorCode}"); Console.WriteLine($"错误信息:{errorMessage}"); // `ErrorCode`类可支持与自身实例或字符串进行对比。 if (errorCode == ErrorCode.SignatureNotMatch /* SDK中预定义的错误码 */) { // 在这里处理业务可处理的错误。。。。。。 Console.WriteLine("Signature not match, {0}.", errorMessage); } else if (errorCode == "ParameterInvalid" /* 业务相关特殊的SDK中未定义的错误码 */) { // 在这里处理业务可处理的错误。。。。。。 Console.WriteLine("Parameter invalid, {0}.", errorMessage); } // 任何处理不到的错误请务必抛出异常中断原流程,避免外部获取到 null 的结果! throw new Exception("这里可以是系统的业务异常。" + response.Error /* 最好带上服务返回的错误信息以便调试 */); } else { // 此处获取Result是安全的。 result = response.Result; } Console.WriteLine($"RequestId:{response.RequestId}"); Console.WriteLine($"日志总数:{result.Count}"); Console.WriteLine($"首条日志:{result.Logs.FirstOrDefault()}"); return(result); }
/// <summary> /// GetLogs 接口查询指定 Project 下某个 Logstore 中的日志数据。还可以通过指定相关参数仅查询符合指定条件的日志数据。 /// 当日志写入到 Logstore 中,日志服务的查询接口(GetHistograms 和 GetLogs)能够查到该日志的延时因写入日志类型不同而异。日志服务按日志时间戳把日志分为如下两类: /// <list type="bullet"> /// <item><description>实时数据:日志中时间点为服务器当前时间点 (-180秒,900秒]。例如,日志时间为 UTC 2014-09-25 12:03:00,服务器收到时为 UTC 2014-09-25 12:05:00,则该日志被作为实时数据处理,一般出现在正常场景下。</description></item> /// <item><description>历史数据:日志中时间点为服务器当前时间点 [-7 x 86400秒, -180秒)。例如,日志时间为 UTC 2014-09-25 12:00:00,服务器收到时为 UTC 2014-09-25 12:05:00,则该日志被作为历史数据处理,一般出现在补数据场景下。</description></item> /// </list> /// /// 其中,实时数据写入至可查询的最大延时为3秒(99.9%情况下1秒内即可查询)。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstorename">需要查询日志的 Logstore 名称。</param> /// <param name="from">查询开始时间点(精度为秒,从 1970-1-1 00:00:00 UTC 计算起的秒数)。</param> /// <param name="to">查询结束时间点(精度为秒,从 1970-1-1 00:00:00 UTC 计算起的秒数)。</param> /// <param name="topic">查询日志主题。</param> /// <param name="query">查询表达式。关于查询表达式的详细语法,请参考 查询语法。</param> /// <param name="line">请求返回的最大日志条数。取值范围为 0~100,默认值为 100。</param> /// <param name="offset">请求返回日志的起始点。取值范围为 0 或正整数,默认值为 0。</param> /// <param name="reverse">是否按日志时间戳逆序返回日志。true 表示逆序,false 表示顺序,默认值为 false。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.GetLogsAsync"/> public static Task <IResponse <GetLogsResult> > GetLogsAsync(this ILogServiceClient client, String logstorename, DateTimeOffset from, DateTimeOffset to, String topic = null, String query = null, Int32 line = GetLogsRequest.DefaultLine, Int32 offset = GetLogsRequest.DefaultOffset, Boolean reverse = GetLogsRequest.DefaultReverse, String project = null) => client.GetLogsAsync(new GetLogsRequest(logstorename, (Int32)from.ToUnixTimeSeconds(), (Int32)to.ToUnixTimeSeconds()) { Topic = topic, Query = query, Line = line, Offset = offset, Reverse = reverse, ProjectName = project });
/// <summary> /// 使用同步阻塞方式获取结果。 /// </summary> public static GetLogsResult InvokeSynchronously(ILogServiceClient client) { var asyncTask = client.GetLogsAsync ( // 「必填参数」作为方法的普通必须参数 "example-logstore", DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow, // 「可选参数」作为方法的可选参数,可通过命名参数方式指定 offset: 1, line: 10 ); #if ASPNET || WINFORM // NOTE: // 需要注意的是,在 WinForm/ASP.NET 环境中,由于设置了 SynchronizationContext , // 所有异步后续操作(Continuation)都会被回传到调用线程上执行,此时不能直接阻塞请求,否则会造成当前线程无限等待。 // See: http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html // 在上述环境中,需要使用同步调用,必须在另一线程中等待异步任务的结果。 var waitTask = Task.Run(() => asyncTask.Result); var response = waitTask.Result; #else // 在普通控制台的环境下同步等待结果直接调用即可。 var response = asyncTask.Result; #endif var result = response // 此方法会确保返回的响应失败时候抛出`LogServiceException`。 .EnsureSuccess() // 此处获取Result是安全的。 .Result; Console.WriteLine($"RequestId:{response.RequestId}"); Console.WriteLine($"日志总数:{result.Count}"); Console.WriteLine($"首条日志:{result.Logs.FirstOrDefault()}"); return(result); }