# cloudevents

## 1 CloudEvents 规范

ST2 的 sensor 和 rule 之间之所以需要使用 trigger 关联，就是因为 sensor 产生的事件没有一个规范。

```
当然这也和 ST2 的设计有关，ST2 会从多个监控系统、平台感知事件，各个平台的事件的定义是有  diff 的，要么是在 sensor 侧做统一，要么是通过一种方式进行管理（即 trigger）。
```

制定一个特定的规范后，sensor 产生的事件就可以直接被 rule 识别，rule 处理的是个通用的事件

这个事件规范，也就是 [cloudevents](https://github.com/cloudevents/spec)

## 2 什么是 CloudEvents

CloudEvents 是一种规范，用于以通用格式描述事件数据，以提供跨服务、平台和系统的交互能力。 事件格式指定了如何使用某些编码格式来序列化 CloudEvent。支持这些编码的兼容 CloudEvents 实现必须遵循在相应的事件格式中指定的编码规则。所有实现都必须支持 JSON 格式。

## 3 协议规范

### 3.1 命名规范

CloudEvents 属性名称必须由 ASCII 字符集的小写字母（“a”到“z”）或数字（“0”到“9”）组成，并且必须以小写字母开头。属性名称应具有描述性和简洁性，长度不应超过20个字符。

### 3.2 术语定义

本规范定义如下术语：

> * Occurrence： “Occurrence”是指在软件系统运行期间捕获描述信息。
> * Event： "Event" 是表示事件及其上下文的数据记录。
> * Context: Context 表示上下文，元数据将封装在 Context 属性中。应用程序代码可以使用这些信息来标识事件与系统或其他事件之间的关系。
> * Data： 实际事件中有效信息载荷。
> * Message： 事件通过 Message 从数据源传输到目标地址。
> * Protocol： 消息可以通过各种行业标准协议（如http、amqp、mqtt、smtp）、开源协议（如kafka、nats）或平台/供应商特定协议（aws-kineis、azure-event-grid）进行传递。

### 3.3 上下文属性（Context Attributes）

符合本规范的每个 CloudEvent 必须包括根据需要指定的上下文属性，并且可以包括一个或多个可选的上下文属性。

> 参考示例：

```
  specversion: 0.2
  type: dev.knative.k8s.event
  source: /apis/serving.knative.dev/v1alpha1/namespaces/default/routes/sls-cloudevent
  id: 269345ff-7d0a-11e9-b1f1-00163f005e02
  time: 2019-05-23T03:23:36Z
  contenttype: application/json
```

> * type： 【必须】事件类型， 通常此属性用于路由、监控、安全策略等。
> * specversion：【必须】表示CloudEvents 规范的版本。引用 0.2 版本的规范时，事件生产者必须使用 0.2 设置此值。
> * source：【必须】表示事件的产生者, 也就是事件源。
> * id: 【必须】事件的 id
> * time: 【可选】事件的产生时间
> * contenttype：【可选】表示 Data 的数据内容格式

### 3.4 扩展属性（Extension Attributes）

CloudEvents 生产者可以在事件中包含其他上下文属性，这些属性可能用于与事件处理相关的辅助操作。

### 3.5 Data

正如术语Data所定义的，CloudEvents 产生具体事件的内容信息封装在数据属性中。例如，KubernetesEventSource所产生的 CloudEvent 的Data信息如下：

```
data:
  {
    "metadata": {
      "name": "event-display.15a0a2b54007189b",
      "namespace": "default",
      "selfLink": "/api/v1/namespaces/default/events/event-display.15a0a2b54007189b",
      "uid": "9195ff11-7b9b-11e9-b1f1-00163f005e02",
      "resourceVersion": "18070551",
      "creationTimestamp": "2019-05-21T07:39:30Z"
    },
    "involvedObject": {
      "kind": "Route",
      "namespace": "default",
      "name": "event-display",
      "uid": "31c68419-675b-11e9-a087-00163e08f3bc",
      "apiVersion": "serving.knative.dev/v1alpha1",
      "resourceVersion": "9242540"
    },
    "reason": "InternalError",
    "message": "Operation cannot be fulfilled on clusteringresses.networking.internal.knative.dev \"route-31c68419-675b-11e9-a087-00163e08f3bc\": the object has been modified; please apply your changes to the latest version and try again",
    "source": {
      "component": "route-controller"
    },
    "firstTimestamp": "2019-05-21T07:39:30Z",
    "lastTimestamp": "2019-05-26T07:10:51Z",
    "count": 5636,
    "type": "Warning",
    "eventTime": null,
    "reportingComponent": "",
    "reportingInstance": ""
  }
```

## 4 实践

### 4.1 event 生成

```
from xlib.util import cloudevents

event_obj = cloudevents.create(
    reqid,                          # ID
    source,                         # source
    "trigger",                      # type
    data=event_data,                # data
    event_target=target_id,         # 扩展数据
    event_region=config.SERVER_IDC, # 扩展数据
    event_status=event_status,      # 扩展数据
    datacontenttype="application/json"
)
event_json = cloudevents.dumps(event_obj)
```

### 4.2 event 例子

```
{
    "specversion": "1.0",

    "id": "A4E40A56410B14B7_0",                             # ID
    "source": "scs_proxy_load_check",                       # source
    "type": "trigger",                                      # type
    "data": {                                               # data
            "app_info": {
                    "user_id": "xxxxx",
                    "instance_num": 8,
                    "sync_group_id": "",
                    "proxy_num": 16,
                    "user_info": "",
                    "node_type": "pega.g4s1.medium",
                    "groupcloud_user_info": ""
            },
            "is_check_data_changes": "no",
            "net_out_data": {
                    "mean": 45094.69507575757
            },
            "proxy_info": {
                    "proxy_num": 16,
                    "interface_num": 8,
                    "proxy_num_for_base": 16,
                    "proxy_num_in_one_interface": 2,
                    "proxy_num_for_op": 0
            },
            "cpu_usage_data": {
                    "max": 1.5181818225167014,
                    "min": 0.6000000021674416,
                    "cf": 0.2549883537201132,
                    "mean": 0.9692708343888322
            }
    },

    "event_region": "onlinebj",                             # 扩展数据
    "event_target": "scs-bj-xxxxxxx",                       # 扩展数据
    "event_status": "OK",                                   # 扩展数据

    "datacontenttype": "application/json",
    "dataschema": null,
    "subject": null,

    "time": "2025-06-27 10:16:47"
}

```

## 5 库

> * https://github.com/cloudevents/sdk-python (仅支持 Python3)
>   * https://github.com/cloudevents/sdk-python/blob/master/cloudevents/sdk/event/v1.py
> * https://github.com/williamhogman/cloudevents-python (基于 v0.1 ，需要适配)
