/// <summary> /// 合并两个相邻的 readwrite 状态的 Shards。在参数中指定一个 shardid,服务端自动找相邻的下一个 Shard。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称</param> /// <param name="shardId">Shard ID</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.MergeShardsAsync"/> public static Task <IResponse <IList <ShardInfo> > > MergeShardsAsync(this ILogServiceClient client, String logstoreName, Int32 shardId, String project = null) => client.MergeShardsAsync(new MergeShardRequest(logstoreName, shardId) { ProjectName = project });
/// <summary> /// 根据时间获得游标(cursor)。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称</param> /// <param name="shardId">Shard ID</param> /// <param name="from">时间点(UNIX下秒数),或 begin,end</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.GetCursorAsync"/> public static Task <IResponse <GetCursorResult> > GetCursorAsync(this ILogServiceClient client, String logstoreName, Int32 shardId, String from, String project = null) => client.GetCursorAsync(new GetCursorRequest(logstoreName, shardId, from) { ProjectName = project });
/// <summary> /// 列出 Logstore 下当前所有可用 Shard。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.ListShardsAsync"/> public static Task <IResponse <IList <ShardInfo> > > ListShardsAsync(this ILogServiceClient client, String logstoreName, String project = null) => client.ListShardsAsync(new ListShardRequest(logstoreName) { ProjectName = project });
/// <summary> /// 分裂一个指定的 readwrite 状态的 Shard。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称</param> /// <param name="shardId">Shard ID</param> /// <param name="splitKey">split 切分位置</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.SplitShardAsync"/> public static Task <IResponse <IList <ShardInfo> > > SplitShardAsync(this ILogServiceClient client, String logstoreName, Int32 shardId, String splitKey, String project = null) => client.SplitShardAsync(new SplitShardRequest(logstoreName, shardId, splitKey) { ProjectName = project });
/// <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); });
public AliyunLogger(string name, AliyunLoggerConfiguration config) { lock (_tmrLock) { if (null == _client) { var client = LogServiceClientBuilders.HttpBuilder // 服务入口<endpoint>及项目名<projectName>。 .Endpoint($"{config.Project_name}.{config.Region_endpoint}", config.Project_name) // 访问密钥信息。 .Credential(config.AccessKeyId, config.AccessKeySecret) // 设置每次请求超时时间。 .RequestTimeout(1000) .Build(); _name = name; _config = config; _client = client; tmr = new System.Timers.Timer(config.MaxDelaySecends * 1000); tmr.Elapsed += Tmr_Elapsed; tmr.Start(); } } }
/// <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> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称,同一 Project 下唯一。</param> /// <param name="shipperName">日志投递规则名称,同一 Logstore 下唯一。</param> /// <param name="taskIds">需要重试的任务ID。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.RetryShipperTaskAsync"/> public static Task <IResponse> RetryShipperTaskAsync(this ILogServiceClient client, String logstoreName, String shipperName, IEnumerable <String> taskIds, String project = null) => client.RetryShipperTaskAsync(new RetryShipperRequest(logstoreName, shipperName, taskIds) { ProjectName = project });
/// <summary> /// 从机器组中删除配置。 /// </summary> /// <param name="client">client实例。</param> /// <param name="groupName">机器分组名称。</param> /// <param name="configName">日志配置名称。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.RemoveConfigFromMachineGroupAsync"/> public static Task <IResponse> RemoveConfigFromMachineGroupAsync(this ILogServiceClient client, String groupName, String configName, String project = null) => client.RemoveConfigFromMachineGroupAsync(new RemoveConfigFromMachineGroupRequest(groupName, configName) { ProjectName = project });
public AliyunLogger(string categoryName, AliyunLoggerConfiguration config, ILoggerProvider Provider) { this.Provider = Provider; if (categoryName == null) { throw new NotImplementedException("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); } lock (_tmrLock) { if (null == _client) { var client = LogServiceClientBuilders.HttpBuilder // 服务入口<endpoint>及项目名<projectName>。 .Endpoint($"{config.Project_name}.{config.Region_endpoint}", config.Project_name) // 访问密钥信息。 .Credential(config.AccessKeyId, config.AccessKeySecret) // 设置每次请求超时时间。 .RequestTimeout(1000) .Build(); this.categoryName = categoryName.Clone() as string; _config = config; _client = client; tmr = new System.Timers.Timer(config.MaxDelaySecends * 1000); tmr.Elapsed += Tmr_Elapsed; tmr.Start(); } } }
/// <summary> /// 统计Project下所有日志。 /// <list type="bullet"> /// <item><description>该接口的query是一个标准的SQL查询语句。</description></item> /// <item><description>查询的Project,在请求的域名中指定。</description></item> /// <item><description>查询的logstore,在查询语句的from条件中指定。logstore相当于SQL中的表。</description></item> /// <item><description>在查询的SQL条件中,必须指定要查询的时间范围,时间范围由__date__(timestamp类型)来指定,或__time__(int 类型,单位是unix_time)来指定。</description></item> /// <item><description>如上所述,该接口一次调用必须要在限定时间内返回结果,每次查询只能扫描指定条数的日志量。如果一次请求需要处理的数据量非常大的时候,该请求会返回不完整的结果(并在返回结果中的 x-log-progress 成员标示是否完整)。如此同时,服务端会缓存 15 分钟内的查询结果。当查询请求的结果有部分被缓存命中,则服务端会在这次请求中继续扫描未被缓存命中的日志数据。为了减少您合并多次查询结果的工作量,服务端会把缓存命中的查询结果与本次查询新命中的结果合并返回给您。因此,日志服务可以让您通过以相同参数反复调用该接口来获取最终完整结果。因为您的查询涉及的日志数据量变化非常大,日志服务 API 无法预测需要调用多少次该接口而获取完整结果。所以需要用户通过检查每次请求的返回结果中的x-log-progress成员状态值来确定是否需要继续。需要注意的是,每次重复调用该接口都会重新消耗相同数量的查询 CU。</description></item> /// </list> /// </summary> /// <param name="client">client实例。</param> /// <param name="query">查询sql条件。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.GetProjectLogsAsync"/> public static Task <IResponse <GetLogsResult> > GetProjectLogsAsync(this ILogServiceClient client, String query, String project = null) => client.GetProjectLogsAsync(new GetProjectLogsRequest(query) { ProjectName = project });
/// <summary> /// 更新配置内容,如果配置被应用到机器组,对应机器也会同时更新。 /// </summary> /// <param name="client">client实例。</param> /// <param name="configName">日志配置名称, Project 下唯一。</param> /// <param name="inputType">输入类型,现在只支持 file。</param> /// <param name="inputDetail">输入详情。</param> /// <param name="outputType">输出类型,现在只支持 LogService。</param> /// <param name="outputDetail">输出详情。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.UpdateConfigAsync"/> public static Task <IResponse> UpdateConfigAsync(this ILogServiceClient client, String configName, String inputType, ConfigInputDetailInfo inputDetail, String outputType, ConfigOutputDetailInfo outputDetail, String project = null) => client.UpdateConfigAsync(new UpdateConfigRequest(configName, inputType, inputDetail, outputType, outputDetail) { ProjectName = project });
/// <summary> /// 处理以异常形式抛出的错误。 /// </summary> public static async Task <GetLogsResult> InvokeWithExceptionHandling(ILogServiceClient client) { try { return(await Invoke(client)); } catch (LogServiceException e) { // 错误码 var errorCode = e.ErrorCode; // 错误消息 var errorMessage = e.ErrorMessage; Console.WriteLine($"RequestId:{e.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("这里可以是系统的业务异常。", e /* 在自定义的异常中最好带上服务返回的异常以便调试 */); } }
/// <summary> /// 创建新的客户端 /// </summary> internal static void ReConfig() { var config = LogConfigLoader.CurrentValue.Aliyun; if (_options == null || _options.Endpoint != config.Endpoint || _options.ProjectName != config.ProjectName || _options.AccessKeyId != config.AccessKeyId || _options.AccessKeySecret != config.AccessKeySecret) { if (!string.IsNullOrWhiteSpace(config.Endpoint) && !string.IsNullOrWhiteSpace(config.ProjectName) && !string.IsNullOrWhiteSpace(config.AccessKeyId) && !string.IsNullOrWhiteSpace(config.AccessKeySecret)) { Client = LogServiceClientBuilders.HttpBuilder .Endpoint(config.Endpoint, config.ProjectName) .UseProxy(config.UseProxy) .Credential(config.AccessKeyId, config.AccessKeySecret) .Build(); } else { Client = null; } } _options = config; }
/// <summary> /// /// </summary> /// <param name="sinkConfiguration">Logger sink configuration.</param> /// <param name="logServiceClient"></param> /// <param name="formatter">Text formatter used by sink.</param> /// <param name="logstoreName">Logstore 的名称</param> /// <param name="project">Project 名称</param> /// <param name="source">日志的来源地,例如产生该日志机器的IP地址。</param> /// <param name="topic">用户自定义字段,用以标记一批日志。例如访问日志可根据不同站点进行标记。</param> /// <param name="logTags">日志的标签</param> /// <param name="restrictedToMinimumLevel">The minimum level for /// events passed through the sink. Ignored when <paramref name="levelSwitch"/> is specified.</param> /// <param name="levelSwitch">A switch allowing the pass-through minimum level /// to be changed at runtime.</param> /// <returns>Configuration object allowing method chaining.</returns> public static LoggerConfiguration AliyunLog( this LoggerSinkConfiguration sinkConfiguration, ILogServiceClient logServiceClient, ITextFormatter formatter, string logstoreName = null, string project = null, string source = null, string topic = null, IDictionary <string, string> logTags = null, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, LoggingLevelSwitch levelSwitch = null) { if (sinkConfiguration == null) { throw new ArgumentNullException(nameof(sinkConfiguration)); } if (logstoreName == null) { throw new ArgumentNullException(nameof(logstoreName)); } if (logServiceClient == null) { throw new ArgumentNullException(nameof(logServiceClient)); } var sink = new AliyunLogSink(logServiceClient, formatter, logstoreName, project, source, topic, logTags); return(sinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch)); }
public static LoggerConfiguration AliyunLog( this LoggerSinkConfiguration sinkConfiguration, ILogServiceClient logServiceClient, string logstoreName = null, string project = null, string source = null, string topic = null, IDictionary <string, string> logTags = null, LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum, string outputTemplate = DefaultOutputTemplate, IFormatProvider formatProvider = null, LoggingLevelSwitch levelSwitch = null) { if (sinkConfiguration == null) { throw new ArgumentNullException(nameof(sinkConfiguration)); } if (logstoreName == null) { throw new ArgumentNullException(nameof(logstoreName)); } if (logServiceClient == null) { throw new ArgumentNullException(nameof(logServiceClient)); } return(sinkConfiguration.AliyunLog(logServiceClient, null, logstoreName, project, source, topic, logTags, restrictedToMinimumLevel, levelSwitch)); }
/// <summary> /// 根据游标、数量获得日志。获得日志时必须指定 shard。 /// 如果在 storm 等情况下可以通过 LoghubClientLib 进行选举与协同消费。 /// 目前仅支持读取 PB 格式 LogGroupList 数据。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称</param> /// <param name="shardId">Shard ID</param> /// <param name="cursor">游标,用以表示从什么位置开始读取数据,相当于起点。</param> /// <param name="count">返回的 loggroup 数目,范围为 0~1000。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.PullLogsAsync"/> public static Task <IResponse <PullLogsResult> > PullLogsAsync(this ILogServiceClient client, String logstoreName, Int32 shardId, String cursor, Int32 count, String project = null) => client.PullLogsAsync(new PullLogsRequest(logstoreName, shardId, cursor, count) { ProjectName = project });
public static async Task <IEnumerable <LogInfo> > PullLogs(ILogServiceClient client) { // 获取ShardId var listShardsResponse = await client.ListShardsAsync(LogStoreName); var listShardsResult = listShardsResponse.EnsureSuccess().Result; var shardId = listShardsResult.First().ShardId; // 获取游标 var getCursorRsponse = await client.GetCursorAsync(LogStoreName, shardId, "begin"); var getCursorResult = getCursorRsponse.EnsureSuccess().Result; var cursor = getCursorResult.Cursor; // 在指定分片(shard)上从游标(cursor)开始位置获取100条日志 var response = await client.PullLogsAsync(LogStoreName, shardId, cursor, 100); var result = response.EnsureSuccess().Result; // 获取Header上的下一条游标(cursor)位置 var nextCursor = response.GetLogCursor(); return(result.LogGroups .SelectMany(x => x.Logs)); }
/// <summary> /// 查看具体的 MachineGroup 信息。 /// </summary> /// <param name="client">client实例。</param> /// <param name="groupName">机器分组名称。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.GetMachineGroupAsync"/> public static Task <IResponse <GetMachineGroupResult> > GetMachineGroupAsync(this ILogServiceClient client, String groupName, String project = null) => client.GetMachineGroupAsync(new GetMachineGroupRequest(groupName) { ProjectName = project });
/// <summary> /// 获得一个配置的详细信息。 /// </summary> /// <param name="client">client实例。</param> /// <param name="configName">日志配置名称。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.GetConfigAsync"/> public static Task <IResponse <GetConfigResult> > GetConfigAsync(this ILogServiceClient client, String configName, String project = null) => client.GetConfigAsync(new GetConfigRequest(configName) { ProjectName = project });
/// <summary> /// 删除特定 config,如果 config 已被 应用到机器组,则 Logtail 配置也会被删除。 /// </summary> /// <param name="client">client实例。</param> /// <param name="configName">日志配置名称。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.DeleteConfigAsync"/> public static Task <IResponse> DeleteConfigAsync(this ILogServiceClient client, String configName, String project = null) => client.DeleteConfigAsync(new DeleteConfigRequest(configName) { ProjectName = project });
/// <summary> /// 删除 Logstore,包括所有 Shard 数据,以及索引等。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">Logstore 的名称,在 Project 下必须唯一。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.DeleteLogStoreAsync"/> public static Task <IResponse> DeleteLogStoreAsync(this ILogServiceClient client, String logstoreName, String project = null) => client.DeleteLogStoreAsync(new DeleteLogStoreRequest(logstoreName) { ProjectName = project });
/// <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); }
public void Prepare() { this.client = LogServiceClientBuilders.HttpBuilder .Endpoint("cn-shenzhen.log.aliyuncs.com", "dotnet-sdk-sz") .Credential("<secret>", "<secret>") .Build(); var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); this.logstoreName = $"logstore-dotnet-sdk-test-{timestamp}"; // Create logstore for benchmark this.client.CreateLogStoreAsync(this.logstoreName, 1, 1).Result.EnsureSuccess(); Console.WriteLine($"// LogStore {this.logstoreName} created."); // Wait logstore prepared this.WaitLogStorePrepared().Wait(); // Prepare data var logLines = this.SizeK * 1024 / (10 * LogContentSize) + 1; this.logGroup = new LogGroupInfo { Topic = "PressureTest", Source = "PressureTest", LogTags = { { "Tag1", "Value1" },
/// <summary> /// 更新 Logstore 的属性。目前只支持更新 TTL和shard 属性。 /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">Logstore 的名称,在 Project 下必须唯一。</param> /// <param name="ttl">数据的保存时间,单位为天,范围1~365(额外需求请提交工单)。</param> /// <param name="shardCount">该 Logstore 的 Shard 数量,单位为个,范围为 1~10。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.UpdateLogStoreAsync"/> public static Task <IResponse> UpdateLogStoreAsync(this ILogServiceClient client, String logstoreName, Int32 ttl, Int32 shardCount, String project = null) => client.UpdateLogStoreAsync(new UpdateLogStoreRequest(logstoreName, ttl, shardCount) { ProjectName = project });
/// <summary> /// 获取指定区域Project列表。 /// </summary> /// <param name="client">client实例。</param> /// <param name="projectName">用于过滤返回结果的project名称(支持部分匹配)。</param> /// <param name="offset">请求结果的起始位置,默认为0。</param> /// <param name="size">每次请求返回结果最大数量,默认500(最大值)。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.ListProjectAsync"/> public static Task <IResponse <ListProjectResult> > ListProjectAsync(this ILogServiceClient client, String projectName = "", Int32 offset = ListProjectRequest.DefaultOffset, Int32 size = ListProjectRequest.DefaultSize) => client.ListProjectAsync(new ListProjectRequest { ProjectName = projectName, Offset = offset, Size = size });
/// <summary> /// 列出 Project 下所有配置信息,可以通过参数进行翻页。 /// </summary> /// <param name="client">client实例。</param> /// <param name="offset">返回记录的起始位置,默认为 0。</param> /// <param name="size">每页返回最大条目,默认 500(最大值)。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.ListConfigAsync"/> public static Task <IResponse <ListConfigResult> > ListConfigAsync(this ILogServiceClient client, Int32 offset = ListConfigRequest.DefaultOffset, Int32 size = ListConfigRequest.DefaultSize, String project = null) => client.ListConfigAsync(new ListConfigRequest { Offset = offset, Size = size, ProjectName = project });
/// <summary> /// 向指定的 LogStore 写入日志数据。目前仅支持写入 PB 格式的 <see cref="LogGroupInfo"/> 日志数据。写入时有两种模式: /// <list type="bullet"> /// <item> /// <description>负载均衡模式(LoadBalance): 自动根据 Logstore 下所有可写的 shard 进行负载均衡写入。该方法对写入可用性较高(SLA: 99.95%),适合写入与消费数据与 shard 无关的场景,例如不保序。</description> /// </item> /// <item> /// <description>根据 Key 路由 shard 模式(KeyHash):写入时需要传递一个 Key,服务端自动根据 Key 选择当前符合该 Key 区间的 Shard 写入。例如,可以将某个生产者(例如 instance)根据名称 Hash 到固定 Shard 上,这样就能保证写入与消费在该 Shard 上是严格有序的(在 Merge/Split 过程中能够严格保证对于 Key 在一个时间点只会出现在一个 Shard 上,参见 <see cref="http://help.aliyun.com/document_detail/28976.html">shard 数据模型</see>)。</description> /// </item> /// </list> /// </summary> /// <param name="client">client实例。</param> /// <param name="logstoreName">日志库名称。</param> /// <param name="logGroup">一组日志。</param> /// <param name="hashKey">(可选)标记日志应该路由到哪个 shard 的标记。</param> /// <param name="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.PostLogStoreLogsAsync"/> public static Task <IResponse> PostLogStoreLogsAsync(this ILogServiceClient client, String logstoreName, LogGroupInfo logGroup, String hashKey = null, String project = null) => client.PostLogStoreLogsAsync(new PostLogsRequest(logstoreName, logGroup) { HashKey = hashKey, ProjectName = project });
/// <summary> /// GetHistograms 接口查询指定的 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秒。 /// </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="project">项目名,此参数将覆盖 client 中默认设置。</param> /// <returns>异步响应结果。</returns> /// <seealso cref="ILogServiceClient.GetHistogramsAsync"/> public static Task <IResponse <GetLogHistogramsResult> > GetHistogramsAsync(this ILogServiceClient client, String logstorename, DateTimeOffset from, DateTimeOffset to, String topic = null, String query = null, String project = null) => client.GetHistogramsAsync(new GetLogHistogramsRequest(logstorename, (Int32)from.ToUnixTimeSeconds(), (Int32)to.ToUnixTimeSeconds()) { Topic = topic, Query = query, ProjectName = project });
public QueueLoggerProvider(ILogQueue logQueue, ILogServiceClient logServiceClient, LogOptions options) { _logQueue = logQueue; _logServiceClient = logServiceClient; _options = options; _filter = (category, logLevel) => logLevel >= options.MinLevel && category.StartsWith(""); _cancellationTokenSource = new CancellationTokenSource(); _logHandlerTask = Task.Factory.StartNew(ProcessLogQueue, null, TaskCreationOptions.LongRunning); }