管理Store

Store是日志服务中日志数据的采集、存储和查询单元。针对不同的数据类型,日志服务提供日志库(Logstore)、时序库(MetricStore)和事件库(EventStore),本文介绍不同Store的基本概念。

日志库(Logstore)

每个Logstore隶属于一个Project,每个Project中可创建多个Logstore。例如您可以创建一个名为app-aProject,并在该Project下创建名为operation_logapplication_logaccess_logLogstore,分别存储App A所涉及的操作日志、应用程序日志和访问日志。

您在执行写入日志、查询和分析日志、加工日志、消费日志、投递日志等操作时,都需要指定Logstore。具体说明如下:

  • Logstore为采集单元,采集日志。

  • Logstore为存储单元,存储日志以及执行加工、消费、投递等操作。

  • Logstore中建立索引,用于查询和分析日志。

日志(Log)格式

文本日志(LogFile)、事件(Event)、数据库日志(BinLog)、时序数据(Metric)等数据都是日志的不同载体。日志服务采用半结构化的数据模式定义一条日志,包含日志主题、日志时间、日志内容、日志来源和日志标签五个数据域。日志服务对各个数据域的格式要求不同,详细说明如下表所示。

数据域

说明

格式

日志主题

日志服务保留字段(__topic__)用于标识日志主题。例如您可以根据日志类型为网站相关日志设置不同的日志主题(access_log、operation_log)。更多信息,请参见日志主题(Topic)

包括空字符串在内的任意字符串,大小为0~128字节。

该字段值为空字符串时,表示未设置日志主题。

日志时间

日志服务保留字段(__time__)用于标识日志时间。更多信息,请参见保留字段

Unix时间戳。

日志内容

日志的具体内容,由一个或多个内容项组成,内容项为Key:Value格式。

您通过Logtail极简模式(单行或多行)采集日志时,Logtail不会对日志内容进行解析。整条原始日志将被上传到content字段中。

Key:Value的详细说明如下:

  • Key为字段名称,需为UTF-8编码字符串(字母、下划线和数字但不以数字开头)。字符串大小为1~128字节。不可使用如下字段。

    • __time__

    • __source__

    • __topic__

    • __partition_time__

    • _extract_others_

    • __extract_others__

  • Value为字段值,可以为任意字符串,大小不超过1 MB。

日志来源

日志服务保留字段(__source__)用于标识日志来源,例如产生日志的服务器IP地址。

任意字符串,大小为0~128字节。

日志标签

日志标签。包括:

  • 自定义标签:通过PutLogs接口,在写入日志时添加标签。

  • 系统标签:日志服务为日志添加的标签,包括__client_ip____receive_time__

字典格式,KeyValue均为字符串类型。在日志中以__tag__:为前缀进行展示。

