精通日志查询: 如何翻页获取日志和计算结果

本文涉及的产品
对象存储 OSS,20GB 3个月
阿里云盘企业版 CDE,企业版用户数5人 500GB空间
日志服务 SLS,月写入数据量 50GB 1个月
简介: 精通日志查询: 如何翻页获取日志和计算结果 日志服务提供一站式的日志采集、存储、查询、计算功能。交互式的日志采集体验,释放用户的运维压力,解放用户的双手; 交互式的查询分析体验,让用户自由的构建数据模型、探索式分析挖掘数据深层。

精通日志查询: 如何翻页获取日志和计算结果

日志服务提供一站式的日志采集、存储、查询、计算功能。交互式的日志采集体验,释放用户的运维压力,解放用户的双手; 交互式的查询分析体验,让用户自由的构建数据模型、探索式分析挖掘数据深层。

image.png

用户使用日志服务的查询分析能力,不仅可以在控制台交互式查询,也可以使用SDK,在程序中使用查询分析。 当计算结果比较大时,怎么把全量结果读取到本地,是一个比较比较头疼的问题。幸好,日志服务提供了翻页的功能,不仅可以翻页读取原始日志内容,也可以把SQL的计算结果翻页读取到本地。开发者可以通过日志服务提供的SDK,或者Cli,通过读数据接口翻页读取日志。

查询和分析使用不同的分页方式

image.png

日志服务提供一个统一的查询日志入口:GetLogstoreLogs,既可以根据关键字查询日志原始内容,也可以提交SQL计算,获取计算结果。

查询翻页使用案例

在GetLogStoreLogs api中,包含offset和lines两个参数

  • offset : 用于指定从第一行开始读取日志
  • lines : 用于指定当前的请求读取多少行,该参数最大100行,如果设置该参数大于100行,则仍然返回100行。

在翻页读取时,不停的增大offset,知道读取到某个offset后,获取的结果行数为0,并且结果的progress为complete状态,则认为读取到了全部数据,可以结束了。

翻页代码样例

翻页的伪代码:

offset = 0                           // 从第0行开始读取
lines = 100                          //每次读取100行
query = "status:200"                 //查询status字段包含200的所有日志
while True:
     response = get_logstore_logs(query, offset, lines) // 执行读取请求
     process (response)                                 //调用自定义逻辑,处理返回的结果
     如果 response.get_count() == 0 && response.is_complete()   
         则读取结束,跳出当前循环
     否则
        offset += 100                           offset增加100,读取下一个100行

python 翻页读取样例

更详细案例参考文档

    endpoint = ''       # 选择与上面步骤创建Project所属区域匹配的Endpoint
    accessKeyId = ''    # 使用您的阿里云访问密钥AccessKeyId
    accessKey = ''      # 使用您的阿里云访问密钥AccessKeySecret
    project = ''        # 上面步骤创建的项目名称
    logstore = ''       # 上面步骤创建的日志库名称
    client = LogClient(endpoint, accessKeyId, accessKey)
    topic = ""
    query = "index"
    From = int(time.time()) - 600
    To = int(time.time())
    log_line = 100
    offset = 0
    while True:
        res4 = None
        for retry_time in range(0, 3):
            req4 = GetLogsRequest(project, logstore, From, To, topic, query, log_line, offset, False)
            res4 = client.get_logs(req4)
            if res4 is not None and res4.is_completed():
                break
            time.sleep(1)
        offset += 100
        if res4.is_completed() && res4.get_count() == 0:
              break;
        if res4 is not None:
            res4.log_print()  # 这里处理结果

Java 翻页读取样例

