# 定期巡检(扁鹊)

## 扁鹊（定期巡检功能）

* [1 项目概述](#1-项目概述)
  * [1.1 背景介绍及目标](#11-背景介绍及目标)
  * [1.2 名词说明](#12-名词说明)
  * [1.3 Roadmap](#13-roadmap)
* [2 需求分析](#2-需求分析)
  * [2.1 功能需求](#21-功能需求)
  * [2.2 非功能需求](#22-非功能需求)
  * [2.3 调研](#23-调研)
    * [2.3.1 zabbix](#231-zabbix)
    * [2.3.2 openstack ceilometer](#232-openstack-ceilometer)
    * [2.3.3 小型项目（星络）](#233-小型项目星络)
    * [2.3.4 shinken](#234-shinken)
    * [2.3.5 StackStorm](#235-stackstorm)
* [3 总体设计](#3-总体设计)
  * [3.1 系统架构](#31-系统架构)
  * [3.2 模块简介](#32-模块简介)
  * [3.3 设计与折衷](#33-设计与折衷)
    * [3.3.1 规则引擎](#331-规则引擎)
  * [3.4 潜在风险](#34-潜在风险)
* [4 详细设计](#4-详细设计)
  * [4.1 模块 xx](#41-模块-xx)
    * [4.1.1 交互流程](#411-交互流程)
    * [4.1.2 数据库设计](#412-数据库设计)
    * [4.1.3 接口形式](#413-接口形式)
* [5 传送门](#5-传送门)

## 1 项目概述

### 1.1 背景介绍及目标

* 对管理的服务进行定期巡检，早期发现隐患
* 巡检服务与监控服务很类似

目标

* 方便添加巡检项

### 1.2 名词说明

### 1.3 Roadmap

## 2 需求分析

> 需求分析重点是需求

### 2.1 功能需求

### 2.2 非功能需求

### 2.3 调研

#### 2.3.1 zabbix

> trigger

```
{<server>:<key>.<function>(<parameter>)}<operator><constant>


{www.zabbix.com:system.cpu.load[all,avg1].last(0) }> 5
它指定的服务器是'www.zabbix.com'，Items 是'system.cpu.load[all,avg1]'，使用函数'last()'
取最近一次获取到的值，'>5'表示来自 www.zabbix.com 主机最后负载值大于 5 时触发器进入异常状态
```

#### 2.3.2 openstack ceilometer

<https://github.com/openstack/ceilometer>

#### 2.3.3 小型项目（星络）

```
基于 socket 自己封装协议，详细可以看 x-luo（星络）
    +---------------------------+
    | +---------+               |
    | |my_sender|               | alarm
    | +---------+               |
    +------|--------------------+
    +------|--------------------+
    |   +------+     +-----+    |
    |   |filter|     |saver|    |
    |   +------+     +-----+    |
    |        \        /         |  server
    |         +-------+         |
    |         |trans  |         |
    |         +-------+         |
    +---------------------------+
            ^          ^
           /            \
          /              \
    +---------------------------+
    |   +------+     +------+   |
    |   |agent1|     |agent2|   |  agent
    |   +------+     +------+   |
    +---------------------------+
```

只能由 agent 往 trans 进行发送数据，当监控项需要变更时，需要在 agent 侧进行变更，即监控项的管理缺失

#### 2.3.4 shinken

#### 2.3.4.1 shinken 架构

```
组件间使用 http 协议


    +--------------------------------------------------------------+
    | +----------------------+   +-------------------------------+ |
    | |Reactionner(Satellite)|   |Broker                         | |
    | |* send notifications  |   |* manage broks                 | |
    | |                      |   |* send check results to backend| |
    | +----------------------+   +-------------------------------+ |         +---------+ * Load configuration
    |                      \           /                           |  server | Arbiter | * Dispath configuration
    |                   +------------------+                       |         +---------+
    |                   |Scheduler         |                       |
    |                   | * schedule checks|                       |
    |                   +------------------+                       |
    +--------------------------------------------------------------+
                            ^          ^
             Active check  /            \ passive check
                          V              \
    +-------------------------------------------------------------+
    |   +------------------------+    +------------------------+  |
    |   |Poller(Satellite)       |    |Receiver(Satellite)     |  |  agent
    |   |* execute check commands|    |* receive passive checks|  |
    |   +------------------------+    +------------------------+  |
    +-------------------------------------------------------------+
```

#### 2.3.4.2 shinken 组件

> * Arbiter（仲裁）: Arbiter 节点读取本地的配置，然后将配置切分之后分发到多个合适的 schedulers 节点。
> * Scheduler（调度）: scheduler 节点负责分别管理 poller 和 reactionner 节点的任务调度。
> * Poller（轮询）: poller 节点通过各类插件执行 scheduler 节点的任务，获取各种健康指标。
> * Reactionner（响应）: reactionner 节点的任务是一旦满足要求将触发 event\_handlers 机制（比如发送通知等）。
> * Broker（中间人）: broker 节点的任务真的是中间人——导出和管理 scheduler 节点中的数据。
> * Receiver （接收人）: 可选节点，在某些特定场景下可以通过 reciver 节点汇总数据（比如汇总私网内部数据，统一转发）

> 主动监控与被动监控（对象都指的服务端）

```
Active  check:（主动检查）
--- Scheduler 主动发起命令给 Poller，然后 Poller 回调 Scheduler 写入数据
--- shinken.daemons.pollerdaemon:Poller


Passive check:（被动检查）
--- Receiver 主动将数据上报到 Scheduler
--- shinken.daemons.receiverdaemon.py:Receiver

Reactionner: (动作)
--- shinken.daemons.receiverdaemon.py:reactionnerdaemon.py
```

> * 除了 Arbiter 节点之外，任何的节点都可以不是唯一的。节点之间的关系也都是多对多的。
> * 每一个节点都支持 / 依赖插件，或者说 Shinken 本身只是一个插件的框架而已。
> * 保障性能和可靠性——根据 CAP 法则，放弃了一致性。

#### 2.3.4.3 shinken 代码

> Satellite（shinken/satellite.py）--卫星

```
```

#### 2.3.5 StackStorm

![st2](https://github.com/meetbill/meetbill_static/blob/master/st2/st2_flow.png?raw=true)

> * 主要角色
>   * 传感器（Sensors）是用于分别接收或监视事件的入站或出站集成的 Python 插件。 当来自外部系统的事件发生并由传感器处理时，StackStorm 触发器将发射到系统中。
>   * 触发器（Triggers）是外部事件的 StackStorm 表示形式。 有通用触发器（例如定时器，webhooks）和集成触发器（例如，Sensu 告警，JIRA 问题更新）。 通过编写传感器插件可以定义新的触发器类型。
>   * 动作（Actions）是 StackStorm 出站集成。 有通用动作（ssh，REST 调用），集成（OpenStack，Docker，Puppet）或自定义操作。 动作是 Python 插件或任何脚本，通过添加几行元数据将其消耗到 StackStorm 中。 动作可以由用户通过 CLI 或 API 直接调用，或者作为规则和工作流程的一部分使用和调用。
>   * 规则（Rules）将触发器映射到动作（或工作流），应用匹配条件并将触发器加载到动作输入中。
>   * 工作流（Workflows）将动作拼接成“超级动作”，定义顺序，转换条件以及传递数据。 大多数自动化不止一步，因此需要多个动作。 工作流就像“原子”动作一样，可在 Action 库中使用，并且可以手动调用或由规则触发。
>   * 包 (Packs) 是内容部署的单位。 它们通过对集成（触发器和动作）和自动化（规则和工作流）进行分组，简化了 StackStorm 可插拔内容的管理和共享。 StackStorm Exchange 上有越来越多的包可用。 用户可以创建自己的包，在 Github 上共享它们，或者提交给 StackStorm Exchange.
>   * 审计跟踪（Audit Trail）记录并存储手动或自动操作执行的审计跟踪，并存储触发上下文和执行结果的全部细节。 它还被记录在审计日志中，用于集成外部日志记录和分析工具：LogStash，Splunk，statsd，syslog
> * 大概执行流程
>   * 从各个服务系统通过 push 或 pull 的方式把 event 传给 sensors， sensors 会产生一个 trigger
>   * 到规则配置中查询该 trigger 对应的动作或者工作流
>   * 将来自工作流的 Action 发送到消息队列（内置 rabbitmq）中
>   * Actions 到达外部的系统后就执行相应的动作
>   * 日志和审计历史被推送到数据库进行存储（Mongodb）
>   * 处理后的结果被发送回规则引擎进行进一步处理

## 3 总体设计

> 总体设计重点是设计与折衷

### 3.1 系统架构

> 一般来说会有个简单的架构图，并配以文字对架构进行简要说明；

### 3.2 模块简介

> 架构图中如果有很多模块，需要对各个模块的功能进行简要介绍；

### 3.3 设计与折衷

> 设计与折衷是总体设计中最重要的部分；

#### 3.3.1 规则引擎

<https://github.com/zeroSteiner/rule-engine>

> * 需要 Python3 支持

```
import rule_engine
# match a literal first name and applying a regex to the email
rule = rule_engine.Rule(
    'first_name == "Luke" and email =~ ".*@rebels.org$"'
) # => <Rule text='first_name == "Luke" and email =~ ".*@rebels.org$"' >
rule.matches({
    'first_name': 'Luke', 'last_name': 'Skywalker', 'email': 'luke@rebels.org'
}) # => True
rule.matches({
   'first_name': 'Darth', 'last_name': 'Vader', 'email': 'dvader@empire.net'
}) # => False
```

```
import rule_engine
# define the custom context with two symbols
context = rule_engine.Context(type_resolver=rule_engine.type_resolver_from_dict({
    'first_name': rule_engine.DataType.STRING,
    'age': rule_engine.DataType.FLOAT
}))

# receive an error when an unknown symbol is used
rule = rule_engine.Rule('last_name == "Vader"', context=context)
# => SymbolResolutionError: last_name

# receive an error when an invalid operation is used
rule = rule_engine.Rule('first_name + 1', context=context)
# => EvaluationError: data type mismatch
```

### 3.4 潜在风险

## 4 详细设计

> // 详细设计重点在“详细”

### 4.1 模块 xx

> （有了数据库 + 接口 + 流程，别的同学拿到详设文档，基本也能够搞定了）

#### 4.1.1 交互流程

> 简要的交互可用文字说明，复杂的交互建议使用流程图，交互图或其他图形进行说明

#### 4.1.2 数据库设计

#### 4.1.3 接口形式

## 5 传送门

> * [yzhao062/pyod](https://github.com/yzhao062/pyod) --- 异常检测算法库
> * [redis](https://github.com/meetbill/op_practice_book/blob/master/doc/db/redis.md)
> * graphite(Python)
> * [o/simmetrica](https://github.com/o/simmetrica)
> * [cloud-custodian/cloud-custodian](https://github.com/cloud-custodian/cloud-custodian) 适配了 AWS


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://meetbill.gitbook.io/butterfly-project-doc/project-handlers/chunfeng/butterfly-bianque.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