日志主题(Topic

Topic可用于区分不同服务、用户或实例产生的日志。例如,系统A包含前端HTTP请求处理、缓存、逻辑处理、存储等模块时,可分别为其日志设置Topic(如http_module、cache_module、logic_module、store_module)。日志采集至同一Logstore后,可通过Topic快速区分来源。日志主题(Topic)需在采集配置全局配置中设置。

如果不需要区分Logstore中的日志,则在采集日志时设置Topic空-不生成Topic即可。空字符串是一个有效的Topic,即Topic的值为空字符串。

Logstore、Topic、Shard之间的关系如下:

image

日志组(LogGroup)

日志组(LogGroup)是一组日志的集合,是写入与读取日志的基本单元。一个日志组中的数据包含相同Meta(IP地址、Source等信息)。写入日志到日志服务或从日志服务读取日志时,多条日志被打包为一个日志组,以日志组为单元进行写入与读取。该方式可减少读写次数,提高业务效率。每个日志组最大长度为5 MB。

日志服务的基本数据模型请参见Logstore数据模型

日志组

示例

以下以一条网站访问日志为例,说明原始日志与日志服务中数据模型的映射关系。

  • 原始日志

    127.0.0.1 - - [01/Mar/2021:12:36:49  0800] "GET /index.html HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
  • 通过极简模式采集到日志服务后的日志

    整条原始日志将被上传到content字段中。

    日志样例

  • 通过完整正则模式采集到日志服务后的日志

    Logtail将日志内容结构化,即根据您所设置的正则表达式将日志内容提取为多个键值对。

    日志样例

时序库(MetricStore)

每个MetricStore隶属于一个Project,每个Project中可创建多个MetricStore。例如您可以创建一个名为demo-monitorProject,然后在该Project下创建名为host-metricscloud-service-metricsapp-metricsMetricStore,用于分类存储基础主机监控数据、云服务监控数据和业务应用监控数据。

您在执行写入、查询和分析、消费时序数据时,都需要指定MetricStore。具体说明如下:

  • MetricStore为采集单元,采集时序数据。

  • MetricStore为存储单元,存储时序数据以及执行消费操作。

  • 查询和分析时序数据,支持PromQL语法、SQL92语法和SQL+PromQL语法。

时序数据(Metric)

时序数据由时序标识和数据点组成,相同时序标识的数据组成时间线。

image

时序标识

每条时间线都有一个唯一的时序标识,由Metric nameLabels组成。

  • Metric name是一个字符串类型的标识符,用于标识指标类型。Metric name需遵循正则表达式[a-zA-Z_:][a-zA-Z0-9_:]* 。例如http_request_total表示接收到的HTTP请求的总数。

  • Labels由一组组键值对组成,各组键值对之间使用竖线(|)分割,用于标识指标的相关属性。Key需遵循正则表达式 [a-zA-Z_][a-zA-Z0-9_]* ,Value不能包含竖线( | ),其它不做限制。例如methodPOSTURL/api/v1/get

数据点

数据点代表时间线在具体某个时间点的值,每个数据点由时间戳和值组成。其中时间戳精度为纳秒,值的类型为double。

数据结构

日志服务的时序数据类型遵循Prometheus定义规范,在时序库中所有的数据都按照时序类型存储。时序数据的写入协议和日志写入协议一致,使用Protobuf数据编码方式。时序标识和数据点都在content字段中,具体表示方式如下所示。

字段

说明

示例

__name__

Metric名称。

nginx_ingress_controller_response_size

__labels__

Label信息,格式为{key}#$#{value}|{key}#$#{value}|{key}#$#{value}

说明
  • LabelKey需按照字母顺序进行排序。

  • 建议不要写入Value为空字符串的Label。例如Label信息为app#$#|controller_class#$#nginx,则不建议将KeyappLabel写入时序库,可能造成PromQL聚合计算报错。

app#$#ingress-nginx|controller_class#$#nginx|controller_namespace#$#kube-system|controller_pod#$#nginx-ingress-controller-589877c6b7-hw9cj

__time_nano__

时间戳,单位为纳秒。

1585727297293000000

__value__

值。

36.0

示例

查询process_resident_memory_bytes指标在指定时间区间内的所有原始时序数据。

* | select * from "sls-mall-k8s-metrics.prom" where __name__ = 'process_resident_memory_bytes' limit all

image

事件库(EventStore)

每个EventStore隶属于一个Project,每个Project中可创建多个EventStore。您可以根据实际需求为某个项目创建多个EventStore,一般是为不同类型的事件数据创建不同的EventStore。例如您可以根据基础设施异常事件、业务应用事件、自定义事件等进行分类,通过不同的EventStore来进行存储和分析。

您在执行写入、查询和分析、消费事件数据时,都需要指定EventStore。具体说明如下:

  • EventStore为采集单元,采集事件数据。

  • EventStore为存储单元,存储事件数据以及执行消费操作。

事件数据(Event)格式

日志服务的事件数据遵循CloudEvents协议规范,具体说明如下表所示。

字段类型

字段名

是否必选

数据格式

说明

协议字段

specversion

String

根据CloudEvents协议规范,默认使用1.0

id

String

事件ID,您可以根据source+id来区分事件的唯一性。

source

String

通常用来标识事件发生的上下文信息,例如事件来源、发布事件的实例等。

type

String

事件类型,例如sls.alert

subject

String

事件主题,是对source字段的补充,例如用于描述实际触发事件的对象。

datacontenttype

String

事件类型,默认取值为application/cloudevents+json

dataschema

URI

data字段需要遵循的Schema,默认为空。

data

JSON

具体的事件内容。不同来源和类型的事件格式会有差异。

time

Timestamp

事件时间,具体格式,请参见RFC 3339。例如2022-10-17T11:20:45.984+0800

扩展字段

title

String

事件标题。

message

String

事件描述。

status

String

事件状态。取值:

  • ok

  • info

  • warning

  • error

示例

例如一个告警事件,示例数据如下:

{
    "specversion": "1.0",
    "id": "af****6c",
    "source": "acs:sls",
    "type": "sls.alert",
    "subject": "https://sls.console.aliyun.com/lognext/project/demo-alert-chengdu/logsearch/nginx-access-log?encode=base64&endTime=1684312259&queryString=c3RhdHVzID49IDQwMCB8IHNlbGVjdCByZXF1ZXN0X21ldGhvZCwgY291bnQoKikgYXMgY250IGdyb3VwIGJ5IHJlcXVlc3RfbWV0aG9kIA%3D%3D&queryTimeType=99&startTime=1684311959",
    "datacontenttype": "application/cloudevents+json",
    "data": {
        "aliuid": "16****50",
        "region": "cn-chengdu",
        "project": "demo-alert-chengdu",
        "alert_id": "alert-16****96-247190",
        "alert_name": "Nginx访问错误",
        "alert_instance_id": "77****e4-1aad9f7",
        "alert_type": "sls_alert",
        "next_eval_interval": 300,
        "fire_time": 1684299959,
        "alert_time": 1684312259,
        "resolve_time": 0,
        "status": "firing",
        "severity": 10,
        "labels": {
            "request_method": "GET"
        },
        "annotations": {
            "__count__": "1",
            "cnt": "49",
            "desc": "Nginx最近五分钟内GET请求错误49次",
            "title": "Nginx访问错误告警触发"
        },
        "results": [
            {
                "region": "cn-chengdu",
                "project": "demo-alert-chengdu",
                "store": "nginx-access-log",
                "store_type": "log",
                "role_arn": "",
                "query": "status >= 400 | select request_method, count(*) as cnt group by request_method ",
                "start_time": 1684311959,
                "end_time": 1684312259,
                "fire_result": {
                    "cnt": "49",
                    "request_method": "GET"
                },
                "raw_results": [
                    {
                        "cnt": "49",
                        "request_method": "GET"
                    },
                    {
                        "cnt": "3",
                        "request_method": "DELETE"
                    },
                    {
                        "cnt": "7",
                        "request_method": "POST"
                    },
                    {
                        "cnt": "6",
                        "request_method": "PUT"
                    }
                ],
                "raw_result_count": 4,
                "truncated": false,
                "dashboard_id": "",
                "chart_title": "",
                "is_complete": true,
                "power_sql_mode": "auto"
            }
        ],
        "fire_results": [
            {
                "cnt": "49",
                "request_method": "GET"
            }
        ],
        "fire_results_count": 1,
        "condition": "Count:[1] > 0; Condition:[49] > 20",
        "raw_condition": "Count:__count__ > 0; Condition:cnt > 20"
    },
    "time": "2023-05-17T08:30:59Z",
    "title": "Nginx访问错误告警触发",
    "message": "Nginx最近五分钟内GET请求错误49次",
    "status": "error"
}