更详细的案例参考文档

        int log_offset = 0;
        int log_line = 100;//log_line 最大值为100,每次获取100行数据。若需要读取更多数据,请使用offset翻页。offset和lines只对关键字查询有效,若使用SQL查询,则无效。在SQL查询中返回更多数据,请使用limit语法。
        while (true) {
            GetLogsResponse res4 = null;
            // 对于每个 log offset,一次读取 10 行 log,如果读取失败,最多重复读取 3 次。
            for (int retry_time = 0; retry_time < 3; retry_time++) {
                GetLogsRequest req4 = new GetLogsRequest(project, logstore, from, to, topic, query, log_offset,
                        log_line, false);
                res4 = client.GetLogs(req4);

                if (res4 != null && res4.IsCompleted()) {
                    break;
                }
                Thread.sleep(200);
            }
            System.out.println("Read log count:" + String.valueOf(res4.GetCount()));
            log_offset += log_line;
            if (res4.IsCompleted() && res4.GetCount() == 0) {
                        break;
            }

        }

SQL分析结果翻页读取

在SQL分析中,GetLogStoreLogs API 参数中的offset 和lines是无效的,填写。也就是说,如果按照上文翻页读取原始内容的方式,遍历offset翻页,那么每次SQL执行的结果都是一样的。理论上,我们可以在一次调用中,获取全部的计算结果,但是如果结果集太大,可能会产生以下问题:

  • 网络上传输大量数据延时比较高。
  • 客户端的内存要保存大量的结果,供进一步处理。

为了解决SQL翻页的问题,我们提供了标准SQL的limit翻页语法

limit Offset, Line
  • Offset表示从第几行开始读取结果
  • Line表示读取多少行,Line没有大小限制;但是如果一次读取太多,会影响网络延时和客户端的处理。

一个典型案例,假如以下SQL共产生2000条日志

* | select count(1) , url  group by url

那么可以翻页,每次读取500行,共4次读取完成:

* | select count(1) , url  group by url  limit 0, 500
* | select count(1) , url  group by url  limit 500, 500
* | select count(1) , url  group by url  limit 1000, 500
* | select count(1) , url  group by url  limit 1500, 500

SQL翻页样例

在程序中,SQL翻页的伪代码这样写:

offset = 0                           // 从第0行开始读取
lines = 500                          //每次读取500行
query = "* | select count(1) , url  group by url  limit "                
while True:
     real_query = query + offset + "," +  lines
     response = get_logstore_logs(real_query) // 执行读取请求
     process (response)                                 //调用自定义逻辑,处理返回的结果
     如果 response.get_count() == 0   
         则读取结束,跳出当前循环
     否则
        offset += 500                           offset增加100,读取下一个500行

Python程序样例:

    endpoint = ''       # 选择与上面步骤创建Project所属区域匹配的Endpoint
    accessKeyId = ''    # 使用您的阿里云访问密钥AccessKeyId
    accessKey = ''      # 使用您的阿里云访问密钥AccessKeySecret
    project = ''        # 上面步骤创建的项目名称
    logstore = ''       # 上面步骤创建的日志库名称
    client = LogClient(endpoint, accessKeyId, accessKey)
    topic = ""
    origin_query = "* | select count(1) , url  group by url  limit "
    From = int(time.time()) - 600
    To = int(time.time())
    log_line = 100
    offset = 0
    while True:
        res4 = None
        query = origin_query + str(offset) + " , " + str(log_line)
        for retry_time in range(0, 3):
            req4 = GetLogsRequest(project, logstore, From, To, topic, query)
            res4 = client.get_logs(req4)
            if res4 is not None and res4.is_completed():
                break
            time.sleep(1)
        offset += 100
        if res4.is_completed() && res4.get_count() == 0:
              break;
        if res4 is not None:
            res4.log_print()  # 这里处理结果

