snap telemetry

Snap Telemetry

简介:

Snap是一个开放式遥测框架,旨在通过单一API简化系统数据的收集,处理和发布。该项目的目标是:

 使系统能够公开一组一致的遥测数据

 简化无处不在的存储系统中的遥测数据抽取

 允许灵活处理代理上的遥测数据(例如过滤和装饰)

 为小型或大型集群提供强大的遥测工作流集群控制

1 概览

Snap遥测框架是一个由多个部分组成的项目:

• 经过强化,经过广泛测试的守护进程snapteld和CLI,snaptel(在此repo中)

• 越来越多的成熟plugins(在插件目录中找到)

• 很多tasks收集和发布指标的示例(可在Examples文件夹中找到)


Snap架构的主要特点:

1、  插件架构,可根据需求灵活扩展,可以自己研发、或将现有插件集成到snap。如上图所示,snap的按照流程分为三个主要部分:采集、处理、发布。这三个部分都是采用插件的形式存在,collect有collect插件、proccess有process的插件、publish有publish的插件,其中,collcet插件有可以分为两种:一种是普通的采集插件,这种就是按照特定的时间间隔进行采集;另一种可以理解是实时上报插件,采集完之后通过grpc通道实时上报到snap daemon。当我们新建一个plugin的时候,相当于新建了一个grpc server,调用关系如下:

startPlugin-->buildGRPCServer-->rpc.RegisterCollectorServer。snapteld与plugin通过gRPC通信,plugin是server,snapteld是client,snapteld向plugin发送请求并获取返回数据。plugin的代码里面实现了对应的server api。

2、  动态更新,插件架构能够为snap提供非常灵活的插件更新服务,snap daemon可以动态加载和卸载plugin,因此可以在服务不停止的情况下加载更新各种插件。

3、  Snap节点批量管理。可以按照特定的规则将多个snap节点组成一个群体,然后对这个群体进行管理(只需要操作一个节点),这个规则可以自己制定,比如可以按照下发的任务,ABC三个节点,A和B创建了cpu信息采集处理任务,C配置的是磁盘信息采集任务,那么AB分为一组,C是另一组,就可以对AB进行批量管理,当有新的节点D配置了cpu采集任务时,通过配置采集插件和导入采集任务时给定分组可以将D加入AB组,然后就可以对ABD批量管理了(A应该是可以加入其他组的,比如A和C都配置了采集网卡信息,那么他们就是一个组,批量操作只能针对这个分组策略,比如AC只能针对网卡信息采集处理操作,这个还没细看,待验证)。

2 运行任务

想要收集数据,首先需要通过加载一个Task Manifest的方式。Task Manifest包含了对一系列度量数据的收集间隔、数据的转换方式以及信息发布的位置的规范。

2.1 与task相关的各个命令行

3 Task Manifest

任务清单中描述了一个具体的任务,可以是Json或者YAML。任务清单被划分为两部分,头部与工作流。

3.1 头部

---

  version: 1

  schedule:

    type: "simple"

    interval: "1s"

  max-failures: 10

version:在这里代表的是清单解析器的版本,这里仅仅具备一个版本号:1.。

schedule:

schedule描述了运行任务的计划类型与时间间隔。在撰写文本时,Snap具备以下三种调度:

simple、windowed、cron与[streaming] (#streaming-schedule)。

Snap的设计方式可以轻松地放入自定义调度程序。如果使用自定义计划,则可能需要清单的计划部分中有更多的键/值对。

3.1.1 Simple schedule

参数:interval string类型,每个执行计划之间的间隔时间,必须要大于0.

count:unit 运行次数,默认为0,代表无限制。

例:永远运行的schedule

"version": 1,

  "schedule": {

  "type": "simple",

  "interval": "1s"

  },

  "max-failures": 10,

跑x次的schedule

"version": 1,

  "schedule": {

  "type": "simple",

  "interval": "1s",

  "count": 1

  },

  "max-failures": 1,

3.1.2 Windowed Schedule

Windowded schedule相对于simple schedule而言,加了一个起始和终止时间

"version": 1,

  "schedule": {

  "type": "windowed",

  "interval": "1s",

  "start_timestamp": "2016-10-27T16:00:00+01:00",

  "stop_timestamp": "2016-10-28T16:30:00+01:00"

      },

  "max-failures": 10,

会永远运行的schedule

"version": 1,

  "schedule": {

  "type": "windowed",

  "interval": "1s",

  "start_timestamp": "2016-10-27T16:00:00+01:00"

      },

  "max-failures": 10,

某个时刻停止

"version": 1,

  "schedule": {

  "type": "windowed",

  "interval": "1s",

  "stop_timestamp": "2016-10-28T16:30:00+01:00"

      },

  "max-failures": 10,

某个时刻开始跑n次

"version": 1,

  "schedule": {

  "type": "windowed",

  "interval": "1s",

  "start_timestamp": "2016-10-27T16:00:00+01:00",

  "count": 1

      },

  "max-failures": 1,

3.1.3 Cron Schedule

Cron Schedule是以Cron表达式类型来进行任务调度的,需要注意的是和Linux中的crontab略有不同:crontab的时程表如下:

f1 f2 f3 f4 f5 program  其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。

Snap中的cron的时程表如下:

秒 分 时 日 月


常用的时程表达式


"version": 1,

  "schedule": {

      "type": "cron",

      "interval" : "0 30 * * * *"

  },

  "max-failures": 10,

3.1.4 Streaming Schedule

---

  version: 1

  schedule:

type: "streaming"

不支持interval和count类型的字段

3.2 The Workflow

---

  collect:

    metrics:

      /intel/mock/foo: {}

      /intel/mock/bar: {}

      /intel/mock/*/baz: {}

    config:

      /intel/mock:

        user: "root"

        password: "secret"

    tags:

      /intel/mock:

        experiment: "experiment 11"

      /intel/mock/bar:

        os: "linux"

    process:

      -

        plugin_name: "passthru"

        publish:

          -

            plugin_name: "file"

            config:

              file: "/tmp/published"

Workflow是一个DAG,它描述了任务的方式和内容。它总是以collect为根,包含了任意数量的process es和publish es。

3.2.1 远程target

Snapteld和plugin是否可以跨节点部署?

Snapteld与plugin可以跨界点部署,snapteld与plugin通信有两个通道,一个是http服务端的的插件load管理通道,另外一个是grpc的数据通道

Plugin中的不同类型的组件是否可以跨节点部署?

工作流中的Process和Publish节点也可以通过“target”键定位远程Snap节点。这样做的目的是允许从正在进行数据收集的节点 卸载资源密集型的Workflow步骤。

分布式工作流具体采用了什么技术?

分布式工作流是一种工作流的类型,其中的一个或者多个步骤指定了远程target,即process和publish出可以指定远程ip和端口

修改上面的示例我们有

---

  collect:

    metrics:

      /intel/mock/foo: {}

      /intel/mock/bar: {}

      /intel/mock/*/baz: {}

    config:

      /intel/mock:

        user: "root"

        password: "secret"

    tags:

      /intel/mock:

        experiment: "experiment 11"

      /intel/mock/bar:

        os: "linux"

    process:

      -

        plugin_name: "passthru"

        target: "127.0.0.1:8082"

        publish:

          -

            plugin_name: "file"

            target: "127.0.0.1:8082"

            config:

              file: "/tmp/published"

如果为工作流中的步骤指定了目标,则该步骤将在ip:port target指定的远程实例上执行。工作流中的每个节点都是独立评估的,因此工作流可以远程完成任何,全部或全部步骤(如果target省略了键,则该步骤默认为本地)

3.2.2 Collect

Collect部分描述了由命名空间指示的请求度量标准。

命名空间的元素由命名空间分隔符分隔,命名空间分隔符可以在任务清单中设置为不同的字符,并具有区分任务清单格式的一些限制。命名空间中的第一个字符定义命名空间分隔符。

3.2.3 具体的命名空间

完全按照度量目录中显示的方式声明度量标准名称(请参阅参考资料snaptel metric list)。

Task Manifest中要请求的度量指标 实际的收集指标

intel/mock/foo /intel/mock/foo

/intel/mock/bar /intel/mock/bar

/intel/mock/*/baz

(dynamic metric) /intel/mock/host0/baz

/intel/mock/host1/baz

/intel/mock/host2/baz

/intel/mock/host3/baz

/intel/mock/host4/baz

/intel/mock/host5/baz

/intel/mock/host6/baz

/intel/mock/host7/baz

/intel/mock/host8/baz

/intel/mock/host9/baz

(collect metrics for all instances of the dynamic metric)

3.2.4 动态度量指标的指定实例

指定动态度量指标指的是value在命名空间中提供代替动态元素(例如,hostname,cgroup id等)。重要的是要记住,当在度量目录中显示时,动态元素由星号表示。当任务清单包含动态度量的特定实例时,仅收集该实例。如果该值不存在,则任务将出错。

任务清单中请求的度量标准 收集的指标

/ intel / mock / host0 / baz

(“/ intel / mock / * / baz”的具体实例) / intel / mock / host0 / baz

(只收集这一个指标)

3.2.5 动态查询

*表示完全匹配,:表示and。

/intel/mock/(foo;bar) /intel/mock/foo

/intel/mock/bar

/intel/mock/(host0;host1;host2)/baz /intel/mock/host0/baz

/intel/mock/host1/baz

/intel/mock/host2/baz

命名空间是另一个嵌套对象的键,它可能包含特定版本的插件,例如:

---

/foo/bar/baz:

  version: 4

如果没有诶出具体的版本号,snap会自动选择一个最近的版本号

什么是load

3.2.6 Tag

Tag描述了度量指标其他的元数据。和config类似,tag也可以直接在命名空间的分支处描述,分支下所有的子节点都会接受到给出的标签。

---

metrics:

  /intel/perf/foo: {}

  /intel/perf/bar: {}

  /intel/perf/baz: {}

tags:

  /intel/perf:

    experiment: "experiment 11"

  /intel/perf/bar:

    os: "linux"

4 其余的Snap示例

4.1 配置文件

snapteld.conf,默认全局配置文件易于自定义(取消注释所需参数并调整其值)

snap-config-sample.yaml,YAML格式的全局配置文件示例

snap-config-sample.json,JSON格式的全局配置文件示例

snaptel-config-sample.json,snaptel配置文件。请注意,不建议使用它。

5 Snap应用的简易安装流程

5.1 系统要求

Linux、amd64/ OS X

意味着GoLand只能用来查看代码,不能用来debug。另外要在Windows系统上使用make需要用到MINGW,并不太熟悉。

5.2 前置条件

Snap需要安装swagger for go 才能在成功构建后更新OpenAPI文件。

手动安装Swagger,go get 类似于git clone 和go

go get -u github.com/go-swagger/go-swagger/cmd/swagger

5.3 安装

在RedHat中直接进行安装:

$ curl -s https://packagecloud.io/install/repositories/intelsdi-x/snap/script.rpm.sh | sudo bash

$ sudo yum install -y snap-telemetry

5.4 运行Snap

service snap-telemetry start

systemctl start snap-telemetry

如果您从二进制文件安装Snap,则可以通过以下命令启动Snap守护程序:

$ sudo mkdir -p /var/log/snap

$ sudo snapteld --plugin-trust 0 --log-level 1 --log-path /var/log/snap &

要查看服务日志:

$ tail -f /var/log/snap/snapteld.log

5.5 加载插件

Snap通过使用插件获得力量。该插件目录中包含了所有已知的捕捉插件与链接到他们的回购和释放网页的集合。

首先,让我们下载文件和psutil插件(同时确保安装了psutil):

$ export OS=$(uname -s | tr '[:upper:]' '[:lower:]')

$ export ARCH=$(uname -m)

$ curl -sfL "https://github.com/intelsdi-x/snap-plugin-publisher-file/releases/download/2/snap-plugin-publisher-file_${OS}_${ARCH}" -o snap-plugin-publisher-file

$ curl -sfL "https://github.com/intelsdi-x/snap-plugin-collector-psutil/releases/download/8/snap-plugin-collector-psutil_${OS}_${ARCH}" -o snap-plugin-collector-psutil

接下来使用snaptel以下命令将插件加载到Snap守护程序中:

$ snaptel plugin load snap-plugin-publisher-file

Plugin loaded

Name: file

Version: 2

Type: publisher

Signed: false

Loaded Time: Fri, 14 Oct 2016 10:53:59 PDT

$ snaptel plugin load snap-plugin-collector-psutil

Plugin loaded

Name: psutil

Version: 8

Type: collector

Signed: false

Loaded Time: Fri, 14 Oct 2016 10:54:07 PDT

验证插件是否已加载:

$ snaptel plugin list

NAME      VERSION    TYPE        SIGNED    STATUS    LOADED TIME

file      2          publisher    false      loaded    Fri, 14 Oct 2016 10:55:20 PDT

psutil    8          collector    false      loaded    Fri, 14 Oct 2016 10:55:29 PDT

查看可用的指标:

$ snaptel metric list

NAMESPACE                                VERSIONS

/intel/psutil/cpu/cpu-total/guest        8

/intel/psutil/cpu/cpu-total/guest_nice  8

/intel/psutil/cpu/cpu-total/idle        8

/intel/psutil/cpu/cpu-total/iowait      8

/intel/psutil/cpu/cpu-total/irq          8

/intel/psutil/cpu/cpu-total/nice        8

/intel/psutil/cpu/cpu-total/softirq      8

/intel/psutil/cpu/cpu-total/steal        8

/intel/psutil/cpu/cpu-total/stolen      8

/intel/psutil/cpu/cpu-total/system      8

/intel/psutil/cpu/cpu-total/user        8

/intel/psutil/load/load1                8

/intel/psutil/load/load15                8

/intel/psutil/load/load5                8

...

5.6 运行任务

运行任务

要收集数据,您需要通过加载a来创建任务Task Manifest。任务清单包含一组规范的收集规范,数据转换方式以及信息发布的位置。有关更多信息,请参阅任务文档

现在,下载并加载psutil示例:

$ curl https://raw.githubusercontent.com/intelsdi-x/snap/master/examples/tasks/psutil-file.yaml -o /tmp/psutil-file.yaml

$ snaptel task create -t /tmp/psutil-file.yaml

Using task manifest to create task

Task created

ID: 8b9babad-b3bc-4a16-9e06-1f35664a7679

Name: Task-8b9babad-b3bc-4a16-9e06-1f35664a7679

State: Running

注意:在后续命令中,使用CLI输出中的任务ID代替<task_id>。

这将启动通过psutil收集度量标准的任务,然后将数据发布到文件。要查看发布到文件的数据(要退出CTRL + C):

$ tail -f /tmp/psutil_metrics.log

或者直接使用Snap收集的数据流snaptel task watch <task_id>:

$ snaptel task watch 8b9babad-b3bc-4a16-9e06-1f35664a7679

NAMESPACE                            DATA            TIMESTAMP

/intel/psutil/cpu/cpu-total/idle      451176.5        2016-10-14 11:01:44.666137773 -0700 PDT

/intel/psutil/cpu/cpu-total/system    33749.2734375    2016-10-14 11:01:44.666139698 -0700 PDT

/intel/psutil/cpu/cpu-total/user      65653.2578125    2016-10-14 11:01:44.666145594 -0700 PDT

/intel/psutil/load/load1              1.81            2016-10-14 11:01:44.666072208 -0700 PDT

/intel/psutil/load/load15            2.62            2016-10-14 11:01:44.666074302 -0700 PDT

/intel/psutil/load/load5              2.38            2016-10-14 11:01:44.666074098 -0700 PDT

干得好 - 你完成了这个例子。根据您之前开始snap-telemetry服务的方式,使用适当的命令停止守护程序:

init.d服务: service snap-telemetry stop

系统服务: systemctl stop snap-telemetry

snapteld手动运行:sudo pkill snapteld

当您准备好继续前进时,请浏览Examples文件夹中可用的Snap的其他用法。

6 简要分析

6.1 Processor之filter

Filter是根据在Manifest里面的标签和过滤规则来过滤的。

假设过滤规则是这样的:

{

  "version": 1,

  "schedule": {

    "type": "simple",

    "interval": "1s"

  },

  "max-failures": 1,

  "workflow": {

    "collect": {

      "tags": {

        "/intel/psutil/cpu/cpu-total/idle": {

          "other": "otherval",

          "foo": "fooval"

        },

        "/intel/psutil/cpu/cpu-total/iowait": {

          "baz": "bazval"

        },

        "/intel/psutil/cpu/cpu-total/stolen": {

          "bar": "barval",

          "foo": "valfoo",

          "baz": "otherval"

        },

        "/intel/psutil/cpu/cpu-total/system": {

          "bar": "barval",

          "foo": "foovalue"

        }

      },

      "metrics": {

        "/intel/psutil/cpu/cpu-total/idle": {},

        "/intel/psutil/cpu/cpu-total/iowait": {},

        "/intel/psutil/cpu/cpu-total/stolen": {},

        "/intel/psutil/cpu/cpu-total/system": {}

      },

      "process": [

        {

          "plugin_name": "tags-filter",

          "config": {

            "foo.allow": "foovalue,fooval",

            "baz.allow": "bazval",

            "bar.deny": "barval"

          },

          "publish": [

            {

              "plugin_name": "file",

              "config": {

                "file": "/tmp/psutil-tags-filter-file.log"

              }

            }

          ]

        }

      ]

    }

  }

}

由"bar.deny": "barval"可知,带着barval类型的标签最后不会出现在我们的publisher中,结合来看,即我们的publishers中不会出现"/intel/psutil/cpu/cpu-total/idle": {},    "/intel/psutil/cpu/cpu-total/iowait": {},这两项metric,到file publisher中查看处理过后的数据:

[{

"timestamp": "2019-05-16T14:16:33.475892533+08:00",

"namespace": "/intel/psutil/cpu/cpu-total/idle",

"data": 1.0197728507e+08,

"unit": "",

"tags": {

"foo": "fooval",

"other": "otherval",

"plugin_running_on": "compute"

},

"version": 0,

"last_advertised_time": "2019-05-16T14:16:33.479258438+08:00"

},

{

"timestamp": "2019-05-16T14:16:33.475894903+08:00",

"namespace": "/intel/psutil/cpu/cpu-total/iowait",

"data": 9050.86,

"unit": "",

"tags": {

"baz": "bazval",

"plugin_running_on": "compute"

},

"version": 0,

"last_advertised_time": "2019-05-16T14:16:33.479258994+08:00"

}]

Tags-filter.go 中返回了

rules[tag].allowedValues = values以及rules[tag].deniedValues = values

metric数组某一个元素是否添加到数组,只要判断某一项指标打上的某一类型的具体标签是否在allow数组中且不在deny数组中

6.2 processor-tag

tag插件的目的在于处理数据,并将数据打上标签。

注意:可以在task manifest中来直接打上标签 (即不需要使用tag插件),并且不是每一个snap publisher的插件都支持tagging(打标签)。

6.3 Add context

Change-detector里面,有一点点获取到上下文的意思。

Change detector该插件的目的是检测现在和前一时刻度量值的变化。度量的当前值被设置为度量的数据,度量的先前值被保留在度量的tag中。

该插件通过以下参数进行配置:

Rules –正则表达式。多个正则表达式用|来分割

正则表达式的特殊字符需要进行转义

6.4 Logs-regexp

使用正则表达式来处理日志

以前也使用过对应的插件,在logstash中也存在grok插件,logstash在获取日志是整个一串获取,如果把日志中每个字段代表的意思分割开来在传给elasticsearch。这样呈现出来的数据更加清晰,而且也能让kibana更方便的绘制图形。

filter {

  if [type] == "apache" {

    grok {

      match => ["message" => "%{IPORHOST:addre} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] \"%{WORD:http_method} %{NOTSPACE:request} HTTP/%{NUMBER:httpversion}\" %{NUMBER:status} (?:%{NUMBER:bytes}|-) \"(?:%{URI:http_referer}|-)\" \"%{GREEDYDATA:User_Agent}\""]

      remove_field => ["message"]

    }

    date {

      match => [ "timestamp", "dd/MMM/YYYY:HH:mm:ss Z" ]

    }

  }

}

%是grok pattern内置的正则表达式,:后面跟的是变量名,该变量名可以直接传到es在es中显示,插件解析后会直接返回json数据。


{

  "addre": [

    [

      "192.168.10.97"

    ]

  ],

  "HOSTNAME": [

    [

      "192.168.10.97",

      "192.168.10.175"

    ]

...........中间省略多行...........

  "http_referer": [

    [

      "http://192.168.10.175/"

    ]

  ],

7 插件开发

https://github.com/intelsdi-x/snap-plugin-lib-go

Snap架构的主要特点:

1、  插件架构,可根据需求灵活扩展,可以自己研发、或将现有插件集成到snap。如上图所示,snap的按照流程分为三个主要部分:采集、处理、发布。这三个部分都是采用插件的形式存在,collect有collect插件、proccess有process的插件、publish有publish的插件,其中,collcet插件有可以分为两种:一种是普通的采集插件,这种就是按照特定的时间间隔进行采集;另一种可以理解是实时上报插件,采集完之后通过grpc通道实时上报到snap daemon。

2、  动态更新,插件架构能够为snap提供非常灵活的插件更新服务,snap daemon可以动态加载和卸载plugin,因此可以在服务不停止的情况下加载更新各种插件。

3、  Snap节点批量管理。可以按照特定的规则将多个snap节点组成一个群体,然后对这个群体进行管理(只需要操作一个节点),这个规则可以自己制定,比如可以按照下发的任务,ABC三个节点,A和B创建了cpu信息采集处理任务,C配置的是磁盘信息采集任务,那么AB分为一组,C是另一组,就可以对AB进行批量管理,当有新的节点D配置了cpu采集任务时,通过配置采集插件和导入采集任务时给定分组可以将D加入AB组,然后就可以对ABD批量管理了(A应该是可以加入其他组的,比如A和C都配置了采集网卡信息,那么他们就是一个组,批量操作只能针对这个分组策略,比如AC只能针对网卡信息采集处理操作,这个还没细看,待验证)。

当我们新建一个plugin的时候,相当于新建了一个grpc server,调用关系如下:

startPlugin-->buildGRPCServer-->rpc.RegisterCollectorServer

8 与logstash的区别

Logstash的配置文件如下:

input {

lumberjack {

port => 5043

type => "logs"

ssl_certificate => "/etc/pki/tls/certs/logstash-forwarder.crt"

ssl_key => "/etc/pki/tls/private/logstash-forwarder.key"

}

}

filter {

grok {

match => { "message" => "%{COMBINEDAPACHELOG}" }

}

date {

match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]

}

}

output {

elasticsearch { hosts => ["localhost:9200"] }

stdout { codec => rubydebug }

}


9 整体通信

在snap-plugin-lib-go库中,有相关的介绍

Brief Overview of Snap Architecture:

Snap is an open and modular telemetry framework designed to simplify the collection, processing and publishing of data through a single HTTP based API. Plugins provide the functionality of collection, processing and publishing and can be loaded/unloaded, upgraded and swapped without requiring a restart of the Snap daemon.

A Snap plugin is a program that responds to a set of well defined gRPC services with parameters and return types specified as protocol buffer messages (see plugin.proto). The Snap daemon handshakes with the plugin over stdout and then communicates over gRPC.

Snap是一个开放的模块化遥测框架,旨在通过单个基于HTTP的API简化数据的收集,处理和发布。 插件提供收集,处理和发布的功能,可以加载/卸载,升级和交换,而无需重新启动Snap守护程序。

Snap插件是一个响应一组定义良好的gRPC服务的程序,其参数和返回类型被指定为pb message类型(请参阅plugin.proto)。 Snap守护进程与stdout上的插件握手,然后通过gRPC进行通信。

10 Shell脚本

以anomalydetection检测的脚本为例:

deps.sh的内容如下:

#只要返回值非0则停止执行

set –e

#遇到不存在的变量会报错并且停止执行

set -u

#因为set –e 不适用于管道命令。在管道情况下,Bash默认会把最后一个子命令的返回值作为这整个命令集合的返回值。Set –o就是为了确保只要有一个子命令不生效,那么就报错并且停止执行。

set -o pipefail

#返回当前路径

__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

__proj_dir="$(dirname "$__dir")"#返回工程路径

# shellcheck source=scripts/common.sh

. "${__dir}/common.sh"

detect_go_dep() {

#判断对应的文件是否存在

#&&表示只有左边的成功执行之后,才执行右边的命令、

  [[ -f "${__proj_dir}/Godeps/Godeps.json" ]] && _dep='godep'

  [[ -f "${__proj_dir}/glide.yaml" ]] && _dep='glide'

  [[ -f "${__proj_dir}/vendor/vendor.json" ]] && _dep='govendor'

  _info "golang dependency tool: ${_dep}"

  echo "${_dep}"

}

install_go_dep() {

  local _dep=${_dep:=$(_detect_dep)}

  _info "ensuring ${_dep} is available"

  case $_dep in

    godep)

      _go_get github.com/tools/godep

      ;;

    glide)

      _go_get github.com/Masterminds/glide

      ;;

    govendor)

      _go_get github.com/kardianos/govendor

      ;;

  esac

}

restore_go_dep() {

  local _dep=${_dep:=$(_detect_dep)}

  _info "restoring dependency with ${_dep}"

  case $_dep in

    godep)

      (cd "${__proj_dir}" && godep restore)

      ;;

    glide)

      (cd "${__proj_dir}" && glide install)

      ;;

    govendor)

      (cd "${__proj_dir}" && govendor sync)

      ;;

  esac

}

_dep=$(detect_go_dep)

install_go_dep

restore_go_dep

11 异常检测

11.1 Tukey filter

什么是上四分位数/值,

第一四分位数( {\displaystyle Q_{1}} Q_{1}),又称较小四分位数,等于该样本中所有数值由小到大排列后第25%的数字。上四分位数。

第二四分位数( {\displaystyle Q_{2}} Q_{2}),又称中位数,等于该样本中所有数值由小到大排列后第50%的数字。

第三四分位数( {\displaystyle Q_{3}} Q_{3}),又称较大四分位数,等于该样本中所有数值由小到大排列后第75%的数字。下四分位数

第三四分位数与第一四分位数的差距又称四分位距(InterQuartile Range, IQR)。

关于四分位数值的选择尚存争议

主要选择四分位的百分比值  p,及样本总量  n有以下数学公式可以表示:

L=n*p/100

情况1:如果 L是一个整数,则取第 L和第L+1的平均值

情况2:如果 L不是一个整数,则取下一个最近的整数。(L=1.2则取2)


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容