传感器是一种集成外部系统和StackStorm事件的方式。传感器是由Python代码组成,
可以周期性轮询一些外部系统,或者被动等待到达的事件。它们使用StackStorm中的触发器,
这样可以被规则所匹配,可以用于潜在的动作执行。
Sensores是用Python写的,并且必须遵守StackStorm定义的传感器接口要求。
Triggers是StackStorm构建的,可以识别即将发送给StackStorm的事件。
一个trigger是一个元组类型和可选的参数(对象)。规则是用于和triggers一起工作。
Sensors注册trigger,尽管着不是强烈需要的。例如,
又一个通用的webhooks触发器被注册到了StackStorm,这不需要一个定制化的传感器。
StackStorm默认实现了一些内部的触发器,你可以应用到规则中。可以很好地区分系统触发器
和非系统触发器,系统触发器都有前缀st2.
每个资源的触发器列表如下:
Action
Reference Description Properties
st2.generic.actiontrigger Trigger encapsulating the completion of an action execution. status, start_timestamp, result, parameters, action_ref, runner_ref, execution_id, action_name
st2.generic.notifytrigger Notification trigger. status, data, start_timestamp, channel, route, action_ref, message, runner_ref, execution_id, end_timestamp
st2.action.file_writen Trigger encapsulating action file being written on disk. host_info, ref, file_path
st2.generic.inquiry Trigger indicating a new “inquiry” has entered “pending” status route, id
键值对
Reference Description Properties
st2.key_value_pair.create Trigger encapsulating datastore item creation. object
st2.key_value_pair.update Trigger encapsulating datastore set action. object
st2.key_value_pair.value_change Trigger encapsulating a change of datastore item value. new_object, old_object
st2.key_value_pair.delete Trigger encapsulating datastore item deletion. object
Sensor
Reference Description Properties
st2.sensor.process_spawn Trigger indicating sensor process is started up. object
st2.sensor.process_exit Trigger indicating sensor process is stopped. object
创建一个传感器包含编写的Python文件和一个定义传感器地YAML元数据文件。
这是metadata文件:
---
class_name: "SampleSensor"
entry_point: "sample_sensor.py"
description: "Sample sensor that emits triggers."
trigger_types:
-
name: "event"
description: "An example trigger."
payload_schema:
type: "object"
properties:
executed_at:
type: "string"
format: "date-time"
default: "2014-07-30 05:04:24.578325"
下面是对应的Python文件结构
from st2reactor.sensor.base import Sensor
class SampleSensor(Sensor):
"""
* self.sensor_service
- provides utilities like
- get_logger() - returns logger instance specific to this sensor.
- dispatch() for dispatching triggers into the system.
* self._config
- contains parsed configuration that was specified as
config.yaml in the pack.
"""
def setup(self):
# Setup stuff goes here. For example, you might establish connections
# to external system once and reuse it. This is called only once by the system.
pass
def run(self):
# This is where the crux of the sensor work goes.
# This is called once by the system.
# (If you want to sleep for regular intervals and keep
# interacting with your external system, you'd inherit from PollingSensor.)
# For example, let's consider a simple flask app. You'd run the flask app here.
# You can dispatch triggers using sensor_service like so:
# self.sensor_service(trigger, payload, trace_tag)
# # You can refer to the trigger as dict
# # { "name": ${trigger_name}, "pack": ${trigger_pack} }
# # or just simply by reference as string.
# # i.e. dispatch(${trigger_pack}.${trigger_name}, payload)
# # E.g.: dispatch('examples.foo_sensor', {'k1': 'stuff', 'k2': 'foo'})
# # trace_tag is a tag you would like to associate with the dispatched TriggerInstance
# # Typically the trace_tag is unique and a reference to an external event.
pass
def cleanup(self):
# This is called when the st2 system goes down. You can perform cleanup operations like
# closing the connections to external system here.
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
这是一个最小化版本的sensor的样子。对于更份额杂的sensor的实现以及诸如trigger到系统中,
请看例子。
你的传感器应该以Python字典的格式生成triggers:
trigger = 'pack.name'
payload = {
'executed_at': '2014-08-01T00:00:00.000000Z'
}
trace_tag = external_event_id
传感器通过使用sensor_service来注入这些triggers
self.sensor_service.dispatch(trigger=trigger, payload=payload, trace_tag=trace_tag)
如果你想要一个传感器周期性轮询一个外部系统,你可以使用一个PollingSensor而不是Sensor作为基类。
from st2reactor.sensor.base import PollingSensor
class SamplePollingSensor(PollingSensor):
"""
* self.sensor_service
- provides utilities like
get_logger() for writing to logs.
dispatch() for dispatching triggers into the system.
* self._config
- contains configuration that was specified as
config.yaml in the pack.
* self._poll_interval
- indicates the interval between two successive poll() calls.
"""
def setup(self):
# Setup stuff goes here. For example, you might establish connections
# to external system once and reuse it. This is called only once by the system.
pass
def poll(self):
# This is where the crux of the sensor work goes.
# This is called every self._poll_interval.
# For example, let's assume you want to query ec2 and get
# health information about your instances:
# some_data = aws_client.get('')
# payload = self._to_payload(some_data)
# # _to_triggers is something you'd write to convert the data format you have
# # into a standard python dictionary. This should follow the payload schema
# # registered for the trigger.
# self.sensor_service.dispatch(trigger, payload)
# # You can refer to the trigger as dict
# # { "name": ${trigger_name}, "pack": ${trigger_pack} }
# # or just simply by reference as string.
# # i.e. dispatch(${trigger_pack}.${trigger_name}, payload)
# # E.g.: dispatch('examples.foo_sensor', {'k1': 'stuff', 'k2': 'foo'})
# # trace_tag is a tag you would like to associate with the dispatched TriggerInstance
# # Typically the trace_tag is unique and a reference to an external event.
pass
def cleanup(self):
# This is called when the st2 system goes down. You can perform cleanup operations like
# closing the connections to external system here.
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
轮询传感器需要一个poll_interval参数在元数据文件中。这个定义了每隔多场时间
poll()方法会被调用。
每隔传感器以一个单独的进程运行。
st2sensorcontainer启动sensor_wrapper.py
在st2reactor.container.sensor_wrapper.SensorWrapper中
包裹你的传感器类(
例如SampleSensor或者上述的SamplePollingSensor)
正如你在上述例子中看到的,一个sensore_service
在被实例化的时候被传入到每个sensor类构造器中。
传感器服务通过public方法向sensor提供了不同的服务。
所有的public方法如下所示:
1). dispatch(trigger, payload, trace_tag)
允许传感器注入触发器到系统中,例如:
trigger = 'pack.name'
payload = {
'executed_at': '2014-08-01T00:00:00.000000Z'
}
trace_tag = uuid.uuid4().hex
self.sensor_service.dispatch(trigger=trigger, payload=payload, trace_tag=trace_tag)
2) get_logger(name)
这个方法允许传感器实例查询这个传感器的日志实例
例如:
self._logger = self.sensor_service.get_logger(name=self.__class__.__name__)
self._logger.debug('Polling 3rd party system for information')
......
一旦你编写了自己的茶unganqi,下面的步骤可以被用于运行你的传感器
1) 将传感器的Python文件和YAML元数据文件放到default的pack的目录:
/opt/stackstorm/packs/default/sensors/
目录下。或者你可以在/opt/stackstorm/packs/下自己创建一个pack,
该pack需要有正确的包结构。
2)通过st2ctl注册传感器
st2ctl reload --register-all
如果出现出错,修复错误并重新注册。
3)如果注册成功,传感器将会自动运行。
一旦你喜欢上你的传感器,你可以提升它为一个pack,通过创建一个pack到
/opt/stackstorm/packs/${pack_name}并移动传感器的YAML和Python文件到
/opt/stackstorm/packs/${pack_name}/sensors/。
下面的例子是一个简单传感器,每隔10秒注册了一个传感器。
Metadata:
---
class_name: "HelloSensor"
entry_point: "sensor1.py"
description: "Test sensor that emits triggers."
trigger_types:
-
name: "event1"
description: "An example trigger."
payload_schema:
type: "object"
Python代码:
import eventlet
from st2reactor.sensor.base import Sensor
class HelloSensor(Sensor):
def __init__(self, sensor_service, config):
super(HelloSensor, self).__init__(sensor_service=sensor_service, config=config)
self._logger = self.sensor_service.get_logger(name=self.__class__.__name__)
self._stop = False
def setup(self):
pass
def run(self):
while not self._stop:
self._logger.debug('HelloSensor dispatching trigger...')
count = self.sensor_service.get_value('hello_st2.count') or 0
payload = {'greeting': 'Yo, StackStorm!', 'count': int(count) + 1}
self.sensor_service.dispatch(trigger='hello_st2.event1', payload=payload)
self.sensor_service.set_value('hello_st2.count', payload['count'])
eventlet.sleep(60)
def cleanup(self):
self._stop = True
# Methods required for programmable sensors.
def add_trigger(self, trigger):
pass
def update_trigger(self, trigger):
pass
def remove_trigger(self, trigger):
pass
如果你想要从一个pack中单独运行一个sensor,并且这个传感器已经注册了,
你可以使用st2sensorcontainer来运行这个单独的single sensor:
/opt/stackstorm/st2/bin/st2sensorcontainer --config-file=/etc/st2/st2.conf --sensor-ref=pack.SensorClassName
例如:
/opt/stackstorm/st2/bin/st2sensorcontainer --config-file=/etc/st2/st2.conf --sensor-ref=git.GitCommitSensor
以上内容翻译自:
https://docs.stackstorm.com/sensors.html