Java程序样例:

        int log_offset = 0;
        int log_line = 500;
        String origin_query = "* | select count(1) , url  group by url  limit "
        while (true) {
            GetLogsResponse res4 = null;
            // 对于每个 log offset,一次读取 500 行 log,如果读取失败,最多重复读取 3 次。
            query = origin_query + log_offset + "," + log_line;
            for (int retry_time = 0; retry_time < 3; retry_time++) {
                GetLogsRequest req4 = new GetLogsRequest(project, logstore, from, to, topic, query);
                res4 = client.GetLogs(req4);

                if (res4 != null && res4.IsCompleted()) {
                    break;
                }
                Thread.sleep(200);
            }
            System.out.println("Read log count:" + String.valueOf(res4.GetCount()));
            log_offset += log_line;
            if (res4.GetCount() == 0) {
                        break;
            }

        }

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
存储 监控 Serverless
阿里泛日志设计与实践问题之Grafana Loki在日志查询方案中存在哪些设计限制,如何解决
阿里泛日志设计与实践问题之Grafana Loki在日志查询方案中存在哪些设计限制,如何解决
|
4月前
|
SQL 存储 JSON
更快更强,SLS 推出高性能 SPL 日志查询模式
从海量的日志数据中,按照各种灵活的条件进行即时查询搜索,是可观测场景下的基本需求。本文介绍了 SLS 新推出的高性能 SPL 日志查询模式,支持 Unix 风格级联管道式语法,以及各种丰富的 SQL 处理函数。同时通过计算下推、向量化计算等优化,使得 SPL 查询可以在数秒内处理亿级数据,并支持 SPL 过滤结果分布图、随机翻页等特性。
12293 115
|
2月前
|
Web App开发 存储 监控
iLogtail 开源两周年:UC 工程师分享日志查询服务建设实践案例
本文为 iLogtail 开源两周年的实践案例分享,讨论了 iLogtail 作为日志采集工具的优势,包括它在性能上超越 Filebeat 的能力,并通过一系列优化解决了在生产环境中替换 Filebeat 和 Logstash 时遇到的挑战。
134 15
|
6月前
|
SQL 监控 关系型数据库
|
3月前
|
SQL 存储 缓存
高基数 GroupBy 在 SLS SQL 中的查询加速
本文详细介绍了SLS中的高基数GroupBy查询加速技术。
140 20
|
4月前
|
存储 消息中间件 人工智能
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
早期 MiniMax 基于 Grafana Loki 构建了日志系统,在资源消耗、写入性能及系统稳定性上都面临巨大的挑战。为此 MiniMax 开始寻找全新的日志系统方案,并基于阿里云数据库 SelectDB 版内核 Apache Doris 升级了日志系统,新系统已接入 MiniMax 内部所有业务线日志数据,数据规模为 PB 级, 整体可用性达到 99.9% 以上,10 亿级日志数据的检索速度可实现秒级响应。
AI大模型独角兽 MiniMax 基于阿里云数据库 SelectDB 版内核 Apache Doris 升级日志系统,PB 数据秒级查询响应
|
2月前
|
监控 网络协议 CDN
阿里云国际监控查询流量、用量查询流量与日志统计流量有差异?
阿里云国际监控查询流量、用量查询流量与日志统计流量有差异?
|
5月前
|
Shell 测试技术 Linux
Shell 脚本循环遍历日志文件中的值进行求和并计算平均值,最大值和最小值
Shell 脚本循环遍历日志文件中的值进行求和并计算平均值,最大值和最小值
73 3
|
4月前
|
SQL JavaScript 前端开发
【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题
【Azure 应用服务】Azure JS Function 异步方法中执行SQL查询后,Callback函数中日志无法输出问题
|
5月前
|
分布式计算 资源调度 DataWorks
MaxCompute操作报错合集之出现“查询运行日志失败”的报错,一般是什么导致的
MaxCompute是阿里云提供的大规模离线数据处理服务,用于大数据分析、挖掘和报表生成等场景。在使用MaxCompute进行数据处理时,可能会遇到各种操作报错。以下是一些常见的MaxCompute操作报错及其可能的原因与解决措施的合集。

相关产品

  • 日志服务