stackstorm 17.编写stackstorm的sensor

1 传感器Sensor基础


Sensors:  获取事件发送给StackStorm。Python编写的。
Triggers: 识别即将发送给StackStorm的事件。trigger是一个元组类型和可选的参数。Sensores注册trigger。

传感器组成: python脚本文件和传感器的YAML元数据文件。
传感器元数据文件: 
组成: 
class_name: 类名,
entry_point: 是python脚本文件名称, 
trigger_types: 触发器类型,包含: 触发器名称name, payload_schema: 

2 编写传感器元数据文件


文件名为: count_sensor.yaml
内容如下:

---
  class_name: "CountSensor"
  entry_point: "count_sensor.py"
  description: "Simple polling sensor that emits count number."
  poll_interval: 5
  trigger_types:
    -
      name: "count"
      description: "A count trigger."
      payload_schema:
        type: "object"
        properties:
          count:
            type: "number"
          pythonpath:
            type: "string"
          name:
            type: "string"

分析:
传感器 payload_schema中定义的属性,就是生成的数据,生成的数据是一个字典,
传递给后续 规则使用
polling sensor必须有一个配置项: poll_interval
否则可能导致sensor运行异常

 

3 编写传感器python文件


文件名为: count_sensor.py
内容如下:

from datetime import datetime
import os

from st2reactor.sensor.base import PollingSensor


class CountSensor(PollingSensor):

    def __init__(self, sensor_service, config,
                 poll_interval=5):
        super(CountSensor, self).__init__(
            sensor_service=sensor_service,
            config=config,
            poll_interval=poll_interval
        )
        self.count = None
        self.logger = None

    def setup(self):
        self.count = 1
        self.logger = self.sensor_service.get_logger(name=self.__class__.__name__)

    def poll(self):
        payload = {
            "count": self.count,
            "pythonpath": os.environ.get("PYTHONPATH", None),
            "name": "chao"
          }
        currTime = str(datetime.now())
        info = "############## time: {currTime}, count: {count}, payload: {payload}".format(
            currTime=currTime,
            count=self.count,
            payload=payload,
        )

        self.logger.info(info)

        self.sensor_service.dispatch(trigger="default.count", payload=payload)
        self.count = self.count + 1

    def cleanup(self):
        pass

    def add_trigger(self, trigger):
        # This method is called when trigger is created
        pass

    def update_trigger(self, trigger):
        # This method is called when trigger is updated
        pass

    def remove_trigger(self, trigger):
        # This method is called when trigger is deleted
        pass

 

4 运行传感器


将传感器的Python文件和YAML元数据文件放到自己需要存放的pack的目录
地址如下:
/opt/stackstorm/packs//sensors/
这里放入到:
/opt/stackstorm/packs/default/sensors/目录下

5 注册传感器


执行如下命令:
st2ctl reload --register-sensors

6 编写传感器sensor对应的规则rule


6.1 编写rule


文件名: count_sensor_rule.yaml
内容如下:

---
    name: "count_sensor_rule"
    pack: "default"
    description: "count sensor rule description"
    enabled: true

    trigger:
        type: "default.count"

    criteria:
        trigger.name:
            type: "equals"
            pattern: "chao"

    action:
        ref: default.count_action
        parameters:
            content: "{{ trigger.name }}"

将count_sensor_rule.yaml放在
/opt/stackstorm/packs/default/rules/目录下


6.2 创建rule


执行:
st2 rule create /opt/stackstorm/packs/default/rules/count_sensor_rule.yaml


7 创建rule中对应的action


7.1 编写mistral的元数据文件


文件名为:  multi_task_mistral_meta.yaml
内容如下:

---
name: 'multi_task_mistral'
description: 'multi task mistral description'
enabled: true
runner_type: 'mistral-v2'
entry_point: 'workflows/multi_task_mistral.yaml'
parameters:
  cmd:
    required: true
    type: string
  timeout:
    type: integer
    default: 60

将multi_task_mistral_meta.yaml
放入到/opt/stackstorm/packs/default/actions目录下

7.2 编写mistral的的脚本文件


文件名为: multi_task_mistral.yaml
内容如下:

version: '2.0'
default.multi_task_mistral:
    desctiption: "milti task mistral desctiption"
    type: direct
    input:
        - cmd
        - timeout
    output:
        stdout: <% $.stdout %>
    tasks:
        task1:
            action: core.local cmd=<% $.cmd %> timeout=<% $.timeout %>
            publish:
                result1: '<% task(task1).result.stdout %>'
                stdout: <% task(task1).result.stdout %>
                stderr: <% task(task1).result.stderr %>
            on-success:
                - task2
            on-error:
                - task4
        task2:
            action: core.local cmd='llll'
            publish:
                stdout: <% task(task2).result.stdout %>
                stderr: <% task(task2).result.stderr %>
            on-success:
                - task3
            on-error:
                - task4
        task3:
            action: core.local cmd='echo task3'
            publish:
                stdout: <% task(task3).result.stdout %>
                stderr: <% task(task3).result.stderr %>
            on-error:
                - task4
        task4:
            action: core.local cmd='echo task4'
            publish:
                stdout: <% task(task4).result.stdout %>
                stderr: <% task(task4).result.stderr %>

将multi_task_mistral.yaml
放在/opt/stackstorm/packs/default/actions/workflows目录下

7.3 编写mistral中的action的元数据文件


文件名为: count_sensor_action_meta.yaml
内容如下:

name: "count_action"
description: "count action description"
runner_type: "python-script"
enabled: true
entry_point: "count_sensor_action.py"
parameters:
    content:
        type: "string"
        description: "the content parameter"
        required: true
        position: 0

将count_sensor_action_meta.yaml
放在/opt/stackstorm/packs/default/actions目录下

7.4 编写mistral中的action的脚本文件


文件名为: count_sensor_action.py
内容如下:

from datetime import datetime

from st2common.runners.base_action import Action

class CountAction(Action):

    # append content into file
    def run(self, content):
        fileName = "/home/count.txt"
        try:
            currTime = str(datetime.now())
            # note, a+ means append instead of w+
            with open(fileName, "a+") as fr:
                realContent = str(content) + " time: " + currTime + "\n"
                fr.write(realContent)
            info = "content: {content}, time: {time}".format(
                content=content,
                time=currTime
            )
            print info
            return (True, content)
        except Exception as ex:
            info = "write content : {content}, exception: {exp}, message: {mes}".format(
                content=content,
                exp=ex.__class__.__name__,
                mes=ex
            )
            print info
            return (False, content)

将count_sensor_action.py放在
/opt/stackstorm/packs/default/actions目录下

7.5 注册mistral和action


7.5.1 先注册action


即执行如下命令:
st2 action create /opt/stackstorm/packs/default/actions/count_sensor_action_meta.yaml

7.5.2 再注册mistral


st2 action create /opt/stackstorm/packs/default/actions/multi_task_mistral_meta.yaml


8 总结


1) stackstorm完整的数据处理过程是:
sensors->triggers->rules->mistrals/actions
2) 编写一个复杂sensor的调试过程如下:
先跑通action/mistral(可以单独执行action或mistral)
然后跑通rule
然后跑通sensor,通过添加日志方式查看信息
最后打通sensor和rule

参考:
[1] https://docs.stackstorm.com/sensors.html
[2] https://docs.stackstorm.com/2.8/reference/packs.html

你可能感兴趣的:(stackstorm)